style(13-03): apply Prettier formatting across repo

Mechanical reformat — no logic changes. 398 files changed, 19125
insertions(+), 16457 deletions(-). Prettier 3.8.4 with .prettierrc
(singleQuote:true, semi:true, tabWidth:2, trailingComma:all,
printWidth:100). Isolated per D-13-08 for reviewability.
This commit is contained in:
Lucas Berger
2026-06-11 20:35:18 -04:00
parent 4bc0445173
commit 982438dc10
398 changed files with 19050 additions and 16382 deletions
@@ -36,44 +36,44 @@ autonomous: false
requirements: [CAL-01]
user_setup:
- service: mariadb
why: "Local stack DB; provisioned via Docker Compose (no external account)"
why: 'Local stack DB; provisioned via Docker Compose (no external account)'
env_vars:
- name: DB_PASSWORD
source: "Choose any strong password; set in .env (consumed by both mariadb and api services)"
source: 'Choose any strong password; set in .env (consumed by both mariadb and api services)'
- name: DB_ROOT_PASSWORD
source: "Choose any strong password; set in .env (MariaDB root)"
source: 'Choose any strong password; set in .env (MariaDB root)'
must_haves:
truths:
- "docker compose up brings MariaDB healthy and the Hono API serving"
- "GET /health returns 200 and proves a real DB round-trip (write then read)"
- "The React PWA builds and renders a shell that fetches /health"
- "npx drizzle-kit push applies the users/member_credentials/calendars/calendar_events schema to the live MariaDB"
- "vitest runs and the Wave 0 test files exist and execute (red or green)"
- 'docker compose up brings MariaDB healthy and the Hono API serving'
- 'GET /health returns 200 and proves a real DB round-trip (write then read)'
- 'The React PWA builds and renders a shell that fetches /health'
- 'npx drizzle-kit push applies the users/member_credentials/calendars/calendar_events schema to the live MariaDB'
- 'vitest runs and the Wave 0 test files exist and execute (red or green)'
artifacts:
- path: "apps/api/src/db/schema.ts"
provides: "Drizzle mysqlTable definitions for users, member_credentials, calendars, calendar_events"
- path: 'apps/api/src/db/schema.ts'
provides: 'Drizzle mysqlTable definitions for users, member_credentials, calendars, calendar_events'
contains: "mysqlTable('users'"
- path: "apps/api/src/db/client.ts"
provides: "drizzle(mysql2 pool) singleton export `db`"
exports: ["db"]
- path: "apps/api/src/routes/health.ts"
provides: "GET /health with real DB read/write"
- path: "docker-compose.yml"
provides: "api + mariadb + redis services with mariadb healthcheck"
contains: "healthcheck"
- path: "apps/api/vitest.config.ts"
provides: "Node-environment vitest config"
- path: "apps/pwa/src/App.tsx"
provides: "React shell that fetches /health"
- path: 'apps/api/src/db/client.ts'
provides: 'drizzle(mysql2 pool) singleton export `db`'
exports: ['db']
- path: 'apps/api/src/routes/health.ts'
provides: 'GET /health with real DB read/write'
- path: 'docker-compose.yml'
provides: 'api + mariadb + redis services with mariadb healthcheck'
contains: 'healthcheck'
- path: 'apps/api/vitest.config.ts'
provides: 'Node-environment vitest config'
- path: 'apps/pwa/src/App.tsx'
provides: 'React shell that fetches /health'
key_links:
- from: "apps/api/src/routes/health.ts"
to: "apps/api/src/db/client.ts"
via: "db query"
pattern: "from ['\"].*db/client"
- from: "apps/pwa/src/App.tsx"
to: "/health"
via: "fetch"
- from: 'apps/api/src/routes/health.ts'
to: 'apps/api/src/db/client.ts'
via: 'db query'
pattern: 'from [''"].*db/client'
- from: 'apps/pwa/src/App.tsx'
to: '/health'
via: 'fetch'
pattern: "fetch\\(.*health"
---
@@ -103,6 +103,7 @@ Output: Running Docker stack, applied DB schema, a green `/health` slice, and th
</context>
<artifacts_produced>
## Artifacts this phase produces (Plan 01)
New files: `package.json` (root workspace), `pnpm-workspace.yaml`, `.gitignore`, `.env.example`, `docker-compose.yml`, `docker-compose.dev.yml`, `apps/api/package.json`, `apps/api/tsconfig.json`, `apps/api/Dockerfile`, `apps/api/drizzle.config.ts`, `apps/api/vitest.config.ts`, `apps/api/src/index.ts`, `apps/api/src/db/schema.ts`, `apps/api/src/db/client.ts`, `apps/api/src/routes/health.ts`, `apps/api/tests/helpers/db.ts`, `apps/api/tests/health.test.ts`, `apps/api/tests/auth/user.test.ts`, `apps/api/tests/broker/crypto.test.ts`, `apps/api/tests/broker/sync.test.ts`, `apps/api/tests/broker/poller.test.ts`, `apps/pwa/package.json`, `apps/pwa/tsconfig.json`, `apps/pwa/vite.config.ts`, `apps/pwa/index.html`, `apps/pwa/src/main.tsx`, `apps/pwa/src/App.tsx`.
@@ -138,6 +139,7 @@ New env vars: `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`, `DB_ROO
docker-compose.yml per RESEARCH Pattern 6: services `api` (build ./apps/api, env DB_* + placeholders for OIDC/encryption used by later plans, depends_on mariadb service_healthy, port 3000:3000), `mariadb` (image mariadb:11, MARIADB_* env, named volume mariadb_data, healthcheck using healthcheck.sh --connect --innodb_initialized interval 10s retries 5), `redis` (redis:7-alpine, present but unused in Phase 1). docker-compose.dev.yml overrides for local dev (bind mounts, expose mariadb 3306). `.env.example` lists every env var referenced (DB_HOST=mariadb, DB_PORT=3306, DB_USER=familysync, DB_NAME=familysync, DB_PASSWORD, DB_ROOT_PASSWORD, plus OIDC_* and APP_PASSWORD_ENCRYPTION_KEY placeholders for later plans). `.gitignore` excludes node_modules, dist, .env (NEVER commit .env — security: secrets at rest).
Create the Wave 0 test files as RED stubs that import the not-yet-existing modules from later plans, each with `it.todo` or a failing assertion plus a comment naming the plan that fills it: `tests/helpers/db.ts` (Drizzle test-DB fixture against the Docker MariaDB or a throwaway schema), `tests/auth/user.test.ts` (upsertUser color round-robin + identity stability — Plan 02), `tests/broker/crypto.test.ts` (AES-GCM roundtrip + IV uniqueness — Plan 03), `tests/broker/sync.test.ts` (allDay → dtstart_date vs dtstart_utc, UID upsert — Plan 03), `tests/broker/poller.test.ts` (ctag unchanged → no write — Plan 03), `tests/health.test.ts` (GET /health 200 — filled by Task 2 below). Do NOT place fenced code in this plan; follow the patterns in RESEARCH.
</action>
<verify>
<automated>cd apps/api && pnpm install && pnpm vitest run --reporter=dot; test -f ../../docker-compose.yml && grep -q "healthcheck" ../../docker-compose.yml && grep -q "mariadb:11" ../../docker-compose.yml</automated>
@@ -177,6 +179,7 @@ New env vars: `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`, `DB_ROO
Fill `tests/health.test.ts` GREEN: mock or use the test-DB fixture to assert GET /health returns 200 `{ ok: true }`.
Update `apps/pwa/src/App.tsx`: a thin shell that fetches `/health` via React Query and renders "stack: up" / "stack: down". This is the one real UI interaction wired to the API for the skeleton.
</action>
<verify>
<automated>cd apps/api && pnpm vitest run tests/health.test.ts --reporter=verbose && pnpm exec tsc --noEmit</automated>
@@ -211,21 +214,23 @@ New env vars: `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`, `DB_ROO
</tasks>
<threat_model>
## Trust Boundaries
| Boundary | Description |
|----------|-------------|
| Docker host → MariaDB container | DB credentials cross here; never hardcoded, sourced from .env |
| .env file → process env | Secrets (DB passwords, later OIDC + encryption key) loaded here; .env never committed |
| Boundary | Description |
| ------------------------------- | ------------------------------------------------------------------------------------- |
| Docker host → MariaDB container | DB credentials cross here; never hardcoded, sourced from .env |
| .env file → process env | Secrets (DB passwords, later OIDC + encryption key) loaded here; .env never committed |
## STRIDE Threat Register
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|-----------|----------|-----------|-------------|-----------------|
| T-01-01 | Information Disclosure | .env with DB + future OIDC/encryption secrets | mitigate | `.gitignore` excludes `.env`; only `.env.example` (no real values) is committed |
| T-01-02 | Tampering | MariaDB container | mitigate | Dedicated `familysync` DB user (not root) for the app; root password separate and unused by api service |
| T-01-03 | Elevation of Privilege | /health route | accept | Intentionally unauthenticated and read-mostly; returns no secrets or user data, only `{ ok, db }` |
| T-01-SC | Tampering | pnpm installs (hono, drizzle, mysql2, tsdav, ical.js, node-cron, react, vite) | accept | All packages reviewed [OK] in RESEARCH § Package Legitimacy Audit (multi-year histories, official repos); no [ASSUMED]/[SUS]/[SLOP] packages |
| Threat ID | Category | Component | Disposition | Mitigation Plan |
| --------- | ---------------------- | ----------------------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| T-01-01 | Information Disclosure | .env with DB + future OIDC/encryption secrets | mitigate | `.gitignore` excludes `.env`; only `.env.example` (no real values) is committed |
| T-01-02 | Tampering | MariaDB container | mitigate | Dedicated `familysync` DB user (not root) for the app; root password separate and unused by api service |
| T-01-03 | Elevation of Privilege | /health route | accept | Intentionally unauthenticated and read-mostly; returns no secrets or user data, only `{ ok, db }` |
| T-01-SC | Tampering | pnpm installs (hono, drizzle, mysql2, tsdav, ical.js, node-cron, react, vite) | accept | All packages reviewed [OK] in RESEARCH § Package Legitimacy Audit (multi-year histories, official repos); no [ASSUMED]/[SUS]/[SLOP] packages |
</threat_model>
<verification>
@@ -238,12 +243,13 @@ New env vars: `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASSWORD`, `DB_NAME`, `DB_ROO
</verification>
<success_criteria>
- Monorepo scaffold (apps/api + apps/pwa) builds and type-checks
- Docker stack runs MariaDB (healthy) + Hono API
- Schema applied to live DB via drizzle-kit push (all four tables present)
- /health proves a real DB read+write round-trip; React shell renders its result
- Wave 0 test files exist and run; health test green
</success_criteria>
</success_criteria>
<output>
Create `.planning/phases/01-foundation-broker-spike/01-01-SUMMARY.md` when done.