Commit Graph

13 Commits

Author SHA1 Message Date
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 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 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 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 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 44dff1991f fix(rcart): recognize existing session without wallet + show username
checkExistingSession() required a derived wallet address to set
authenticated=true, causing a re-login prompt even with a valid session.
Now authenticates on valid session and derives wallet lazily at payment
generation time. Also extracts claims.username for display instead of
showing raw did:key identifiers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 21:25:26 -07:00
Jeff Emmett adb0d173d8 feat(shell): add module sub-nav bar + rCart UX polish + fix TS errors
- Add secondary pill navigation bar between tab-row and <main> showing
  each module's outputPaths + subPageInfos as navigable links with
  client-side active highlighting
- Rename rcart /buy/:id route to /group-buy/:id, add payments and
  group-buys outputPaths, rename products → catalog
- Add outputPaths (mailboxes) to rinbox module
- Polish group buy page: hero stat cards, fill-up liquid progress
  visual with tier markers, warm amber→green gradient, pledge avatars,
  green CTA button, price box, responsive improvements
- Fix centering for narrow rcart form pages (flex layout in cart.css)
- Fix TS error: add walletAddress to rstack-identity SessionState type
- Fix TS errors: add ambient type declarations for 3d-force-graph and
  three (dynamically imported in folk-graph-viewer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:44:45 -07:00
Jeff Emmett 28dbb059eb fix: remove stray brace in folk-payment-request checkExistingSession
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:22:23 -07:00
Jeff Emmett 911713e9aa fix(rcart): use rstack-identity auth instead of separate passkey flow
folk-payment-request now triggers the rstack-identity auth modal
instead of its own passkey flow. This ensures the username displays
correctly in the identity badge and avoids duplicate session management.
Also checks both session sources for wallet address and access token.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:21:18 -07:00
Jeff Emmett 71b2acd47b feat(rcart): persist payment request ID in URL for reloadability
After generating a payment request, push ?id=<paymentId> into the URL.
On page load, if ?id= is present, fetch the payment from the API and
display the QR/share view directly. Reset clears the URL param.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 20:14:10 -07:00
Jeff Emmett 4199a8c6e0 feat(rcart): add "Payer Decides" option for payment type and amount
- Add 'payer_choice' as third paymentType option on request form
- When set, the payment page shows a One-time / Recurring toggle for the payer
- Payer's choice sent to server via chosenPaymentType in status update
- Server uses chosenPaymentType to determine subscription reset behavior
- Combined with existing amountEditable, creators can now leave both
  amount and payment type fully up to the payer

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:57:09 -07:00
Jeff Emmett 636fc133fe feat(rcart): add subscription/inventory/method-toggles to payment requests + fix 403
- Fix: add publicWrite to cartModule so payment routes aren't blocked
  by space-level write auth (routes have their own auth checks)
- Add paymentType field: 'single' (one-time) or 'subscription' (reusable QR)
- Add maxPayments inventory limit: QR codes auto-fill when limit reached
- Add paymentCount to track how many payments received
- Add enabledMethods: toggle card/wallet/encryptid per payment request
- Payment page only shows enabled tabs, shows inventory progress bar
- Subscriptions reset to 'pending' after each payment until filled
- New 'filled' status for inventory-limited payments that are full

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:35:11 -07:00
Jeff Emmett c049d7e8df feat(rcart): QR code payment requests with self-service generator
Add shareable QR payment system to rCart:
- PaymentRequestDoc schema with amountEditable support
- Payment API routes (create, list, get, update, QR SVG, Transak session)
- folk-payment-page: 3-tab payer view (Card/Wallet/EncryptID passkey)
- folk-payment-request: self-service QR generator with passkey auth
- Payments tab in folk-cart-shop for managing requests
- Extract Transak utils to shared/transak.ts (used by rFlows + rCart)

Routes: /:space/rcart/request (generator), /:space/rcart/pay/:id (payer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:11:20 -07:00