chore: archive v1.0 milestone files
This commit is contained in:
+22
-248
@@ -1,266 +1,40 @@
|
||||
# Roadmap: FamilySync
|
||||
|
||||
## Overview
|
||||
## Milestones
|
||||
|
||||
FamilySync is built in five phases, each delivering an end-to-end user-observable capability. Phase 1 is both the foundation and the highest-risk gate: OIDC auth must work and the CalDAV broker must prove it can read personal Fastmail calendars before any calendar UI is built. Phases 2–3 complete the calendar. Phase 4 delivers shared lists with live co-edit sync. Phase 5 wires up Web Push notifications. The dependency chain is strict: each phase is a prerequisite for the next, except the lists track (Phase 4) which is independent of the calendar write path.
|
||||
- ✅ **v1.0 MVP** — Phases 1–6 (shipped 2026-06-10) — see [`milestones/v1.0-ROADMAP.md`](milestones/v1.0-ROADMAP.md)
|
||||
|
||||
## Phases
|
||||
|
||||
**Phase Numbering:**
|
||||
<details>
|
||||
<summary>✅ v1.0 MVP (Phases 1–6) — SHIPPED 2026-06-10</summary>
|
||||
|
||||
- Integer phases (1, 2, 3): Planned milestone work
|
||||
- Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED)
|
||||
- [x] Phase 1: Foundation + Broker Spike (4/4 plans) — completed 2026-06-04
|
||||
- [x] Phase 2: Calendar Display (5/5 plans) — completed 2026-06-05
|
||||
- [x] Phase 3: Event Write-Back + PWA Install (12/12 plans) — completed 2026-06-07
|
||||
- [x] Phase 4: Shared Lists + Live Sync (7/7 plans) — completed 2026-06-09
|
||||
- [x] Phase 5: Web Push Notifications (8/8 plans) — completed 2026-06-10
|
||||
- [x] Phase 6: UX Polish (6/6 plans) — completed 2026-06-10
|
||||
|
||||
Decimal phases appear between their surrounding integers in numeric order.
|
||||
Full phase detail archived in [`milestones/v1.0-ROADMAP.md`](milestones/v1.0-ROADMAP.md).
|
||||
|
||||
- [x] **Phase 1: Foundation + Broker Spike** - Auth, Docker scaffold, CalDAV broker read path, and personal-calendar ACL spike (go/no-go gate) (completed 2026-06-04)
|
||||
- [x] **Phase 2: Calendar Display** - Read-only unified color-coded calendar (week/month/day/agenda) built on the confirmed broker (completed 2026-06-05)
|
||||
- [x] **Phase 3: Event Write-Back + PWA Install** - Full event CRUD written back to Fastmail, PWA manifest + service worker, guided iOS install flow (completed 2026-06-07)
|
||||
- [x] **Phase 4: Shared Lists + Live Sync** - Named collaborative lists with item CRUD and real-time SSE co-edit sync (completed 2026-06-09)
|
||||
- [x] **Phase 5: Web Push Notifications** - VAPID push for event reminders, event changes, and list-change alerts (completed 2026-06-10; on-device UAT 1/2/5 PASS, T3 dropped as non-gating, T4 Android event-change push deferred to Phase 6 verification — see 05-UAT.md)
|
||||
- [x] **Phase 6: UX Polish** - All-day visual distinction, event-form date/recurrence behavior, recurring-series edit, and auth-flow smoothing (completed 2026-06-10)
|
||||
</details>
|
||||
|
||||
## Phase Details
|
||||
### 🚧 v1.x (Planned)
|
||||
|
||||
### Phase 1: Foundation + Broker Spike
|
||||
|
||||
**Goal**: The app stack is running, both members can authenticate, and the CalDAV broker can read Fastmail calendars — with a confirmed go/no-go decision on personal-calendar cross-account sharing
|
||||
**Mode:** mvp
|
||||
**Depends on**: Nothing (first phase)
|
||||
**Requirements**: AUTH-01, AUTH-02, AUTH-03, CAL-01, CAL-08
|
||||
**Success Criteria** (what must be TRUE):
|
||||
|
||||
1. Both members can reach the app URL, authenticate through Authelia OIDC, and land on the app home page without entering any Fastmail credentials
|
||||
2. Sessions persist across browser restarts — neither member is asked to log in again on the next visit
|
||||
3. Each member is assigned a stable, distinct display color that does not change between sessions
|
||||
4. The broker successfully fetches and caches at least one event from the shared Fastmail calendar via CalDAV PROPFIND/REPORT
|
||||
5. The personal-calendar ACL spike produces a documented go/no-go decision: either the broker token sees the wife's personal calendar after Fastmail share+accept, or the fallback strategy (shared-family-only or per-member app password) is chosen and recorded
|
||||
|
||||
**Verification status (D-14, 2026-06-04):** Code + **Gate 1** complete. Gate 1 = stack up (`/health` live), CAL-01 proven live (503 real events cached via REPORT), CAL-08 = **GO** (per-member app-password model, see `CAL-08-DECISION.md`). **Gate 2 deferred** — criteria 1/2/3 (live Authelia OIDC login over Pangolin, session persistence, distinct colors in a real browser) and the SSE-over-Pangolin smoke test require the operator's Authelia + Pangolin/Newt infra; tracked in `01-HUMAN-UAT.md` and `docs/deployment.md`. The live AUTH smoke (incl. iOS) is folded into **Phase 3**; the SSE smoke is a hard gate before **Phase 4**. Phases 2–3 develop behind a documented dev-auth bypass.
|
||||
|
||||
**Plans**: 4 plans
|
||||
Plans:
|
||||
|
||||
- [x] 01-01-PLAN.md — Walking skeleton: monorepo scaffold + Docker/MariaDB + Drizzle schema (push) + /health end-to-end slice + Vitest Wave 0 harness
|
||||
- [x] 01-02-PLAN.md — Authelia OIDC slice: stable identity (iss+sub) + auto-assigned member color + /api/me + authenticated PWA shell (AUTH-01/02/03)
|
||||
- [x] 01-03-PLAN.md — CalDAV broker slice: AES-256-GCM credential encryption + tsdav broker + ical.js sync (all-day DATE) + ctag poller + /api/events (CAL-01)
|
||||
- [x] 01-04-PLAN.md — Integration + gate: wire poller/routes, event-proof landing page, CAL-08 spike + go/no-go doc, live Pangolin deploy + SSE smoke test
|
||||
|
||||
### Phase 2: Calendar Display
|
||||
|
||||
**Goal**: Both members can see a unified, color-coded calendar aggregating all accessible Fastmail calendars across day, week, month, and agenda views — read-only, no write-back yet
|
||||
**Mode:** mvp
|
||||
**Depends on**: Phase 1
|
||||
**Requirements**: CAL-02, CAL-03, CAL-07
|
||||
**Success Criteria** (what must be TRUE):
|
||||
|
||||
1. Opening the app shows a color-coded calendar where each member's events appear in their assigned color, with shared events distinguishable from personal events
|
||||
2. The user can switch between day, week, month, and agenda views and all events render correctly in each view
|
||||
3. A recurring event (e.g., weekly meeting) displays all its occurrences correctly in the current view window, including correct behavior across DST boundaries
|
||||
4. All-day events (birthdays, holidays) appear as full-day banners on the correct date with no timezone shift
|
||||
|
||||
**Plans**: 5 plansPlans:
|
||||
**Wave 1**
|
||||
|
||||
- [x] 02-01-PLAN.md — Foundation: schema (hasRrule + calendars.isShared, pushed) + dev-auth bypass + PWA vitest/jsdom harness + ICS fixtures + RED test stubs
|
||||
|
||||
**Wave 2** *(blocked on Wave 1 completion)*
|
||||
|
||||
- [x] 02-02-PLAN.md — Backend slice: expandOccurrences() (VTIMEZONE/DST + all-day + EXDATE) + windowed/joined/zod-validated /api/events + shared-calendar checkpoint (CAL-02/CAL-07)
|
||||
- [x] 02-03-PLAN.md — Frontend foundation: CSS token layer + colorUtils + calendarConfig (firstDayOfWeek 0→7) + hydrateEvents (Temporal/PlainDate guard) + Zustand store + windowed fetchEvents
|
||||
|
||||
**Wave 3** *(blocked on Wave 2 completion)*
|
||||
|
||||
- [x] 02-04-PLAN.md — Vertical slice: CalendarShell mounts Schedule-X, renders real windowed Fastmail events color-coded across all four views (CAL-02/CAL-03)
|
||||
|
||||
**Wave 4** *(blocked on Wave 3 completion)*
|
||||
|
||||
- [x] 02-05-PLAN.md — UX completion: read-only EventDetailPopover + ColorLegend + nav/toolbar + skeleton/empty/error states + human visual verification
|
||||
|
||||
**Gap-closure waves** *(from 03-REVIEW.md — write path was broken end-to-end; Gate 2 / 03-08 is blocked on these)*
|
||||
|
||||
- [x] 03-09-PLAN.md — Route layer: align zod schema to client title/start/end contract (CR-01) + real OIDC iss/sub→users.id resolution on all 5 handlers (CR-06) [wave 1]
|
||||
- [x] 03-12-PLAN.md — PWA EventForm: edit-mode population + recurrence preselect (WR-03), zone-consistent dates (WR-05), real focus trap (WR-07); PWA-01/02 install assets verified [wave 1]
|
||||
- [x] 03-10-PLAN.md — Worker dispatch: build real VEVENT via buildVeventString + all-day DTEND+1 (CR-02/WR-04), fail closed on bad creds (CR-03), backoff index + randomUUID (WR-01/WR-08) [wave 2, after 03-09]
|
||||
- [x] 03-11-PLAN.md — Outbox durability: durable create-before-delete (CR-04), drain concurrency guard (CR-05), fresh-etag-before-PUT (WR-02) [wave 3, after 03-10]
|
||||
|
||||
**UI hint**: yes
|
||||
|
||||
### Phase 3: Event Write-Back + PWA Install
|
||||
|
||||
**Goal**: Both members can create, edit, and delete events that are written back to the correct Fastmail calendar, and the app is installable to the iPhone and Android home screens with a guided onboarding flow
|
||||
**Mode:** mvp
|
||||
**Depends on**: Phase 2
|
||||
**Requirements**: CAL-04, CAL-05, CAL-06, CAL-07, PWA-01, PWA-02
|
||||
**Success Criteria** (what must be TRUE):
|
||||
|
||||
1. A member can create a timed or all-day event (including recurring events) in the app and see it appear in the native Fastmail app within the next sync cycle
|
||||
2. A member can edit an existing event's title, time, or description and the change persists correctly in Fastmail
|
||||
3. A member can delete an event and it disappears from all views on the next sync
|
||||
4. On Android, the app shows a browser install prompt and installs to the home screen; on iOS, the app shows a guided "Add to Home Screen" walkthrough with annotated screenshots that a non-technical user can follow independently
|
||||
5. The installed PWA opens full-screen without browser chrome on both iOS and Android
|
||||
6. **(Carried from Phase 1 Gate 2, D-14)** Live Authelia OIDC login works over the public Pangolin URL — including the **iOS standalone-PWA** flow: the wife can install to Home Screen and complete login without the redirect breaking out of standalone mode; sessions persist (AUTH-01/02) and members get distinct stable colors (AUTH-03). Verify per `docs/deployment.md` Gate 2 checklist; this is the first real external deploy (local Newt test rig is sufficient — Unraid prod is optional until go-live).
|
||||
|
||||
**Plans**: 12 plans (8 original + 4 gap-closure from 03-REVIEW.md)
|
||||
Plans:
|
||||
**Wave 1**
|
||||
|
||||
- [x] 03-01-PLAN.md — Foundation: calendarOutbox table + calendarEvents.objectUrl (pushed), vite-plugin-pwa install + legitimacy gate, sync.ts objectUrl, full Wave 0 RED test scaffold
|
||||
|
||||
**Wave 2** *(blocked on Wave 1)*
|
||||
|
||||
- [x] 03-02-PLAN.md — TDD: VEVENT builder (vevent.ts, D-13 DATE/DATETIME + RRULE) + tsdav write wrappers (write.ts, D-12 broker boundary)
|
||||
- [x] 03-03-PLAN.md — Write API: POST/PATCH/DELETE events + GET sync-status, enqueue-only, D-03 ownership, D-04 edit-as-move pair (CAL-04/05/06/07)
|
||||
|
||||
**Wave 3** *(blocked on Wave 2)*
|
||||
|
||||
- [x] 03-04-PLAN.md — TDD: outbox worker state machine (D-05/06/07/08 retry/backoff/dead/conflict, edit-as-move ordering) + index.ts wiring
|
||||
- [x] 03-05-PLAN.md — Frontend create/edit slice: write client calls + Zustand keys + EventForm (D-01/02/11) + New Event FAB
|
||||
- [x] 03-07-PLAN.md — PWA install: VitePWA manifest + auth-safe SW denylist + icons + InstallPrompt (iOS walkthrough + Android prompt) (PWA-01/02)
|
||||
|
||||
**Wave 4** *(blocked on Wave 3)*
|
||||
|
||||
- [x] 03-06-PLAN.md — Delete + sync feedback: popover Edit/Delete footer + DeleteConfirmationDialog + SyncStateToast polling (D-06/08/09) (CAL-05/06)
|
||||
|
||||
**Wave 5** *(blocked on Wave 4)*
|
||||
|
||||
- [x] 03-08-PLAN.md — Gate 2 live verification: real Authelia OIDC over Pangolin + iOS standalone login + end-to-end Fastmail write round-trips (success criterion 6, D-14/D-15)
|
||||
|
||||
**UI hint**: yes
|
||||
|
||||
### Phase 4: Shared Lists + Live Sync
|
||||
|
||||
**Goal**: Both members can create and manage shared named lists with real-time co-edit sync — edits by one member appear for the other without any manual refresh
|
||||
**Mode:** mvp
|
||||
**Depends on**: Phase 1
|
||||
**⚠️ Entry gate (D-14):** The **SSE-over-Pangolin smoke test** (deferred from Phase 1 Gate 2, issue #1034) MUST pass before building live sync — hold `/api/sse/heartbeat` open 5+ min through the tunnel without it being cut (see `docs/deployment.md`). If it FAILS: fix Pangolin idle-timeout/buffering, or plan a reconnect/polling fallback into this phase before proceeding. Do not build the live-sync layer on an unverified transport.
|
||||
**Requirements**: LIST-01, LIST-02, LIST-03, LIST-04
|
||||
**Success Criteria** (what must be TRUE):
|
||||
|
||||
1. Either member can create a named list (e.g., "Groceries") and delete a list they no longer need
|
||||
2. Either member can add items to a list, check items off, reorder them by drag-and-drop, and delete individual items
|
||||
3. When one member adds or checks off an item, the other member sees the change appear in the list within a few seconds without refreshing — even if they reconnect after a brief network gap
|
||||
|
||||
**Entry gate status (2026-06-08):** CLEARED — SSE-over-Pangolin smoke test PASSED (35 heartbeats over ~6 min, buffering off, no cut). Live sync may be built directly on SSE; polling fallback (D-12) retained as belt-and-suspenders.
|
||||
|
||||
**Plans**: 7 plans (6 + 1 gap-closure)
|
||||
Plans:
|
||||
**Wave 1**
|
||||
|
||||
- [x] 04-01-PLAN.md — Foundation + app shell: deps install (+ legitimacy gate), list tables generate+migrate [BLOCKING], API test harness + Wave-0 RED stubs, react-router + BottomTabBar + empty ListsIndex (D-13/D-16/D-17/D-18)
|
||||
|
||||
**Wave 2** *(blocked on Wave 1)*
|
||||
|
||||
- [x] 04-02-PLAN.md — TDD: scoped in-memory fan-out (listEmitter) + getAccessibleListIds access scope — the load-bearing D-04 no-leak primitive (LIST-04)
|
||||
- [x] 04-03-PLAN.md — List CRUD slice: POST/GET/PATCH/DELETE /api/lists with scoped access + auto-share-on-create + ListsIndex/ListCard/CreateListSheet/ListDeleteDialog (LIST-01, D-01/D-02/D-06)
|
||||
|
||||
**Wave 3** *(blocked on Wave 2)*
|
||||
|
||||
- [x] 04-04-PLAN.md — Item CRUD + checked-sink slice: item endpoints + fractional rank + per-field LWW PATCH + ListDetail/ItemRow/AddItemInput + optimistic UI (LIST-02, D-05/D-07/D-08/D-09)
|
||||
|
||||
**Wave 4** *(blocked on Wave 3)*
|
||||
|
||||
- [x] 04-05-PLAN.md — Reorder slice: dnd-kit sortable + generateKeyBetween rank + one-row position PATCH + animate-on-remote (LIST-03, D-13/D-14/D-15)
|
||||
|
||||
**Wave 5** *(blocked on Waves 2 + 4)*
|
||||
|
||||
- [x] 04-06-PLAN.md — Live-sync slice: scoped /api/sse/lists + fan-out triggers + useListSSE bounded-backoff hook + LiveSyncIndicator + polling fallback (LIST-04, D-04/D-10/D-11/D-12)
|
||||
|
||||
**Wave 6** *(gap closure — blocked on Waves 2 + 4)*
|
||||
|
||||
- [x] 04-07-PLAN.md — Gap closure: migrate list_items.rank to COLLATE utf8mb4_bin (LIST-03 drag-to-top) + owner-only guard on PATCH isShared (T-04-08/T-04-05) — two TDD features (LIST-03)
|
||||
|
||||
**UI hint**: yes
|
||||
|
||||
### Phase 5: Web Push Notifications
|
||||
|
||||
**Goal**: Both members receive timely Web Push alerts for upcoming events, event changes made by the other member, and list changes — reliably on both iOS and Android
|
||||
**Mode:** mvp
|
||||
**Depends on**: Phase 3, Phase 4
|
||||
**Requirements**: NOTIF-01, NOTIF-02, NOTIF-03
|
||||
**Success Criteria** (what must be TRUE):
|
||||
|
||||
1. A member receives a push notification on their phone approximately 15 minutes before a calendar event starts — delivered to the installed PWA, including on iOS
|
||||
2. When the other member adds or changes a calendar event, the first member receives a push notification with the event title and action described in the payload
|
||||
3. When the other member modifies a shared list (adds, checks off, or deletes an item), the first member receives a push notification identifying the list and the change
|
||||
4. After an extended period of app inactivity, push notifications are still delivered (subscription health-check prevents silent revocation on iOS)
|
||||
|
||||
**Plans**: 8 plans (6 waves)
|
||||
Plans:
|
||||
**Wave 1**
|
||||
|
||||
- [x] 05-01-PLAN.md — Foundation: install web-push + workbox deps (legitimacy gate), generate VAPID keypair, push_subscriptions table + calendar_events.title generate+migrate [BLOCKING], Wave-0 RED scaffolds (D-11/D-12)
|
||||
|
||||
**Wave 2** *(blocked on Wave 1)*
|
||||
|
||||
- [x] 05-02-PLAN.md — TDD: pushDispatcher (VAPID send + dual-format payload + 410/404 prune) (D-11)
|
||||
- [x] 05-03-PLAN.md — TDD: pushCoalescer (per-list/actor debounce, generic copy, self-suppress) (D-01/D-02/D-03)
|
||||
|
||||
**Wave 3** *(blocked on Wave 2)*
|
||||
|
||||
- [x] 05-04-PLAN.md — Subscribe slice (end-to-end): push subscription API + setVapidDetails, generateSW→injectManifest SW migration (push/notificationclick/denylist), usePushSubscription + PushPermissionPrompt (D-08/D-11/D-14)
|
||||
|
||||
**Wave 4** *(blocked on Wave 3)*
|
||||
|
||||
- [x] 05-05-PLAN.md — NOTIF-02 list-change slice: listChangeDispatcher + hook coalescer into mutations, reorder-silent (D-01/D-02/D-03)
|
||||
- [x] 05-06-PLAN.md — TDD: NOTIF-01 reminderScheduler — shared-timed 15-min scan (query-enforced D-05), all-day excl, dedup, empty-set safe (D-05/D-06/D-07)
|
||||
|
||||
**Wave 5** *(blocked on Wave 4)*
|
||||
|
||||
- [x] 05-07-PLAN.md — TDD: NOTIF-03 eventChangeDispatcher + syncCalendar diff/title/onChanges hook (poller + outbox), meaningful-only, actor-suppressed (D-02/D-03/D-04/D-13)
|
||||
|
||||
**Wave 6** *(blocked on Wave 3)*
|
||||
|
||||
- [x] 05-08-PLAN.md — Settings + reliability: master toggle (D-09) + silent re-subscribe (D-10) + PermissionDeniedBanner + avatar→Settings sheet
|
||||
|
||||
**UI hint**: yes
|
||||
|
||||
### Phase 6: UX Polish
|
||||
|
||||
**Goal**: Smooth the rough edges surfaced during live use — clearer all-day events, saner event-form date/recurrence behavior, recurring-series editing, and auth-flow polish — so the app feels slick for the non-technical Apple member (hard UX constraint).
|
||||
**Mode:** mvp
|
||||
**Depends on**: Phase 3 (calendar/event-form polish); Phase 4 for any list-related polish
|
||||
**Requirements**: none (all v1 REQ-IDs complete in Phases 1–5; this is a polish phase tracked against backlog items 999.2/3/6/7/8/9 and locked decisions D-01..D-13)
|
||||
**Success Criteria** (what must be TRUE):
|
||||
|
||||
1. All-day events are visually distinct from timed events at a glance
|
||||
2. The event form keeps a sane duration when the start moves, all-day edits don't grow the event, and a recurrence can be bounded (repeat-until / count)
|
||||
3. A recurring series can be edited as a whole
|
||||
4. A session that expires mid-use redirects cleanly to sign-in instead of hanging on a generic error
|
||||
5. Unauthenticated cold load shows a neutral "signing you in…" splash — no calendar/"sign-in required" flash before Authelia
|
||||
|
||||
**Scope** (promoted from backlog, locked at planning): 999.2 (login flash), 999.3 (session-timeout redirect), 999.6 (all-day visual), 999.7 (form end-tracking + all-day-edit off-by-one), 999.8 (recurrence bound), 999.9 (recurring-series edit). 999.4 (reminders) and 999.5 (provider setup) deferred to milestone 1.1 (D-01/D-02).
|
||||
|
||||
**Plans**: 6 plans (2 waves)
|
||||
Plans:
|
||||
**Wave 1** *(parallel — exclusive file ownership)*
|
||||
|
||||
- [x] 06-01-PLAN.md — TDD: duration-preserving end-tracking math (computeNewTimedEnd/computeNewAllDayEnd) in eventDateTime.ts (D-04)
|
||||
- [x] 06-02-PLAN.md — TDD: RRULE UNTIL/COUNT serialization + Zod acceptance + FREQ-persistence regression (vevent/outboxWorker/events route) (D-06/D-07)
|
||||
- [x] 06-03-PLAN.md — TDD: hasRrule on CalendarOccurrence + bounded-expansion lock (expand.ts) (D-06/D-08)
|
||||
- [x] 06-04-PLAN.md — Spinner/pulse: global @keyframes pulse + remove redundant spin redefinition (D-13)
|
||||
- [x] 06-05-PLAN.md — Auth gating slice: SessionExpiredError + AuthSplash + global QueryCache/MutationCache error handler; client.ts type mirrors (D-10/D-11, + D-06/D-08 type carriers)
|
||||
|
||||
**Wave 2** *(blocked on 06-01/02/03/05)*
|
||||
|
||||
- [x] 06-06-PLAN.md — EventForm integration slice: end-tracking wiring + recurrence-bound control + series-edit prompt + all-day pill (D-03/D-04/D-05/D-06/D-07/D-08/D-09/D-12)
|
||||
|
||||
**UI hint**: yes
|
||||
No phases planned yet. Promote items from the Backlog with `/gsd-review-backlog`, or start the next cycle with `/gsd-new-milestone`.
|
||||
|
||||
## Progress
|
||||
|
||||
**Execution Order:**
|
||||
Phases execute in numeric order: 1 → 2 → 3 → 4 → 5 → 6
|
||||
Note: Phase 4 depends only on Phase 1 and can begin as soon as Phase 1 is complete. It is serialized here to reduce work-in-progress.
|
||||
| Phase | Milestone | Plans Complete | Status | Completed |
|
||||
| ----- | --------- | -------------- | -------- | ---------- |
|
||||
| 1. Foundation + Broker Spike | v1.0 | 4/4 | Complete | 2026-06-04 |
|
||||
| 2. Calendar Display | v1.0 | 5/5 | Complete | 2026-06-05 |
|
||||
| 3. Event Write-Back + PWA Install| v1.0 | 12/12 | Complete | 2026-06-07 |
|
||||
| 4. Shared Lists + Live Sync | v1.0 | 7/7 | Complete | 2026-06-09 |
|
||||
| 5. Web Push Notifications | v1.0 | 8/8 | Complete | 2026-06-10 |
|
||||
| 6. UX Polish | v1.0 | 6/6 | Complete | 2026-06-10 |
|
||||
|
||||
| Phase | Plans Complete | Status | Completed |
|
||||
|-------|----------------|--------|-----------|
|
||||
| 1. Foundation + Broker Spike | 4/4 | Complete | 2026-06-04 |
|
||||
| 2. Calendar Display | 5/5 | Complete | 2026-06-05 |
|
||||
| 3. Event Write-Back + PWA Install | 12/12 | Complete | 2026-06-07 |
|
||||
| 4. Shared Lists + Live Sync | 6/6 | Complete | 2026-06-09 |
|
||||
| 5. Web Push Notifications | 8/8 | Complete | 2026-06-10 |
|
||||
| 6. UX Polish | 6/6 | Complete | 2026-06-10 |
|
||||
|
||||
## Backlog
|
||||
|
||||
|
||||
Reference in New Issue
Block a user