Svelte Commerce
A standalone open-source storefront built with SvelteKit, headless across 26 commerce backends. MIT licensed.
Cartory Wash gives your cashiers a three-tap payment desk and gives you a live view of cars washed, money collected and who collected it, by bank transfer or POS.
CommerceTypeScript · CSSGitHub @Iknow6aintOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗The web app for the Cartory Wash platform. Car washes register themselves; once a super admin
approves them, their cashiers and admins record sales in three taps, issue receipts, and see
revenue by payment method, service and cashier. Super admins review registrations and approve,
suspend or reactivate businesses from /platform (ADR-002 in ../carwash-api/docs/adr/).
Next.js 16 (App Router), React
19, TanStack Query 5, Zod 4, Tailwind CSS v4, Radix (dialog, dropdown), sonner, Vitest.
The product rules live in ../PROJECT_GUIDE.md. The screens, copy and behaviour come from
../Carwash payment system prototype/. The API contract (every request, response, message and
error code) is in ../carwash-api/docs/api/. The browser never calls the API: every call goes
server to server from a Server Action or Route Handler, with the token from an HttpOnly cookie.
nvm use # Node 24
npm install
cp .env.example .env.local # API_INTERNAL_BASE_URL must end in /v1
npm run dev # http://localhost:3000 (the API runs on :4000, see ../carwash-api)
| Script | What it does |
|---|---|
npm run dev | Dev server on port 3000 |
npm run build | Production build (next build, Turbopack) |
npm run start | Serve the build |
npm run typecheck | tsc --noEmit |
npm run lint | ESLint (next core-web-vitals + TypeScript) |
npm test | Vitest once (npm run test:watch to watch) |
npm run format | Prettier (with the Tailwind class sorter) |
Environment (validated in src/config/env.ts):
| Variable | Where | Value |
|---|---|---|
NEXT_PUBLIC_APP_NAME | browser | Cartory Wash (fallback name before settings load) |
API_INTERNAL_BASE_URL | server only | The API origin including /v1, e.g. http://localhost:4000/v1 |
API_SECURITY_KEY | server only | Same value as carwash-api's API_SECURITY_KEY (32+ characters). Optional locally, required on Vercel. |
NEXT_PUBLIC_DEMO_WHATSAPP_NUMBER | browser | Optional. WhatsApp number for the landing page's "Book a demo" form, international digits only (10–15, e.g. 2348030000000). Unset: the form is replaced by "Demo booking opens soon." Inlined at build time, so redeploy after changing it. |
Every server-to-server call (Server Actions, the proxy's refresh, the CSV handlers) sends
X-Security-Key (when the key is set) and X-Client-Ip (the browser's IP: the first
x-forwarded-for entry, else x-real-ip). The API then rate-limits sign-in and refresh per
browser rather than per Vercel server (lib/api/server-headers.ts).
src/
proxy.ts Renews the session 60 s before the access token expires; else /login?returnTo=
config/env.ts publicEnv (eager) + getServerEnv() (server only)
app/
page.tsx Public landing page (static; outside the proxy matcher)
(auth)/login Sign in (Server Action form)
(auth)/register A car wash registers itself and its owner (public)
(auth)/change-password Temporary passwords are changed here first
(auth)/business-status Staff of a pending or suspended business wait here
(desk)/ Staff shell: dashboard, new, transactions, services, qr-menu, reports, settings
(platform)/platform Super admin shell: overview, businesses, transactions, disputes,
withdrawals, revenue, notifications, settings
api/export/… Two CSV Route Handlers (transactions, daily totals)
menu/[id] Public QR menu (no session; outside the proxy's protected pages)
components/
ui/ feedback/ layout/ navigation/ access/
features/<domain>/ components/ hooks/ schemas/ services/ utils/
lib/
api/ server client, envelope, ApiError, ServiceResult, endpoints, query keys
auth/ cookies, session (requireUser/StaffUser/SuperAdmin), refresh, return-to, access
format/ money, date, plate, payment-method, text (all Lagos-pinned)
providers/ QueryProvider, SessionProvider (useSession, useCan), AppProviders
testing/ Typed fixtures and renderWithDesk()
This is the beginning of the README. Read the rest at the original. Read the full README ↗