POS Architecture
Core Principle
Emali2 POS is a bounded operational system, not the source of truth for platform money.
There are two ledgers:
Platform ledger- Wallet money
- Till balances
- Settlements and transfers
- Organization-portal financial truth
POS operational tender ledger- Cash
- External card
- External mobile money
- QR
- Loyalty redemption
- Emali tender references
Only Emali tenders create or reconcile against the platform ledger.
Bounded Contexts
flowchart LR
ORG["Main Platform<br/>Organizations, users, units, wallet ledger"] --> POS["POS Service<br/>Inventory, sales, sessions, receipts"]
POS --> BO["POS Backoffice Web"]
BO -->|"Organization, card-present, and onboarding APIs"| ORG
POS --> CW["POS Cashier Web"]
POS --> AND["POS Android"]
POS --> OBJ["Private S3-compatible storage<br/>Item images, receipt assets"]
POS --> EXT["External Integrations<br/>Acquirer, ERP, ecommerce, webhooks"]
Entity Scope
Organization- Legal or commercial parent
OrganizationUnit- Flat child operational unit
MERCHANT,AGENT,BILLERMerchant unit- POS-enabled store
- Inventory-enabled store
- Owns terminals, sessions, store stock, and store reporting
Agent and merchant units can belong to the same organization but remain operationally separate.
Client Strategy
- Use
POS Cashier Webfor countertop supermarket lanes. - Use
POS Androidfor handheld, mobile, or supervisor-driven flows. - Keep inventory and merchant operations in
POS Backoffice Web.
Data Strategy
- Product master is organization-scoped.
- Store assortment, price overrides, and stock are merchant-unit scoped.
- Sessions and sales are terminal scoped.
- Image bytes are stored in private S3-compatible storage and exposed through opaque, managed URLs on the POS API host.
Database identity boundary
POS owns a separate PostgreSQL database and never reads a platform database.
The runtime POS service authenticates as an application role that owns its
database and pos schema so Flyway and transactional DML work, but it cannot
create databases or roles, replicate, bypass row security, or act as a
superuser. A separately stored bootstrap-administrator credential is available
only to PostgreSQL and guarded one-shot administration Jobs. Physical backup
uses a third SCRAM LOGIN REPLICATION role with no application-table
privileges. These identities, Secrets, and network paths are independent of
country, fiscal authority, and payment provider.
Terminal identity-session boundary
Android, browser and dedicated hardware terminals prove possession of their enrolled device key on protected mutations. After proof succeeds, POS records only the opaque OIDC session ID and subject against that terminal, never the access or refresh token. Terminal revocation atomically queues every bound session, then uses the POS machine identity to ask Core to verify subject ownership and terminate that exact identity-provider session. A PostgreSQL dispatcher retries temporary failures, so local terminal revocation remains committed even when IAM is briefly unavailable.
If the enrolled device and its private key are unavailable, an authorized manager can invoke the separate idempotent recovery boundary. It locks the terminal and named open shift, automatically voids only fully unpaid open carts with no unresolved electronic tender, submits the shift, seals the signed close-of-day pack and revokes the device atomically. Partially paid or uncertain electronic sales fail closed for explicit reconciliation. This control is country-neutral and does not inspect or select any payment or fiscal adapter.
Offline Strategy
POS Android- Offline-first
- Local Room storage
- Sync and replay later
POS Cashier Web- Online-first
- Session recovery from backend
- Browser local persistence only for operator convenience, not as the authoritative offline store
POS Backoffice- Online-only in v1
Recommended Evolution
- Keep current POS routes stable.
- Continue extracting POS into
emali2-pos-service. - Publish POS domain events:
sale.createdsale.paidsale.refundedreceipt.generatedshift.openedshift.closedstock.changed- Add service-account integrations between POS and the main platform.