cookie-tracker/CLAUDE.md
adamp e1e6670603 Update CLAUDE.md with SPA route whitelist details
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-10 00:37:03 -06:00

67 lines
4.3 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Install dependencies (both root and client)
npm install && cd client && npm install && cd ..
# Development (runs API server + Vite dev server concurrently)
npm run dev
# API: http://localhost:3002
# Client: http://localhost:5173 (proxies /api to :3002)
# Run only the API server
npm run server
# Run only the client dev server
npm run client
# Production build and run
npm run build # Builds client into client/dist/
npm start # Serves API + static client from client/dist/
```
No test runner or linter is currently configured.
## Architecture
Full-stack monorepo: Express.js API + React 18 SPA (Vite + React Router v7).
**Server** (`server/`):
- `index.js` — Express entry point. Applies `helmet()` for security headers, a global API rate limiter (100 req/min/IP via `express-rate-limit`), mounts all route groups under `/api`, and applies auth middleware to non-auth routes. Unmatched `/api` routes return 404 JSON. In production, serves the built client as static files with a whitelisted SPA fallback — only known client routes (`/`, `/inventory`, `/customers`, `/orders`, `/orders/new`, `/orders/:id`, `/restock`, `/reports`) serve `index.html`; all other paths return 404. **When adding new client routes, update the `spaRoutes` regex in `index.js`.**
- `db.js` — SQLite via `better-sqlite3` (synchronous). Auto-creates the `data/` directory and tables on first run. Foreign keys are enabled.
- `middleware/auth.js` — Optional HMAC-SHA256 session cookie auth. If `APP_PASSWORD` is not set in `.env`, authentication is disabled entirely (middleware passes through). Login route has a dedicated rate limiter (5 attempts/min/IP).
- `utils.js` — Shared helpers (`parseId`, `isValidDate`, `parseLimit`) used across routes.
- `routes/` — CRUD for products, customers, orders, plus dashboard summary and reports endpoints.
**Client** (`client/`):
- `src/App.jsx` — Top-level `AuthGate` checks `/api/auth/me` on mount; renders `<Login>` or the authenticated `<Layout>` with routes.
- `src/api.js` — Thin fetch wrapper that prefixes `/api`, includes credentials, and handles JSON serialization.
- `src/pages/` — One component per route: Dashboard, Inventory, Customers, Orders, OrderNew, OrderDetail, Reports, Restock, Login.
- Vite dev server proxies `/api` requests to the Express backend (configured in `vite.config.js`).
**Key data flow**: Orders deduct product stock on creation, restore stock on deletion, and recalculate stock differences on update. All stock changes are logged to `stock_adjustments`. This logic lives in `server/routes/orders.js` with helper functions `atomicDeductStock()` and `applyOrderItems()`. The product PUT endpoint does not allow `quantity_on_hand` changes — all stock modifications must go through PATCH `/products/:id/stock`.
**Validation**: All `:id` route params are validated via `parseId()` (positive integer). Report dates validated as YYYY-MM-DD. Product/customer deletes check for references and return 409 instead of FK errors.
**Schema migrations**: `server/db.js` uses a `schema_version` table. New migrations are added to `runMigrations()` gated by version number.
## Database Schema
Six tables: `products`, `customers`, `orders`, `order_items`, `stock_adjustments`, `schema_version`. Orders reference customers (nullable for walk-ins). Order items have a `UNIQUE(order_id, product_id)` constraint and `ON DELETE CASCADE` from orders. Prices are snapshot at time of sale (`price_at_sale`). Orders track `payment_method` and `amount_paid`. Stock adjustments log every inventory change with reason and optional reference_id.
## Change Documentation
Every change must be meticulously documented. When making commits, each change should be clearly described in the commit message with enough detail to understand what was changed and why. Update CLAUDE.md and README.md when changes affect architecture, schema, deployment, or available features.
## Environment
Configured via `.env` (see `.env.example`):
- `APP_PASSWORD` — If set, enables login gate. If unset, app runs without authentication.
- `APP_SECRET` — Signs session cookies (HMAC-SHA256).
- `PORT` — API server port (default 3002).
- `DATABASE_PATH` — SQLite file path (default `./data/cookies.db`).