diff --git a/architecture/working-spec.md b/architecture/working-spec.md new file mode 100644 index 0000000..f346e25 --- /dev/null +++ b/architecture/working-spec.md @@ -0,0 +1,48 @@ +# Working Spec + +## Overview + +**SDLC QOTD — Quote of the Day API** is a small, self-contained REST API that serves inspirational quotes. The service is built with Node.js, Express, and TypeScript and uses an in-memory data store seeded with five starter quotes. It exposes endpoints to retrieve a random quote, list all quotes, and add new quotes, along with a health-check endpoint and a suite of unit tests covering the core quote store logic. + +## Actors + +| Actor | Description | +|---|---| +| **API Consumer** | Any HTTP client (browser, mobile app, CLI, or third-party service) that calls the REST endpoints to read or create quotes. | +| **Developer / Operator** | The engineer who deploys, monitors, and maintains the service; uses the `/health` endpoint for liveness checks. | + +## Functional Requirements + +1. **Random Quote** — `GET /quote` returns a single randomly selected quote as a JSON object with the shape `{ text: string, author: string }`. +2. **List All Quotes** — `GET /quotes` returns a JSON array of all quotes currently held in the in-memory store, each with the shape `{ text: string, author: string }`. +3. **Add a Quote** — `POST /quotes` accepts a JSON body `{ text: string, author: string }`, validates that both fields are present and non-empty strings, persists the new quote to the in-memory store, and returns the created quote (HTTP 201). Invalid payloads are rejected with HTTP 400 and a descriptive error message. +4. **Health Check** — `GET /health` returns HTTP 200 and a JSON body (e.g. `{ status: "ok" }`) so that load balancers and monitoring systems can verify liveness. +5. **Seed Data** — The in-memory store is pre-populated with exactly five inspirational quotes at application startup; no database migration or external seed script is required. +6. **Unit Tests** — The quote store module has dedicated unit tests covering: retrieving a random quote, listing all quotes, adding a valid quote, and rejecting an invalid quote. + +## Non-Functional Requirements + +| # | Category | Requirement | +|---|---|---| +| NFR-1 | **Language / Runtime** | TypeScript (strict mode) compiled to JavaScript; Node.js LTS (≥ 20). | +| NFR-2 | **Framework** | Express.js (v4 or v5). | +| NFR-3 | **Input Validation** | All user-supplied inputs validated before touching the store; 400 responses must include a human-readable `error` field. | +| NFR-4 | **Response Format** | All responses are `application/json`. | +| NFR-5 | **Error Handling** | Unhandled errors return HTTP 500 with `{ error: "Internal server error" }`; stack traces are never leaked to the client. | +| NFR-6 | **Test Coverage** | Unit tests cover the quote store module; a test runner (e.g. Jest or Vitest) must be runnable via `npm test`. | +| NFR-7 | **Code Quality** | ESLint (or equivalent) configured; `npm run lint` exits cleanly on the committed codebase. | +| NFR-8 | **Startup Time** | Cold-start to first successful `GET /health` response within 3 seconds on a standard developer machine. | +| NFR-9 | **Persistence** | No persistence beyond the current process lifetime is required; data resets on restart. | + +## Assumptions + +1. **In-memory only** — No database is required for the initial delivery; persistence across restarts is explicitly out of scope. +2. **Single-process** — The service runs as a single Node.js process; horizontal scaling and shared state are out of scope. +3. **No authentication** — All endpoints are unauthenticated and publicly accessible; auth/authorisation is out of scope. +4. **Quote uniqueness** — The API does not enforce uniqueness of quote text; duplicate entries are allowed. +5. **ID field** — Individual quotes do not require a stable unique ID in the v1 payload; if needed for future `DELETE`/`PUT` endpoints, an auto-incremented numeric or UUID field should be added at that time. +6. **Pagination** — `GET /quotes` returns the full list without pagination; the initial seed size is five quotes and growth is assumed to be small enough to avoid pagination for this phase. +7. **Port configuration** — The server listens on the port defined by the `PORT` environment variable, defaulting to `3000` if unset. +8. **TypeScript build** — A `tsconfig.json` targeting `ES2020` (or later) with `strict: true` is included in the repository; the compiled output goes to a `dist/` directory. +9. **Test framework** — Jest (with `ts-jest`) or Vitest is used for unit testing; the choice is left to the implementing developer. +10. **No rate limiting** — Rate limiting, throttling, and DDoS protection are out of scope for this phase.