Commit Graph

65 Commits

Author SHA1 Message Date
Jeff Emmett c1e8048089 fix: allow TRANSAK_ENV to be set via Infisical (default STAGING)
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>
2026-04-03 05:46:41 +00:00
Jeff Emmett 1b8fcbdf47 fix(rcart): add Transak API key to docker-compose environment
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>
2026-04-03 02:06:57 +00:00
Jeff Emmett 5b4300db77 fix(ipfs): correct Kubo container hostname (collab-server-ipfs-1)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-02 15:06:05 -07:00
Jeff Emmett 1672477f68 feat(ipfs): add IPFS integration for backups and generated files
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>
2026-04-02 14:24:39 -07:00
Jeff Emmett 14f7ccb090 fix(scribus): add healthcheck override for scribus-novnc
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>
2026-04-01 15:21:30 -07:00
Jeff Emmett d2fa533519 Improve rTasks drag-drop UX + sync space members on invite claim
CI/CD / deploy (push) Failing after 9s Details
rTasks: port backlog-md ordinal algorithm (bisection + rebalance),
fix column detection via bounding-box hit test, add empty-column
drop zones, source column dimming, no-op detection, and optimistic
DOM updates (no flash). New bulk-sort-order rebalance endpoint.

EncryptID: sync claimed invite members to Automerge doc immediately,
redirect to space subdomain after identity claim.

Server: add /api/internal/sync-space-member endpoint, fallback
member check in WebSocket auth for not-yet-synced invites.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-01 12:19:37 -07:00
Jeff Emmett dbfddb2fb5 feat(infra): on-demand sidecar lifecycle + resource caps
KiCad, FreeCAD, and Blender sidecars now start on API request and stop
after 5min idle, saving ~8GB RAM when not in use. Docker socket mounted
into rspace container for container lifecycle control. Memory/CPU limits
added to all services to prevent runaway resource consumption.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-31 13:29:42 -07:00
Jeff Emmett 55771eb26e chore: switch Transak to production environment
Staging doesn't support USDC on Base network (test tokens only).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 23:18:54 -07:00
Jeff Emmett c4972079dd fix(cad): CSS containment + Scribus image gen for all CAD shapes
- KiCad, FreeCAD, Blender, Scribus: add .wrapper flex container with
  height:100% + min-height:0 so content stays within element bounds
- KiCad assembler: regex fallback for non-JSON tool results (SVG, Gerber, PDF)
- Scribus image gen: actually write downloaded fal.ai images to disk
  (was creating imagePath but never saving bytes)
