Files
familysync/.planning/milestones/v1.0-phases/03-event-write-back-pwa-install/03-DISCUSSION-LOG.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.2 KiB
Raw Blame History

Phase 3: Event Write-Back + PWA Install - Discussion Log

Audit trail only. Do not use as input to planning, research, or execution agents. Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.

Date: 2026-06-05 Phase: 3-Event Write-Back + PWA Install Areas discussed: Target calendar pick, Write feedback & sync

Areas offered but not selected (left to Claude's discretion): Event form & fields, iOS install onboarding.


Target calendar pick

Default target calendar for a new event

Option Description Selected
Their own personal New events default to the creator's own personal calendar
Shared Family Default to the shared Family calendar; personal is opt-out (needs fallback, may not exist)
Remember last-used Default to whatever calendar they last wrote to, persisted per member

User's choice: Remember last-used Notes: Seed/first-time default set to creator's own personal (always exists; shared may not, per D-16).

Calendar selector visibility

Option Description Selected
Only when >1 writable Hide picker when only one writable calendar exists; show once shared Family exists
Always show Always render the selector with default pre-selected

User's choice: Only when >1 writable

Move event between calendars on edit

Option Description Selected
Lock calendar on edit Calendar fixed once created; defer cross-calendar move to v1.x
Allow move Edit may change target calendar (CalDAV delete-old + create-new)

User's choice: Allow move Notes: Researcher/planner must handle UID/etag and partial-failure safety.

Writable calendar set

Option Description Selected
Own personal + shared Family Write to own personal + shared Family; other member's personal is read-only overlay
Any visible calendar Allow writing to any aggregated calendar incl. other member's personal

User's choice: Own personal + shared Family


Write feedback & sync

How the member sees their own change after save (poll-based cache)

Option Description Selected
Optimistic + forced re-sync Optimistic UI update + background targeted re-sync of that calendar (evolved into)
Forced re-sync, then show Synchronously re-sync that calendar, then refresh; ~0.51s spinner ✓ (initial)
Wait for poll Let the ctag poller pick it up next cycle; visibly laggy

User's choice: Forced re-sync, then show — subsequently evolved (via the failure-handling answer) into optimistic-accept + queued write + re-sync on confirm. Same authoritative-cache guarantee, async instead of blocking.

Behavior when the CalDAV write fails

Option Description Selected
Inline error + retry, keep form Keep form + input, show inline error, manual retry
Toast + silent rollback Close form, roll back optimistic change, transient toast

User's choice: Free-text — "accept the edit, queue it, keep a toast showing it isn't sync'd yet and keep retrying. Transient failures should be short; anything beyond that is a hard fail that won't auto-resolve." Notes: Reframed the save path into an optimistic-accept + queued-write-with-retry model (outbox).

Edit-conflict (etag mismatch / 412) handling

Option Description Selected
Detect + warn, reload latest If-Match cached etag; on 412 abort, re-sync, warn before retry
Last-write-wins No If-Match; overwrite whatever is on Fastmail

User's choice: Detect + warn, reload latest

Pending-write queue location

Option Description Selected
Server-side outbox (MariaDB) API persists pending row; backend worker drains with backoff; survives app close
Client-side queue (PWA) PWA holds + retries; stops when app closed unless persisted

User's choice: Server-side outbox (MariaDB)

Transient vs hard-failure classification

Option Description Selected
Backoff transient; fail-fast hard errors Network/5xx/timeout → bounded backoff; 401/403/400/412 → stop/surface
Let me refine the thresholds Operator specifies retry window/backoff/status codes

User's choice: Backoff transient; fail-fast hard errors (412 routed to the conflict-reload flow)


Claude's Discretion

  • Event form & fields (field set, layout) — build into / alongside the reused EventDetailPopover.
  • Recurrence creation UX (presets vs custom builder) — whole-series only for v1.
  • iOS install onboarding (trigger + annotated walkthrough) and Android beforeinstallprompt.
  • vite-plugin-pwa manifest + service worker config (keep SW conservative re: OIDC/iOS login).
  • Outbox worker mechanics (interval/trigger, idempotency key, max attempts, dead-letter).

Deferred Ideas

  • Single-occurrence / "this-and-following" recurring edits (CAL-09/CAL-10) — v1.x.
  • Writing to the other member's personal calendar — out (read-only overlay in v1).
  • SSE-based live sync-state push — after the Phase 4 SSE-over-Pangolin gate; Phase 3 uses polling.