4.1 KiB
4.1 KiB
F-186 — Implementer evidence
Implemented
POS cashier
- Eight quick-product slots rendered in a 4×2 touch grid.
- Touch-sized line-discount button; hidden when
terminal.settings.lineDiscountsEnabled=false. - Touch payment modal per configured method with “total” / “partial” choice.
- Mixed payment allocations remain visible with paid and outstanding totals and can be removed.
- Cash tender captures overpayment and previews/records change.
- Separate “Confirmar y cerrar ticket” step; disabled until applied amounts equal total.
- Receipt modal supports browser print and SMTP email; cashier is only reset after one delivery action completes.
- Free-item modal adds non-stock service/product lines by name and positive price.
Admin
- Terminal config expanded from 4 to 8 quick slots.
- Per-terminal discount switch for self-payment terminals.
- Payment-method management supports custom active/inactive cash/card/other methods (Bizum, Stripe, Apple Pay labels, etc.; no external processor integration).
- Company identity, ticket prefix/next number/padding, header/footer and return-policy settings.
Backend and persistence
- Migration
054_pos_checkout_receipts.jsadds transaction-safe receipt settings/sequence, immutable receipt numbers, and nullable stock IDs for CHECK-constrained free lines. - POS sale now reloads catalog prices/names/SKU server-side, locks/decrements stock, rejects disabled discounts/methods, validates exact payment allocation and cash tender, and commits as
COMPLETED. - Payment transactions preserve configured method, tender and change in immutable raw data.
- Each payment is captured in
reporting_payment_lines; this addresses new POS sales not reaching reporting. - Cash session expected balance increases by applied cash, never by tendered cash (change excluded).
- Rich receipt builder contains company, time, ticket number, item details, totals, payment allocations, change and return policy.
- Receipt access is terminal-scoped for cashier/manager and unrestricted only for admin.
- Receipt email uses existing SMTP settings and cannot inject custom content.
- POS cashier creation was corrected to use
backoffice_userswith Argon2 instead of invalid identity rows/SHA-256.
Tests and verification
cd project && npm run typecheck— PASS.cd project && npm test— PASS: 268 unit tests; DB tests skipped without env.TEST_DATABASE_URL=... npx vitest run --no-file-parallelism— PASS: 78 files / 350 tests, including all real-PostgreSQL integration files sequentially.- New
payment-allocation.test.ts— PASS: mixed partial allocation, cash change, exact total, disabled method and legacy mapping. - New
pos-checkout-receipts.itest.ts— PASS: complete state, stock decrement, free line, mixed payment/change, reporting capture, receipt sequence, cash expected amount and idempotent replay. - Migration fresh up / no-op second up / full down / re-up — PASS.
- POS Next.js production build — PASS.
- Admin Next.js production build — PASS (pre-existing dynamic upload tracing warnings only).
./scripts/verify.sh— PASS.git diff --check— PASS.- Targeted ESLint and Prettier for all changed backend/admin/POS files — PASS.
Known repository-wide pre-existing checks
- Root
npm run lintremains red on 9 unrelated pre-existing errors ingenerate-thumbnails.mjs,log-broadcaster.ts, oldstore-repository.test.ts, and reporting files. Changed files pass targeted ESLint/Prettier. - Boundary violations were reduced from 8 to 1 by adding the POS public index and removing old deep imports. The remaining violation is pre-existing
security.routes.ts -> infrastructure/logging/log-broadcaster.tsand is outside F-186.
Follow-up tickets captured from user additions
- F-187 cashier deletion/deactivation.
- F-188 pending-payment orders (paid POS orders are already
COMPLETEDhere). - F-189 negative quantity returns and return tickets.
- F-190 full reporting update/refresh audit (new POS payment lines are captured here).
- F-191 terminal and daily close reconciliation.
- F-192 simplified storefront VAT label.
- F-193 storefront expiry/weight and shipping-weight calculation.