Commit Graph

52 Commits

Author SHA1 Message Date
Jeff Emmett 4b75464b93 fix: handle non-JSON error responses in design pipeline
Frontend was crashing with "Unexpected token 'I'" when the backend
returned plain text errors (e.g. "Internal Server Error" from proxy).
Now safely falls back to response.text() when JSON parsing fails.
Also prevents backend from swallowing HTTPException in catch-all.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 17:48:14 -08:00
Jeff Emmett f6b640e4a3 Merge branch 'dev' 2026-02-25 16:15:54 -08:00
Jeff Emmett 1eca70dcb4 feat: replace Next.js app with static landing page, add demo CTA
Simplify deployment to serve only the static landing page at rswag.online.
The actual swag app now lives in rspace-online at /demo/swag.
Remove PostgreSQL, Redis, FastAPI backend, and Next.js frontend services.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 16:15:48 -08:00
Jeff Emmett 7e83454e9d chore: remove CLAUDE.md from git tracking
CLAUDE.md may contain project context with credentials and is now
covered by global gitignore to prevent accidental secret commits.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:41:12 -08:00
Jeff Emmett 452427a68f Merge branch 'dev' 2026-02-25 14:31:56 -08:00
Jeff Emmett 05737179cc fix: add Traefik priority 130 to override rspace-online routing
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:31:52 -08:00
Jeff Emmett f575f8f313 Merge branch 'dev' 2026-02-25 14:22:56 -08:00
Jeff Emmett 7241a7645c feat: standardize header, categories, cross-app spaces
- Replace custom HeaderBar with standard Header.tsx + SwagNavActions
- AppSwitcher: rTube/rSwag → Creating, rSocials → Sharing, rData → Observing
- EcosystemFooter: updated link order to match new categories
- UserMenu: 🔑 Sign In button, 🔐 lock when logged in
- SpaceSwitcher: reads EncryptID token, sends Bearer header
- /api/spaces proxy: forwards to rspace.online (canonical spaces)
- /api/me: verifies EncryptID token for auth status

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 14:21:30 -08:00
Jeff Emmett d33d4183cf Merge remote main with unrelated histories
Accept remote docker-compose.yml (full rswag app stack)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:38:01 -08:00
Jeff Emmett 90b48e9eb9 Add landing page from rswag-online, update ecosystem emojis
Consolidating rswag-online static landing page into landing/ directory
before renaming this repo to rswag-online on Gitea.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:33:43 -08:00
Jeff Emmett 5a93e79837 feat: add space subdomain routing and ownership support
- Traefik wildcard HostRegexp for <space>.r*.online subdomains
- Middleware subdomain extraction and path rewriting
- Provision endpoint with owner_did acknowledgement
- Registry enforces space ownership via EncryptID JWT

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 13:20:15 -08:00
Jeff Emmett 46cf27906b Standardize emojis across header, favicons, and ecosystem links
Canonical emoji set for consistency:
- 🕸️ rNetwork (was 🌐), ⚖️ rChoices (was 🔀), 📋 rWork (was 💼)
- 🔐 rIdentity (was 🔑), 📖 rPubs (was 📰), 💸 rFunds (was 💰)
- 💰 rWallet (was 💼 in footer), 📬 rInbox (was ✉️)
- 💭 rForum (was 💬, differentiates from rChats)
- 📢 rSocials (was 📱), 🔨 rAuctions (was 🏛️ in footer)
- 🎬 rTube (was 📹 in footer)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:57:12 -08:00
Jeff Emmett 9837a4d232 Add 👕 emoji favicon to rSwag
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 12:39:54 -08:00
Jeff Emmett b80ae7c8c3 chore: update task-6 notes and create task-11 for SMTP migration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:26:41 -08:00
Jeff Emmett 55ea2925ec chore: update backlog tasks from prior session
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:25:51 -08:00
Jeff Emmett 920c90984d Initial landing page 2026-02-25 00:20:09 -08:00
Jeff Emmett 0b54b765df fix: fetch all SMTP config (host, user, password) from claude-ops
The rSwag Infisical project has stale SMTP values that can't be
updated (admin identity not a project member). Fetch authoritative
SMTP_HOST, SMTP_USER, and SMTP_PASSWORD from claude-ops /mail
folder which overrides stale values from both .env and rSwag
Infisical project.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:19:52 -08:00
Jeff Emmett 4d2d5d3132 feat: fetch SMTP password from claude-ops infisical at startup
Entrypoint now fetches RSWAG_SMTP_PASSWORD from claude-ops /mail
folder if SMTP_PASSWORD is not already set. This allows the rSwag
container to get its SMTP credentials without needing direct write
access to the .env file.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:12:38 -08:00
Jeff Emmett b050eff37f feat: wire SMTP email credentials for noreply@rswag.online
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 00:09:08 -08:00
Jeff Emmett 9b432ed388 fix: migrate SMTP host from mx.jeffemmett.com to mail.rmail.online
All email sending now uses mail.rmail.online as the SMTP host,
replacing the legacy mx.jeffemmett.com hostname.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:37:46 -08:00
Jeff Emmett c4857a0222 feat: add order confirmation and shipping notification emails
- EmailService with async SMTP via aiosmtplib (Mailcow)
- HTML email templates matching rSwag dark theme branding
- Order confirmation sent after successful Mollie payment
- Shipping notification with tracking info sent when POD ships
- Non-blocking: email failures logged but don't break order flow
- SMTP config: smtp_host, smtp_port, smtp_user, smtp_password in .env

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:33:22 -08:00
Jeff Emmett f4f1e140a9 fix: standardize SpaceSwitcher to use subdomain URLs
Space links now go to <space>.<app-domain> (e.g., myspace.rswag.online)
instead of rspace.online/<space>. Matches the standard rApp header
pattern used across all rStack apps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 23:17:55 -08:00
Jeff Emmett 9b85041226 feat: add SpaceSwitcher dropdown next to AppSwitcher in header
Matches the rApp header pattern: [AppSwitcher | SpaceSwitcher | Logo].
SpaceSwitcher fetches available spaces from /api/spaces and allows
switching between community storefronts (rSwag, Fungi Flows, etc.).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:55:56 -08:00
Jeff Emmett 068d9a9368 feat: standardize AppSwitcher and EcosystemFooter across all rApps
- Update AppSwitcher with all 26 r*Apps in 8 categories
- Add EcosystemFooter component with consistent ecosystem links
- Categories: Creating, Planning, Communicating, Deciding,
  Funding & Commerce, Social & Media, Work & Productivity,
  Identity & Infrastructure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:48:11 -08:00
