Files
familysync/.planning/milestones/v1.0-phases/03-event-write-back-pwa-install/03-UAT.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

7.0 KiB
Raw Blame History

status, phase, mode, source, scope, method, started, updated
status phase mode source scope method started updated
complete 03-event-write-back-pwa-install mvp
03-05-SUMMARY.md (Event Write UI)
03-06-SUMMARY.md (Edit/Delete + SyncStateToast)
03-07-SUMMARY.md (PWA Install)
03-08-SUMMARY.md (Gate 2 Live Verification)
03-12-SUMMARY.md (EventForm gap closure)
03-REVIEW.md / 03-REVIEW-FIX.md (code-review fix cycle, this session)
regression-focused (post code-review-fix) playwright-cli desktop drive (local dev-bypass stack, no real Fastmail writes) + green test suites + Gate 2 record 2026-06-09T15:20:00Z 2026-06-09T15:30:00Z

Current Test

[testing complete]

Context

Gate 2 (Plan 03-08) already operator-verified the full event write-back + iOS-install user story live against real Authelia/Fastmail on desktop and the wife's iPhone (A1A3, B1B4, D1D6). This UAT pass is regression-focused: it re-confirms the behaviours touched by the code-review fix cycle run this session (CR-01/CR-02 member-scoped lookups, CR-03 all-day inclusive/exclusive, WR-01/move-path RRULE preservation, WR-04 sync-status ranking, IN-03 payload re-validation), which landed after Gate 2.

Browser drive used a local dev-bypass stack (MariaDB + API + PWA) as the credential-less dev user, so no event ever reached a real Fastmail calendar. Seeded test data (one dev user, one uat.local calendar, one recurring event) was removed after the run; DB restored to original state (real users 2/3 and their 538 events untouched).

Tests

1. Cold-start smoke — app boots and renders after the fixes

expected: PWA loads, calendar shell renders (nav, Calendars legend, New Event control), no real console errors. result: pass evidence: Loaded http://localhost:5173 in real Chromium. Title "FamilySync"; nav + "New Event" + Schedule-X month grid (June 2026) rendered; legend showed distinct member colours (Dev User #4A90D9, Family #F25C7A). Only console error was a benign favicon.ico 404.

2. Create-event UI flow → enqueue → sync feedback

expected: New Event → fill form → Save → event enqueues (202) and SyncStateToast shows pending state. result: pass evidence: Opened EventForm (all UI-SPEC fields, focus on Title). Filled title, clicked "Create Event"; dialog closed, calendar_outbox row id=20 created (operation=create, pending), and SyncStateToast rendered role="status" "Syncing…". (Dispatch intentionally cannot complete — dev user has no Fastmail credential — so nothing hit a real calendar; the done/Saved transition is covered by outboxWorker tests + Gate 2 D1.)

3. All-day toggle hides time inputs

expected: Toggling All day on removes the start/end time fields; off restores them. result: pass evidence: Toggled the all-day switch → [checked]; the 09:00 / 10:00 time textboxes disappeared, Start/End showed date-only.

4. Edit mode pre-fill + recurrence preserved (WR-01 / WR-02 fix)

expected: Editing an event pre-populates fields; recurrence picker is disabled in edit mode with copy explaining the schedule is kept. result: pass evidence: Clicked a recurring occurrence → EventDetailPopover (live Edit/Delete footer) → Edit. "Edit Event" dialog pre-populated (title, dates 2026-06-10, times 10:00/11:00). Recurrence combobox rendered [disabled] with helper text "Repeat can't be changed yet — edits keep the existing schedule." — the exact preserve-on-edit guidance the WR-01/WR-02 fix added. Footer button correctly labelled "Save Changes".

5. Member-scoped read (CR-01 GET path)

expected: A member sees only events from calendars in their writable set. result: pass evidence: As dev user 1 (owns only the seeded UAT calendar), GET /api/events returned only that calendar's occurrences and writable-calendars returned only it — never the 538 events on user 2's calendars. Confirms the member-scoped query.

6. CR-01/CR-02 member-scoped edit/delete + freshest-etag (byte/SQL level)

expected: Edit/delete resolve the acting member's row (not an arbitrary shared-account duplicate); worker re-reads the writing member's etag. result: pass evidence: Certified by green API integration tests re-run this session (events.test.ts member-scoping + 503-join regression; outboxWorker freshest-etag WR-02 cases) — api 108 passed. Live-verified at Gate 2 D4/D5. Not UI-observable without a two-member shared-account dataset.

7. CR-03 all-day inclusive/exclusive round-trip (byte level)

expected: All-day events write exclusive DTEND, pre-fill inclusive on edit; span does not grow on re-edit. result: pass evidence: Certified by vevent.test.ts (inclusive→exclusive write) + EventForm.test.tsx (exclusive→inclusive pre-fill) — green. The all-day off-by-one was also fixed and confirmed live at Gate 2.

8. WR-01 + move-path RRULE preservation (byte level)

expected: Editing a recurring event keeps its RRULE, including edit-as-move to another calendar (worker create branch re-applies the source rule). result: pass evidence: Certified by the iteration-2 regression tests (events.test.ts _preservedRrule forwarding + outboxWorker create-branch RRULE re-apply) — green. UI half (disabled picker + helper) browser-verified in Test 4. Recurring round-trip live-verified at Gate 2 D3.

9. WR-04 sync-status ranking + IN-03 payload re-validation

expected: sync-status ranks a failed/dead row above an older done row; worker hard-fails malformed outbox payloads before any CalDAV call. result: pass evidence: Certified by green API integration tests (sync-status priority CASE; outbox payload safeParse hard-fail) re-run this session.

10. Coverage check (goal-backward against the phase user story)

expected: Members can create/edit/delete events written to the correct Fastmail calendar; app installable to iPhone & Android home screens with guided onboarding. result: pass (with documented deferrals) evidence: Create/edit/delete → correct Fastmail calendar: Gate 2 D1D6 (live). iPhone install + standalone OIDC login + onboarding walkthrough: Gate 2 B1B4 (live, load-bearing). Code paths present: EventForm/Edit/Delete + outbox worker, VitePWA manifest/SW + InstallPrompt walkthrough. Deferred (not failures): B5 Android install walkthrough (device check), C SSE smoke (Phase 4 entry gate per D-14).

Summary

total: 10 passed: 10 issues: 0 pending: 0 skipped: 0

Gaps

[none — 0 UAT issues]

Accepted limitations (carried forward, not UAT failures)

  • WR-01 (code-review Warning): a missing cached etag still produces an unconditional PUT/DELETE; has a console.warn, but true conflict prevention needs a deeper D-08 change. v1-accepted.
  • WR-02 (code-review Warning): edit cannot change/remove an RRULE — "omitted recurrence" means "keep existing"; surfaced to the user via the helper text verified in Test 4. Deferred to the recurrence-editing milestone.
  • Gate 2 deferrals: B5 Android install walkthrough (device-only human check); C SSE 5-min smoke (Phase 4 entry gate); backlog 999.3999.9 (session-timeout redirect, VALARM reminders, first-login app-password setup, all-day visual distinction, recurrence bound, edit-recurring-series).