WebCart
Public overview of the WebCart e-commerce platform - open-shop single-tenant starter and cloudshop multi-tenant storefront with per-tenant subdomains, plan-gated quotas, and public import API.
What It Is
WebCart is an e-commerce platform built as two sibling Remix apps on a Cloudflare Pages + D1 + R2 + Stripe foundation. open-shop is a single-tenant starter you can self-host as a standalone storefront. cloudshop is a multi-tenant SaaS that hosts many storefronts behind per-tenant subdomains or custom domains, with plan-gated product and monthly order quotas, tenant-scoped admin, AI-assisted catalog generation, and a Bearer-authenticated public product-import API.
Architecture
The repo contains two deployable Pages apps and a routing Worker:
apps/cloudshop- multi-tenant SaaS storefront with a shared D1 database scoped per tenant.apps/open-shop- single-tenant Remix storefront used as both a reference template and a vendored shared-component source for cloudshop.apps/cloudshop/workers/subdomain-router- Cloudflare Worker that proxieswebcart.ukand*.webcart.uktraffic to the cloudshop Pages origin with the resolved tenant context.
Shared TopoloAuth SDKs live in packages/topolo-auth-client and packages/topolo-auth-middleware.
Runtime Surfaces
https://webcart.uk- cloudshop bare domain.https://{tenant}.webcart.uk- cloudshop tenant subdomains.https://cloudshop.pages.dev- cloudshop Pages origin.https://open-shop.pages.dev- open-shop reference deployment.
Plans and Quotas
cloudshop enforces plan-based quotas at every mutation boundary. starter, growth, pro, and enterprise plans each cap product count and monthly order volume. Attempted creations beyond the cap return 402 Payment Required with an explicit upgrade message.
Public API
POST /api/import/:tenant accepts Bearer-token-authenticated product imports, including optional category creation, duplicate skipping, and SKU-keyed updates. Import volume is gated against the tenant’s remaining product quota so partial imports are possible up to the cap.
Auth
Cloudshop admin login uses TopoloAuth via @topolo/auth-client against srv_webcart, with email/password retained as a fallback sign-in path.