Commit Graph

751 Commits

Author SHA1 Message Date
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 602544ecdf feat(seo): add OG/Twitter meta tags + generated OG banner image
- Add og:title, og:description, og:image, twitter:card meta tags to landing page
- Add default OG tags to renderShell for all module pages
- Generate 1024x576 OG banner image via fal.ai Flux Pro (dark indigo + network pattern)
- Update meta description: "rSpace is a local-first platform where communities own their tools, data, and governance"
- Update page title to "rSpace — Own Your Community Infrastructure"

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:51:25 -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 b8788fa81e refactor: move rcal, rinbox, rnetwork into Connect category
App-switcher: new "Connecting" category with rcal, rinbox, rnetwork.
Canvas toolbar: new "Connect" group with rCal, rInbox, rNetwork
(moved out of Embed dropdown).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:33:48 -07:00
Jeff Emmett ba3d45372d feat: integrate heartbeat with rSchedule shapes
folk-calendar subscribes to clock:tick/daily to refresh today marker.
folk-reminders-widget auto-refreshes every 5 minutes.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:24:21 -07:00
Jeff Emmett fee72573ba feat: system clock heartbeat + ephemeral clock delivery (TASK-47)
Server-side SystemClock broadcasts tick/5min/hourly/daily events via
WebSocket to all connected clients. Events are ephemeral (not persisted
in CRDT). Client-side fallback clock activates when server connection
is lost.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:20:04 -07:00
Jeff Emmett 05a7fbfc5a fix(rflows): align Coinbase env vars with Infisical names (CDP prefix)
COINBASE_API_KEY_ID → COINBASE_CDP_KEY_ID
COINBASE_API_KEY_SECRET → COINBASE_CDP_KEY_SECRET
COINBASE_PROJECT_ID → COINBASE_CDP_PROJECT_ID

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:19:17 -07:00
Jeff Emmett efb5810b31 feat: canvas event broadcasting pub/sub system (TASK-43)
Add CanvasEventBus with emit/subscribe/unsubscribe for cross-shape
communication. Events persisted in Automerge CRDT eventLog (ring buffer
100 entries), synced via WebSocket, with re-entrancy guard at depth 10.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:14:30 -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
Jeff Emmett b3c449f54e feat(rflows+rwallet): diverse relay providers — on-ramp abstraction, configurable RPC, Pimlico bundler
- On-ramp provider interface + registry (transak > coinbase > ramp priority)
- TransakOnrampAdapter, CoinbaseOnrampAdapter, RampOnrampAdapter
- Provider-agnostic user-onramp endpoint with dynamic /api/onramp/config
- Coinbase + Ramp Network webhook handlers
- Frontend provider dropdown in Fund modal with multi-provider postMessage
- Configurable RPC: env var overrides (RPC_BASE etc), Alchemy auto-construct, public fallback
- Pimlico ERC-4337 bundler client + auth-gated routes (submit/send/receipt)
- Remove hardcoded Transak staging creds from entrypoint.sh (use Infisical)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:10:44 -07:00
Jeff Emmett c4717e3c68 feat: auth-fetch, shape registry, and data pipes (TASK-13, TASK-41, TASK-42)
TASK-13: rApp frontends now inject EncryptID bearer tokens via authFetch()
and gate mutations behind requireAuth() — rvote, rfiles, rmaps all protected.
Demo mode unaffected.

TASK-41: Dynamic shape registry replaces 300-line switch in canvas.html and
165-line if-chain in community-sync.ts. All 41 shape classes now co-locate
fromData()/applyData() with their existing toJSON(), making shape creation
and sync fully data-driven.

TASK-42: Data pipes between shapes via typed ports. Shapes declare
input/output PortDescriptors, arrows connect ports with type checking,
100ms debounce, and color tinting. AI shapes (prompt, image-gen, video-gen,
transcription) have initial port descriptors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:59:51 -07:00
Jeff Emmett 9bb00a8bab feat(rflows+rtasks): BCRG demo flow with live rTasks integration
Replace TBFF preset with 19-node BCRG Community Flow (2 sources →
central funnel → 5 person funnels → 11 outcomes). Seed matching
BCRG Outcomes board in rTasks (4 DONE, 5 IN_PROGRESS, 2 TODO).

