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

66 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 MariaDB** — `push` 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.
---
## Cross-Milestone Trends
### 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)