# Tech Architecture Document ## Stack | Layer | Technology | Version / Notes | |---|---|---| | **Runtime** | Node.js | LTS ≥ 20 | | **Language** | TypeScript | Strict mode; compiled to ES2020+; output to `dist/` | | **Framework** | Express.js | v4 or v5 | | **Validation** | Inline guard functions (or lightweight library such as `zod`) | Applied in route handlers before touching the store | | **Testing** | Jest + `ts-jest` _or_ Vitest | Runnable via `npm test` | | **Linting** | ESLint (TypeScript-aware ruleset) | Runnable via `npm run lint` | | **Build tooling** | `tsc` (TypeScript compiler) | `tsconfig.json` with `strict: true` | | **Package manager** | npm | Standard `package.json` / `package-lock.json` | --- ## Components ```mermaid graph TD Client["HTTP Client\n(browser / CLI / app)"] subgraph "Express Application" Router["Express Router\n(routes/quotes.ts)"] HealthRoute["Health Route\nGET /health"] Validator["Input Validator\n(validation.ts)"] Store["Quote Store\n(store.ts)"] ErrorHandler["Global Error Handler\n(middleware/error.ts)"] end Client -- "HTTP request" --> Router Router --> HealthRoute Router --> Validator Validator -- "valid" --> Store Validator -- "invalid → 400" --> Client Store -- "quote data" --> Router Router -- "JSON response" --> Client ErrorHandler -- "500 response" --> Client ``` ### Component descriptions | Component | Responsibility | |---|---| | **`server.ts`** | Entry point. Creates the Express app, registers middleware (JSON body parser, routes, error handler), and starts the HTTP listener on `process.env.PORT \|\| 3000`. | | **`routes/quotes.ts`** | Defines all four REST routes (`GET /health`, `GET /quote`, `GET /quotes`, `POST /quotes`). Delegates to the validator and store; formats JSON responses. | | **`store.ts`** | In-memory quote repository. Exports `getAll()`, `getRandom()`, and `add(quote)`. Initialised at module load with five seed quotes. This is the unit-tested module. | | **`validation.ts`** | Pure functions that inspect request bodies and return either a typed `Quote` object or a descriptive error string. No side effects. | | **`middleware/error.ts`** | Express error-handling middleware (four-argument signature). Catches any unhandled error, logs it server-side, and returns `{ error: "Internal server error" }` with HTTP 500 — never leaking stack traces. | --- ## Data Model The single domain object used throughout the service: ``` Quote { text : string // non-empty; the body of the quote author : string // non-empty; attribution } ``` The in-memory store holds an array of `Quote` objects (`Quote[]`). There is no stable ID field in v1; if `DELETE`/`PUT` endpoints are added in a later phase an auto-incremented numeric index or UUID should be introduced. **Seed data** — five `Quote` objects are hard-coded in `store.ts` and loaded at process startup. No migration, seeding script, or external database is required. --- ## Integrations There are **no external integrations** in this version of the service. All data is held in process memory. | Integration point | Status | |---|---| | Database / cache | Out of scope (NFR-9) | | External quote APIs | Out of scope | | Authentication / identity provider | Out of scope (Assumption 3) | | Message broker / event bus | Out of scope | The `GET /health` endpoint is designed to integrate with load-balancer liveness probes and monitoring systems (e.g. AWS ALB health checks, Kubernetes liveness probes, UptimeRobot) without any additional configuration. --- ## Non-Functional Requirements (Architectural Implications) | Ref | Requirement | Architectural decision | |---|---|---| | NFR-1 | TypeScript strict mode, Node.js ≥ 20 | `tsconfig.json` with `"strict": true`, `"target": "ES2020"`; CI/CD should pin the Node version via `.nvmrc` or `engines` in `package.json`. | | NFR-2 | Express.js v4 or v5 | Single dependency; middleware chain provides natural extension points for future auth or rate-limit layers. | | NFR-3 | Input validation; 400 with `error` field | Validation extracted to `validation.ts` (pure, testable); route handlers call it before mutating the store. | | NFR-4 | `application/json` responses | `express.json()` middleware for request parsing; all route handlers call `res.json(...)`. | | NFR-5 | HTTP 500 without stack leaks | Centralised error-handling middleware catches everything; `console.error` on the server, sanitised body to the client. | | NFR-6 | Unit tests via `npm test` | `store.ts` and `validation.ts` are pure modules with no Express dependency — easy to unit-test in isolation. | | NFR-7 | `npm run lint` exits cleanly | ESLint configured with `@typescript-eslint` rules; no warnings allowed on the committed codebase. | | NFR-8 | Cold-start ≤ 3 s | In-memory store eliminates DB connection overhead; Express startup is sub-second on any modern hardware. | | NFR-9 | No persistence required | Intentional; simplifies the architecture and removes infrastructure dependencies for this phase. | --- ## Risks | # | Risk | Likelihood | Impact | Mitigation | |---|---|---|---|---| | R-1 | **Data loss on restart** | Certain (by design) | Low for this phase | Accepted per Assumption 1; documented clearly so consumers are not surprised. | | R-2 | **Memory growth under heavy `POST /quotes` load** | Low (dev/demo context) | Low | Array growth is unbounded; if the service is ever exposed publicly, add a maximum-store-size guard or migrate to a persistent store. | | R-3 | **No authentication — open write access** | Medium if publicly deployed | Medium | Acceptable for a development/demo service per Assumption 3; must be addressed before any production exposure. | | R-4 | **Single process — no fault isolation** | Low | Low | In-scope by design (Assumption 2); the global error handler prevents a single bad request from crashing the process. | | R-5 | **TypeScript / Express version drift** | Low | Low | Pin exact versions in `package.json`; run `npm audit` in CI. |