Commit Graph

864 Commits

Author SHA1 Message Date
Jeff Emmett 6ed4cba4ac Merge branch 'main' of ssh://gitea.jeffemmett.com:223/jeffemmett/rspace-online 2026-03-12 20:13:12 -07:00
Jeff Emmett fcea37b91b feat(rcart): clickable demo orders with detail view
Enrich 5 demo orders with items, buyer, payment, provider, and timeline.
Order cards show thumbnails and item counts; clicking opens a detail view
with payment info, buyer, provider, and timeline using the existing
catalog-detail 2-column layout. Demo payments expanded to 5 (3 linked).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:12:45 -07:00
Jeff Emmett cc9a58b702 Move rforum, rtube, rtrips, rbooks to bottom of app switcher
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 03:08:33 +00:00
Jeff Emmett 073a64fe56 feat(rnetwork): expand demo CRM to 48 members with delegation-only flows
Remove Demo DAO and space hub placeholder nodes — members now connect
only via trust delegation edges. Add 24 new members (m25–m48) with
ops-vertical specializations and expand delegation arrays to 141 edges
(47 per authority) with proper hierarchical flow patterns.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:08:05 -07:00
Jeff Emmett 9343dc13ab fix(routing): proxy /encryptid/* to encryptid container
The encryptid API routes live on the separate encryptid container, not
rspace. Clients on space subdomains (jeff.rspace.online) fetch
/encryptid/* relative to the rspace server. Add a catch-all proxy that
forwards these requests to the internal encryptid service.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:47:39 -07:00
Jeff Emmett 058592f5e3 fix(rwallet): fix stuck loading, auth, and add Sepolia ERC20 tokens
- Add /encryptid/ to subdomain routing passthrough (was 404 on demo.rspace.online)
- Replace rwallet's custom JWT verify with SDK's verifyEncryptIDToken (supports
  remote fallback when JWT_SECRET unavailable in rspace container)
- Fix CRDT balance loading stuck spinner (early return skipped crdtLoading=false)
- Add Sepolia testnet ERC20 tokens (USDC, WETH, LINK)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:40:02 -07:00
Jeff Emmett 81fb92284b fix(shell): move subnav/tabbar below tab row (top: 128px)
The subnav and tabbar were sticking at top: 92px which overlapped
with the tab row (header 56px + tab row ~36px = 92px). Bumped to
128px so they sit cleanly below the tab row.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:39:24 -07:00
Jeff Emmett 5f63e51a2f fix(shell): responsive subnav and tabbar on mobile
- Tab row: set top: 0 on mobile (was inheriting top: 56px from desktop
  fixed positioning while being sticky on mobile)
- Subnav + tabbar: switch from sticky to relative on mobile so they
  scroll naturally instead of fighting with the sticky header
- Smaller pill padding/font on ≤480px screens

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 19:00:56 -07:00
Jeff Emmett 5350b76b7d fix(rcart): resolve merge conflict — combine centering + subnav hiding
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:59:24 -07:00
Jeff Emmett 45c2130980 fix(rcart): center form pages with margin auto instead of flex
The flex centering on main:has() was causing the subnav to shrink-wrap
and the page content to left-align on desktop. Use margin: 0 auto on
the components directly so the subnav stays full-width.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:59:01 -07:00
Jeff Emmett 1448909ffd Merge branch 'dev' 2026-03-12 18:55:24 -07:00
Jeff Emmett f0cc50a060 feat(rflows): water-themed canvas visual overhaul — taps, vessels, pools
Replaces vertical faucet sources with horizontal side taps (pipe → rotary
valve → angled nozzle → stream), rectangular tank funnels with tapered
vessels (wide top → narrow drain spout, overflow pipes at max threshold),
and card-style outcomes with U-shaped collection basins (status-colored
water fill, ripple patterns, phase markers).

Adds SVG defs for metallic pipe gradients, water surface shimmer, ripple
patterns, overflow splash effects, and status-colored basin water fills.
CSS animations for water shimmer, overflow pulse, basin transitions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:55:10 -07:00
Jeff Emmett 746e4a8b59 Merge branch 'dev' 2026-03-12 18:48:30 -07:00
Jeff Emmett 3b3a642813 fix(routing): remove hardcoded /demo/ path prefix from URLs
demo.rspace.online subdomain already identifies the space, so paths
should not redundantly include /demo/. Replaced 7 occurrences across
rcart, rswag, rpubs, rschedule, and space-switcher with either relative
paths or full demo.rspace.online URLs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:48:20 -07:00
Jeff Emmett 82123937b3 fix(encryptid): persist verified email and fix OIDC re-prompt bug
Normalize emails to lowercase at all setUserEmail() call sites so
case mismatches no longer break the OIDC allowedEmails check. Split
the authorize error into email_required (shows verification form) vs
access_denied (shows error message) so users with a verified email
are never re-prompted unnecessarily.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:28:27 -07:00
Jeff Emmett 79448a230a fix(encryptid): persist verified email and fix OIDC re-prompt bug
Normalize emails to lowercase at all setUserEmail() call sites so
case mismatches no longer break the OIDC allowedEmails check. Split
the authorize error into email_required (shows verification form) vs
access_denied (shows error message) so users with a verified email
are never re-prompted unnecessarily.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:28:07 -07:00
Jeff Emmett fb9448681c Populate demo CRM with 24 DAO members and delegation network
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 00:24:01 +00:00
Jeff Emmett d2637aff0b Fix rMeets hub page theme support and add subnav items
Theme fix: Hub page CSS used non-existent variable names with dark-mode
fallbacks (--rs-surface, --rs-bg, --rs-surface-hover), so it always
rendered dark regardless of user theme. Fixed to use correct theme
variables (--rs-bg-surface, --rs-input-bg, --rs-bg-hover, etc.).

Also removed forced theme:"dark" override on the hub page route.

Subnav: Added "Create Call" to outputPaths so the module subnav shows
Create Call / Rooms / Recordings pills. Added mobile breakpoint for
the hub nav cards.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:28:18 +00:00
Jeff Emmett 71a108980c Fix payment page mobile layout — remove conflicting flex container
The cart.css had `display:flex; align-items:center` on main:has(folk-payment-page)
which fought with the component's own `width:100%; margin:0 auto` centering:
- flex align-items:center shrunk the subnav to content width
- padding:0 0.5rem overrode shell.css padding-top:92px (desktop)
- Redundant since all components already self-center with margin:auto

Also hide the shop subnav on public-facing pages (/pay/:id, /group-buy/:id)
since payers/pledgers don't need Carts/Catalog/Orders navigation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 23:08:30 +00:00
Jeff Emmett 661aca972e Fix mobile layout across all rcart pages and remove duplicate nav
- Remove duplicate internal nav (.rapp-nav tabs) from folk-cart-shop —
  the shell subnav pills already provide this navigation
- Read initial-view attribute so shell subnav routing works correctly
- Add margin: 0 auto centering to all narrow page components
  (payment-page, payment-request, payments-dashboard, group-buy-page)
- Add overflow-wrap: break-word to prevent text/address overflow
- Comprehensive mobile breakpoints across all components:
  - folk-cart-shop: 600px + 400px (grid stacking, card sizing, forms)
  - folk-payments-dashboard: 600px + 480px (header, cards, tabs)
  - folk-group-buy-page: already had good breakpoints, added centering
  - cart.css: remove justify-content:center (bad for long pages),
    add horizontal padding for mobile
- Fix share-input overflow with min-width:0 + text-overflow

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:50:21 +00:00
Jeff Emmett 73431d7a88 Fix mobile layout on payment page — center content and prevent overflow
- Add margin: 0 auto to center the page instead of left-aligning
- Add overflow-wrap/word-break on wallet addresses, tx hashes, URLs
- Add min-width: 0 + text-overflow on share input to prevent flex overflow
- Comprehensive mobile breakpoints at 600px and 380px for all sections
  (staging banner, recipient info, header, amount, tabs, footer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:41:37 +00:00
Jeff Emmett 61f5544b4e Fix mobile formatting on payment request page
Add comprehensive responsive breakpoints at 600px and 380px:
- Stack step card, form field rows, share rows vertically
- Scale down typography (title, amount, hints)
- Reduce padding and QR code size for narrow screens
- Make toggle buttons and method toggles compact
- Full-width action buttons on mobile

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 22:36:55 +00:00
Jeff Emmett 97a077b256 feat(rcart): Layer 3 — automated recurring payment execution via ERC-20 allowance
Recurring Executor (new module):
- Server-managed relayer keypair derived deterministically via HKDF
- Checks on-chain ERC-20 allowance before pulling funds
- Executes transferFrom when subscriptions are due
- Supports Base, Base Sepolia, and Ethereum mainnet

New API Endpoints:
- GET /api/payments/:id/subscription-info — returns relayer address and
  approve calldata for the client to authorize recurring pulls
- POST /api/payments/:id/subscribe — registers a subscription after
  payer approves on-chain allowance, verifies allowance exists

Scheduler Upgrade:
- Attempts automated pull first for subscriptions with approved allowance
- Falls back to email reminder if auto-pull fails or is not configured
- Sends branded receipt email after successful automated payments
- Extracted email templates into reusable helper functions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:32:13 +00:00
Jeff Emmett 4304170a9a feat(rcart): recurring payment infrastructure with interval scheduling
Layer 1 — Schema & History:
- Added PaymentRecord type for individual payment tracking
- Added interval (weekly/biweekly/monthly/quarterly/yearly), nextDueAt,
  subscriberEmail, and paymentHistory[] to PaymentRequestMeta
- Payment history records txHash, method, amount, paidAt for each payment

Layer 2 — Server-Side Scheduler:
- Hourly subscription reminder scheduler sends email notifications
  when recurring payments are due (based on nextDueAt)
- nextDueAt auto-computed after each successful subscription payment
- Grace period prevents duplicate reminders
- Branded HTML reminder emails with "Pay Now" button

UI Updates:
- Billing interval selector (weekly through yearly) shown for
  subscription and payer_choice payment types
- Payment page shows subscription badge with interval and history count
- Next due date displayed for active subscriptions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:22:58 +00:00
Jeff Emmett 8345648d61 fix(rcart): fix floating-point precision in wallet payment amounts
Replace parseFloat * 10^decimals with string-based decimal parsing to
avoid precision loss for 18-decimal tokens (ETH). Affects both MetaMask
and EncryptID payment paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:11:03 +00:00
Jeff Emmett f5ac038803 feat(rcart): show creator username + wallet on payment page, add email sharing
- Payment schema now includes creatorUsername, displayed alongside the
  truncated wallet address on the payer-facing payment page
- New "Share by email" feature on the payment request page: enter
  comma-separated emails to send branded payment links via email
- New POST /api/payments/:id/share-email endpoint with HTML email template

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 21:06:51 +00:00
Jeff Emmett 00e5229ef7 Merge branch 'main' of ssh://gitea.jeffemmett.com:223/jeffemmett/rspace-online 2026-03-12 14:00:23 -07:00
Jeff Emmett 3b666b4434 Merge branch 'dev' 2026-03-12 14:00:08 -07:00
Jeff Emmett 154f1230dc feat(rsocials): AI campaign generator from event brief
Add "Generate from Brief" feature: paste unstructured event text, AI
(Gemini 2.5 Pro) creates a full multi-phase, multi-platform campaign
with threads, emojis, newsletter content, and platform-specific formatting.

- Schema v4: add threadPosts, emailSubject, emailHtml to CampaignPost
- New POST /api/campaign/generate endpoint with platform-aware prompting
- Generate modal with platform checkboxes, tone/style selectors
- Preview mode with save/regenerate/discard flow
- Dynamic phase rendering (supports 3-5 AI-generated phases)
- Thread badge with expandable individual posts
- Newsletter platform support (icon + color)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:59:56 -07:00
Jeff Emmett fc1776aedf feat(encryptid): sync wallet associations across devices via encrypted vault
Wallets stored in local WalletStore are now bidirectionally synced with
the encrypted AccountVault on the server. On login, vault wallets are
restored to the local store; on wallet changes, local state is pushed
back to the vault. The server user profile wallet_address is also set
on login so mobile devices (without PRF) get the address via JWT.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:55:10 +00:00
Jeff Emmett 564c16e431 feat(responsive): adaptive tablet/fold breakpoints, touch/pen parity, pointer events drag
Add intermediate breakpoints (960px, 1024px, 900px, 640px, 600px) for tablets and fold
devices across all 12 rApp components. Add touch-action: manipulation and
-webkit-tap-highlight-color to eliminate 300ms tap delay. Fix undersized tap targets
(<36px) in rtasks, rfiles, rinbox, and rcart. Replace HTML5 drag API with pointer events
in rtasks kanban and rchoices ranking for touch/pen/mouse parity. Replace mouseenter/
mouseleave with pointerenter/pointerleave in rchoices spider chart with click toggle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:41:29 -07:00
Jeff Emmett 9a1afe9be9 fix(encryptid): use CONFIG.smtp.from for OIDC verification emails
The sendVerificationEmail function was hardcoding noreply@ridentity.online
as the sender, but SMTP authenticates as noreply@rspace.online. Mailcow
rejected the mismatch with 553 "Sender address rejected: not owned by user".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:41:29 -07:00
Jeff Emmett 233b7e3689 feat(responsive): adaptive tablet/fold breakpoints, touch/pen parity, pointer events drag
Add intermediate breakpoints (960px, 1024px, 900px, 640px, 600px) for tablets and fold
devices across all 12 rApp components. Add touch-action: manipulation and
-webkit-tap-highlight-color to eliminate 300ms tap delay. Fix undersized tap targets
(<36px) in rtasks, rfiles, rinbox, and rcart. Replace HTML5 drag API with pointer events
in rtasks kanban and rchoices ranking for touch/pen/mouse parity. Replace mouseenter/
mouseleave with pointerenter/pointerleave in rchoices spider chart with click toggle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:41:08 -07:00
Jeff Emmett d6be2f2039 feat(rcart): add payment context, staging banner, and Transak amount pre-fill
- Payment page now shows recipient info and available payment methods
- Testnet chains show staging environment disclaimer
- Transak widget receives effective amount for editable-amount payments

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:40:58 +00:00
Jeff Emmett 12f25edaf3 fix(rcart): add mobile wallet derivation fallback for payment requests
WebAuthn PRF extension is unsupported on most mobile browsers, causing
"Could not derive wallet address" error. Added 3-layer fallback:
1. Client-side PRF derivation (desktop)
2. Server-side wallet lookup via session API
3. DID-based deterministic address provisioning

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 20:34:46 +00:00
Jeff Emmett fab970e439 fix(encryptid): use CONFIG.smtp.from for OIDC verification emails
The sendVerificationEmail function was hardcoding noreply@ridentity.online
as the sender, but SMTP authenticates as noreply@rspace.online. Mailcow
rejected the mismatch with 553 "Sender address rejected: not owned by user".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 13:09:45 -07:00
Jeff Emmett 2d636f5f25 feat(rcart): send branded payment success email on completed payments
Sends an HTML email with payment details, rFlows CTA, and resource links
when a card/Transak payment completes. Fire-and-forget (never blocks response).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:53:58 -07:00
Jeff Emmett e614df1b54 feat(responsive): add mobile breakpoints (768px/480px) across all rApps
Payment pages (folk-payment-page, folk-payment-request, folk-group-buy-page)
had zero or minimal media queries — now stack headers, reduce padding, and
resize iframes for 375px viewports. Other rApp dashboards (rchoices, rwallet,
rnotes, rfiles, rinbox, rforum, rtasks, rvote) gain consistent 768px/480px
breakpoints: collapsing grids to 1-column, shrinking fonts and padding, and
stacking flex rows on mobile. Also adds folk-payments-dashboard to the flex
centering rule in cart.css.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:32:47 -07:00
Jeff Emmett ba5ce34620 feat(transak): pre-fill fiat amount and currency in widget
Pass fiatAmount, defaultFiatAmount, fiatCurrency, and defaultFiatCurrency
to the Transak widget URL so users see the transaction total immediately
without manual entry. Applied to both rcart payment sessions and rflows
onramp adapter.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:12:31 -07:00
Jeff Emmett 1abb29d18f feat(canvas): drag-to-select, Ctrl+A select all, bulk delete warning
- Swap interaction model: click+drag is now marquee selection (was pan),
  hold-and-drag or space/middle-click is pan
- Ctrl+A / Cmd+A selects all visible shapes on the canvas
- Deleting more than 5 elements shows a confirmation dialog requiring
  the user to click DELETE to proceed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:11:22 -07: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 a8b99d3462 fix(shell): hide subnav bar on rspace canvas page
The rspace module's outputPaths caused renderModuleSubNav to render an
unwanted "rspace | Canvases" bar across the canvas. Skip subnav for the
root rspace module since the canvas has its own chrome.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 12:04:34 -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 8af4309b41 feat(rwallet): show EncryptID identity card with both CRDT and EVM wallets
Every EncryptID identity has two wallets: a CRDT wallet (DID-based for
local tokens) and an EVM wallet (passkey-derived for on-chain tokens).
The My Wallets tab now always shows both in a dedicated EncryptID card
with distinct sections, rather than burying CRDT tokens as a subsection
that only appears when balances are non-empty.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:41:42 -07:00
Jeff Emmett a4a4175e9f feat(rwallet): add My Wallets tab with per-wallet balance breakdowns
Restructure rWallet with a top-level tab system: "My Wallets" (default
for authenticated users) shows wallet cards with on-chain balances and
CRDT tokens, while "Wallet Visualizer" preserves existing explore-any-
address functionality. View Flows button bridges the two tabs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:36:23 -07:00
Jeff Emmett 2cb1ff092b feat(shell): redesign rApp info popup as centered modal with overlay
- Fix z-index (9000 → 10001) so popup renders above header and tab bar
- Center popup as a proper modal with blurred backdrop overlay
- Header now shows module emoji icon + name (fetched from API)
- Bigger, bolder CTA buttons with gradient fills and hover effects
- Tour/guide links auto-promoted to prominent purple-accent buttons
- Loading spinner animation, Escape key to dismiss, click-outside-to-close
- Mobile: slides up from bottom instead of top-right corner
- Also: rcart/rwallet subnav route support, rcart tour simplification

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:24:41 -07:00
Jeff Emmett 7ec1434e64 feat(rcart): add payments dashboard for Payments subnav tab
New folk-payments-dashboard component shows payment requests in/out with
status badges, links to pay pages, and a create button. Resolves 404 on
the existing Payments outputPath.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 11:17:54 -07:00
Jeff Emmett c668d5700c fix(transak): derive referrerDomain from request hostname instead of hardcoding
Resolves T-INF-101 Access Denied when accessing payment links from
subdomains like demo.rspace.online. Adds extractRootDomain() helper
to shared/transak.ts, used by both rcart and rflows onramp adapters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:49:29 -07:00
Jeff Emmett 87d5e8b1cb fix(rnetwork): pre-load THREE before graph creation
nodeThreeObject callback was returning a Promise (from async
createNodeObjectAsync) because THREE wasn't cached yet. Pre-load
THREE via import("three") before creating the graph so the callback
always returns a synchronous Three.js object.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:30:43 -07:00
Jeff Emmett f4d7448c9d fix(rnetwork): use UMD build for 3d-force-graph, avoid ESM bare specifiers
ESM builds on esm.sh kept resolving transitive deps to latest versions
that import three/webgpu. Switch to the pre-built UMD bundle from
jsdelivr which bundles all deps including Three.js. Keep separate
import map entry for "three" ESM for custom node object creation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 10:23:04 -07:00