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

115 lines
7.0 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.
---
status: complete
phase: 03-event-write-back-pwa-install
mode: mvp
source:
- 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)
scope: regression-focused (post code-review-fix)
method: playwright-cli desktop drive (local dev-bypass stack, no real Fastmail writes) + green test suites + Gate 2 record
started: 2026-06-09T15:20:00Z
updated: 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).