diff --git a/architecture/tad.md b/architecture/tad.md new file mode 100644 index 0000000..101994e --- /dev/null +++ b/architecture/tad.md @@ -0,0 +1,116 @@ +# Tech Architecture Document + +## Stack + +| Layer | Choice | Rationale | +|---|---|---| +| Language | TypeScript | Type safety for arithmetic logic; catches operand/type bugs at compile time. | +| UI Framework | React 18 (Vite) | Lightweight component model; Vite gives fast dev HMR and a zero-config static build output. | +| Styling | CSS Modules | Scoped styles, no runtime overhead, easy responsive layout. | +| Testing | Vitest + React Testing Library | Co-located with Vite; unit tests for arithmetic logic, component interaction tests for UI. | +| Build / Deploy | Vite `build` → static files | Produces a plain `dist/` folder deployable to any static host (Netlify, GitHub Pages, S3, etc.). | +| CI | GitHub Actions | Lint, type-check, test, and build on every push; deploy `dist/` on merge to `main`. | + +--- + +## Components + +```mermaid +graph TD + App["App (root)"] + Display["Display\n• shows current operand A, operator, operand B\n• shows result or error"] + OperandInput["OperandInput × 2\n• controlled numeric text field\n• accepts decimal & negative values"] + OperatorSelector["OperatorSelector\n• four buttons: + − × ÷\n• highlights active operator"] + ActionBar["ActionBar\n• = (Calculate) button\n• C (Clear) button"] + Calculator["calculator.ts\n(pure logic module)"] + + App --> Display + App --> OperandInput + App --> OperatorSelector + App --> ActionBar + App -- "calls" --> Calculator +``` + +### Component responsibilities + +| Component | Responsibility | +|---|---| +| `App` | Owns all state (operandA, operandB, operator, result, error). Wires child events to state updates and calls the calculator module. | +| `Display` | Pure presentational; renders the current expression and result/error string. | +| `OperandInput` | Controlled `` that accepts numeric strings including decimals; reports `onChange` to `App`. | +| `OperatorSelector` | Renders four operator buttons; reports `onSelect` to `App`. | +| `ActionBar` | Renders **=** and **C** buttons; fires `onCalculate` / `onClear` callbacks. | +| `calculator.ts` | Pure-function module: `calculate(a: number, op: Operator, b: number): number \| CalcError`. No DOM dependency; fully unit-testable. | + +--- + +## Data Model + +All state is ephemeral (in-memory React state). There is no database, localStorage, or network persistence. + +```mermaid +erDiagram + APP_STATE { + string operandA "raw input string for operand A" + string operandB "raw input string for operand B" + Operator operator "'+' | '-' | '*' | '/'" + number result "computed result (null until calculated)" + string errorMessage "non-null when a calc error occurs" + } +``` + +### Type definitions (TypeScript) + +```ts +type Operator = '+' | '-' | '*' | '/'; + +type CalcError = + | { kind: 'DIVISION_BY_ZERO' } + | { kind: 'INVALID_INPUT'; field: 'a' | 'b' }; + +type CalcResult = { ok: true; value: number } | { ok: false; error: CalcError }; +``` + +`calculator.ts` exports a single function: + +```ts +export function calculate(a: number, op: Operator, b: number): CalcResult; +``` + +--- + +## Integrations + +This version has **no external integrations**. All computation runs entirely in the browser. + +| Integration | Status | Notes | +|---|---|---| +| Backend API | None | All arithmetic is client-side; NFR-6 (static deployability) rules out a server runtime. | +| Authentication service | None | No accounts or sessions (Assumption 2). | +| Analytics / telemetry | None | Out of scope for v1; can be added later without architectural change. | +| CDN / static host | Optional | Any static host works (`dist/` is self-contained). Recommended: Netlify or GitHub Pages for zero-cost deployment. | + +--- + +## Non-Functional Requirements + +| ID | NFR | Architectural approach | +|---|---|---| +| NFR-1 | Result ≤ 100 ms | All logic runs synchronously in the browser; no network round-trip. Vite-bundled output is ≤ 50 kB gzipped. | +| NFR-2 | Responsive (desktop + mobile) | CSS Modules with a fluid grid; `OperandInput` and `OperatorSelector` reflow to single-column below 480 px. | +| NFR-3 | WCAG 2.1 AA | Semantic HTML (`