- Mount rspace-files volume in scribus-novnc so generated images are
  accessible from both containers

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:53:42 -07:00
Jeff Emmett aa02473d0d fix(shell): evict tab pane from cache on script load failure
When a module script (e.g. canvas-*.js) fails to load (502 during
deploy, network error), the pane stayed in cache with a blank canvas.
Subsequent tab switches showed the broken cached pane instead of
re-fetching. Now script onerror removes the failed tag and evicts
the pane, so the next switchTo does a fresh fetch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 17:10:23 -07:00
Jeff Emmett 395623af66 feat(rdesign): deploy KiCad & FreeCAD MCP as Docker sidecars
Switch from broken StdioClientTransport (child process) to
SSEClientTransport (HTTP to sidecar containers via supergateway).
Both sidecars share rspace-files volume so generated CAD files
(STEP, STL, Gerber, SVG) are directly servable without copying.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 16:25:23 -07:00
Jeff Emmett 77b7aba893 feat(rdesign): Scribus noVNC + AI design agent + CRDT sync
Replace Affine wrapper with full Scribus DTP stack:
- Docker container: Scribus 1.5 + Xvfb + x11vnc + noVNC + Python bridge
- Bridge API: Flask server (port 8765) proxying to Scribus Python API via Unix socket
- Design agent: Gemini tool-calling loop drives Scribus headlessly from text briefs
- CRDT sync: Automerge schema v2 with pages/frames, bidirectional SLA bridge
- Canvas tool: folk-design-agent shape + create_design_agent in canvas-tools registry
- Module UI: inline text prompt + step log + SVG layout preview (no iframe)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 10:06:04 -07:00
Jeff Emmett 5775e810d6 fix(docker): pass INTERNAL_API_KEY env var to rspace container
Required for on-ramp/off-ramp internal API endpoints.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-23 17:53:30 -07:00
Jeff Emmett 7618433498 refactor(auth): replace @encryptid/sdk imports with local auth module
Consolidates token verification into server/auth.ts, removing the
external SDK dependency. All modules now import from the local module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 16:41:59 -07:00
Jeff Emmett 33a0f9ab04 chore(secrets): remove redundant env passthrough from docker-compose
Secrets now fetched from Infisical at container startup instead of
being passed through docker-compose from .env. Reduces .env to only
Infisical auth creds and non-Infisical container secrets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:48:20 -07:00
Jeff Emmett 8b61203e17 revert: remove standalone domains we don't own
Reverts Traefik rules and removes standaloneDomain from rdesign, rvnb,
rbnb, rdocs, and crowdsurf — we don't have these domains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:31:17 -07:00
Jeff Emmett d315375a93 fix(routing): add missing Traefik rules for 5 standalone domains
rdesign.online, rvnb.online, rbnb.online, rdocs.online, crowdsurf.online
had standaloneDomain declared in their modules but no Traefik router rules,
so {space}.r*.online subdomain redirects wouldn't reach the server.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-21 18:27:11 -07:00
Jeff Emmett 1f97a2ceba fix(smtp): use noreply@rmail.online as sender across all modules
Mailcow rejects noreply@rspace.online because the authenticated user
is noreply@rmail.online. Updated all SMTP_FROM and SMTP_USER defaults
to use rmail.online consistently: spaces invites, rSplat notifications,
EncryptID auth emails, and rCart payment receipts.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 21:00:41 -07:00
Jeff Emmett d270e7c03a feat(rtube): integrate 360split for splitting 360° videos into flat perspectives
Server-side proxy routes (POST /api/360split, GET status, POST import) fetch
video from R2, submit to video360-splitter, and import results back. Frontend
adds Split 360° button with settings modal, progress polling, and library import.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 13:55:31 -07:00
Jeff Emmett 9ecffff692 fix: use internal Docker SMTP hostname and fix noreply@rmail.online creds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:17:05 -07:00
Jeff Emmett be92e7839b fix: correct dev-ops volume mount path on Netcup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:03:41 -07:00
Jeff Emmett 0ad67c54a6 feat(rtasks): add email checklist with HMAC-signed click-to-check links
POST /checklist/send builds and emails a styled checklist from backlog AC items.
GET /checklist/:token verifies the HMAC signature, toggles the AC in the
markdown file, and re-renders the page with fresh links for remaining items.

