diff --git a/.planning/PROJECT.md b/.planning/PROJECT.md index ea7399d..6bb76e3 100644 --- a/.planning/PROJECT.md +++ b/.planning/PROJECT.md @@ -67,6 +67,17 @@ desktop for read-only awareness. `/api/mobile/engagement/trend` (daily-hours time-series). Existing `/api/engagement/users` reused as-is. Read-only on mobile. Validated in Phase 7: Engagement Overview (ENG-01..05, ENG-09) +- ✓ Per-user IANA timezone — `user.timezone` column (default `'UTC'`), + `session.user.timezone` exposed via Better Auth `additionalFields`, + `GET`/`PUT /api/me/timezone` (IANA-validated; allowlist includes `UTC`/`Etc/UTC`/`GMT`), + shared `getUserTimezone(session)` server helper, shared `useUserTimezone()` + client hook (single source of truth — 52 client files migrated), all 6 + affected read paths (`/api/dashboard/{overview,trends}`, + `/api/mobile/{dashboard,finance,engagement/summary,engagement/trend}`) + switched to `(value AT TIME ZONE 'UTC') AT TIME ZONE $tz` day-boundary math. + `/api/mobile/finance` hardened with `requireAuth()`. Storage UTC unchanged. + Engagement `_snapshots`-derived metrics keep UTC bucketing (documented + carve-out). Validated in Phase 7.1: User Timezone Fix (TZ-01..04) ### Active @@ -157,4 +168,4 @@ This document evolves at phase transitions and milestone boundaries. 4. Update Context with current state --- -*Last updated: 2026-05-04 — Phase 7 complete (Engagement Overview)* +*Last updated: 2026-05-07 — Phase 7.1 complete (User Timezone Fix)* diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index ca2e98d..3e4c24f 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -149,11 +149,11 @@ Decimal phases appear between their surrounding integers in numeric order. 4. A shared client hook (`useUserTimezone()`) reads the value from `useSession()` so all components use a single source of truth — no per-page `Intl` calls scattered around 5. Existing UTC-stored data stays untouched (no destructive migration); only formatting and range-bucketing change **Plans**: 5 plans -- [ ] 07.1-01-PLAN.md — Add timezone column to user table + Better Auth additionalField (TZ-01) -- [ ] 07.1-02-PLAN.md — /api/me/timezone GET + PUT with IANA validation (TZ-03) -- [ ] 07.1-03-PLAN.md — Server-side read paths use user.timezone for day/week/month boundaries; auth-gates /api/mobile/finance; migrates /api/dashboard/trends (TZ-02) -- [ ] 07.1-04-PLAN.md — useUserTimezone() client hook + reported-bug-surface mobile page migration + codebase-wide audit (TZ-04, TZ-02 client portion) -- [ ] 07.1-05-PLAN.md — Codebase-wide useUserTimezone() adoption per the Plan 04 audit (TZ-04 SC#4 single-source-of-truth at codebase scale) +- [x] 07.1-01-PLAN.md — Add timezone column to user table + Better Auth additionalField (TZ-01) +- [x] 07.1-02-PLAN.md — /api/me/timezone GET + PUT with IANA validation (TZ-03) +- [x] 07.1-03-PLAN.md — Server-side read paths use user.timezone for day/week/month boundaries; auth-gates /api/mobile/finance; migrates /api/dashboard/trends (TZ-02) +- [x] 07.1-04-PLAN.md — useUserTimezone() client hook + reported-bug-surface mobile page migration + codebase-wide audit (TZ-04, TZ-02 client portion) +- [x] 07.1-05-PLAN.md — Codebase-wide useUserTimezone() adoption per the Plan 04 audit (TZ-04 SC#4 single-source-of-truth at codebase scale) **UI hint**: no (this is a data/plumbing phase; the picker UI is part of Phase 9) ### Phase 8: Engagement User Profile (NEW) diff --git a/.planning/STATE.md b/.planning/STATE.md index a03bce7..186c06b 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,14 +4,14 @@ milestone: v1.0 milestone_name: milestone status: executing stopped_at: Phase 7 UI-SPEC approved -last_updated: "2026-05-07T11:01:40.811Z" -last_activity: 2026-05-07 -- Phase 7.1 planning complete +last_updated: "2026-05-07T21:24:59.029Z" +last_activity: 2026-05-07 progress: total_phases: 10 - completed_phases: 7 + completed_phases: 8 total_plans: 22 - completed_plans: 17 - percent: 77 + completed_plans: 22 + percent: 100 --- # Project State @@ -28,7 +28,7 @@ See: .planning/PROJECT.md (updated 2026-05-03) Phase: 8 Plan: Not started Status: Ready to execute -Last activity: 2026-05-07 -- Phase 7.1 planning complete +Last activity: 2026-05-07 Progress: [░░░░░░░░░░] 0% @@ -36,7 +36,7 @@ Progress: [░░░░░░░░░░] 0% **Velocity:** -- Total plans completed: 17 +- Total plans completed: 22 - Average duration: — - Total execution time: 0.0 hours @@ -51,6 +51,7 @@ Progress: [░░░░░░░░░░] 0% | 05 | 2 | - | - | | 06 | 3 | - | - | | 07 | 3 | - | - | +| 07.1 | 5 | - | - | **Recent Trend:** diff --git a/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-HUMAN-UAT.md b/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-HUMAN-UAT.md index 57ad481..00d5253 100644 --- a/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-HUMAN-UAT.md +++ b/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-HUMAN-UAT.md @@ -1,14 +1,16 @@ --- -status: partial +status: approved phase: 07.1-user-timezone-fix-inserted-urgent source: [07.1-VERIFICATION.md] started: 2026-05-07T13:30:00Z -updated: 2026-05-07T20:30:00Z +updated: 2026-05-07T20:45:00Z +approved: 2026-05-07T20:45:00Z +approved_by: lorentz@wulfconsulting.com --- ## Current Test -[2 gaps blocking; 6 of 8 items verified — see Gaps below] +[user-approved; 6 of 8 items verified, 2 deferred to browser-observation] ## Tests diff --git a/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-VERIFICATION.md b/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-VERIFICATION.md index b02af33..093665e 100644 --- a/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-VERIFICATION.md +++ b/.planning/phases/07.1-user-timezone-fix-inserted-urgent/07.1-VERIFICATION.md @@ -1,8 +1,11 @@ --- phase: 07.1-user-timezone-fix-inserted-urgent verified: 2026-05-07T13:30:00Z -status: human_needed +status: passed score: 5/5 must-haves verified +approved: 2026-05-07T20:30:00Z +approved_by: lorentz@wulfconsulting.com +notes: User-approved after 6/8 UAT items passed via curl; 2 fixes applied during UAT (BUG-7.1-A `updated_at` typo in d31fd48; BUG-7.1-B UTC validator allowlist in 660d039). Items 1 & 8 (two-browser TZ visual + Plan 5 page-render spot-check) deferred — require browser observation, not blocking. human_verification: - test: "Two-browser-same-user timezone consistency" expected: "User has timezone='America/New_York'. Open /mobile/finance and /dashboard in two browsers — one with system tz UTC, one with Eastern. Both browsers render IDENTICAL date strings (because both pull America/New_York from session, regardless of device tz)."