Jeff Emmett ee6d57a245 chore: remove unused SpaceSwitcher component
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:34:42 -08:00
Jeff Emmett 25482f9085 feat: add EncryptID auth + consistent rApp header bar
- Add @encryptid/sdk (vendored) for WebAuthn passkey authentication
- Add zustand auth store matching rMaps/rWork pattern
- Create AuthButton component (sign in / register / sign out)
- Create HeaderBar client component: AppSwitcher + logo + nav + auth + cart
- Remove custom SpaceSwitcher (not part of standard rApp header)
- Fix hero: "Noticed" and "rMerch" now use same gradient color

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:33:04 -08:00
Jeff Emmett c31e440edf fix: move SpaceSwitcher next to AppSwitcher on the left, matching rApp header pattern
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:18:34 -08:00
Jeff Emmett 08bda9a76b style: color-highlight "Noticed" and "rMerch" in hero, "(you)" in white
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 22:12:45 -08:00
Jeff Emmett 52ba999dda feat: add rApp-style header with AppSwitcher and SpaceSwitcher dropdowns
Matches the shared header pattern used across rWork, rMaps, and other rApps.
AppSwitcher shows all 19 r* ecosystem apps grouped by category.
SpaceSwitcher allows switching between rSwag spaces (e.g. Fungi Flows).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:53:48 -08:00
Jeff Emmett d5f742341b fix: update hero copy — "Get Your Community Noticed with (you)rMerch"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:45:24 -08:00
Jeff Emmett a152e77fed feat: dark mode, community revenue messaging, design catalog update
- Switch to dark theme by default (globals.css + default space.yaml)
- Rewrite landing page copy to emphasize community revenue streams
  - "Revenue for Your Community" hero
  - "Merch That Funds Your Mission" section with revenue breakdown
  - Revenue routing to rFunds/DAOs/treasuries
