From 168d88f3c73592d859895c985b2a03e6983b8c98 Mon Sep 17 00:00:00 2001 From: sdlcadmin Date: Mon, 20 Jul 2026 11:03:04 +0000 Subject: [PATCH] docs(architecture): sync working spec + TAD from AI-SDLC (Gate 2) --- architecture/tad.md | 110 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 architecture/tad.md diff --git a/architecture/tad.md b/architecture/tad.md new file mode 100644 index 0000000..5168408 --- /dev/null +++ b/architecture/tad.md @@ -0,0 +1,110 @@ +# 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. |