cookie-tracker/CLAUDE.md
adamp bb2b43d1c1 Update CLAUDE.md with helmet and rate limiting details
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 22:08:05 -06:00

4.0 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Commands

# 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. 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). 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).