9.7 KiB
9.7 KiB
POS System — End-to-End Testing Checklist
Work through this top-to-bottom. Each section depends on the one above it.
Mark [x] as you go. Note failures with a short comment.
0. Prerequisites
- Docker Desktop is running
- You are in the project root:
c:\development\simple-pos-system - All
.envfiles are filled in correctly (see below)
.env quick reference
cloud_backend/.env
SECRET_KEY=<long random string>
DATABASE_URL=sqlite:////app/data/cloud.db
ACCESS_TOKEN_EXPIRE_MINUTES=60
ADMIN_USERNAME=sysadmin
ADMIN_PASSWORD=<your password>
local_backend/.env
SITE_ID=<filled in after step 2.4>
SITE_KEY=<filled in after step 2.4>
CLOUD_URL=http://cloud_backend:8001
SECRET_KEY=<long random string>
LICENSE_GRACE_HOURS=24
sysadmin_panel/.env
VITE_CLOUD_URL=http://localhost:8001
waiter_pwa/.env
VITE_API_URL=http://<local-backend-ip>:8000
manager_dashboard/.env
VITE_API_URL=http://<local-backend-ip>:8000
1. Cloud Backend
1.1 Start
docker compose up cloud_backend -d
- Container starts without errors (
docker compose logs cloud_backend)
1.2 Health check
GET http://localhost:8001/health
- Returns
{"status": "ok"}
1.3 Sysadmin login
POST http://localhost:8001/api/auth/login
Body: { "username": "sysadmin", "password": "changeme" }
- Returns a JWT
access_token - Save token for next steps
1.4 List sites (empty)
GET http://localhost:8001/api/sites/
Header: Authorization: Bearer <token>
- Returns
[](empty list)
2. Sysadmin Panel
2.1 Start
docker compose up sysadmin_panel -d
- Container starts,
npm installcompletes, dev server on port 5175
2.2 Open in browser
http://localhost:5175
- Redirects to
/login - Login form appears (username + password, NOT pin pad)
2.3 Login
- Enter
sysadmin/changeme→ redirects to/sites - Sites page shows "0 registered", "Register New Site" button visible
- Summary counts (Active / Locked / Expired) visible
2.4 Register a site
- Click "Register New Site"
- Form fields: Restaurant Name, Owner Name, Contact Email, License Expiry
- Fill in test data, set expiry date to at least 1 year from now
- Submit → success screen shows
- Site ID and Secret Key are displayed
- Warning banner "Copy this secret key now" is visible
- "Copy .env vars" button works (copies to clipboard)
- Copy the
SITE_IDandSITE_SECRETvalues - Paste them into
local_backend/.envasSITE_ID=andSITE_KEY=
2.5 Verify site in list
- Navigate to
/sites→ new site card appears - Status shows yellow "No Heartbeat" (expected — local backend hasn't connected yet)
- Click site card → SiteDetailPage shows correct name, owner, expiry
- Lock/Unlock/Extend License buttons are visible
3. Local Backend
3.1 Start
docker compose up backend -d
- Container starts without errors
- Logs show:
Application startup complete - Logs show cloud sync attempt: either
Cloud sync OKorCloud sync failed(if cloud URL not yet reachable from inside Docker — checkCLOUD_URL=http://cloud_backend:8001)
3.2 Health check
GET http://localhost:8000/api/system/health
- Returns
{"status": "ok"}(this endpoint is exempt from license check)
3.3 Heartbeat appears in sysadmin panel
- In Sysadmin Panel → SiteDetailPage: "Last seen" updates to recent timestamp
- Status indicator turns green "Active"
- Last IP field shows the Docker container IP
Note: Cloud sync runs immediately on startup, so this should update within seconds.
3.4 Auth — create initial manager
If no manager user exists in the DB yet, seed one via the seed script or direct API call:
docker compose exec backend python seed.py
- Seed runs without errors (or manager already exists)
3.5 Auth — login as manager
POST http://localhost:8000/api/auth/login
Body: { "username": "manager", "pin": "1234" }
- Returns
{ access_token, user: { id, username, role: "manager" } }
3.6 Auth — login as waiter
POST http://localhost:8000/api/auth/login
Body: { "username": "<waiter-username>", "pin": "<pin>" }
- Returns token with
role: "waiter"
3.7 Tables endpoint
GET http://localhost:8000/api/tables/
Header: Authorization: Bearer <manager-token>
- Returns list of tables (may be empty if not seeded)
3.8 Products endpoint
GET http://localhost:8000/api/products/
Header: Authorization: Bearer <manager-token>
- Returns list of products and categories
4. Manager Dashboard
4.1 Start
docker compose up manager_dashboard -d
- Dev server starts on port 5174
4.2 Open in browser
http://localhost:5174
- Redirects to
/login - PIN pad + username field visible
4.3 Login
- Enter manager username + PIN → redirects to
/dashboard - Dashboard shows table grid (empty or with existing tables)
- No console errors
4.4 Tables page
- Navigate to Tables → existing tables shown
- Create a new table (e.g. Table 10) → appears in list
- Table groups section visible
4.5 Products page
- Navigate to Products → existing products shown
- Create a new category
- Create a new product in that category, assign a price
- Toggle product availability → greyed out when unavailable
- Assign a printer zone to a product (if printer is configured)
- Product image upload works on an existing product
4.6 Waiters page
- Navigate to Waiters → existing waiters shown
- Create a new waiter (username + PIN)
- Block/unblock a waiter works
- Reset PIN works
4.7 Dashboard live grid
- Open an order from the Waiter PWA (step 5 below), then return here
- Table card updates within 30 seconds (polling interval)
- Click table → OrderDetailPage loads with correct items
4.8 Reports page
- Navigate to Reports → no crash
- Date picker works, summary loads (may be empty)
4.9 Settings page
- Navigate to Settings → no crash
- Printer config visible
5. Waiter PWA
5.1 Open on phone (or browser)
http://<local-machine-ip>:5173
- App loads, redirects to
/login - Username field + PIN pad visible
5.2 Login as waiter
- Enter waiter credentials → redirects to table list
- Only active tables visible (not deactivated ones)
5.3 Open a table order
- Tap a table → if no open order, "Open Order" button appears
- Tap "Open Order" → order is created, table turns active
5.4 Add items
- Category tabs visible at top
- Tap a product → added to order
- Products with options show option selector
- Products with removable ingredients show toggle list
- Item with note field → can add freetext note
5.5 Verify print routing
- After adding items: check printer (if connected) received the ticket
- If no physical printer: check
docker compose logs backend— should show print attempt log (success or failure, NOT a crash)
5.6 View order total
- Order total shows correct sum (base price + selected option deltas)
- Individual item prices shown
5.7 Partial payment
- Select some items → "Mark as Paid" → those items turn grey/paid
- Order status changes to "partially_paid"
- Remaining total updates
5.8 Full payment and close
- Mark all items as paid → order status = "paid"
- "Close Order" button becomes active
- Tap "Close Order" → confirmation prompt
- Confirm → order closes, table returns to "available"
5.9 Multi-waiter scenario
- From Manager Dashboard, add a second waiter to the order
- Second waiter can see and manage the table in their PWA
5.10 Blocked waiter
- From Manager Dashboard, block a waiter
- That waiter is immediately redirected to login on their next PWA request (401 interceptor)
6. License / Lock Testing
6.1 Lock site from sysadmin panel
- In Sysadmin Panel → SiteDetailPage → Lock Site → enter reason → confirm
- Site shows "Locked" status with red indicator
- Within the next sync cycle (or restart local backend to force immediate sync):
- Local backend logs show lock status received
- All local backend endpoints return HTTP 423 (except
/api/system/health) - Waiter PWA shows error / cannot load data
- Manager Dashboard shows error
6.2 Unlock
- In Sysadmin Panel → Unlock Site
- After next sync: local backend resumes normal operation
6.3 Expired license
- In Sysadmin Panel → Extend License → set expiry date in the PAST → save
- After local backend sync: returns HTTP 402 on all endpoints
- Restore to future date → normal operation resumes
6.4 Cloud unreachable (grace period)
- Stop cloud backend:
docker compose stop cloud_backend - Local backend continues to serve requests (last known state + 24h grace)
- Logs show repeated
Cloud sync failedwarnings - Restart cloud backend → next sync succeeds
7. Known Issues to Watch For
- Product image upload only works on existing products (not at creation time)
- Printer zone must be assigned via Manager Dashboard before items will route to a printer
- Some manager/PWA interactions have rough edges (noted in CLAUDE_CODE_INSTRUCTIONS.md)
SITE_KEYinlocal_backend/.envmust match the secret generated at site registration (copy it immediately, it's shown only once)
Done?
All steps checked → the system is fully operational end-to-end.
Log any failures as GitHub issues or in CLAUDE_CODE_INSTRUCTIONS.md under a new "Phase 5 Known Issues" section.