
Easy Clean DMV
An office CRM and website for a cleaning company: leads, a price calculator, quotes with deposits, crew scheduling and invoicing
- Type
- CRM and website
- Status
- Private system
- Year
- 2026
- 6 slices delivered, from CRM core to reporting
- 5 roles: owner, admin, office, finance, crew
- 0 prices in the website's HTML or JavaScript

Two systems for a cleaning company near Washington, DC. The public website is a Next.js static export with small PHP endpoints for the quote form, booking, contact form and chat assistant. No price appears in the shipped HTML or JavaScript, and a content-source map records where each claim on the site comes from.
Behind it is the office CRM, a Next.js and MySQL app delivered in six slices: the lead inbox and contacts, quotes with deposits, scheduling with a crew app, invoicing and payments, online booking from the website, and reports with consent-based marketing. Each of the five roles, from owner to crew, sees only what its job needs.
How it works
- Website quote or booking
- Lead inbox
- Quote link and deposit
- Crew schedule
- Visit done
- Invoice and payment
- Review request
Screens






Engineering decisions
- Quotes go out as signed links that expire after 14 days, with the token stored hashed. The customer accepts by typing their name: the lead is marked won, the first visit is booked and a deposit is opened, paid by card through Stripe Checkout when it is connected, or recorded by hand for Zelle, Venmo or check.
- Recurring bookings (weekly, or every 2 or 4 weeks) generate visits 12 weeks ahead and roll forward on their own. The crew view is built for phones, with directions, checklists and On my way, Clock in and Clock out buttons, and workers only see their own visits.
- The website books online through public CRM endpoints with an origin allow-list, per-IP rate limits and a honeypot, and falls back to its own PHP form whenever the CRM can't be reached.
- The rate tables stay on the server. The booking form, the estimate form and the quote chat ask it for a starting price, so no rate ships in the website's code, and the chat reads free text like "3 bed 2 bath deep clean in Alexandria, biweekly" and asks only for what is missing.
- A price calculator gives the office an exact price during a call, from the rates the owner keeps in Settings → Pricing, and can save the caller as a contact, lead and draft quote in one step. Email the quote sends a fresh quote link from the business's own mailbox.
- Texts and emails go through an outbox. Only contacts who agreed get campaigns, STOP replies are recorded from signature-verified webhooks, and a review request is queued three hours after each completed job.
Built with
- Next.js
- React 19
- TypeScript
- Drizzle ORM
- MySQL
- Stripe
- Tailwind
- PHP