diff --git a/specs/frontend/j5-shopping-list.html b/specs/frontend/j5-shopping-list.html index fb6213f..3f8beea 100644 --- a/specs/frontend/j5-shopping-list.html +++ b/specs/frontend/j5-shopping-list.html @@ -132,7 +132,7 @@

J5 — Shopping list

-

Journey spec — Generate shopping list, real-time shared checklist

+

Journey spec — Generate shopping list, shared checklist

v1.0
@@ -143,12 +143,12 @@
J5
-

Generate shopping list

Merge ingredients, filter staples. Always live and shared with household.

C1 → D1 (always live) · Planner generates · All members add/remove/check off
+

Generate shopping list

Merge ingredients, filter staples. Shared with household.

C1 → D1 · Planner generates · All members add/remove/check off
-

Shopping list (live)

D1
+

Shopping list

D1
V1 Checklist with sources. Desktop: sidebar + topbar + two-column content — checklist on the left, a "This week's recipes" reference panel on the right that shows which recipes contributed which items. The panel is a page section (surface bg), not a card.
V1 · Checklist with sources — desktop: list left, recipe reference right
@@ -162,7 +162,7 @@
-
Shared with household · 2 members online
+
Shared with household
5 items remaining
@@ -188,7 +188,7 @@
Plan
📅Planner
📖Recipes
🛒Shopping
-
Shopping list
2 members online
+
Shopping list
Shared with household
@@ -237,20 +237,20 @@

D1 · Shopping list

-
/* Desktop: 224px sidebar + topbar (title + shared status badge) + 2-col content:
+      
/* Desktop: 224px sidebar + topbar (title + shared badge) + 2-col content:
  *   Left (flex:1, page bg): remaining count + checklist rows + "checked off" section + add custom
  *   Right (280px, surface bg): recipe reference cards + filtered staples list + edit staples link
  * Recipe reference panel: page-section with surface bg, not a floating card.
  * Mobile: full-width checklist + shared banner + bottom tabs.
- * Real-time sync: is_checked updates broadcast to all connected clients.
+ * Sync model: server-authoritative — check/uncheck persists via form action, other users see changes on page refresh.
  * Both roles: planner + member can view and check off. Only planner can regenerate. */
- - + +
ElementValueNotes
Desktop
Checklist areaflex:1, page bg, 20px 24px paddingRemaining items + divider + checked items
Recipe reference280px, surface bg, border-leftRecipe name + day + ingredient count. Filtered staples below.
Shared state
Banner (mobile)blue-tint, blue dot, radius-lg"Shared · N online"
Badge (desktop)blue-tint pill in topbarCompact: dot + "N members online"
Banner (mobile)blue-tint, blue dot, radius-lg"Shared with household"
Badge (desktop)blue-tint pill in topbarCompact: dot + "Shared with household"
@@ -269,22 +269,23 @@

1. Journey flow

/* J5 flow
- * C1 (week confirmed) → D1 (shopping list, always live).
+ * C1 (week confirmed) → D1 (shopping list).
  * Actor: Planner generates the list. All household members shop (view, check off, add items).
  * Preconditions: J1 (recipes exist) + J2 (week is planned) for generating a list.
  *                J6 (household setup) for shared access.
- * There is NO draft/publish workflow — the list is always live. */
+ * Sync model: server-authoritative. Changes persist via form actions. + * Other users see updates on page refresh (no WebSocket/SSE). */ -

2. Screen D1 — Shopping list (live shared)

+

2. Screen D1 — Shopping list

/* Mobile layout:
  *   topbar (title + settings icon)
- *   + blue-tint shared banner ("Shared with household · N members online", blue dot)
+ *   + blue-tint shared banner ("Shared with household", blue dot)
  *   + checklist (unchecked items, then checked items below divider)
  *   + "+ Add custom item" link (blue-dark, centred)
  *   + bottom tabs (Planner | Recipes | Shopping [active] | Settings)
  *
  * Desktop layout:
- *   sidebar (224px, dsb) + topbar (dtb: title + blue-tint "N members online" badge)
+ *   sidebar (224px, dsb) + topbar (dtb: title + blue-tint "Shared with household" badge)
  *   + split content area:
  *     Left: checklist (flex:1, page bg, 20px 24px padding)
  *       - eyebrow "N items remaining · N checked off"
@@ -319,15 +320,14 @@
       
  • Filtered staples are listed in the recipe reference panel (desktop) for transparency
  • -

    4. Real-time sync

    -
    /* Real-time rules:
    - * - is_checked updates broadcast to ALL connected clients instantly
    - * - "N members online" indicator shows who is currently viewing the shopping list
    - * - Prevents double-buying when multiple family members shop simultaneously or at different times
    - * - Blue accent colour for all shared-state UI:
    - *     Mobile: blue-tint banner with blue dot
    - *     Desktop: blue-tint badge in topbar with blue dot
    - * - WebSocket or SSE for real-time — implementation choice, but must be instant */
    +

    4. Sync model

    +
    /* Sync rules:
    + * - Server-authoritative: all mutations (check, uncheck, add) go through form actions / API calls
    + * - No WebSocket or SSE — other users see changes on page refresh
    + * - Each check/uncheck is a single server round-trip (form action with use:enhance)
    + * - Blue accent colour for shared-state UI:
    + *     Mobile: blue-tint banner with blue dot ("Shared with household")
    + *     Desktop: blue-tint badge in topbar with blue dot ("Shared with household") */

    5. Custom items

      @@ -352,22 +352,20 @@ * UPDATE shopping_list_item * SET is_checked = true/false * WHERE id = :item_id - * → broadcast change to all connected clients via real-time channel * * Add custom: * INSERT INTO shopping_list_item (name, quantity, is_custom, is_checked, shopping_list_id) - * VALUES (:name, :quantity, true, false, :list_id) - * → broadcast new item to all connected clients */
    + * VALUES (:name, :quantity, true, false, :list_id) */

    7. Design constraints

      -
    • List is ALWAYS live — no draft/publish workflow, no approval step
    • +
    • List is shared — all household members see the same list on refresh
    • Both planner and member can: view, check off, add custom items, remove items
    • Only planner can: generate list, regenerate list
    • "Edit staples" link navigates to D3 (same component as A3 — build once, reference from two entry points)
    • CalDAV export is future scope (E3) — do not build in v1
    • Recipe reference panel is a page section with surface bg — NOT a floating card
    • -
    • Blue accent colour is reserved for shared/collaborative state indicators
    • +
    • Blue accent colour for shared-state banner/badge ("Shared with household")
    • Checked items must visually separate from unchecked via a divider and "Checked off" label
    @@ -375,7 +373,7 @@
    /* Precondition chain:
      * J1 (recipes exist) — cannot generate a shopping list without recipes
      * J2 (week is planned) — cannot generate a shopping list without planned meals
    - * J6 (household setup) — required for shared access (multiple members online)
    + * J6 (household setup) — required for shared access
      *
      * If no meals are planned: show empty state on D1 with prompt to plan the week first
      * If no household members: list works for solo planner, shared banner is hidden */