- Step 1: "Upload or Create a Design"
- Step 3: "Ship Locally — Worldwide" (local fulfillment, less carbon)
- Features: Revenue Streams, Local Fulfillment replace old cards
- All designs now show on default space (space: all)
- DefectFi design gets hoodie product variant
- Fix light-mode hardcoded colors for dark compatibility (red-50, green-600)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 21:38:56 -08:00
Jeff Emmett dd873b91b5 fix: reorder nav buttons to Design, Upload, Shop (highlighted)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:14:51 -08:00
Jeff Emmett 500f232a54 feat: redesign landing page to match rApp ecosystem pattern
Replaces simple hero+products page with full rApp-style landing:
- Ecosystem badge ("Part of the rSpace Ecosystem")
- Hero section with gradient text and dual CTA
- "How It Works" 3-step cards (Upload → Pick Products → Ship)
- 6-feature grid (AI Studio, Spaces, Zero Inventory, Mockups, Payments, Ecosystem)
- Featured products section (first 6, with "view all" link)
- CTA card with gradient background
- Sticky nav with logo badge, cart icon, and compact links
- r* ecosystem footer with links to all rApps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 18:05:23 -08:00
Jeff Emmett f2462c8e87 fix: remove black background from DefectFi design file
Flood-fill from edges to make background transparent while
preserving white text, red accents, and bug illustrations.
Design now works on any shirt color.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:17:34 -08:00
Jeff Emmett 9c9c070fbd fix: handle Printful v2 API list response format
v2 returns {data: [...]} (array) not {data: {...}} (object).
Also fixes mockup task polling to use ?id= query param and
extracts mockup_url from nested catalog_variant_mockups structure.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:08:53 -08:00
Jeff Emmett be893db11e chore: pass PRINTFUL_STORE_ID and PUBLIC_URL to backend container
Secrets are stored in Infisical and injected at startup via the
entrypoint script. Docker-compose also passes them as fallback env
vars from the host .env.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 17:04:44 -08:00
Jeff Emmett e5317dab27 feat: update Printful client to v2 mockup-tasks API format
The v2 API uses products array with catalog source, nested layers in
placements, and GET /mockup-tasks/{id} for polling. Also removes
hardcoded domain in favor of PUBLIC_URL setting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 16:57:04 -08:00
Jeff Emmett a794f4732a fix: enlarge shirt print area for more realistic sizing
Design box expanded from 370x370 to 500x450 and repositioned
higher on the chest for typical t-shirt print proportions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:48:03 -08:00
Jeff Emmett eda9a0df23 fix: luminance-masked screen blend + cache bypass param
- Screen blend now uses brightness mask from the design so only
  non-dark pixels show through. Prevents visible dark rectangle
  when design has its own dark background (e.g. DefectFi tee).
- Add ?fresh=1 query param to /mockup endpoint for cache bypass.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:46:26 -08:00
Jeff Emmett 067e14ed0c feat: photorealistic mockups and professional storefront
Backend:
- Replace tiny placeholder templates with photorealistic 1024x1024 product
  photos (blank t-shirt, sticker with peeling corner, framed print)
- Rewrite Pillow compositing: screen blend for dark garments (design looks
  printed on fabric), direct paste for stickers/prints
- Add PRINTFUL_STORE_ID config + X-PF-Store-Id header to Printful client
  (unblocks existing account-level tokens)

Frontend:
- Product listing: rounded cards with shadows, category badges, hover
  animations, lazy loading, empty state
- Product detail: skeleton loading, mockup type switcher with loading
  indicator, raw design preview, inline price in Add to Cart button,
  shipping/quality info section
- Homepage: featured products now show mockups instead of raw designs,
  professional card layout matching products page
- Client-side mockups: updated coordinates for new templates, screen
  blend support via Canvas globalCompositeOperation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:43:49 -08:00
Jeff Emmett 0624cdec6f chore: activate DefectFi t-shirt design
API activate endpoint returned 500 (file permission issue in container).
Setting status directly to active in metadata.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:31:50 -08:00
Jeff Emmett 406ed7e1d3 feat: add DefectFi "Don't Abuse the Holes!" t-shirt design
Punk-style distressed typography with beetles and glitch effects.
Generated via Gemini Nano Banana Pro, sized to Printful 3600x4800 specs.
Starts as draft — activate via API when ready.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-24 15:29:43 -08:00
Jeff Emmett b35df552f7 feat: wire rswag backend to pull secrets from Infisical at startup
Add Python-based entrypoint.sh that authenticates with Infisical via
universal-auth, fetches secrets, and exports them as env vars before
starting uvicorn. Secrets like MOLLIE_API_KEY, PRODIGI_API_KEY,
PRINTFUL_API_TOKEN, JWT_SECRET, GEMINI_API_KEY, and FLOW_* vars are
now pulled from Infisical instead of being passed through docker-compose.

