eWash is a multi-tenant laundry management platform for operating laundry businesses, branches, users, orders, payments, finance, reporting, and platform-level tenancy billing from one Cloudflare-hosted application.
The application is built as one deployable service: a Cloudflare Worker serves the REST API under /api/* and the built Vue SPA from the same origin. There is no separate production frontend server.
| Layer | Technology |
|---|---|
| Frontend | Vue 3, Vite, Pinia, Vue Router |
| Backend | Cloudflare Workers, Hono |
| Database | Cloudflare D1 SQLite, Drizzle ORM |
| Auth | JWT access tokens, rotating refresh tokens, PBKDF2 password hashes |
| Deployment | Wrangler, single Worker serving API and SPA assets |
- Tenant onboarding with seeded laundry service catalog, default roles, default branches, and expense categories.
- Platform control centre for tenants, branches, subscriptions, invoices, platform revenue, and audit logs.
- Branch-aware tenant operations where tenant admins can manage all branches and branch users are limited to their assigned branch.
- Order intake, service pricing, rider/add-on services, kanban workflow, handoff recording, and historical order fulfilment.
- Cash and manual M-Pesa payment recording, credit customers, refunds, expenses, service providers, and recurring expenses.
- Finance reports, daily registers, dashboard KPIs, customer records, audit logs, and notification records.
- Password reset email flow using SMTP configuration.
Tenant dashboard with daily KPIs, active orders, notifications, and branch context.
Orders board with workflow columns for received, washing, ironing, ready, and delivered orders.
New order assessment with seeded services, express handling, rider/add-on services, and price snapshot preparation.
Platform overview with tenant counts, active tenancy status, outstanding billing, and recent registrations.
Tenant management with search, lifecycle status, plan, branch, user, and outstanding billing columns.
Platform tenant revenue view with operating revenue, collections, closed orders, and ranked tenant performance.
Install dependencies:
bun installStart the full local app:
bun startThis builds the web app, applies local D1 migrations, and starts the Worker at:
http://localhost:8787
Useful commands:
bun run build
bun run dev:api
bun run dev:web
bun run db:generate
bun run db:migrate:local
bun run db:migrate:remoteThe platform console is available at:
http://localhost:8787/platform/login
For local development, add bootstrap values to api/.dev.vars:
PLATFORM_ADMIN_EMAIL=owner@example.com
PLATFORM_ADMIN_PASSWORD=use-a-long-unique-password
PLATFORM_ADMIN_NAME=Platform OwnerFor production, set these as Worker secrets:
cd api
bunx wrangler secret put PLATFORM_ADMIN_EMAIL
bunx wrangler secret put PLATFORM_ADMIN_PASSWORD
bunx wrangler secret put PLATFORM_ADMIN_NAMEThe first matching platform sign-in creates the platform owner account. After that, sign-in uses the stored PBKDF2 password hash in D1.
Authenticate Wrangler once:
bunx wrangler loginDeploy:
bun run deployThe deployment script builds the SPA, applies remote D1 migrations, deploys the Worker, and ensures required deployment configuration is present.
Before contributing, read:
AGENTS.mdfor repository rules followed by coding agents.CLAUDE.mdandinstructions.mdfor additional workflow and architectural context.CONTRIBUTING.mdfor human contributor workflow.
Important project rules:
- Reuse existing components and backend helpers before adding new abstractions.
- Keep all tenant data tenant-scoped and branch-aware where relevant.
- Use Drizzle schema changes with named migrations.
- Keep money in integer cents.
- Audit meaningful administrative, financial, pricing, and order-state changes.
- Run
bun run buildand relevant migration checks before submitting changes.
This project is licensed under the MIT License. See LICENSE.