Adds dev-ops volume mount and RTASKS_HMAC_SECRET/RTASKS_API_KEY env vars.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 12:02:14 -07:00
Jeff Emmett ccca8318a3 feat: payment email notifications, GLB viewer, and EncryptID email lookup
- Add EncryptID internal endpoint for email lookup by userId
- rcart: send "Payment Sent" to payer and "Payment Received" to recipient
- rcart: resolve emails via EncryptID when not provided in request
- rsplat: add GLB/GLTF 3D viewer using Three.js GLTFLoader
- rsplat: enable publicWrite for photo uploads without space membership
- docker-compose: add SITE_URL and SPLAT_NOTIFY_EMAIL env vars

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-15 04:02:07 +00:00
Jeff Emmett 357e0bb4c0 refactor(transak): split API keys by environment (staging/production)
Add getTransakApiKey() and getTransakWebhookSecret() helpers that
resolve TRANSAK_API_KEY_STAGING or TRANSAK_API_KEY_PRODUCTION based
on TRANSAK_ENV, with fallback to legacy TRANSAK_API_KEY. All consumers
(rcart, rflows, transak-onramp) now use the shared helpers instead of
reading env vars directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:06:33 -07:00
Jeff Emmett 9d34eca103 fix(transak): default to STAGING environment for all purchases
Switch TRANSAK_ENV default from PRODUCTION to STAGING in shared/transak.ts,
docker-compose.yml, and rflows config endpoint. All card purchases now
route through Transak's staging gateway until production is ready.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:54:42 -07:00
Jeff Emmett 7ecb6f0417 feat: Transak-only gateway + pass credentials via docker-compose
Remove Coinbase and Ramp Network from onramp registry, keeping
Transak as the sole payment gateway. Add TRANSAK_* env vars to
docker-compose for .env override of Infisical values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:06:25 -07:00
Jeff Emmett 751a2c8e7b fix(infra): consolidate external service URLs to rspace.online (TASK-51.1)
- Replace rdata.online/collect.js with /collect.js proxy route (7 files)
- Update MAPS_SYNC_URL to wss://maps-sync.rspace.online
- Fix legacy TWENTY_API_URL to crm.rspace.online
- Add Traefik host exclusions for maps-sync, crm, analytics, newsletter
- Close TASK-23 (feature parity audit) and TASK-51.2 (301 redirects)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 19:12:51 -07:00
Jeff Emmett 3e409dcfea fix: restore TWENTY_API_TOKEN pass-through with empty default
Uses ${TWENTY_API_TOKEN:-} so it won't override Infisical when
.env doesn't define it, but allows .env to provide the value
when Infisical's stored token needs regeneration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:24:04 -07:00
Jeff Emmett 72a7bf5255 fix: remove TWENTY_API_TOKEN pass-through (Infisical provides it)
The docker-compose env var override was setting an empty string,
preventing the Infisical-injected value from being used.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:18:00 -07:00
Jeff Emmett 4212a651e1 fix(auth): exchange WebAuthn credential for server-signed JWT + rNetwork CRM cleanup
- Session manager now calls EncryptID /api/auth/start + /api/auth/complete
  to get a properly signed JWT instead of creating unsigned local tokens.
  This fixes 401 errors on /api/payments, /api/notifications, and other
  authenticated endpoints that verify tokens via EncryptID server.
- Token refresh calls /api/session/refresh instead of extending unsigned tokens
- Server generateSessionToken now includes authTime, jti, recoveryConfigured
- rNetwork: /crm route renders folk-crm-view instead of iframe
- rNetwork: ?view=app redirects 301 to /crm (backward compat)
- rNetwork: graph viewer always uses API (removed hardcoded demo data)
- docker-compose: pass through TWENTY_API_TOKEN from Infisical
- rcart: add catalog product images

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:13:19 -07:00
Jeff Emmett 31b088543e feat: add ViewHistory for in-app back navigation, rename rWork to rTasks
Add shared ViewHistory<V> utility class that provides a proper navigation
stack for rApps with hierarchical views. Replaces hardcoded data-back
targets with stack-based back navigation across 10 rApps: rtrips, rmaps,
rtasks, rforum, rphotos, rvote, rnotes, rinbox, rschedule, rcart.

Rename rWork module to rTasks — directory, component (folk-tasks-board),
CSS, exports, domains, and all cross-module references updated.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:04:13 -07:00
Jeff Emmett a28eb88140 chore: remove dead social.jeffemmett.com redirect labels
Domain has no DNS record and all traffic now routes via demo.rsocials.online.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 18:26:43 -07:00
Jeff Emmett 0e9d00d2ac feat(rsocials): add Listmonk newsletter page + legacy domain redirect
- Add /newsletter-list route embedding Listmonk via iframe
- Add LISTMONK_URL env var to docker-compose
- Add Traefik redirect: social.jeffemmett.com → demo.rspace.online/rsocials
- Add backlog task for linked wallets security hardening (TASK-HIGH.5)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 18:15:05 -07:00
Jeff Emmett a6008a4f2d refactor: complete rfunds → rflows rename across configs and references
Update docker-compose, vite config, Traefik labels, module imports,
and all cross-module references to use the new rflows naming.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 19:13:14 -08:00
Jeff Emmett 59b1ae2d05 feat: add rSchedule module — persistent cron-based job scheduling
New module providing in-process, Automerge-backed job scheduling to
replace system-level crontabs. Includes email, webhook, calendar-event,
broadcast, and backlog-briefing action types with a 60-second tick loop.

