Files
simple-pos-system/PLANS AND STRATEGIES/CLAUDE_CODE_INSTRUCTIONS.md

6.1 KiB
Raw Blame History

Claude Code — Session Instructions

This file is your starting point for every Claude Code session on this project. Paste it (or reference it) at the start of each session to give Claude Code full context.


Project Summary

We are building a local-first restaurant POS system. Full architecture and specs live in the /pos-build-guide/ folder. Always read the relevant guide file before starting work on any component.

Guide Files

  • 00_PROJECT_OVERVIEW.md — Architecture, stack, build order
  • 01_LOCAL_BACKEND.md — FastAPI backend (build this first)
  • 02_WAITER_PWA.md — Waiter-facing PWA (build second)
  • 03_MANAGER_DASHBOARD.md — Manager web app (build third)
  • 04_CLOUD_BACKEND.md — Cloud licensing backend (build fourth)
  • 05_SYSADMIN_PANEL.md — Sysadmin cloud panel (build last)

Git Workflow

  • The project uses git. Commit after every meaningful milestone (e.g. after scaffolding a phase, after a feature is working, after a bug fix).
  • Always commit before starting a new phase or major refactor.
  • Keep commit messages short and descriptive. No co-author lines needed.
  • Never commit .env, *.db, or license_state.json — they are in .gitignore.

Ground Rules for Claude Code

  1. Read the guide before writing code. Each guide has schema, endpoints, and UX specs. Follow them.
  2. Local backend first. Nothing else can be built or tested without it.
  3. Ask before deviating. If something in the spec seems wrong or ambiguous, ask — don't invent.
  4. Keep business logic in the backend. Frontends are display + interaction only.
  5. Never store sensitive data in frontend localStorage beyond token + username.
  6. All prices are stored and calculated on the backend. Frontend only displays them.
  7. The unit_price on order_items is a snapshot — it must be copied from the product price at the time of ordering, not referenced dynamically.
  8. Printer failures must never block order saves. Log and continue.

Current Build Phase

Update this line as you progress: Phase 1: Local Backend — [x] Complete. Smoke tested: health, auth, products, tables, orders, printer routing all working. Phase 2: Waiter PWA — [x] Complete. Smoke tested end-to-end: login, table list, open order, add items, select/pay with confirmation, close order. See "Phase 2 Known Issues & Fixes" below. Phase 3: Manager Dashboard — [x] Complete. Scaffolded and smoke tested. Known issues remain (see below) — not blockers for Phase 4. Phase 4: Cloud Backend — [ ] Not Started Phase 5: Sysadmin Panel — [ ] Not Started

Phase 2 Known Issues & Fixes Applied

  • OrderItemOut schema now includes product { id, name } via ProductNameOut — required for item names to show correctly in the PWA.
  • OrderOut schema now includes waiters: List[OrderWaiterOut] — required for isMyOrder check on the frontend.
  • Close order button is enabled when there are zero active items (not just when all are paid) — allows closing an empty order.
  • Printing silently skips items with no printer_zone_idexpected. Printer zones are assigned in Phase 3 (Manager Dashboard). No code change needed.
  • selected_options and removed_ingredients on OrderItemInput now accept List[dict] from the PWA (name+price_delta objects and name strings respectively), stored as JSON in the DB. The printer service reads them as raw JSON — modifier names print correctly.

Phase 3 — What Was Built

  • Manager Dashboard: React+Vite, TailwindCSS, React Query, react-hot-toast. Port 5174.
  • Pages: Login (PIN pad, manager/sysadmin only), Dashboard (live table grid, 30s polling), OrderDetailPage (full actions), ProductsPage, WaitersPage, TablesPage, ReportsPage, SettingsPage.
  • Docker Compose service added.

Phase 3 Known Issues & Fixes Applied

  • isMyOrder was always false after page reload — fixed: AuthRehydrator fetches /auth/me on app load to rehydrate user from token.
  • OrderItemInput schema mismatch fixed: backend now accepts selected_options as List[{id, name, price_delta}] objects (not int IDs).
  • Blocked waiter now force-logged out of PWA on next request (401 interceptor).
  • opt.price_delta fixed to read opt.extra_cost from backend schema.
  • GET /api/products/?all=true added for manager to see unavailable products (greyed out, not hidden).
  • PUT /api/products/{id} now replaces options, ingredients, and preference_sets.
  • New: ProductPreferenceSet + ProductPreferenceChoice models (exclusive-choice per product).
  • New: Product image upload — POST /api/products/{id}/image, stored at /app/data/product_images, served as static files. Docker volume: ./data/product_images:/app/data/product_images.
  • New: TableGroup model + endpoints (/api/tables/groups). Tables have group_id FK.
  • New: DELETE /api/tables/{id}?hard=true for permanent delete vs deactivate.
  • New: POST /api/tables/batch for bulk table creation with prefix + count.
  • New: POST /api/auth/me endpoint.
  • Auto-migration on startup adds new columns to existing SQLite DB without dropping data.

Phase 3 Known Remaining Issues (to revisit)

  • Some PWA/manager interactions still have rough edges — to be addressed in a dedicated polish pass before or after Phase 5.
  • Product image upload requires the product to already exist (no upload on creation, only on edit).

Phase 2 Dev Data (seeded manually, not in seed.py)

  • Tables 16 exist (table 1 was from Phase 1 smoke test)
  • Category "food" (id=1) exists from Phase 1 smoke test — contains product "arakas"
  • Categories: Ποτά, Σαλάτες, Κυρίως — 3 products each
  • Printer zones can now be assigned via ProductsPage in the Manager Dashboard.

Environment Variables

Local Backend (.env)

SITE_ID=
CLOUD_URL=https://your-vps.com
SECRET_KEY=generate-a-long-random-string
LICENSE_GRACE_HOURS=24
DATABASE_URL=sqlite:///./pos.db

Waiter PWA (.env)

VITE_API_URL=http://192.168.1.10:8000

Manager Dashboard (.env)

VITE_API_URL=http://192.168.1.10:8000

Cloud Backend (.env)

SECRET_KEY=different-long-random-string
DATABASE_URL=postgresql://...  (or sqlite for dev)