Archive milestone artifacts (roadmap, requirements, audit, phase directories) to .planning/milestones/. Evolve PROJECT.md with validated requirements and decision outcomes. Create MILESTONES.md and RETROSPECTIVE.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
3.4 KiB
3.4 KiB
Project Retrospective
A living document updated after each milestone. Lessons feed forward into future planning.
Milestone: v1.0 — Analytics & Monitoring
Shipped: 2026-02-25 Phases: 5 | Plans: 10 | Sessions: ~4
What Was Built
- Database foundation with 3 monitoring tables (service_health_checks, alert_events, document_processing_events) and typed TypeScript models
- Health probe system with real authenticated API calls to Document AI, Claude/OpenAI, Supabase, and Firebase Auth
- Alert service with email delivery via nodemailer, deduplication cooldown, and config-driven recipients
- Fire-and-forget analytics service for non-blocking document processing event tracking
- Admin-authenticated API layer with health, analytics, and alerts endpoints
- Frontend admin dashboard with service health grid, analytics summary, and critical alert banner
- Tech debt cleanup: env-driven config, consolidated retention, removed hardcoded defaults
What Worked
- Strict dependency ordering (data → services → API → frontend) prevented integration surprises — each phase consumed exactly what the prior phase provided
- Fire-and-forget pattern enforced at the type level (void return) caught potential performance issues at compile time
- GSD audit-milestone workflow caught 5 tech debt items before shipping — all resolved
- 2-day milestone completion shows GSD workflow is efficient for well-scoped work
What Was Inefficient
- Phase 5 (tech debt) was added to the roadmap but executed as a direct commit — the GSD plan/execute overhead wasn't warranted for 3 small fixes
- Summary one-liner extraction returned null for all summaries — frontmatter format may not match what gsd-tools expects
Patterns Established
- Static class model pattern for Supabase (no instantiation, getSupabaseServiceClient per-method)
- makeSupabaseChain() factory for Vitest mocking of Supabase client
- requireAdminEmail middleware returns 404 (not 403) to hide admin routes
- Firebase Secrets read inside function body, never at module level
- void return type to prevent accidental await on fire-and-forget operations
Key Lessons
- Small tech debt fixes don't need full GSD plan/execute — direct commits are fine when the audit already defines the scope
- Type-level enforcement (void vs Promise) is more reliable than code review for architectural constraints
- Promise.allSettled is the right pattern when partial results are better than total failure (health probes)
- Admin email should always be config-driven from day one — hardcoding "just for now" creates tech debt immediately
Cost Observations
- Model mix: ~80% sonnet (execution), ~20% haiku (research/verification)
- Sessions: ~4
- Notable: Phase 4 (frontend) completed fastest — well-defined API contracts from Phase 3 made UI wiring straightforward
Cross-Milestone Trends
Process Evolution
| Milestone | Sessions | Phases | Key Change |
|---|---|---|---|
| v1.0 | ~4 | 5 | First milestone — established patterns |
Cumulative Quality
| Milestone | Tests | Coverage | Zero-Dep Additions |
|---|---|---|---|
| v1.0 | 14+ | — | 3 tables, 5 services, 4 routes, 3 components |
Top Lessons (Verified Across Milestones)
- Type-level enforcement > code review for architectural constraints
- Strict phase dependency ordering prevents integration surprises