Audit and fix ~60 violations across 47 files where URLs were constructed
as /{space}/moduleId instead of /moduleId (subdomain provides the space).
- Add getModuleApiBase() helper to shared/url-helpers.ts
- Fix client components: use getModuleApiBase() for fetch URLs,
rspaceNavUrl() for navigation
- Fix server routes: use c.get("isSubdomain") for redirects and
JSON response URLs
- Fix OAuth callbacks (notion, google, clickup): subdomain-aware redirects
- Fix email notification URLs (rvote): use {space}.rspace.online format
- Fix webhook registration (rtasks/clickup): subdomain-aware endpoint URL
- Replace broken #getSpaceSlug() methods in folk-feed, folk-splat
- Replace NODE_ENV checks with proper isSubdomain checks (rdata, rnetwork)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Empty compose env vars were blocking Infisical secret injection at startup.
Only TRANSAK_ENV needs to be in compose; API keys and secrets come from Infisical.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Spaces are subdomains, not path segments. /rspace is correct since
the space context comes from the subdomain.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Seeds demo spaces with a "Build a Climbing Wall" circuit (labor threshold +
capital threshold + proprietor signoff → project) and a "Community Potluck"
circuit (budget knob + RSVPs threshold + venue signoff → project), each
pre-wired with arrows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rich landing page with do-ocratic framing, SVG circuit diagram,
"GovMods" branding, modular governance vs monolithic comparison,
and onboarding action. Module now has landingPage function for
bare-domain rendering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 3-tab layout (Pool/Weave/Collaborate) with 2-tab Canvas + Collaborate.
Canvas tab has collapsible left pool panel with orbs alongside infinite SVG
canvas with pan/zoom (ctrl+wheel zoom, wheel pan, space+drag, touch pinch).
- Long-press orb in pool → drag onto canvas to create commitment node
- Drop on matching task port auto-creates wire connection
- Gold glow highlights unfulfilled task ports matching dragged skill
- "Frame as Tasks" button on solver results creates task nodes with
dashed intent frame on canvas
- Add intentFrameId to Task schema for solver-to-task linkage
- Zoom controls overlay (+/−/reset)
- Light/dark theme support for all new elements
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace 3-tab layout (Pool/Weave/Collaborate) with 2-tab Canvas + Collaborate.
Canvas tab has collapsible left pool panel with orbs alongside infinite SVG
canvas with pan/zoom (ctrl+wheel zoom, wheel pan, space+drag, touch pinch).
- Long-press orb in pool → drag onto canvas to create commitment node
- Drop on matching task port auto-creates wire connection
- Gold glow highlights unfulfilled task ports matching dragged skill
- "Frame as Tasks" button on solver results creates task nodes with
dashed intent frame on canvas
- Add intentFrameId to Task schema for solver-to-task linkage
- Zoom controls overlay (+/−/reset)
- Light/dark theme support for all new elements
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add MoonPay as the primary card payment provider for rCart. MoonPay
uses HMAC-SHA256 signed URLs (no session API needed, no IP whitelisting).
Falls back to Transak if MoonPay keys aren't configured.
- shared/moonpay.ts: URL builder with HMAC signing, currency mapping
- New /api/payments/:id/card-session endpoint picks provider automatically
- Frontend uses unified startCardPayment() with multi-provider message handling
- Set MOONPAY_API_KEY + MOONPAY_SECRET_KEY to activate
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hardcoded PRODUCTION overrode the Infisical value. Use env var with
STAGING default until Transak production gateway auth issue is resolved.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Production gateway rejects tokens from api.transak.com. Try getting
the access token from the gateway endpoint first (which staging
confirms works), then fall back to the legacy API endpoint.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transak now requires widget URLs to be generated server-side via their
gateway session API. Direct query-parameter URLs are deprecated.
- Add getAccessToken() with 7-day caching for partner access tokens
- Add createSecureWidgetUrl() that calls the gateway session endpoint
- Falls back to legacy direct URL if gateway returns an error (e.g.
production IP not yet whitelisted)
- Update rCart and rFlows to use the secure API
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transak rejects `cryptoAmount` when combined with fiatCurrency params.
Use `defaultCryptoAmount` which pre-fills the amount without conflicting.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The payment request form button was cut off on mobile because the shell
uses height:100vh with overflow:hidden on #app. Add padding-bottom to
the .page container so the button scrolls into view within the flex
overflow:auto content area.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
SyncServer.setDoc() was not calling onDocChange, so documents created
via setDoc (including payment requests) were only stored in memory and
lost on container restart. This caused "Payment request not found"
errors after deploys. Now setDoc triggers the same persistence callback
as changeDoc.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Payment request URLs (e.g. /rcart/pay/:id) should be accessible without
authentication, even in private spaces. The API endpoints were already
exempted from auth, but the client-side shell gate was redirecting
unauthenticated visitors to the module landing page. Set
spaceVisibility="public" on the payment page render to bypass this.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Transak production also sends X-Frame-Options: SAMEORIGIN, blocking
iframe embeds. Switch to popup window for all environments, not just
staging. Show "payment opened in new window" status with re-open button.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TRANSAK_ENV was set to PRODUCTION but TRANSAK_API_KEY_PRODUCTION was
missing, causing the Transak session endpoint to return 503. Add the
env var reference so rCart card payments work in production.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use `user-${email}` instead of raw `email` as the Openfort player label,
matching the flow-service convention. Openfort rejects colons in labels,
and both codepaths must use the same format so users get the same wallet
regardless of whether they on-ramp via rfunds.online or rspace.online.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a logged-in user visits a private space they don't have access to,
the gate now shows a "Request Access" button (calls POST /api/spaces/:slug/access-requests)
and a "Go to {username}'s Space" secondary link. Handles already-pending (409) gracefully.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Landing, module-landing, and sub-page-info pages showed a stale "Spaces"
dropdown. Now checks encryptid_session and sets the switcher to
{username}'s Space (logged in) or demo (logged out).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Space creation popup slug field now shows input followed by .rspace.online
suffix instead of rspace.online/ prefix. Also fixes rtasks notification
link and browser extension help text.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Space creation popup slug field now shows input followed by .rspace.online
suffix instead of rspace.online/ prefix. Also fixes rtasks notification
link and browser extension help text.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enable pasting structured shape data from tldraw, Excalidraw, and generic
JSON into the rSpace canvas, with automatic type conversion and viewport
centering. Ctrl+C on selected shapes writes rSpace JSON to clipboard for
round-trip paste or external consumption.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Connection & exec state persistence (POST /api/connections, PUT exec-state)
- Exec step detail forms for all 5 types (venue, comms, notes, prep, launch)
- Step state machine fix: click to expand/collapse, action button to complete
- Task editor links field with dynamic add/remove and server persistence
- Cyclos-aware launch handler with fallback to demo celebration
- Fix dead EXEC_STEPS[taskId] lookup, auto-place first task on empty canvas
- DID display truncation for unreadable DIDs in intent routes
- Dark/light theme toggle with localStorage persistence
- Hex hover stroke, commitment description in hex nodes, edit pencil on tasks
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin encrypted backups and AI-generated files to Kubo (ipfs.jeffemmett.com)
as fire-and-forget redundancy. Filesystem remains primary storage — IPFS
failures are logged and swallowed. Adds /api/ipfs routes for status,
pin/unpin, and gateway proxy.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ImapFlow clients were created without .on('error') handlers. Socket
timeouts emitted unhandled errors that crashed the entire process,
taking down all 32 modules. Added error handlers to all 3 ImapFlow
instantiation sites and a process-level uncaughtException/unhandledRejection
safety net.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Dockerfile's healthcheck hit a nonexistent /health endpoint, causing
permanent "unhealthy" status. Override with a check that accepts any HTTP
response (including 401) as proof the service is running.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>