Add SyncServer.registerWatcher() for cross-module doc change hooks.
When an rFlows outcome is marked "completed", auto-create a DONE task
in rTasks with ref:rflows:outcome:{id} deduplication.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:47:13 -07:00
Jeff Emmett d668ca287c chore(backlog): add tasks 106-108 (ViewHistory, Wallets, CRM graph)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:38:34 -07:00
Jeff Emmett 8af5f3d0b6 chore: increase recent rApps in dropdown from 3 to 5
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:29:33 -07:00
Jeff Emmett d79d560771 feat(rsplat): interactive demo scenes + AI image-to-3D generation
Replace fake demo data with real HuggingFace CDN Gaussian splats (train,
truck, garden) that open in an inline 3D viewer without server round-trips.
Add "Generate from Image" tab that sends images to fal.ai Trellis for
AI-powered 3D model generation. Add gallery header and progress UI.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:29:15 -07:00
Jeff Emmett e47cd35a34 feat(identity): add My Wallets panel to avatar dropdown
Adds a wallet modal accessible from the identity dropdown showing:
- rIdentity wallet card with username, DID, and passkey badge
- Browser wallet discovery via EIP-6963 (MetaMask, Rainbow, etc.)
- Connect flow with eth_requestAccounts
- Quick link to open the full rWallet module

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:23:00 -07:00
Jeff Emmett c36b0abc32 feat(rnetwork): inline force-directed graph in CRM view
Replace the Graph tab's external link with an interactive SVG graph
rendered directly from CRM data (people, companies, opportunities).
Companies appear as colored clusters with people orbiting around them,
and cross-org opportunity links shown as dashed purple edges.

Includes pan/zoom/drag interactions and auto fit-to-view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 14:22:18 -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 9de37d7405 feat(rnotes): real-time transcript rendering + open notebook integration
Add segment-based live transcription to voice recorder and in-editor
dictation, wire AUDIO note recording, and add send-to-notebook endpoint
for RAG indexing via open-notebook service.

- Add openNotebookSourceId field to NoteItem schema
- Add POST /api/notes/send-to-notebook proxy route to open-notebook
- Add dictation preview bar with interim speech below editor toolbar
- Rewrite voice recorder with TranscriptSegment-based live rendering
- Convert transcript segments to Tiptap JSON with timestamps on save
- Wire Record button in AUDIO note view with full MediaRecorder flow
- Add Send to Notebook button + Indexed badge in note meta panel

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:20:31 -07:00
Jeff Emmett fa3441269b feat(rinbox): theme-aware inbox with read/unread/attention states
Replace hardcoded dark-mode colors with --rs-* CSS custom properties
for automatic light/dark theming. Add inbox header bar with unread
count, sender avatar circles, and rich thread status indicators
(replied, forwarded, needs-attention badges with visual hierarchy).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:20:16 -07:00
Jeff Emmett 2b909becdb fix(shell): move info icon to left of layer toggle in tab bar
Slot the rApp info button into the tab-bar's tab-actions area so it
appears immediately left of the view-toggle (layer icon) instead of
after it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:27:07 -07:00
Jeff Emmett 99e486b598 fix(rmeets): add camera/mic/display-capture to iframe permissions
The external app iframe was missing media permissions in its allow
attribute, preventing Jitsi from accessing camera/microphone/screen
when embedded in rMeets.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:19:19 -07:00
Jeff Emmett f0cecc1529 feat(rpubs): add collaborative document editing via Automerge CRDT
Wire rPubs editor to the shared local-first runtime so multiple users
can co-author publications in real time. Drafts persist to IndexedDB
and sync via WebSocket automatically.

