Files
familysync/.planning/RETROSPECTIVE.md
T
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

4.4 KiB
Raw Blame History

Project Retrospective

A living document updated after each milestone. Lessons feed forward into future planning.

Milestone: v1.0 — MVP

Shipped: 2026-06-10 Phases: 6 | Plans: 42 | Sessions: not tracked

What Was Built

  • Unified color-coded Fastmail calendar (shared + personal) with full event CRUD written back via CalDAV — read views, recurrence/DST expansion, all-day, and an enqueue-only outbox write path.
  • Installable React PWA behind Authelia OIDC, taken live over Pangolin/Newt and verified end-to-end on desktop and iOS.
  • Shared collaborative lists with real-time SSE co-edit sync, and VAPID Web Push for reminders / event-change / list alerts.

What Worked

  • Dev-auth bypass to build behind a deferred gate (D-14): Phases 23 were built against a documented bypass while live Authelia/Pangolin infra wasn't ready, with no rework when Gate 2 finally ran live in Phase 3.
  • Wave-based parallel plans within phases kept large phases (Phase 3 = 12 plans) moving.
  • Enqueue-only outbox with optimistic 202 cleanly separated request handling from the slow CalDAV write, and made create-before-delete ordering + etag/412 handling tractable.

What Was Inefficient

  • A long tail of bugs only reproduced under live conditions (Newt MTU blackhole, OIDC state-cookie race, write-path timezone/identity/join/cache bugs, all-day off-by-one, color collisions, silent Android notifications, session-cookie expiry). Building behind the bypass too long delayed their discovery — they all surfaced at once during live bring-up.
  • Background workers silently failed: node-cron 4.2.1 skipped every scheduled tick in the long-lived API process, so reminders/poller/outbox never fired on schedule — caught late, during Phase 5 UAT, not by tests.
  • Repeated mobile-only defects could only be found by the operator on real devices because the test harness is desktop-Chromium and the prod PWA is behind OIDC (→ backlog 999.12).

Patterns Established

  • setInterval, not node-cron, for in-process schedulers (node-cron silently no-ops in a long-lived process). Do not reintroduce node-cron.
  • drizzle-kit generate+migrate, never push, on MariaDBpush emits a false destructive (truncate) diff against populated MariaDB.
  • iOS-Safari standalone behavior is a human/device checkpoint, not a playwright-cli check — keep those as explicit manual gates.
  • Run tsc --noEmit (both apps) in the post-merge gate — esbuild strips types so vitest stays green while tsc fails.

Key Lessons

  1. Bring the real external topology (auth + tunnel) up early and behind a small reversible config, rather than deferring all live verification — the live-only bug class is large and clusters at first contact.
  2. Long-running Node schedulers need an integration-level "does it actually fire on a tick" check; unit tests pass while the scheduler silently does nothing.
  3. Push has hard platform footguns (iOS revokes after 3 silent pushes; standalone install mandatory; VAPID key truncation = silent Apple 403) — encode them as guards from day one, not after a missed notification.

Cost Observations

  • Model mix: not tracked
  • Sessions: not tracked
  • Notable: TDD red→green discipline is visible in commit history, but per-commit gate_status: trailers were never emitted across the milestone — the ship-time TDD audit had nothing structured to aggregate. Wire gate_status trailers in v1.x if the audit is wanted.

Process Evolution

Milestone Sessions Phases Key Change
v1.0 n/a 6 Established GSD plan→execute→verify→ship→complete loop; dev-auth bypass for gated infra; milestone-branch + Gitea PR shipping

Cumulative Quality

Milestone Tests Coverage Zero-Dep Additions
v1.0 PWA 191 + API broker/events 114 green not measured n/a

Top Lessons (Verified Across Milestones)

  1. (pending second milestone to cross-validate)