78 lines
3.8 KiB
Markdown
78 lines
3.8 KiB
Markdown
---
|
|
id: TASK-118
|
|
title: 'Epic: Make all rApps multiplayer with "Pull rApplet to rSpace"'
|
|
status: To Do
|
|
assignee: []
|
|
created_date: '2026-03-16 00:05'
|
|
labels:
|
|
- epic
|
|
- multiplayer
|
|
- architecture
|
|
milestone: Multiplayer Everything
|
|
dependencies: []
|
|
priority: high
|
|
---
|
|
|
|
## Description
|
|
|
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
|
Ensure every rApp module has:
|
|
1. **Multiplayer real-time sync** via existing Automerge/local-first stack — see other participants' changes live
|
|
2. **"Pull rApplet to rSpace" button** — a standard UI pattern letting space owners pull/enable an rApp module into their space from a global catalog
|
|
|
|
## Current State (27 modules)
|
|
- **12 already have local-first/Automerge**: rbooks, rcal, rcart, rfiles, rflows, rinbox, rnotes, rsocials, rsplat, rtasks, rtrips, rvote
|
|
- **2 use ephemeral WebSocket sync** (no Automerge): rmaps, rnetwork
|
|
- **13 have NO real-time sync**: rchoices, rdata, rdesign, rdocs, rforum, rmeets, rphotos, rpubs, rswag, rtube, rwallet, rspace, rschedule
|
|
|
|
## "Pull rApplet to rSpace" Pattern
|
|
A standardized UI component (`folk-applet-pull.ts`) that:
|
|
- Shows available rApps as cards in a global catalog
|
|
- Space owners can enable/disable modules per-space via PATCH `/:space/modules`
|
|
- Each module card shows: name, icon, description, sync status, scope (space/global)
|
|
- Enabled modules appear in the space's app switcher
|
|
- Uses existing `enabledModules` API in `server/spaces.ts`
|
|
|
|
## Multiplayer Tiers
|
|
### Tier 1 — Already multiplayer (12 modules) — just need "Pull to rSpace" button
|
|
rbooks, rcal, rcart, rfiles, rflows, rinbox, rnotes, rsocials, rsplat, rtasks, rtrips, rvote
|
|
|
|
### Tier 2 — Near-multiplayer, need Automerge integration (5 modules)
|
|
- **rchoices**: Add schema + local-first-client for voting sessions, live vote tallies
|
|
- **rswag**: Add schema for shared design state, collaborative editing
|
|
- **rwallet**: Add schema for shared wallet watchlist, collaborative treasury view
|
|
- **rschedule**: Already has schemas, needs local-first-client.ts + component sync
|
|
- **rnetwork**: Already has WebSocket, add Automerge doc for CRM data persistence
|
|
|
|
### Tier 3 — UI-only wrappers, add lightweight sync (4 modules)
|
|
- **rdata**: Sync dashboard config/filters across participants
|
|
- **rphotos**: Sync album curation, shared selections
|
|
- **rtube**: Sync playlists, watch parties, queue state
|
|
- **rpubs**: Sync publication drafts, collaborative editing queue
|
|
|
|
### Tier 4 — External service wrappers, iframe-based (3 modules)
|
|
- **rdesign** (Affine): Add space-scoped project linking, cannot sync internal state
|
|
- **rdocs** (Docmost): Add space-scoped doc linking
|
|
- **rmeets** (Jitsi): Add meeting history/scheduling sync
|
|
|
|
### Tier 5 — Infrastructure, minimal sync needed (3 modules)
|
|
- **rforum**: Provision state only, sync forum URL/status per space
|
|
- **rmaps**: Already has ephemeral WebSocket rooms — add persistent map annotations via Automerge
|
|
- **rspace**: Core module — canvas state already synced via Automerge in host app
|
|
|
|
## Architecture Decisions
|
|
- All new local-first clients follow the established pattern: `local-first-client.ts` + `schemas.ts` per module
|
|
- Document ID format: `{space}:{module}:{collection}`
|
|
- "Pull to rSpace" UI reuses existing `PATCH /:space/modules` API
|
|
- Shared `folk-applet-catalog.ts` component renders the catalog modal
|
|
<!-- SECTION:DESCRIPTION:END -->
|
|
|
|
## Acceptance Criteria
|
|
<!-- AC:BEGIN -->
|
|
- [ ] #1 Every rApp module has real-time multiplayer sync or a clear reason why not (external iframe wrappers)
|
|
- [ ] #2 Standard 'Pull rApplet to rSpace' UI exists in space settings and is accessible from app switcher
|
|
- [ ] #3 Space owners can enable/disable any module via the catalog UI
|
|
- [ ] #4 All new sync follows established local-first-client.ts + schemas.ts pattern
|
|
- [ ] #5 Demo/unauthenticated mode still works as local-only fallback for all modules
|
|
<!-- AC:END -->
|