--- id: TASK-16 title: Live interconnected r* demo pages via shared rSpace data layer status: Done assignee: [] created_date: '2026-02-15 16:40' updated_date: '2026-02-15 16:40' labels: - feature - demo - real-time - cross-app dependencies: [] priority: high --- ## Description Replace all static demo pages across the r* ecosystem with live, interactable demos connected through a shared rSpace "demo" community. Changes in one app propagate to all others in real-time via WebSocket. ## Acceptance Criteria - [x] #1 JSON WebSocket mode added to rSpace server (?mode=json) - [x] #2 GET /api/communities/:slug/shapes endpoint - [x] #3 POST /api/communities/demo/reset with rate limiting - [x] #4 Alpine Explorer 2026 seed data (~40 shapes) via seed-demo.ts - [x] #5 useDemoSync React hook (~220 lines, zero deps beyond React) - [x] #6 rTrips demo rewritten with live data (hub showing all shape types) - [x] #7 rNotes demo rewritten with live notes, notebooks, packing lists - [x] #8 rCart demo rewritten with live cart items and funding - [x] #9 rVote demo rewritten with live polls and voting - [x] #10 rMaps demo rewritten with live map markers and destinations - [x] #11 rFunds demo created with live expenses and budget tracking - [x] #12 All changes sync across apps in real-time via shared demo community ## Final Summary ## Implementation Complete ### Server-side (rspace-online) - **JSON WebSocket mode**: Added `?mode=json` query param to WS upgrade. Server bridges Automerge↔JSON, avoiding ~500KB Automerge bundle in demo pages - **GET shapes endpoint**: `GET /api/communities/:slug/shapes` returns all shapes as JSON - **Demo reset**: `POST /api/communities/demo/reset` clears and re-seeds (5-min rate limit) - **Seed script**: `server/seed-demo.ts` creates "demo" community with `visibility: "public"` and populates ~40 shapes for Alpine Explorer 2026 scenario ### Shared hook - **useDemoSync**: `src/lib/demo-sync.ts` (~220 lines) — WebSocket JSON mode, auto-reconnect, exponential backoff, ping keepalive, optimistic updates, shape type filtering, resetDemo() ### Demo page rewrites (6 apps) | App | Shape Types | Key Interactions | |-----|-------------|-----------------| | rTrips | all (hub) | View cross-app data, toggle packing | | rNotes | folk-note, folk-notebook, folk-packing-list | Expand notes, toggle packing checkboxes | | rCart | demo-cart-item | Fund items, add to cart | | rVote | demo-poll | Cast votes, see live tallies | | rMaps | demo-map-marker, folk-destination | Click markers, view details | | rFunds | demo-expense, folk-budget | Edit expenses, see balances | ### Commits pushed to Gitea - rspace-online: `0a32944` - rtrips-online: `fa778ed` - rnotes-online: `30f3383` - rcart-online: `9d16bf3` - rvote-online: `160a556` - rmaps-online: `8e96d4e` - rfunds-online: `216df8c`