- modules/rschedule/ — schemas, mod, landing page, web component UI
- Seed jobs: morning/weekly/monthly backlog briefings
- SMTP env vars added to docker-compose for email actions
- ONTOLOGY.md updated (26+ modules, rSchedule in Planning & Spatial)
- Also: Twenty CRM docker-compose aligned to rspace-internal network

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 14:34:53 -08:00
Jeff Emmett 588a52f2cc fix: rename Twenty CRM containers to twenty-ch-* prefix to avoid conflicts
Existing Twenty instances on Netcup use twenty-server/twenty-db/twenty-redis
names. Renamed to twenty-ch-server/twenty-ch-db/twenty-ch-redis for the
commons-hub instance. Updated TWENTY_API_URL accordingly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 13:56:53 -08:00
Jeff Emmett 07e53d6aa1 feat: add Twenty CRM /crm route + deploy stack for commons-hub lead funnel
Adds dedicated /crm sub-route to rNetwork module embedding Twenty CRM
via ExternalAppShell iframe. Updates TWENTY_API_URL to use internal Docker
networking (http://twenty-server:3000). Includes full Twenty CRM Docker
stack (server, worker, postgres, redis) with Traefik routing for
crm.rspace.online and deployment instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 13:53:50 -08:00
Jeff Emmett 74a5142349 feat: Gemini AI integration + zine generator + fix Ollama network
- Add /api/prompt multi-provider endpoint (Gemini Flash/Pro + 4 Ollama models)
- Add /api/gemini/image with fallback cascade (gemini-2.0-flash → imagen-3.0)
- Add /api/zine/outline, /api/zine/page, /api/zine/regenerate-section
- Create folk-zine-gen.ts: 8-page MycroZine generator with editable text
  and per-section regeneration (text + image independently)
- Update folk-prompt.ts: multi-provider model dropdown (Gemini + Ollama)
- Update folk-image-gen.ts: add Gemini provider toggle + new styles
- Connect rspace to ai-internal Docker network for Ollama access
- Fetch GEMINI_API_KEY from Infisical claude-ops/ai (no plaintext secrets)
- Update entrypoint.sh: dual Infisical project support (primary + AI)
- Install @google/generative-ai, @google/genai SDKs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 21:27:11 -08:00
Jeff Emmett e4ad1b68e9 fix: move encryptid containers to rspace-internal network
The encryptid-internal network had persistent Docker networking issues
(TCP CONNECT_TIMEOUT between containers on the same bridge). Using the
rspace-internal network which already works for rspace↔rspace-db.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:28:35 -08:00
Jeff Emmett 1ff4c5ace7 refactor: consolidate EncryptID into main docker-compose.yml
Merge encryptid + encryptid-db services from separate docker-compose.encryptid.yml
into the main compose file. Update Dockerfile.encryptid to use additional_contexts
for encryptid-sdk (matching main Dockerfile pattern) instead of fragile context: ..

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 19:36:17 -08:00
Jeff Emmett 46c2a0b035 feat: layered local-first data architecture — encrypted backup, relay persistence, at-rest encryption
Implement the 4-layer data model (device → encrypted backup → shared sync → federated):

- Extract shared encryption-utils from community-store (deriveSpaceKey, AES-256-GCM, rSEN format)
- Encrypt module docs at rest when space has meta.encrypted === true
- Fix relay mode persistence: relay-backup/relay-restore wire protocol + .automerge.enc blob storage
- Add backup store + REST API (PUT/GET/DELETE /api/backup/:space/:docId) with JWT auth
- Add client BackupSyncManager with delta-only push, full restore, auto-backup
- Wire backup stubs in encryptid-bridge to BackupSyncManager
- Add rspace-backups Docker volume
- Create docs/DATA-ARCHITECTURE.md design doc with threat model and data flow diagrams

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 17:09:07 -08:00
Jeff Emmett 5090676eda fix: remove DATABASE_URL from docker-compose, now in Infisical
DATABASE_URL, ADMIN_DIDS, and ENCRYPTID_DEMO_SPACES are now stored
in Infisical and injected via the entrypoint. Remove the last
docker-compose.yml reference that was temporarily re-added.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:41:16 -08:00
Jeff Emmett 424152415a fix: add DATABASE_URL to docker-compose environment
The shared/db/pool.ts requires DATABASE_URL but it was missing from
both docker-compose.yml and Infisical, causing the container to
crash-loop on startup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:31:02 -08:00
Jeff Emmett 7850b9d34c feat: move rApp secrets to Infisical, add seed script
Remove DATABASE_URL and ADMIN_DIDS from docker-compose.yml (now
injected via Infisical entrypoint). Add scripts/seed-infisical.sh
to interactively populate 21 module-specific secrets (R2, Immich,
Twenty, Discourse, FAL, RunPod, etc.) into the rspace Infisical
project. Update Dockerfile to include scripts/ in the image.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:06:21 -08:00
Jeff Emmett b12cc52892 feat: admin dashboard with user management and delete capabilities
- Add tabbed admin UI (Spaces | Users) with auth gate
- Add admin API endpoints on EncryptID: list users, delete user, clean space members
- Add admin force-delete space endpoint on rSpace (bypasses owner check)
- Protect all admin endpoints with ADMIN_DIDS env var
- Add ADMIN_DIDS to both Docker Compose configs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 22:30:21 -08:00
Jeff Emmett b32d752858 feat: redirect all r*.online domains to rspace.online/r*
Replace internal rewrites with 301 redirects for all standalone
domains. Handles bare domains, subdomains, paths, and query strings:
- rnotes.online/ → rspace.online/rnotes
- rnotes.online/alice/path → alice.rspace.online/rnotes/path
- alice.rnotes.online/path → alice.rspace.online/rnotes/path
- rnotes.online/api/... → rspace.online/rnotes/api/...

Traefik labels updated to also match *.r*.online subdomains.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 17:51:57 -08:00
Jeff Emmett 0555b5fa7f feat: add rSocials module + redirect standalone domains to rspace.online landing pages
- New rSocials module (federated social feed aggregator) with demo timeline
- Standalone domain root (r*.online/) now 302 redirects to rspace.online/{moduleId}
- Self-fetch detection breaks circular proxy loop (User-Agent: rSpace-Proxy/1.0)
- Traefik label for rsocials.online

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 14:05:03 -08:00
Jeff Emmett f84b0b9914 refactor: remove rProviders from rApps, fix rSwag domain to rswag.online
rProviders (providers.mycofi.earth) is a separate project — removed
module registration, app switcher entry, tab bar badge, canvas embed
button, Traefik router, and standalone config. rSwag domain updated
from swag.mycofi.earth to rswag.online across all references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:39:43 -08:00
Jeff Emmett 19ce7080e8 feat: add missing standalone domain routing for all rApps
Added standaloneDomain to rsplat module (rsplat.online). Added 8 missing
Traefik routers: rnotes, rfiles, rphotos, rinbox, rcart, rsplat,
swag.mycofi.earth, providers.mycofi.earth. All 22 standalone-domain
modules now have matching Traefik routing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 23:34:25 -08:00
Jeff Emmett 0fb4135ac6 feat: wire DocSyncManager into rSpace WebSocket server
Protocol multiplexing on existing /ws/{slug} endpoint:
- Messages with docId (subscribe/unsubscribe/sync/awareness) → SyncServer
- Messages without docId → legacy canvas handlers (unchanged)

New files: doc-persistence.ts (debounced Automerge save/load),
sync-instance.ts (SyncServer singleton with participant mode).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 05:19:21 +00:00