Internal tools

Cleaning company quoting, contracts and job tracking tool

Next.js and Postgres internal tool with versioned price rules, fast on-site quotes, contracts that generate recurring jobs, photo check-ins, and margin reports.

nextjspostgrestypescriptdrizzlezodplaywright

Built 1 time, downloaded 0 times.

Install from your terminal

Run this in your project folder. It signs you in, shows what changes and asks before it overwrites a file.

npx claude-lab add cleaning-company-quoting-contracts-and-job-tracking-tool-53aa51
11 filesDownload zip
CLAUDE.md
# Cleaning company quoting, contracts and job tracking

## Purpose

Internal tool that replaces 3 spreadsheets and a shared calendar.
A salesperson on site must get a quote out in under 10 minutes,
from versioned price rules, on a phone or tablet.
Approved quotes become contracts that generate recurring jobs.
Cleaners check in and out with a photo, and managers see margin reports.
Pricing errors lose real money, so pricing code is held to the strictest rules in this repo.

Domain terms and the data model live in @SPEC.md.
Phases and /goal prompts live in PLAN.md.
Review rules are imported here so `/code-review` applies them: @REVIEW.md

## Layout

pnpm workspace:

- `apps/web`: Next.js App Router, server actions, mobile-first UI.
- `packages/pricing`: pure TypeScript. Zero I/O, zero DB imports.
  Exports `calculateQuote(input, ruleSet)` and the zod rule set schema.
- `packages/db`: Drizzle schema and migrations, Postgres 16.

## Commands

- `docker compose up -d db`: start local Postgres.
- `pnpm dev`: run the web app.
- `pnpm test`: all tests (Vitest).
- `pnpm --filter @app/pricing test`: pricing tests only.
- `pnpm --filter @app/pricing test --coverage`: pricing tests with coverage.
- `pnpm typecheck`
- `pnpm lint`
- `pnpm build`
- `pnpm e2e`: Playwright (`--project=mobile` for the 390x844 viewport).
- `pnpm verify`: typecheck, lint, pricing coverage, all tests, build.
- `pnpm db:generate`: create a new migration from schema changes.
- `pnpm db:migrate`: ask first. Local or test DB only.

## Hard rule: pricing changes

- Any change under `packages/pricing/` must add or update tests in the same change.
- `pnpm --filter @app/pricing test --coverage` must keep 100% line
  and branch coverage on `packages/pricing/src`.
- Never edit files in `packages/pricing/test/golden/` to make a failing test pass.
  Report the diff instead and let a human decide.
- New golden cases are new files named `YYYY-QN-<case>.json`.

## Money rules

- Integer cents only, using the `Cents` branded type. Never floats, never bare `Number` for money.
- Rounding happens once, at the line-item level, half-up.
  It lives only in `packages/pricing/src/round.ts`, which documents it.
- Currency is fixed to one value in config. Do not add multi-currency logic.

## Versioning rules

- Price rule sets are immutable once published (`status = published`).
  A DB trigger and an app check both enforce this.
- A price change means a new `price_rule_set` row with its own `effective_from`.
- Quotes store `price_rule_set_id` plus a JSON snapshot of inputs and line items.
- Recalculating an old quote must use its stored rule set, never the current one.

## Database

- Never run destructive SQL (DROP, TRUNCATE, unscoped DELETE).
- Never edit an applied migration. Create a new one with `pnpm db:generate`.
- Use the `db-migration` skill for schema changes.

## Scope

- Accounting integration is out of scope for v1.
  Keep only the `InvoiceExporter` interface stub. No API calls.
- No customer portal, no payroll in v1.

## Secrets

- Secrets live in `.env.local` (and `.env.test` for tests). Neither is committed.
- In examples, docs and fixtures use placeholders:
  `YOUR_DATABASE_URL`, `YOUR_S3_BUCKET`.
- No real customer data in code or fixtures.

## Gotchas

- Store times in UTC; display in the company timezone. Recurrence must survive DST changes.
- The job generator must be idempotent: running it twice creates no duplicates.
- Photo uploads use signed URLs to S3-compatible storage. No public buckets.
- Salespeople cannot edit rule sets or see margins; cleaners see only their own jobs.

## Workflow

1. Explore, then plan, then code.
2. Use the `pricing-change` skill for any price logic or rule schema edit.
3. Run the `verify` skill before calling a task done.
4. Use the `test-runner` subagent for full test runs to keep output out of context.
5. For diffs that touch money, ask the `pricing-reviewer` subagent for a review.

## Token habits

- `/clear` between unrelated tasks.
- `/compact` at the end of each phase.
- For pricing work, raise effort with `/effort high` rather than switching models.
  Changing effort keeps the prompt cache; switching models breaks it.
Use for my project