Commit Graph

9 Commits

Author SHA1 Message Date
Jeff Emmett 20c26cd3d7 feat: scope system, cross-space navigation, and spaces-as-layers
Phase 1 — Fix scope system: new scope-resolver.ts resolves global vs
space-scoped docId prefixes. Server middleware sets effectiveSpace on
Hono context. All 18 modules updated to use dataSpace for Automerge
doc access while keeping space for display. Client runtime gets
setModuleScopes() and resolveDocSpace() for local-first scope
resolution.

Phase 2 — Seamless cross-space navigation: TabCache now tracks panes
per space:module key. OfflineRuntime maintains lazy WebSocket
connections per space. Space-switcher dispatches space-switch event
handled client-side with history.pushState instead of full reload.

Phase 3 — Spaces as layers: Layer type extended with spaceSlug and
spaceRole. Tab bar gains "Add Space Layer" picker. Canvas renders
cross-space shapes with visual indicators. Space layers persisted as
SpaceRefs via nesting API. Runtime provides getAllActiveSpaces() and
subscribeModuleAcrossSpaces() for module-level data aggregation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 06:33:32 +00:00
Jeff Emmett 59bdd741be feat: bare-domain sub-pages show info/marketing pages + save-gate
Bare-domain URLs like rspace.online/rsocials/thread now render an info
page with CTAs instead of silently serving the functional app. The
functional app only appears inside a {space} context (e.g.
demo.rspace.online/rsocials/thread). API routes still pass through.

- Add SubPageInfo interface to shared/module.ts
- Add renderSubPageInfo() renderer to server/shell.ts
- Modify bare-domain routing: api/ passthrough → info page → demo fallback
- Add subPageInfos to 8 modules (rsocials, rflows, rnetwork, rtrips,
  rbooks, rphotos, rinbox, rsplat)
- Add window.__rspaceSaveGate() auth prompt on write operations
- Wire save-gate into rsocials Thread Builder save handler

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 12:16:17 -08:00
Jeff Emmett 161f7a10de feat: fall back to demo data when rPhotos/rInbox APIs return empty
Show sample data with an info banner instead of blank empty states
when Immich isn't configured or no mailboxes exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 11:16:22 -08:00
Jeff Emmett b6ddd4a833 fix: getApiBase() across all 16 rApp modules for subdomain routing
All modules had getApiBase() matching wrong module names (e.g. /vote
instead of /rvote) and requiring /{space}/ prefix in the URL path.
On subdomains like jeff.rspace.online, the browser URL is /rfunds/...
not /jeff/rfunds/..., so the regex never matched.

New pattern: /^(\/[^/]+)?\/rmodule/ handles both:
- Subdomain: /rfunds/... → base = /rfunds
- Direct: /demo/rfunds/... → base = /demo/rfunds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:01:06 -08:00
Jeff Emmett b2ea5e04cf feat: unified space lifecycle & module scoping contract (Phase 0+1)
Extend RSpaceModule with scoping, lifecycle hooks (onInit, onSpaceCreate/Delete
with SpaceLifecycleContext, onSpaceEnable/Disable), and DocSchema support.
Add scoping to all 25 modules (8 space, 11 global-configurable, 6 global-fixed).
Consolidate 4 space creation endpoints into shared createSpace() function.
Add enabledModules enforcement middleware and module configuration API
(GET/PATCH /api/spaces/:slug/modules). Deprecation header on /api/communities.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:35:41 -08:00
Jeff Emmett 1a615c29c9 feat(rphotos): fix gallery API routing and embed Immich at /album
Fix getApiBase() regex to match /rphotos instead of /photos, add
/album route with iframe embed via renderExternalAppShell, and update
Immich links to navigate within rSpace instead of opening externally.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 14:31:19 -08:00
Jeff Emmett 5408eb0376 feat: add outputPaths to module interface and browsable list pages
Add OutputPath type to RSpaceModule so each module declares what content
types it produces (e.g. notebooks, routes, campaigns). Auto-generate
browsable list pages at /:space/:moduleId/:path that render a card grid
inside the standard shell, fetching items from the module's API.

Declares outputPaths across 23 modules (rwallet/rinbox skipped).

Move campaign demo from standalone campaign-demo space to
/rsocials/campaign route with a dedicated timeline view and
/api/campaigns endpoint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 13:55:29 -08:00
Jeff Emmett 75b148e772 Merge branch 'dev'
# Conflicts:
#	modules/rcal/mod.ts
#	modules/rfiles/mod.ts
#	modules/rforum/mod.ts
#	modules/rmaps/mod.ts
#	modules/rnetwork/mod.ts
#	modules/rswag/mod.ts
#	modules/rwork/mod.ts
#	shared/module.ts
2026-02-28 19:51:51 -08:00
Jeff Emmett 5613370817 refactor: rename module directories to match r-prefixed module IDs
All 22 module directories under modules/ now match their module IDs
(e.g. modules/cart → modules/rcart, modules/canvas → modules/rspace).
Updated all import paths, vite build config, HTML template asset refs,
docker-compose standalone commands, and .gitignore accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 19:49:26 -08:00