# F-188 — Implementer evidence ## Delivered - Backend: `validatePaymentAllocations` accepts under-allocated amounts and rejects only overpayments (`POS_PAYMENT_OVERPAYMENT`, replacing `POS_PAYMENT_TOTAL_MISMATCH`). - Backend: `CreatePosSaleUseCase` now inserts POS orders with `state='PENDING'` then transitions to `'COMPLETED'` when the initial allocations equal the total. Response gains `state`, `paidCents`, `outstandingCents`. - Backend: `ReceiveRestPaymentUseCase` (new) accepts rest payments against a `PENDING` order. Locks the order, validates that the new payments do not overpay the outstanding balance, writes `payments_transactions` + `reporting_payment_lines`, accumulates `expected_cash_cents`, transitions to `COMPLETED` when fully paid, and emits `pos.sale.partial` / `pos.sale.fulfilled` audit events. Idempotency-keyed retries do not duplicate transactions. - Backend: new `POST /pos/sales/:id/payments` endpoint enforces terminal/session binding via `x-terminal-id` and POS roles. - Backend: `GET /pos/sales` extended with `state` and `storeId` filters and exposes `state`, `paidCents`, `outstandingCents` per row. - Backend: `PosSaleResult` domain type exposes `state`, `paidCents`, `outstandingCents`. - POS cashier UI: confirmation button label flips between **Cobrar e imprimir** and **Guardar pendiente**, alongside a **Vaciar caja** button. - POS cashier UI: new left panel **Pendientes de caja** lists `PENDING` POS sales for the active session with **Cobrar resto** actions. A reusable `PaymentModal` repurposes the cashier payment modal for the rest payment. - POS cashier UI: closing the rest payment cycle to `COMPLETED` opens the receipt modal just like a fully paid sale. - Tests: real PostgreSQL `pos-pending-payments.itest.ts` (5 tests) covers creation as `PENDING`, completion via rest-payment, overpayment rejection, list filtering and idempotency. Updated payment-allocation unit test (4 tests). ## Validation - Backend, POS, admin typecheck: PASS. - Backend, POS, admin production build: PASS. - Real-PostgreSQL sequential suite: 360/360 PASS across 80 files. - Backend unit tests after update: 268/268 PASS. - POS unit tests + new integration: 5/5 PASS. - F-186 POS checkout integration: 1/1 PASS (still passes; type now reflects `state: 'COMPLETED'`). - Migration cycle: 4/4 PASS. - Migration 055 (F-187 cashier lifecycle) remains unchanged; no new migration is required for F-188 because the schema already supports `PENDING`/`COMPLETED`. - Targeted ESLint + Prettier on every changed file: PASS. - `./scripts/verify.sh`: PASS. ## Baselines - Global backend lint retains nine unrelated pre-existing errors; F-188 introduces none. - Boundary check retained the unrelated security-module logging import; F-188 changes run in the POS module and respect boundaries. - Untracked upload JPGs stay excluded from the feature commit.