Dungeon Books Store Rebuild: Architecture Decision + Foundation

Summary

Made the platform decision for the Dungeon Books webshop rebuild and completed the first three implementation briefs. Chose Saleor + Payload + Next.js over Medusa after extensive evaluation. New monorepo dungeonbooks/store is up with local dev environment, Saleor fully configured, and product migration script operational.

Architecture Decision

Evaluated Saleor vs Medusa.js as the commerce backend to replace Square Online. Two rounds of coding agent exploration against the existing codebase, plus independent research.

Chose Saleor. The deciding factor was Saleor’s Paper storefront — a production-grade Next.js starter with ~20K lines of commerce UI (multi-step checkout, faceted filtering, variant selection, customer accounts, image gallery). Paper saves ~20-27 weeks of frontend component work vs ~8-12 weeks with Medusa’s starter. The 12-16 week gap is the entire argument. Building checkout flows, faceted filtering, and variant pickers from scratch is the exact work that was grinding progress to a halt on the old codebase.

Medusa’s advantages (same TypeScript runtime, lighter hosting at ~95/mo, simpler in-process modules for Square sync) don’t offset months of frontend development. The hosting premium is ~$900/year — trivial against developer time savings.

Full stack:

  • Saleor (Python/Django) — commerce engine, self-hosted on Railway
  • Payload CMS (TypeScript) — editorial content layer (staff picks, blog, events, reading lists), independent from Saleor (no product sync)
  • Next.js — fork of Saleor Paper storefront
  • Square POS — unchanged for in-store, bidirectional inventory sync via custom Saleor App
  • Stripe — online payments (replaces Square Web Payments SDK, identical processing fees)

Wrote a full rebuild spec (~3K lines) covering architecture, design direction, Saleor/Payload configuration, all page routes, Square POS sync design, gift cards, wishlists, email, phased build plan, and infrastructure costs. Broke it into 21 self-contained task briefs across 4 phases (~35-50 working days total).

Ingram Strategy Clarified

Had a call with Ingram’s digital sales rep (Jul 17, 2025 — email thread: “Re: [External] Ingram Data - Dungeon Books (Script Wizards) - 20AR561”). The original plan was monthly FTP catalog import (89/mo, 100K hits) as a real-time enrichment + fallback search layer instead of bulk FTP import.

How it works: Staff add a book to Saleor → system queries Ingram Web Service by ISBN for metadata (title, author, cover, availability) → product auto-populated but flagged for human approval → once approved, it’s live and fulfillable via Ingram even if we have zero physical copies. Customer searches for a book we don’t carry → fallback query to Ingram → results show as “Available to Order” → staff approval queue.

This is simpler, cheaper, and more curated than the FTP bulk import approach. Sci-fi/fantasy FTP slice is retired anyway. Web Service gives access to Ingram’s full 10M+ active database on demand. Post-MVP feature.

What Got Done (Implementation)

Brief 1.1 — Monorepo scaffolding and local dev environment:

  • New repo dungeonbooks/store with monorepo structure (storefront/, payload/, sync-app/, scripts/, docs/)
  • Docker Compose with Saleor API, Celery worker, Dashboard, PostgreSQL (dual databases: saleor + payload), Redis
  • db-init script, justfile for common commands, env config
  • All services start clean, Dashboard accessible, GraphQL Playground working

Brief 1.2 — Saleor product types, categories, and channel setup:

  • Idempotent setup script (scripts/setup-saleor.ts) configuring Saleor via GraphQL Admin API
  • 18 attributes across 5 product types (Book, RPG Product, Comic/Graphic Novel, Merchandise, Gift Card)
  • 19 categories in hierarchical tree (Books → Sci-Fi/Fantasy/Horror/etc., RPG → D&D/Pathfinder/OSR/etc.)
  • Jersey City Store warehouse with real address
  • Online channel (USD/US) with warehouse assignment
  • Shipping zones (US Standard, Free over $50, Local Pickup)

Brief 1.3 — Product migration script (in progress):

  • scripts/migrate-products.ts reads from Square Catalog API, enriches with Open Library metadata (author, publisher, page count, publication date, series, language), creates products in Saleor via productBulkCreate
  • Supports --dry-run and --limit N flags
  • Idempotent via SKU-based deduplication
  • Fixed expired token issue during auth flow

Design Direction

Established “The Indie Publisher” as the visual direction for the rebuild — warm, typographically driven, genre-aware without cliché fantasy aesthetics. Reference: independent press design (Penguin Classics, A24, McSweeney’s). Serif headings, humanist sans body, burnt orange accent (#C4501A) on warm off-white (#FAFAF8). Paper’s CSS variable system makes the reskin a 1-3 day effort. Open to a fresh direction entirely — not carrying over the terminal/monospace aesthetic from the current site.

Notes

  • The old repo’s lib/square-catalog.ts and scripts/enrich-catalog.ts were useful reference for Brief 1.3 — Square API patterns, ISBN enrichment via Open Library, category mapping logic
  • Saleor’s CMS App for Payload is thinner than advertised (7 fields, variant-level only, incomplete error handling). Using Payload as an independent content layer instead — no product sync, editorial content references products by slug/ISBN, frontend merges both APIs at render time
  • Square POS hardware is sunk cost, not a lock-in concern. Square stays for in-store, sync layer handles the bridge
  • Gift card situation is the messiest part of the migration — physical Square gift cards can’t auto-redeem in Saleor. Manual process for MVP, unification post-launch

Action Items

Next up (Brief 1.3 completion):

  • Run full migration (all ~1,700 products) and verify in Saleor Dashboard
  • Spot check 10-20 products across types for correct metadata, images, inventory, categories

Remaining Phase 1:

  • Brief 1.4 — Payload CMS setup (collections, seed content)
  • Brief 1.5 — Stripe integration and end-to-end checkout verification
  • Brief 1.6 — Railway staging deployment

Ongoing:

  • Ask Ingram rep to run our ISBN list against Top 100K and Top 250K slices (coverage check)
  • Confirm Ingram Web Service license covers caching product metadata in Saleor for active listings
  • Download and save Ingram data samples from the shared link (folder: DungeonBooks_DataSamples_EXP083025 — may be expired, verify with Carrie if she downloaded them)
  • Evaluate hi.events vs Payload-only for event management during Phase 2 storefront build