# Project guide for AI coding agents

A two-sided marketplace connecting dog owners with local dog walkers: owners search by postcode and filters, book and pay walkers in-app, message them during the engagement, and rate them afterward; walkers manage their calendar, get paid out via connected accounts, and go through an admin approval process before appearing publicly.

## Stack

- Next.js/React frontend with TypeScript
- Node/TypeScript backend (Next.js API routes or a separate service)
- PostgreSQL via Supabase for data, auth, and storage
- Supabase Auth for email/password and role-based sessions
- Stripe + Stripe Connect for checkout, saved cards, and walker payouts
- Supabase Realtime or Pusher for real-time chat
- Zod for request/response validation
- Tailwind CSS for UI
- Sentry for error monitoring
- Vercel or similar for deployment

## Conventions

- Validate every API input with a Zod schema, sharing the schema between client and server where feasible
- Store all monetary amounts as integer cents, never floats, and format only at the display layer
- Enforce every state machine transition (booking, payout, moderation) server-side, never trust client-submitted state
- Never use the Supabase service-role client or Stripe secret key in client-exposed code paths
- Use database migrations for every schema change, never edit the schema by hand in production
- Guard role-specific routes (owner, walker, admin) with shared middleware, not per-page ad hoc checks
- Write every admin-mutating action and the corresponding audit log entry inside the same transaction
- Add automated tests derived directly from a ticket's acceptance criteria before marking it done

## Build order

See build-order.md for the full ticket-by-ticket sequence. Phase summary:

Accounts & auth. You can demo: someone can sign up, log in, and see their profile.
Core workflow. You can demo: the core flow — browse, search, and book or transact — end to end.
Payments. You can demo: money moves — checkout, payouts, and receipts.
Messaging & notifications. You can demo: the two sides of the app can talk to each other.
Admin. You can demo: the app can be managed and moderated without touching the database.
QA & launch. You can demo: the whole thing, tested, live in production.

## How to pick up a ticket

Read the ticket title, module, and its acceptance criteria in full before writing any code; check whether it depends on an earlier module (e.g. booking before payments, payments before payouts, messaging before notifications) and confirm those pieces already exist; create a branch named after the ticket id, implement only what the ticket and its criteria describe, write or update tests that map one-to-one to each acceptance criterion, then open a PR referencing the ticket id and listing which criteria were verified.

## Definition of done

A ticket is done only when every one of its acceptance criteria bullets can be checked off by a reviewer against working, tested code in the relevant environment — passing acceptance criteria is the bar, not code merely existing or looking complete.

## Never do

- Never skip Zod or equivalent server-side validation on any endpoint that touches auth, bookings, or money
- Never use a Supabase service-role client or Stripe secret key from client-side or public-facing code
- Never invent scope or features beyond what is listed in the given ticket backlog
- Never store raw card numbers or full card details on the app's own servers or database
- Never allow a booking, payout, or admin state transition to happen without a server-side authorization check
- Never ship a payment webhook handler without verifying its signature
- Never mark a ticket complete without tests covering its specific acceptance criteria
- Never bypass the walker approval queue when deciding whether a walker appears in public search