---
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

<!-- SECTION:DESCRIPTION:BEGIN -->
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.
<!-- SECTION:DESCRIPTION:END -->

## Acceptance Criteria
<!-- AC:BEGIN -->
- [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
<!-- AC:END -->

## Final Summary

<!-- SECTION:FINAL_SUMMARY:BEGIN -->
## 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`
<!-- SECTION:FINAL_SUMMARY:END -->
