POS & Edge Sync (m_pos)
The m_pos library is Business M’s offline-capable Point-of-Sale (POS) engine. It enables retail outlets and canteens to continue processing sales transactions even when internet connectivity is unavailable, and automatically synchronizes those transactions back to the cloud once reconnected.
Key Use Cases
Section titled “Key Use Cases”1. Canteen & Cafeteria Billing (Beneficiary Card System)
Section titled “1. Canteen & Cafeteria Billing (Beneficiary Card System)”Government canteens, military messes, and institutional cafeterias must serve hundreds of beneficiaries quickly without relying on a live internet connection. m_pos provides:
- Smart Card Billing: Each beneficiary is issued a
PosBeneficiaryCardwith a monthly purchase quota. Purchases are deducted from their quota in real time at the POS terminal. - Offline-First Operation: The POS terminal caches the card registry and item catalog locally. It continues billing even during network outages.
- Quota Enforcement: The system blocks transactions that exceed the configured monthly limit, preventing over-consumption without requiring an online authorization roundtrip.
2. Retail Outlet POS (Distribution Center Outlets)
Section titled “2. Retail Outlet POS (Distribution Center Outlets)”For outlets serviced by Distribution Centers (DCs), m_pos enables:
- Local Invoice Creation: Sales invoices are created and stored locally on the edge device first.
- Batch Cloud Sync: Invoices are synced to the central cloud in configurable batches (controlled by
sync_batch_sizeon thePosProfile). - Conflict Resolution: Uses a Last-Write-Wins (LWW) strategy based on ISO timestamps to safely resolve scenarios where the same record was modified both on the edge and the cloud.
Architecture
Section titled “Architecture”graph TD
subgraph Edge Device ["Edge Device (Offline POS Terminal)"]
UI[POS UI] --> LocalDB["Local SQLite / Cache"]
LocalDB --> SyncQueue["Outbox Queue"]
end
subgraph Cloud ["Cloud (Business M Backend)"]
API["Pull API\n(GET /api/method/m_pos.offline_billing.get_master_data)"]
Push["Push API\n(POST /api/method/m_pos.offline_billing.push_sync_payloads)"]
JetStream["NATS JetStream\nWorker Queue"]
DB["PostgreSQL\n(Central Ledger)"]
end
Edge Device -->|"Periodic Sync\n(Batch push)"| Push
Push --> JetStream
JetStream -->|"process_jetstream_sync job"| DB
Edge Device <-->|"Pull master data\n(Items, Customers)"| API
API --> DB
Data Flow:
- On startup (or periodically), the edge terminal calls
get_master_datato pull the latest item prices and customer/beneficiary list from the cloud. - As invoices are created offline, they are queued locally in an outbox.
- When connectivity is restored, the edge terminal calls
push_sync_payloadswith a batch of queued invoices. - The cloud API enqueues each invoice into NATS JetStream for asynchronous processing.
- The
process_jetstream_syncworker applies LWW conflict resolution and commits the invoice to the central PostgreSQL ledger.
DocTypes
Section titled “DocTypes”PosProfile
Section titled “PosProfile”Configures a POS terminal for a specific company and warehouse context.
| Field | Type | Description |
|---|---|---|
profile_name |
str |
Unique identifier for this terminal profile |
company |
Link(Company) |
The company entity this terminal bills under |
default_warehouse |
Link(Warehouse) |
The warehouse inventory is deducted from |
default_customer |
Link(Customer) |
Optional walk-in customer for anonymous transactions |
sync_batch_size |
int |
Max number of invoices to batch-push per sync cycle (default: 10) |
status |
Active | Inactive |
Whether this terminal is active |
PosBeneficiaryCard
Section titled “PosBeneficiaryCard”Represents a smart card issued to a beneficiary (e.g., canteen member). Quota is tracked monthly.
| Field | Type | Description |
|---|---|---|
card_number |
str |
Unique physical card number |
customer |
Link(Customer) |
The beneficiary linked to this card |
monthly_quota |
Decimal |
Maximum monthly purchase value (default: 1000.00) |
utilized_quota |
Decimal |
Amount consumed this month |
status |
Active | Suspended |
Card status |
API Endpoints
Section titled “API Endpoints”| Method | Endpoint | Description |
|---|---|---|
GET |
/api/method/m_pos.offline_billing.get_master_data |
Pull latest items and customers for the edge cache |
POST |
/api/method/m_pos.offline_billing.push_sync_payloads |
Push a batch of offline invoices for cloud sync |
Both endpoints are allow_guest=True — they are designed to be called by the POS terminal over a local trusted network without requiring a full user session cookie.
Conflict Resolution: Last-Write-Wins (LWW)
Section titled “Conflict Resolution: Last-Write-Wins (LWW)”When the same document exists on both the edge and the cloud (e.g., a voided invoice that was also partially edited on-cloud), m_pos applies a deterministic Last-Write-Wins strategy:
Cloud document modified_at >= Edge document modified_at → Reject the edge payload (marked "rejected_stale") → Log a warning for audit
Cloud document modified_at < Edge document modified_at → Apply edge fields to the cloud document → Save and mark "updated"
Document does not exist on cloud → Insert new document → Mark "inserted"All sync results are logged for traceability.
Enabling m_pos in Your Setup
Section titled “Enabling m_pos in Your Setup”The m_pos library is included as a local workspace package. To activate it in your Business M installation, add it to your pyproject.toml dependencies and include it in your framework_config.toml app registry:
[project]dependencies = [ "business-m-pos", # Local workspace package]Then restart with uv run m dev — the POS DocTypes and API endpoints are discovered and registered automatically at startup.