Commit Graph
792 Commits
Author SHA1 Message Date
Lucas Berger 743c7d92f0 fix(13-03): exclude .planning from Prettier so the format gate stays green
GSD planning artifacts (.planning/**) are rewritten by tooling on every workflow
run and are never hand-formatted. Including them in Prettier scope caused
pnpm format:check to exit 1 on virtually every future PR, making the SC-3
green baseline impossible to hold. Add .planning/ to .prettierignore, mirroring
the same rationale as dist/ and apps/api/src/db/migrations/.

Real source docs (README.md, docs/**) remain in Prettier scope.
No playwright-report/, test-results/, or coverage/ directories exist to ignore.
2026-06-11 20:50:45 -04:00
Lucas Berger f153b7199d docs(13-03): complete Prettier reformat + CI format gate plan 2026-06-11 20:44:52 -04:00
Lucas Berger 0422406c42 feat(13-03): add Format check CI step; remove stale no-op lint comment
- Insert 'Format check: pnpm format:check' after Lint in fast-checks job
- Remove the 3-line comment that said lint was a no-op (no longer true)
- Step order: Install → Lint → Format check → Typecheck → PWA unit tests
- Branch-protection contexts (name:CI, fast-checks, api, harness) unchanged
2026-06-11 20:35:44 -04:00
Lucas Berger 982438dc10 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.
2026-06-11 20:35:18 -04:00
Lucas Berger 4bc0445173 docs(13-02): record post-verification correction — residual lint error and fix 2026-06-11 20:31:10 -04:00
Lucas Berger 3f2e3ea659 fix(13-02): resolve residual no-unnecessary-type-assertion in SyncStateToast.test
- Replace inline 'as string | null' assertion with an explicit typed const
  declaration inside the vi.hoisted() callback body
- 'value: string | null' typed const satisfies both ESLint (no assertion) and
  tsc (null assignment on line 82 is type-safe)
2026-06-11 20:30:51 -04:00
Lucas Berger 1453cbed76 docs(13-02): complete ESLint violation elimination plan 2026-06-11 20:25:47 -04:00
Lucas Berger 03e953158a fix(13-02): eliminate all ESLint violations — pnpm lint exits 0
- eslint.config.js: disable React Compiler rules (v7 flat.recommended enables
  them; codebase does not use the Compiler); add e2e/ to disableTypeChecked
  block; promote exhaustive-deps to error
- API broker: remove redundant as-casts (outboxWorker, poller, reminderScheduler,
  expand, sync, vevent, spike); add targeted ical.js no-unsafe-assignment/argument
  disables with justifying comments inside try blocks
- API routes/sse.ts: fix no-misused-promises on async writeSSE callback with
  void+IIFE+catch pattern
- API routes/lists.ts: let → const for updateValues
- API tests: remove unused imports (beforeEach, eq, vi); rename unused vars
  with _ prefix; remove unused lastActiveId assignment
- PWA components: void navigate() and void queryClient.invalidateQueries() on
  all fire-and-forget call sites; fix CalendarShell explicit-type-casts;
  Couldn't → HTML entity
- PWA test files: as unknown as Response for partial mock objects; string | null
  type annotation on mockLastSyncedUid; remove async from test callbacks without
  await; act(() => {}) not await act(async () => {}) for sync ops
- sw.ts: restructure Notification.data?.url access as let+if so disable
  comments land on the exact violation lines; void self.skipWaiting()
2026-06-11 20:23:38 -04:00
Lucas Berger 39e26561cf docs(13-01): complete lint gate foundation plan — SUMMARY + STATE + ROADMAP
Plan 13-01 complete: ESLint flat config + Prettier installed and wired,
SC-1 gate proven (exit 1 on deliberate violations), 119 real violations
inventoried for Plan 02 (api:42, pwa:77). STATE advanced to Plan 2 of 3.
2026-06-11 19:53:55 -04:00
Lucas Berger 7a255eacaa fix(13-01): disable react/react-in-jsx-scope for React 19 JSX transform
SC-1 smoke revealed flat.recommended enables react/react-in-jsx-scope (error),
while the legacy recommended disables it. This codebase uses jsx:"react-jsx"
(React 17+ automatic transform) so React does not need to be in scope. Disable
the rule explicitly alongside react/prop-types in the pwa-react config block.

Also proved both gate halves:
- pnpm lint exits 1 on no-floating-promises deliberate violation (SC-1 lint)
- pnpm format:check exits 1 listing _format-gate-test.ts (SC-1 format)
Both throwaway files deleted; neither staged nor committed.
2026-06-11 19:52:08 -04:00
Lucas Berger df62d333d0 chore(13-01): install ESLint+Prettier, author flat config, wire lint/format scripts
- Install eslint@9.39.4 @eslint/js@9.39.4 typescript-eslint@8.61.0
  eslint-plugin-react@7.37.5 eslint-plugin-react-hooks@7.1.1
  eslint-config-prettier@10.1.8 prettier@3.8.4 as root devDependencies
- Author eslint.config.js: ignores → base recommendedTypeChecked (projectService:true)
  → pwa-react block (apps/pwa/** only) → disableTypeChecked override (config files +
  apps/api/tests) → prettier-last (eslint-config-prettier/flat)
- Add .prettierrc (singleQuote:true, printWidth:100) and .prettierignore
- Add "type":"module" to root package.json; add format/format:check scripts
- Add lint script (--max-warnings 0) to apps/api and apps/pwa
2026-06-11 19:44:57 -04:00
luckberg 0798046714 Merge pull request 'fix(08): resolve remaining Phase 8 CI review findings (WR-02/03/04/05 + IN-01 doc)' (#7) from gsd/phase-08-fixes into main
Publish / publish (push) Successful in 15s
Reviewed-on: #7
2026-06-11 19:40:44 -04:00
luckberg b645243582 Merge branch 'main' into gsd/phase-08-fixes
CI / fast-checks (pull_request) Successful in 49s
CI / api (pull_request) Successful in 58s
CI / harness (pull_request) Successful in 3m30s
2026-06-11 19:31:13 -04:00
luckberg 60be525836 Merge pull request 'docs(roadmap): promote Phases 13 (lint gate) + 14 (desktop e2e) into v1.1' (#6) from gsd/roadmap-v1.1-phases-13-14 into main
Publish / publish (push) Successful in 7s
Reviewed-on: #6
2026-06-11 19:30:59 -04:00
Lucas Berger 5f065183b0 docs(08-fix): code review + auto-fix report (5 fixed, IN-02 deferred to Phase 13)
CI / fast-checks (pull_request) Successful in 49s
CI / api (pull_request) Successful in 1m3s
CI / harness (pull_request) Successful in 3m27s
2026-06-11 19:29:36 -04:00
Lucas Berger 66c54507ad docs(13): create phase plan 2026-06-11 19:27:50 -04:00
Lucas Berger bf091102f2 fix(08-fix): IN-01 document MariaDB-only long-unique HASH index dependency 2026-06-11 19:27:11 -04:00
Lucas Berger 4001cd5b90 fix(08-fix): WR-04 push immutable sha tag before :latest with strict shell 2026-06-11 19:27:07 -04:00
Lucas Berger 58861d99a8 fix(08-fix): WR-05 bind REGISTRY_PAT via env: and pipe with printf for docker login 2026-06-11 19:27:03 -04:00
Lucas Berger 6bcf867e6c fix(08-fix): WR-03 fail closed on empty GITHUB_SHA when computing image tags 2026-06-11 19:26:53 -04:00
Lucas Berger 44a9c307e2 fix(08-fix): WR-02 upload Playwright HTML report on harness failure 2026-06-11 19:26:28 -04:00
Lucas Berger 694253ecb0 docs(13): create phase plan — 3 plans (lint gate + Prettier format gate)
- 13-01: install ESLint v9/typescript-eslint/React/Prettier (pinned), flat config,
  package lint + root format scripts, root type:module; prove gate fails (SC-1)
- 13-02: fix all first-run violations across both apps, address-not-mask (D-13-05/06)
- 13-03: isolated Prettier reformat (D-13-08) + CI format:check step + green baseline (SC-2/SC-3)
- ROADMAP: add active Phase 13 entry + Progress row; mark backlog 999.16 promoted
2026-06-11 19:25:08 -04:00
Lucas Berger 2863025bcd docs(13): add pattern map 2026-06-11 19:18:46 -04:00
Lucas Berger bcc9682a01 docs(roadmap): promote Phases 13 (real lint gate) + 14 (desktop e2e) into v1.1; fold backlog 999.5 self-service onboarding into admin-credential phase
CI / fast-checks (pull_request) Successful in 50s
CI / api (pull_request) Successful in 1m1s
CI / harness (pull_request) Successful in 3m33s
2026-06-11 19:13:31 -04:00
luckberg b12e10d129 Merge pull request 'chore(ci): split publish into standalone push-only workflow + document release model' (#5) from gsd/quick-split-publish into main
Publish / publish (push) Successful in 7s
Reviewed-on: #5
2026-06-11 19:04:30 -04:00
Lucas Berger ee67dfecef docs(13): add research + validation strategy 2026-06-11 19:04:13 -04:00
Lucas Berger ef87a3edf6 docs(13): research phase — ESLint flat config + Prettier 2026-06-11 19:03:11 -04:00
Lucas Berger 2b6b0da939 docs(state): record phase 13 context session 2026-06-11 18:29:04 -04:00
Lucas Berger 8fbc68f993 docs(13): capture phase context 2026-06-11 18:28:58 -04:00
Lucas Berger 234384c142 docs(quick-260611-ozt): split publish job into standalone gitea workflow + document release model
CI / fast-checks (pull_request) Successful in 49s
CI / api (pull_request) Successful in 56s
CI / harness (pull_request) Successful in 3m22s
2026-06-11 18:08:27 -04:00
Lucas Berger 92353e1860 docs(260611-ozt): document release model in README Publishing/Releases section
- Add Publishing / Releases section covering auto-trigger, image tags,
  REGISTRY_PAT secret naming, branch-protection safety gate, and MILESTONE bump
- publish.yml already carries condensed header block (committed in prior task)
2026-06-11 18:06:46 -04:00
Lucas Berger bb331fd110 chore(260611-ozt): split publish job into standalone publish.yml
- Create .gitea/workflows/publish.yml (push-to-main only, name=Publish)
- Strip publish job, push trigger, and MILESTONE env from ci.yml
- Eliminates orphaned CI / publish (pull_request) status on PRs
- Preserves all three required PR status contexts unchanged
2026-06-11 18:06:46 -04:00
Lucas Berger e14054c264 docs(260611-ozt): pre-dispatch plan for split publish job into standalone gitea workflow 2026-06-11 18:02:57 -04:00
luckberg f153a72c36 Merge pull request 'docs(08): Phase 8 close-out — SUMMARY + VERIFICATION + tracking' (#4) from gsd/phase-08-gitea-ci into main
CI / fast-checks (push) Has been skipped
CI / api (push) Has been skipped
CI / harness (push) Has been skipped
CI / publish (push) Successful in 5s
2026-06-11 16:30:09 -04:00
Lucas Berger b1851f475e docs(08): SUMMARY + VERIFICATION — phase 8 complete, CI-01 + CI-02 delivered
CI / fast-checks (pull_request) Successful in 49s
CI / api (pull_request) Successful in 56s
CI / harness (pull_request) Successful in 3m23s
CI / publish (pull_request) Has been skipped
- 08-04-SUMMARY.md: publish job verified green (run #14), both tags pushed,
  security audit pass (PAT masked, --password-stdin), REGISTRY_PAT naming note
- 08-VERIFICATION.md: all six phase-8 ROADMAP criteria passed with evidence table
- REQUIREMENTS.md: CI-01 + CI-02 marked complete (checkboxes + traceability table)
- ROADMAP.md: phase 8 marked [x] complete (2026-06-11), 08-04 plan ticked
- STATE.md: phase complete, D-PAT-NAMING decision recorded, operator next steps updated
2026-06-11 16:17:53 -04:00
luckberg 98acff8108 Merge pull request 'Phase 8: Gitea CI — runner probe + PR gating jobs (fast-checks + api)' (#3) from gsd/phase-08-gitea-ci into main
CI / fast-checks (push) Has been skipped
CI / api (push) Has been skipped
CI / harness (push) Has been skipped
CI / publish (push) Successful in 1m7s
2026-06-11 16:11:41 -04:00
Lucas Berger 73eecf7559 fix(08-04): reference secrets.REGISTRY_PAT — Gitea reserves the GITEA_ prefix
CI / fast-checks (pull_request) Successful in 49s
CI / api (pull_request) Successful in 57s
CI / harness (pull_request) Successful in 3m30s
CI / publish (pull_request) Has been skipped
The registry PAT secret had to be named REGISTRY_PAT (Gitea forbids the GITEA_
prefix for secret names). Point the publish docker-login at secrets.REGISTRY_PAT.
2026-06-11 16:05:54 -04:00
Lucas Berger dcf42423a5 chore(08): remove throwaway runner-probe workflow before merge to main
CI / fast-checks (pull_request) Successful in 50s
CI / api (pull_request) Successful in 56s
CI / harness (pull_request) Successful in 3m27s
CI / publish (pull_request) Has been skipped
Probe answers are recorded in 08-01-SUMMARY; the probe is no longer needed and
should not live on main (it was workflow_dispatch-only/inert anyway).
2026-06-11 15:57:49 -04:00
Lucas Berger ebcc38d810 feat(08-04): publish job — build + push API image on merge to main
- Add publish job gated on push to refs/heads/main (never pull_request)
- docker login via --password-stdin with secrets.GITEA_REGISTRY_PAT (Pitfall 13)
- docker build --target production -f apps/api/Dockerfile . (repo-root context, T-08-10)
- Push :latest and :${MILESTONE}-${SHORT_SHA} tags per D-04
- docker logout in always() step to drop credential after push
- No dev-bypass flag in publish job (T-08-09 boundary)
2026-06-11 15:56:37 -04:00
Lucas Berger 212d8c1691 docs(08-03): SUMMARY — harness green, 58 specs both profiles on cold CI stack
- Run #11 (PR #3): 58 passed in 1.6 min (iphone/WebKit + pixel/Chromium)
- 4 infrastructure fixes: API-reap at step boundary, IPv4-first for Vite, dev-user FK seed, reporter double-forward via pnpm
- No Phase 7 harness file modified (phase boundary D-01/D-02 held)
- Advance position to 08-04 (publish job)
2026-06-11 15:52:15 -04:00
Lucas Berger 03e8088238 fix(08-03): call pwa test:e2e directly so --reporter forwards cleanly
CI / fast-checks (pull_request) Successful in 49s
CI / api (pull_request) Successful in 1m0s
CI / harness (pull_request) Successful in 3m26s
Run #10 cleared global-setup but playwright errored 'No tests found':
`pnpm test:e2e -- --reporter=list,html` routes through two pnpm script layers
(root→pwa) and the `--` survives into `playwright test -- --reporter=list,html`,
where playwright treats --reporter as a test-file filter. Call the pwa script
directly and append the flag without `--` (validated: 58 specs list vs 0).
2026-06-11 15:43:09 -04:00
Lucas Berger e486c6be9f fix(08-03): seed dev user id=1 — global-setup assumes it exists
CI / fast-checks (pull_request) Successful in 48s
CI / api (pull_request) Successful in 56s
CI / harness (pull_request) Failing after 2m0s
global-setup.ts seeds calendars/lists/events for user_id=1 but never creates
the user (DEV_AUTH_BYPASS injects DEV_USER in-memory only). On a fresh CI DB the
calendars INSERT IGNORE is silently skipped on the users FK → calendar 10 missing
→ calendar_events insert fails FK. Add an idempotent users(id=1) seed after
migrate (validated locally: full insert chain passes). No harness files changed.
2026-06-11 15:36:52 -04:00
Lucas Berger 73897407c7 fix(08-03): harness uses 127.0.0.1 + ipv4first — Vite is IPv4-only
CI / fast-checks (pull_request) Successful in 50s
CI / api (pull_request) Successful in 56s
CI / harness (pull_request) Failing after 1m49s
global-setup polls baseURL/health via Node fetch; the runner resolves localhost
to ::1 first, but Vite binds IPv4-only (127.0.0.1:5173), so localhost→::1:5173
→ ECONNREFUSED → health poll never returns 200. (curl passed for :3000 because
curl falls back IPv4↔IPv6 and the API is dual-stack; Node fetch does not.)
Proven: [::1]:5173 ECONNREFUSED vs 127.0.0.1:5173 200. Point PLAYWRIGHT_BASE_URL
at 127.0.0.1 and add --dns-result-order=ipv4first. No harness files changed.
2026-06-11 15:20:24 -04:00
Lucas Berger 53a989c3fb fix(08-03): keep API alive during harness — start API + run e2e in one step
CI / fast-checks (pull_request) Successful in 49s
CI / api (pull_request) Successful in 56s
CI / harness (pull_request) Failing after 2m50s
Run #7 harness failed: global-setup polled :5173/health (Vite proxy → :3000)
and never got 200. The API connected to the DB and :3000/health was green
during the separate 'Wait for API' step, but the bare-backgrounded node
process was reaped at the step boundary and was dead by the time the e2e step
ran (after the multi-minute browser install). Confirmed locally the API does
not self-crash (alive + healthy for 75s in-shell).

Install browsers first, then start the API and run Playwright in a SINGLE step
so the API stays a child of the test shell for the whole run; capture the test
exit code and kill the API after. No harness files touched.
2026-06-11 15:05:04 -04:00
Lucas Berger 71c89093b1 feat(08-03): add Playwright install + harness run (both profiles) + artifact upload
CI / fast-checks (pull_request) Successful in 48s
CI / api (pull_request) Successful in 56s
CI / harness (pull_request) Failing after 2m53s
- npx playwright install --with-deps webkit chromium from apps/pwa/ (D-PROBE-05)
- pnpm test:e2e -- --reporter=list,html overrides github reporter (Pitfall 5; Gitea ignores annotations)
- Both iphone (WebKit) + pixel (Chromium) profiles run (D-05; no --project filter)
- Step env: CI=true, PLAYWRIGHT_BASE_URL=http://localhost:5173, DEV_AUTH_BYPASS=true, NODE_ENV=development, DB_*
- On failure: upload apps/pwa/test-results/ via ChristopherHX/gitea-upload-artifact@v4 (D-06/D-PROBE-06)
- Always: kill API background process via /tmp/api.pid
- No edits to playwright.config.ts / global-setup.ts / vite.config.ts / specs (phase boundary)
2026-06-11 14:45:52 -04:00
Lucas Berger d55e347a09 feat(08-03): add harness job — DB + migrate + API background + :3000 readiness
- Add harness job to ci.yml (ubuntu-latest, pull_request, parallel with fast-checks + api)
- MariaDB 11 service container with healthcheck.sh readiness (same pattern as api job)
- mysql2 readiness poll (no mysql CLI in runner image, D-PROBE-03)
- db:migrate via drizzle-kit (never db:push, T-08-07)
- pnpm --filter @familysync/api build before starting (Pitfall 4)
- API background: DEV_AUTH_BYPASS=true inline on node line (Pitfall 8), NODE_ENV=development
- curl retry loop on localhost:3000/health, 60s deadline, kill+exit on timeout (D-02/T-08-08)
2026-06-11 14:45:07 -04:00
Lucas Berger 2a34a94cc6 docs(08): correct premature completion — phase 8 + CI-01 still in progress
CI / fast-checks (pull_request) Successful in 48s
CI / api (pull_request) Successful in 57s
Plans 08-03 (harness UI-regression job) and 08-04 (publish job) are not yet
built; CI-01's definition includes the harness step (08-03). Revert phase 8
and CI-01 from complete back to in-progress.
2026-06-11 14:42:33 -04:00
Lucas Berger 694ffe713b docs(08): commit phase research (was untracked) 2026-06-11 14:39:30 -04:00
Lucas Berger 78229168b9 docs(08-02): SUMMARY — PR gating jobs green on cold run 2026-06-11 14:37:32 -04:00
Lucas Berger 181d161da6 docs: add backlog 999.16 — wire real ESLint lint gate (deferred from phase 8) 2026-06-11 14:33:22 -04:00