1---2name: pos-sales-operations-engineering3description: Use when implementing or reviewing a tenant-aware ERP POS, agent POS, or manual sales-entry workflow where customer defaults, product-to-stock identity, inventory timing, payments, permissions, and audit-safe posting must remain consistent. Use the design engine for visual craft.4---56# POS Sales Operations Engineering78This skill owns the application and service contract for operational point of9sale. It keeps fast sales entry aligned with tenant isolation, finished-stock10truth, manufacturing timing, payment idempotency, permissions, accounting11posting, and evidence. Visual hierarchy and typography remain owned by the12external `design-system-skills` engine.1314<!-- dual-compat-start -->15## Prerequisites1617Load `skills/frontend-ux/pos-sales-operations-engineering` for implementation18rules together with the external design engine's `pos-and-retail-operations`19skill for presentation decisions. For money, inventory value, or ledger work,20also route to `chwezi-accounting-doctrine` and the local `accounting-engine`.2122## Use When2324- Building or auditing `pos.php`, `agent-pos.php`, or `encode-sales.php` in an ERP.25- Defining a tenant-wide Walk-in/default customer and its administrator permission.26- Connecting products to finished stock, manufacturing recipes, batches, and sale deductions.27- Consolidating multiple sales writers, payment handlers, or retry paths into one boundary.28- Testing tenant, branch, sales-agent, plant, stock, invoice, payment, GL, and audit controls together.2930## Do Not Use When3132- The work is only visual composition, typography, colour, or interaction polish; use the external design engine.33- The workflow is quotation → customer order → delivery → invoice → payment collection; design that as separate order-to-cash, not POS.34- The task is a financial statement, statutory rule, or accounting policy judgement; use the accounting doctrine.35- The task is generic frontend architecture without POS-specific transaction or stock semantics.3637## Required Inputs3839| Input | Produced by | Required? | Why |40|---|---|---:|---|41| Surface inventory and user journeys | Product owner / route audit | required | Separates shop POS, agent POS, and manual encoding |42| Tenant, branch, store, agent, and plant access model | Architecture / security | required | Prevents accidental scope escalation |43| Product-to-finished-stock map | Inventory and manufacturing | required | Identifies the stock item a sale may deduct |44| Recipe and manufacturing posting rules | Manufacturing / accounting | when applicable | Keeps ingredient consumption at manufacture |45| Customer, tender, tax, invoice, and GL mappings | Sales / finance | required | Defines a complete posting boundary |46| Representative fixtures and replay expectations | QA / demo seeding | required | Proves normal, failed, retried, and isolated paths |4748## Outputs4950| Artefact | Consumed by | Template or acceptance condition |51|---|---|---|52| POS surface contract | Product, design, frontend, QA | Names the three operational pages and the separate order-to-cash workflow |53| Product-stock and manufacturing map | Inventory, manufacturing, sales | Every saleable product has one active finished-stock mapping |54| Default-customer configuration contract | Tenant administration and QA | One server-resolved active customer is shared by all POS surfaces |55| Canonical posting boundary | API, accounting, inventory, audit | One atomic/idempotent service owns invoice, payment, stock, GL, and audit effects |56| Test and evidence bundle | Release owner and finance review | Includes tenant, permission, failure, replay, stock-timing, and reconciliation evidence |5758## Non-negotiables59601. Keep exactly three operational POS surfaces distinct: `pos.php` is the61 general shop POS; `agent-pos.php` posts sales strictly for a sales agent;62 `encode-sales.php` manually records an already-made sale.632. Store one tenant-wide default customer, normally Walk-in, in a tenant-scoped64 configuration key such as `pos_default_customer_id`. Resolve it server-side65 on every POS page. Never choose the first active customer or infer a default66 from a name containing “cash” or “walk”.673. Allow only super administrators, max administrators, or users with the68 dedicated tenant configuration permission to change that setting. Validate69 customer ownership and active status before saving.704. If the setting is missing or inactive, stop the POS page before the selling71 interface opens. Show a clear, localised configuration state and route the72 authorised user to settings; do not post an unassigned sale.735. Sell products, not arbitrary stock items. Each saleable product must map 1:174 to a finished stock item. Ingredients and packaging are not POS catalogue75 cards.766. Manufacturing consumes recipe ingredient stock and produces the finished77 stock item. Sale posting deducts only that finished stock item. Do not deduct78 recipe ingredients again at sale.797. Use one canonical transaction service or explicit adapters into it. Enforce80 tenant scope, customer validation, mapped product identity, batch/FEFO81 availability, price, invoice, payment, stock movement, GL posting, audit82 lineage, and idempotency in the service boundary.838. Keep branch-sales access, sales-agent access, and plant/job access as84 separate permissions. A user who can view branch sales does not automatically85 gain plant access.869. Treat a timeout as an unknown result. Retry with the same idempotency key and87 reconcile persisted records before displaying a new success or creating a88 second invoice.8910. For fiscal POS deployments, apply the mandatory session-locking and receipt90 sequence controls in91 `skills/product-business/product-discovery/references/feature-planning/references/pos-mandatory-requirements.md`.9293## Decision rules9495| Condition | Required action | Failure avoided |96|---|---|---|97| Active tenant default exists | Load it in all three POS pages before async catalogue work | Empty or divergent customer attribution |98| Default is absent or inactive | Block the POS interface and show configuration guidance | Unassigned or guessed customer sales |99| Operator selects a named customer | Preserve it through product, sales-point, review, and retry states | Silent reset to Walk-in |100| Product lacks an active 1:1 finished-stock mapping | Hide or reject it and report the data defect | Raw ingredient or phantom stock sale |101| Recipe ingredient is consumed | Post at manufacturing completion | Double consumption at sale |102| Finished stock is sold | Deduct the mapped finished item by batch | Ingredient deduction or negative stock leakage |103| User has branch rights but no plant rights | Keep plant records and job cards inaccessible | Permission transitivity breach |104| Payment response is unavailable | Reconcile by idempotency key before retrying | Duplicate payment or invoice |105| Any journal, stock, or invoice write fails | Roll back the atomic boundary or post an authorised reversal | Partial economic event |106107## Workflow1081091. **Inventory the surfaces.** Search routes, APIs, JavaScript, services,110 stored procedures, seeders, reports, and tests. Mark every writer and111 payment path; retire fake or random-ID writers rather than leaving them as112 competing authorities.1132. **Write the identity map.** Record product ID, finished stock-item ID,114 recipe ingredient IDs, batch ID, UOM, price, cost, and the direction of each115 manufacturing and sales movement. Keep customer-facing product identity116 separate from inventory identity.1173. **Define tenant configuration.** Add the setting, permission, settings UI,118 API validation, audit metadata, and a repeatable demo seeder. Verify the119 default belongs to the current tenant and is active.1204. **Gate and initialise all pages.** Resolve the default before rendering the121 sale interface or starting asynchronous catalogue calls. Show explicit122 loading, empty, error, disabled, and configuration-required states.1235. **Consolidate posting.** Route normal invoice sales, manual encoding,124 agent sales, and payment receipt through the canonical service. Preserve125 the same request/idempotency contract across retries and replay.1266. **Enforce stock timing.** Manufacture ingredient-to-finished movements at127 job completion; sell product-to-finished-stock movements at sale posting;128 lock and validate the relevant batch quantities in the same transaction.1297. **Verify boundaries.** Test tenant and branch scope, sales-agent scope,130 plant separation, permission changes, inactive defaults, unmapped products,131 insufficient stock, duplicate keys, payment timeouts, voids, and reversals.1328. **Reconcile evidence.** Confirm invoice lines, payments, stock ledger,133 batch balances, GL journals, customer balance, and audit entries agree. Run134 the seeder in dry-run/apply/verify modes and prove replay does not duplicate.135136## Quality Standards137138- Use server-derived tenant context and prepared statements; never trust a139 tenant ID, customer ID, stock ID, branch ID, or plant ID from the browser.140- Keep errors solution-bearing and localisable. Never return a green success141 state before the persisted result is known.142- Require focused unit/contract tests, a database-backed integration path where143 possible, PHP/JavaScript syntax checks, and a release evidence record.144- Keep the implementation separate from the visual system. Hand off spacing,145 type, colour, touch targets, and visual QA to the design engine.146147## Anti-Patterns148149- **Name heuristic default:** selecting the first customer matching “cash”.150 **Fix:** resolve the explicit tenant setting and block when invalid.151- **Terminal override:** letting a sales-point default silently replace the152 tenant default. **Fix:** keep compatibility fields secondary to the tenant key.153- **Raw-stock catalogue:** displaying bottles, jars, labels, or ingredients as154 products. **Fix:** expose only active product-to-finished-stock mappings.155- **Sale-time recipe deduction:** consuming ingredients when a product is sold.156 **Fix:** consume ingredients at manufacture and finished stock at sale.157- **Writer sprawl:** separate fake sale/payment writers for each screen.158 **Fix:** use one canonical transaction boundary and adapters.159- **Permission shortcut:** treating branch visibility as plant access.160 **Fix:** model and enforce plant permissions separately.161- **Retry duplication:** generating a new idempotency key after a timeout.162 **Fix:** query the original key and reconcile before retrying.163- **False success:** trusting a browser toast without invoice, stock, and GL164 evidence. **Fix:** verify persisted records and reconcile the posting.165166## Read next167168- External `design-system-skills/skills/06-sector-and-domain-ux/pos-and-retail-operations`169- `skills/architecture/api-design-first`170- `skills/finance-accounting/accounting-engine`171- `skills/backend-databases/database-design-engineering`172- `skills/security/vibe-security-skill`173- `skills/sdlc-meta/advanced-testing-strategy`174- `skills/sdlc-meta/reliability-engineering`175- `skills/sdlc-meta/skill-composition-standards`176177## References178179- `references/pos-operations-contract.md` — detailed identity, transaction,180 permissions, and evidence contract.181- `skills/product-business/product-discovery/references/feature-planning/references/pos-mandatory-requirements.md` — session and receipt controls.182- `skills/sdlc-meta/skill-composition-standards/references/test-plan-template.md` — test evidence shape.183- `skills/sdlc-meta/skill-composition-standards/references/rollback-plan-template.md` — rollback evidence shape.184<!-- dual-compat-end -->