Gracefully degrades: if no INFISICAL_CLIENT_ID/SECRET are set or if
the fetch fails, the container starts with whatever env vars exist.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 19:36:35 -08:00
Jeff Emmett d8a58f8eb4 backlog: mark task-7 (deploy webhook) as Done
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 11:41:50 -07:00
Jeff Emmett 54d064f3fa feat: add full Printful API v2 integration (mockups + fulfillment)
- PrintfulClient: catalog variants (cached 24h), mockup generation
  (async create+poll), order submission, variant ID resolution
- Mockup endpoint tries Printful API first for Printful-provider designs,
  falls back to Pillow compositing for others (e.g. Prodigi stickers)
- Order service routes items by provider from design metadata:
  provider=printful → Printful API, provider=prodigi → Prodigi API
- Sandbox mode creates draft orders on Printful (not fulfilled)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 14:00:40 -07:00
Jeff Emmett acfe6cc350 feat: add Prodigi POD client + server-side product mockup previews
- Prodigi v4 API client for order fulfillment (create/get orders, quotes)
- Server-side mockup generation: Pillow composites designs onto product
  templates (shirt, sticker, print) at GET /api/designs/{slug}/mockup
- Product listing and detail pages now show designs ON products
- Mockup type switcher on product detail page (T-Shirt/Sticker/Art Print)
- Order service submits to Prodigi after successful payment
- POD webhook endpoint for fulfillment status updates

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:29:47 -07:00
Jeff Emmett b437709510 feat: replace Stripe with Mollie payments + TBFF revenue split to bonding curve
- Swap stripe SDK for mollie-api-python (Dutch data residency, PCI-DSS L1)
- Mollie redirect checkout flow: create payment → hosted page → webhook
- Rename DB columns: stripe_session_id → payment_id, add payment_provider
- Add revenue split: configurable fraction of each sale deposits to
  flow-service TBFF funnel → Transak on-ramp → bonding curve ($MYCO)
- Add checkout success page with cart cleanup
- Add backlog tasks for remaining work
- Remove @stripe/stripe-js from frontend, Stripe env vars from Docker

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 13:16:39 -07:00
Jeff Emmett 45287d66b3 feat: add fungiswag.jeffemmett.com as custom domain for Fungi Flows
Map fungiswag.jeffemmett.com to the fungiflows space so it can be used
independently of the rswag.online domain.

- Middleware: detect fungiswag.jeffemmett.com → fungiflows space
- Traefik: add Host rule for fungiswag.jeffemmett.com
- CORS: allow fungiswag.jeffemmett.com origin
- Space config: update domain field

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:45:21 -07:00
Jeff Emmett 54ccbbc350 feat: add Upload Swag page with product mockup previews
Users can upload their own logo/design, see instant mockup previews on
shirts, stickers, and art prints via client-side Canvas compositing,
then save and activate the design to the store for ordering.

- Backend: POST /api/design/upload with file validation (type, size,
  dimensions), Pillow processing, saves to designs/uploads/
- Frontend: /upload page with drag-and-drop, real-time mockup gallery,
  activate/discard flow matching existing Design Swag pattern
- Fix: activate/delete endpoints now scan all category dirs instead of
  hardcoding stickers/
- Nav: "Upload Swag" button added to header and homepage CTAs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:38:58 -07:00
Jeff Emmett 7be99d37d0 feat: add multi-tenant spaces with Fungi Flows storefront
Add subdomain-based spaces system for branded storefronts. Each space
has its own theme, product catalog, and isolated cart via scoped
localStorage keys.

- Backend: SpaceService loads YAML configs, new /api/spaces endpoints,
  design filtering by space, CORS regex for *.rswag.online
- Frontend: Next.js middleware detects subdomain and sets space_id cookie,
  dynamic CSS variable injection for theming, space-aware API calls
- Spaces: _default (rSwag hub, cyan/orange) and fungiflows (gold/green/purple)
- Docker: Traefik wildcard HostRegexp for subdomain routing
- Designs: Placeholder Fungi Flows sticker and logo tee

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-18 12:20:19 -07:00