# 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. Mounts all route groups under `/api`, applies auth middleware to non-auth routes. In production, serves the built client as static files with SPA fallback. - `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). - `routes/` — CRUD for products, customers, orders, plus a dashboard summary endpoint. **Client** (`client/`): - `src/App.jsx` — Top-level `AuthGate` checks `/api/auth/me` on mount; renders `` or the authenticated `` 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, 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. This logic lives in `server/routes/orders.js` with helper functions `deductStockForOrder()` and `applyOrderItems()`. ## Database Schema Four tables: `products`, `customers`, `orders`, `order_items`. 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`). ## 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`).