- New schemas.ts with PubsDoc schema and pubsDocId helper
- Editor connects to runtime, discovers/creates drafts
- Debounced content sync (800ms) with cursor preservation
- Title/author/format metadata sync between collaborators
- Draft list sidebar with create/switch functionality
- Sync status badge in toolbar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:01:08 -07:00
Jeff Emmett 7177b2882c fix: deduplicate spaces dropdown, group by visibility type
Personal space (slug=username) forced to private so it doesn't appear
as both public and private. Dropdown now groups spaces: Private (red)
at top, Permissioned (yellow) middle, Public (green) bottom.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 12:00:37 -07:00
Jeff Emmett d96130f919 feat: fix tab duplication, add info popover, add rFlows guided tour
Fix tab duplication by syncing tabBar state after layer-add, deduplicating
Automerge layers, and syncing app-switcher tabs to CommunitySync. Add info
icon popover that lazy-loads module landing page content with auto-show on
first visit. Add 5-step guided tour for rFlows with spotlight overlay,
auto-advance on click, and toolbar restart button.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 11:04:33 -07:00
Jeff Emmett 656b34ac1d chore: switch Transak to staging until production IP whitelisted
Production gateway rejects the access token (error 1002). Staging
flow works end-to-end. Will switch back once Transak whitelists
the server IP for production.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:57:35 -07:00
Jeff Emmett 2dbfbe1a7c chore: add TRANSAK_SECRET override in entrypoint
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:38:08 -07:00
Jeff Emmett 649f22834e chore: temp override TRANSAK_API_KEY with production key
Infisical still has the staging key; override in entrypoint until
the dashboard is updated with write-access credentials.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:26:51 -07:00
Jeff Emmett e8a54f1eb6 feat(rflows): migrate to Transak API-based widget URL
Transak deprecated direct query-parameter URLs. The new flow uses
their Create Widget URL API with a Partner Access Token to generate
one-time sessionId-based URLs server-side. Also stops exposing the
API key in config endpoints and adds referrerpolicy to the iframe.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 20:00:46 -07:00
Jeff Emmett 3f71b219bb fix(rflows): remove iframe sandbox restricting Transak widget
The sandbox attribute was blocking Transak's internal redirects,
causing T-INF-101 access denied errors. Transak needs full iframe
capabilities for its payment flow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:41:34 -07:00
Jeff Emmett 23f0cce9a1 fix(rflows): hardcode Base mainnet chainId (8453)
Infisical has BASE_CHAIN_ID=84532 (Base Sepolia testnet) which
conflicts with the live Openfort API key. Hardcode 8453 to prevent
testnet/mainnet mismatch.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:38:38 -07:00
Jeff Emmett 30a409b2f8 fix(rflows): fix Openfort wallet label — colon not allowed in name
Openfort rejects ':' in player name query param. Changed label from
'user:email@example.com' to just 'email@example.com'. Also improved
error serialization for Openfort's non-standard APIError objects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:30:27 -07:00
Jeff Emmett 01a794b0f2 fix(rflows): remove Coinbase onramp, use Transak only
Coinbase CDP integration was causing 500 errors ([object Object]).
Simplify to Transak-only: remove CoinbaseOnrampProvider import/init,
provider selection UI, and popup window branch. Also fix error handler
to properly stringify non-Error objects.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:24:18 -07:00
Jeff Emmett 1c336c8616 fix: migrate folk-rapp shadow DOM colors to --rs-* CSS variables
folk-rapp.ts (the wrapper for all rApps on canvas) had ~30 hardcoded
dark-mode hex colors in its shadow DOM styles, preventing rApp cards
from responding to light/dark theme switching.

Replaces all hardcoded colors with var(--rs-*) tokens: bg-surface,
text-primary, text-secondary, text-muted, text-inverse, border,
shadow, bg-hover, bg-active, etc.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:13:28 -07:00
Jeff Emmett 8072b250ea feat: canvas background selector — grid, dot, or blank preference
Add user-selectable canvas background style via data-canvas-bg attribute
and CSS custom properties (--rs-canvas-bg-image, --rs-canvas-bg-size).
Three options: grid (default), dot, blank — persisted in localStorage.

- theme.css: new tokens + [data-canvas-bg] selectors
- rstack-identity.ts: Grid/Dot/Blank selector in user dropdown
- canvas.html: CSS vars, zoom-aware scaling, canvas-bg-change listener
- flows.css: use shared bg-image/bg-size vars (fixes rFlows theme bug)
- FOUC prevention in all entry points (shell.ts, create-space.html)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:37:50 -07:00
Jeff Emmett 72100c0922 feat: migrate hardcoded colors to --rs-* CSS variables across 18 modules
Replace structural UI colors with theme-aware CSS custom properties so
all rApp modules respond correctly to light/dark theme switching.

Covers: folk-social-post, folk-forum-dashboard, folk-video-player,
folk-video-chat, folk-thread-gallery, folk-campaign-manager,
folk-wallet-viewer, folk-vote-dashboard, folk-swag-designer,
folk-cart-shop, folk-workflow-block, folk-choices-dashboard,
folk-pubs-editor, folk-book-shelf, folk-flows-app, folk-analytics-view,
folk-campaign-planner, and flows.css canvas background.

Intentionally preserved: platform brand colors, chain colors,
data-viz/chart colors, video player black, call action buttons.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:34:13 -07:00
Jeff Emmett a7063d24f5 feat: PWA support — installable app, Web Push notifications, app badge
Phase 1: Installable PWA
- Add web app manifest with multi-size icons (192, 512, maskable, apple-touch)
- Add PWA meta tags to all entry points (shell.ts, canvas.html, index.html, create-space.html)
- Register service worker on all pages (previously only canvas.html)
- Add manifest.json to precache core list
- Capture beforeinstallprompt for custom install UX

Phase 2: Web Push Notifications
- Add web-push dependency + push_subscriptions DB table
- VAPID key endpoint, subscribe/unsubscribe routes in notification-routes.ts
- Web Push delivery in notify() with auto-cleanup of expired subscriptions
- SW push + notificationclick event handlers
- Client push subscription flow in notification bell component

Phase 3: Install UX Polish
- App badge (setAppBadge/clearAppBadge) on unread count changes
- "Enable push" button in notification panel header

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:35:30 -07:00
Jeff Emmett 1cd8225680 feat(rcal): zoom bar relocation, likelihood feature, rich demo data, remove floating map
- Move zoom bars between calendar and map panes when docked (3-column grid layout)
- Add likelihood/pencil-in feature: tentative events render with dashed borders, lower opacity, percentage badges across all 7 view paths + modal + map markers
- Expand demo data from ~47 to 105 events spanning months -1 to +8 with periodic (yoga, standups), episodic (workshop series, book club), and tentative (25-80% likelihood) events
- Add Community and Health source categories
- Remove floating map option — map is now docked or minimized only
- Decouple zoom bars by default (spatialGranularity=Country, zoomCoupled=false)
- Preserve effective spatial index when decoupling via 'c' key or button
- Extend lunar computation range to month+9

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:07:16 -07:00
Jeff Emmett b2347ec418 feat: per-rApp inline config + module-aware settings panel
Add <rstack-module-setup> component for inline module configuration
(replaces static "Not Configured" instructions). Enhance settings
gear panel to show the current module's settingsSchema at the top.
Pass module-id through shell rendering and tab-cache switching.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 16:45:48 -07:00
Jeff Emmett bb432a6af1 chore: add backlog-notify onStatusChange hook
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 15:30:41 -07:00
Jeff Emmett 1f6b019dbf feat(rmaps): theme support, mobile fix, theme-aware map tiles
Replace all hardcoded dark colors with --rs-* CSS variables in both
demo and room modes. Add LIGHT_STYLE (CARTO voyager) tiles and
MutationObserver to swap MapLibre styles on theme toggle. Make SVG
demo map theme-aware (ocean, continents, graticule, pins). Fix mobile
layout with calc(100vh) sizing instead of fixed heights. Remove
hardcoded theme: "dark" from mod.ts renderShell calls.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:22:11 -07:00
Jeff Emmett 53af7fc057 feat(rcal): docked map layout + theme-aware tiles; emoji tab badges
- rCal: default map to docked (side-by-side) layout instead of floating overlay
- rCal: switch map tiles between Voyager (light) and dark_all (dark) based on theme
- rCal: boost dark mode map brightness/contrast for readability
- rCal: watch for theme changes via MutationObserver for live tile swapping
- Tab bar: replace text badges with emoji icons, fix badge colors for light themes
- App switcher: fix badge text color to dark for gradient backgrounds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 14:13:28 -07:00
Jeff Emmett 2131d79f38 chore(encryptid): remove temporary OIDC debug logging
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:40:31 -07:00
Jeff Emmett 6d0ebf2958 debug(encryptid): add OIDC token exchange debug logging
Temporary logging to diagnose invalid_grant errors on token exchange.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:19:32 -07:00
Jeff Emmett 61c735cabd chore(encryptid): brand verification email as rIdentity + footer links
- From address: rIdentity <noreply@ridentity.online>
- Callback URL uses auth.ridentity.online
- Footer links to rIdentity, rStack, rSpace

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 13:03:00 -07:00
Jeff Emmett e37044f599 feat(rflows): redesign canvas toolbar + zoom controls, remove sufficiency badge
Move toolbar from horizontal top-right strip to vertical left-side panel
with larger, more prominent buttons and emoji icons. Replace basic +/-
zoom buttons with a pill-shaped widget showing live zoom percentage and a
fit-to-view button. Remove the "0% Enough" sufficiency badge overlay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 12:39:04 -07:00
Jeff Emmett cf7fab25f3 feat(encryptid): OIDC email verification flow for access_denied
When passkey auth succeeds but user's email doesn't match the OIDC
client's allowedEmails, show an inline email verification form instead
of a dead-end error. Sends a branded verification email with a single-use
30-minute token, then updates users.email on callback and lets the user
retry sign-in.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 12:33:20 -07:00
Jeff Emmett 49f55dffc8 fix: resolve 500s on notifications, cache errors in SW, and [object Object] on-ramp alert
- Notification routes: wrap GET / and GET /count in try-catch, return
  graceful fallbacks instead of 500s when DB table is missing/unavailable
- getUnreadCount: add null safety (row?.count ?? 0) and catch DB errors
- Service worker: add .catch(() => {}) to all cache.put() calls to
  suppress NetworkError on quota-exceeded or corrupted cache entries
- On-ramp error display: coerce err.error to string so alerts show the
  actual message instead of [object Object]

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 12:31:14 -07:00
Jeff Emmett 97da6c729f chore(backlog): add task-105 listmonk newsletter integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 12:28:22 -07:00
Jeff Emmett c92ca0fe05 feat(rsocials): newsletter manager + listmonk proxy + backlog tasks
Add Listmonk newsletter management proxy API with role-based auth,
newsletter manager component, password setting type support, and
new backlog task files. Update newsletter subscribe URL.

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