JikoXpress Financial System Architecture
Version 1.0 | April 2026 | QBIT SPARK CO LIMITED
Full architecture, data flow, user journeys and entity design
Table of Contents
- Overview
- System Components
- Chart of Accounts
- Entity Design
- Data Flows
- User Journeys
- Payment Channels
- Escrow System
- Money Splitting
- Platform Offers
- Settlements & Withdrawals
- P&L & Reporting
- Security & Rules
1. Overview
JikoXpress financial system is a unified internal accounting engine that tracks every single money movement across the platform — regardless of amount (even TZS 0.00), channel, or purpose.
Core Principles
- Every event is a transaction — cash, mobile money, wallet, kitchen wallet, TZS 0 promo orders — all recorded
- Double entry accounting — every debit has a credit, books always balance
- Single source of truth — internal ledger is authoritative, not external provider
- Dynamic money splitting — splits are configurable, not hardcoded
- Escrow is a flag — any transaction can be held, decided at runtime not hardcoded
- Kitchen wallet is separate — platform records usage but does not manage it
Two Separate Financial Worlds
┌─────────────────────────────────────────────┐
│ JikoXpress Platform Treasury │
│ Commission, wallets, settlements, offers │
│ One internal ledger │
└─────────────────────────────────────────────┘
┌─────────────────────────────────────────────┐
│ Kitchen Customer Wallet │
│ Kitchen manages independently │
│ Platform only records "used as payment" │
└─────────────────────────────────────────────┘
2. System Components
2.1 Platform Treasury
The central bank of JikoXpress. All platform money flows through here.
Responsibilities:
- Receive commission from every order
- Receive subscription fees from kitchens
- Hold escrow for remote orders
- Pay delivery partners
- Subsidize platform offers
- Process refunds
- Settle kitchen earnings
- Record admin profit withdrawals
2.2 Platform Wallet
JikoXpress app user wallet. Customer can topup, pay orders, withdraw.
- One wallet per registered app user
- Created automatically on registration
- Has its own transaction ledger
- Linked to treasury LIABILITY account
2.3 Kitchen Earnings
Platform holds kitchen revenue after orders until kitchen owner requests payout.
- Per kitchen
- Accumulates with every completed order
- Depleted on settlement request
- Linked to treasury LIABILITY_SETTLEMENTS account
2.4 Kitchen Customer Wallet
Completely separate from platform. Kitchen manages independently.
- Kitchen issues to loyal customers
- Kitchen handles deposits, deductions, withdrawals
- Has its own ledger — kitchen's books
- Platform only records "channel: KITCHEN_WALLET" in transaction
2.5 External Payment Providers
Physical money handlers — Selcom, Azampay, etc.
- Physical money sits here
- Platform calls their API for collections and disbursements
- Every interaction recorded in platform ledger
- Provider can be swapped without changing internal accounting
2.6 Escrow
Temporary holding account for remote orders.
- Lives in ASSET_ESCROW account in treasury
- Holds money between payment and delivery/confirmation
- Released when release condition is met
- Any transaction can be flagged for escrow at runtime
3. Chart of Accounts
ASSETS (what platform owns)
├── ASSET_FLOAT Working capital for disbursements
├── ASSET_ESCROW Money held pending release
└── ASSET_RECEIVABLES Money owed to platform
REVENUE (money coming in)
├── REVENUE_COMMISSION % taken from every order
├── REVENUE_SUBSCRIPTION Kitchen monthly/yearly fees
├── REVENUE_SERVICE_FEE Platform service charges
└── REVENUE_DELIVERY_MARKUP Markup on delivery price
EXPENSE (money going out)
├── EXPENSE_DELIVERY Paying delivery partners
├── EXPENSE_OFFER_SUBSIDY Platform offer costs
├── EXPENSE_REFUNDS Customer refunds
└── EXPENSE_OPERATIONS Platform operational costs
LIABILITY (what platform owes)
├── LIABILITY_SETTLEMENTS Kitchen earnings awaiting payout
├── LIABILITY_PLATFORM_WALLETS App user wallet balances
└── LIABILITY_ESCROW_DUE Escrow obligations
EQUITY (platform net worth)
├── EQUITY_CAPITAL Admin deposits / investments
└── EQUITY_RETAINED_EARNINGS Accumulated profits
P&L Formula
Total Revenue = sum(REVENUE_*)
Total Expenses = sum(EXPENSE_*)
Net Profit = Total Revenue - Total Expenses
Available Cash = ASSET_FLOAT - LIABILITY_SETTLEMENTS - LIABILITY_PLATFORM_WALLETS
4. Entity Design
4.1 AccountEntity
Chart of accounts — one record per account type.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| code | String | e.g. ASSET_FLOAT, REVENUE_COMMISSION |
| name | String | Human readable |
| type | Enum | ASSET, REVENUE, EXPENSE, LIABILITY, EQUITY |
| balance | BigDecimal | Running balance |
| createdAt | LocalDateTime |
4.2 JournalEntryEntity
Every single money movement. Immutable — never updated or deleted.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| debitAccount | AccountEntity | Account debited |
| creditAccount | AccountEntity | Account credited |
| amount | BigDecimal | Always positive |
| description | String | Human readable note |
| reference | String | Order ID, settlement ID, etc |
| referenceType | Enum | ORDER, SETTLEMENT, TOPUP, WITHDRAWAL, REFUND |
| createdAt | LocalDateTime |
4.3 TransactionEntity
Every payment event — one per payment split per order.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| orderId | UUID | Linked order |
| sessionId | UUID | Linked checkout session |
| channel | UniversalPaymentMethod | CASH, MOBILE_MONEY, CARD, etc |
| amount | BigDecimal | Even 0.00 |
| status | Enum | PENDING, COMPLETED, FAILED, REFUNDED |
| holdInEscrow | Boolean | Dynamic flag |
| escrowReleaseCondition | Enum | IMMEDIATE, DELIVERY_CONFIRMED, PICKUP_CONFIRMED |
| reference | String | USSD ref, card ref, etc |
| kitchenPaymentMethodId | UUID | If KITCHEN_CHANNEL |
| kitchenCustomerId | UUID | If KITCHEN_WALLET |
| paidBy | Enum | CUSTOMER, PLATFORM |
| offerRef | UUID | If platform offer covered this |
| createdAt | LocalDateTime | |
| completedAt | LocalDateTime |
4.4 TransactionSplitEntity
How transaction amount is distributed. Dynamic — not hardcoded.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| transaction | TransactionEntity | |
| splitType | String | KITCHEN_REVENUE, DELIVERY_FEE, COMMISSION, TAX, PACKAGING, etc |
| description | String | Human readable |
| amount | BigDecimal | |
| destination | Enum | KITCHEN, PLATFORM, DELIVERY_PARTNER, TAX_ACCOUNT |
| destinationId | UUID | Which kitchen, which partner, etc |
| status | Enum | PENDING, COMPLETED |
| createdAt | LocalDateTime |
4.5 EscrowEntity
Tracks escrow holdings per transaction.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| transaction | TransactionEntity | |
| amount | BigDecimal | Amount held |
| status | Enum | HELD, RELEASED, REFUNDED |
| releaseCondition | Enum | DELIVERY_CONFIRMED, PICKUP_CONFIRMED, ORDER_CONFIRMED |
| heldAt | LocalDateTime | |
| releasedAt | LocalDateTime |
4.6 DisbursementEntity
Every outgoing payment to external world.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| amount | BigDecimal | |
| purpose | Enum | KITCHEN_SETTLEMENT, DELIVERY_FEE, REFUND, OFFER_SUBSIDY, PROFIT_WITHDRAWAL |
| provider | String | SELCOM, AZAMPAY, etc |
| reference | String | Provider transaction ref |
| status | Enum | PENDING, COMPLETED, FAILED |
| recipientName | String | |
| recipientAccount | String | Phone or bank account |
| orderId | UUID | If related to order |
| kitchenId | UUID | If kitchen settlement |
| createdAt | LocalDateTime | |
| completedAt | LocalDateTime |
4.7 PlatformWalletEntity
JikoXpress app user wallet.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| account | AccountEntity | Linked JikoXpress user |
| balance | BigDecimal | Current balance |
| createdAt | LocalDateTime | |
| updatedAt | LocalDateTime |
4.8 PlatformWalletTransactionEntity
Every platform wallet movement.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| wallet | PlatformWalletEntity | |
| type | Enum | TOPUP, ORDER_PAYMENT, WITHDRAWAL, REFUND |
| direction | Enum | CREDIT, DEBIT |
| amount | BigDecimal | |
| balanceBefore | BigDecimal | |
| balanceAfter | BigDecimal | |
| reference | String | |
| orderId | UUID | If order payment |
| createdAt | LocalDateTime |
4.9 KitchenEarningsEntity
Kitchen revenue held on platform.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| kitchen | KitchenEntity | |
| balance | BigDecimal | Available for payout |
| totalEarned | BigDecimal | All time earnings |
| totalSettled | BigDecimal | All time payouts |
| updatedAt | LocalDateTime |
4.10 SettlementEntity
Kitchen payout records.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| kitchen | KitchenEntity | |
| amount | BigDecimal | |
| status | Enum | PENDING, PROCESSING, COMPLETED, FAILED |
| requestedBy | AccountEntity | Kitchen owner |
| disbursement | DisbursementEntity | Linked disbursement |
| periodFrom | LocalDate | Settlement period |
| periodTo | LocalDate | |
| createdAt | LocalDateTime | |
| completedAt | LocalDateTime |
4.11 TreasuryTopupEntity
Admin deposits to external provider.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| amount | BigDecimal | |
| provider | String | SELCOM, AZAMPAY, etc |
| reference | String | Deposit reference |
| depositedBy | AccountEntity | Admin who deposited |
| note | String | Optional note |
| createdAt | LocalDateTime |
4.12 WithdrawalEntity
Admin profit withdrawals from treasury.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| amount | BigDecimal | |
| requestedBy | AccountEntity | Super admin |
| approvedBy | AccountEntity | Second admin approval |
| purpose | String | Profit withdrawal note |
| destinationAccount | String | Bank/mobile to receive |
| status | Enum | PENDING, APPROVED, COMPLETED, REJECTED |
| disbursement | DisbursementEntity | Linked disbursement |
| createdAt | LocalDateTime | |
| completedAt | LocalDateTime |
4.13 PlatformOfferEntity
Platform offer definitions.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| name | String | |
| type | Enum | FREE_DELIVERY, FREE_ORDERS, DISCOUNT_PERCENT, FREE_ITEM |
| value | BigDecimal | Discount amount or % |
| conditions | JSON | Min order, eligible users, max uses |
| budget | BigDecimal | Total platform budget for this offer |
| budgetUsed | BigDecimal | Running total spent |
| active | Boolean | Auto-deactivates when budget exhausted |
| validFrom | LocalDate | |
| validUntil | LocalDate | |
| createdAt | LocalDateTime |
4.14 PlatformOfferUsageEntity
Who used which offer.
| Field | Type | Description |
|---|---|---|
| id | UUID | |
| offer | PlatformOfferEntity | |
| account | AccountEntity | App user who used it |
| orderId | UUID | |
| amountCovered | BigDecimal | How much platform paid |
| createdAt | LocalDateTime |
5. Data Flows
5.1 Payment Collection Flow
Customer initiates payment
│
▼
CheckoutSession created
(inventory held)
│
▼
TransactionEntity created
- channel set
- holdInEscrow flag set
- status = PENDING
│
├─── Cash / Kitchen Wallet ──────────────────────────────────►
│ No external API call │
│ Cashier confirms manually │
│ │
├─── Mobile Money / Card ──────────────────────────────────► │
│ External provider API called │
│ USSD prompt / card terminal │
│ Webhook fires on confirmation │
│ │
└─── Platform Wallet ───────────────────────────────────────► │
Internal debit only │
No external API │
│
Payment Confirmed ◄────────────┘
│
▼
TransactionEntity status = COMPLETED
│
┌───────────┴───────────┐
│ │
holdInEscrow=false holdInEscrow=true
│ │
▼ ▼
Split money EscrowEntity created
immediately Money held in
to destinations ASSET_ESCROW
│ │
│ Release condition met
│ │
│ ▼
│ Split money
│ to destinations
│ │
└───────────────────────┘
│
▼
Order Created
Kitchen Notified
5.2 Money Split Flow
Total Order Amount: TZS 10,000
│
▼
Split Calculator
│
├── Food Items Total ──────────────► KitchenEarnings += X
│
├── Packaging Fee ────────────────► KitchenEarnings += X
│
├── Delivery Fee ──────────────────► DisbursementEntity
│ (pay delivery partner)
│
├── Platform Commission ──────────► JournalEntry
│ DEBIT ASSET_FLOAT
│ CREDIT REVENUE_COMMISSION
│
└── Tax ────────────────────────────► JournalEntry
DEBIT ASSET_FLOAT
CREDIT TAX_ACCOUNT
5.3 Escrow Release Flow
EscrowEntity status = HELD
│
▼
Release Condition Met
(DELIVERY_CONFIRMED / PICKUP_CONFIRMED)
│
▼
EscrowEntity status = RELEASED
│
▼
JournalEntry:
DEBIT ASSET_FLOAT
CREDIT ASSET_ESCROW
│
▼
Money Split Calculator runs
│
▼
TransactionSplitEntity created per split
│
▼
Each split credited to destination
5.4 Refund Flow
Order Cancelled / Refund Requested
│
▼
Check TransactionEntity
│
├── In Escrow ────────────────────────────────────────────►
│ EscrowEntity status = REFUNDED │
│ JournalEntry: │
│ DEBIT ASSET_FLOAT │
│ CREDIT ASSET_ESCROW │
│ │
└── Already Settled ───────────────────────────────────► │
KitchenEarnings debited │
JournalEntry: │
DEBIT LIABILITY_SETTLEMENTS │
CREDIT ASSET_FLOAT │
│
Refund Processed ◄─────┘
│
▼
DisbursementEntity created
(purpose: REFUND)
│
▼
External provider API
(return money to customer)
│
▼
JournalEntry:
DEBIT EXPENSE_REFUNDS
CREDIT ASSET_FLOAT
5.5 Kitchen Settlement Flow
Kitchen Owner requests payout
│
▼
KitchenEarningsEntity checked
(available balance)
│
▼
SettlementEntity created
status = PENDING
│
▼
JournalEntry:
DEBIT LIABILITY_SETTLEMENTS
CREDIT ASSET_FLOAT
│
▼
DisbursementEntity created
(purpose: KITCHEN_SETTLEMENT)
│
▼
External provider API called
(transfer to owner mobile/bank)
│
▼
Provider webhook confirms
│
▼
DisbursementEntity status = COMPLETED
SettlementEntity status = COMPLETED
KitchenEarningsEntity balance -= amount
5.6 Admin Profit Withdrawal Flow
Super Admin requests withdrawal
│
▼
WithdrawalEntity created
status = PENDING
│
▼
Second Admin approves
│
▼
WithdrawalEntity status = APPROVED
│
▼
JournalEntry:
DEBIT EQUITY_RETAINED_EARNINGS
CREDIT ASSET_FLOAT
│
▼
DisbursementEntity created
(purpose: PROFIT_WITHDRAWAL)
│
▼
External provider transfer
│
▼
WithdrawalEntity status = COMPLETED
5.7 Platform Offer Flow
App customer applies offer at checkout
│
▼
PlatformOfferEntity validated
- Is active?
- Budget available?
- User eligible?
- Conditions met?
│
▼
Offer applied
Customer pays reduced amount
│
▼
Two TransactionEntities created:
1. Customer payment (reduced amount)
2. Platform payment (offer subsidy amount)
- paidBy = PLATFORM
- offerRef = offer uuid
│
▼
PlatformOfferUsageEntity created
PlatformOfferEntity.budgetUsed += subsidy amount
│
▼
If budgetUsed >= budget
→ offer auto-deactivated
│
▼
JournalEntry:
DEBIT EXPENSE_OFFER_SUBSIDY
CREDIT ASSET_FLOAT
│
▼
Both transactions confirmed
→ Order created
→ Kitchen gets full amount
→ Platform covered the difference
6. User Journeys
6.1 Customer — Pay for Order (POS Cash)
Customer at counter
│
▼
Staff adds items to checkout session
│
▼
Staff selects: Pay Now → Cash
│
▼
System calculates total
│
▼
Staff collects cash from customer
│
▼
Staff confirms payment in system
│
▼
Transaction recorded (CASH, no escrow)
Money split immediately
│
▼
Order created → kitchen notified
│
▼
Receipt printed (frontend)
│
▼
Kitchen prepares → food ready
│
▼
Customer receives food
6.2 Customer — App Delivery with Mobile Money
App customer browses kitchens
│
▼
Adds items to cart
│
▼
Proceeds to checkout
Enters delivery address
│
▼
Selects Mobile Money payment
│
▼
System creates checkout session
Inventory held
│
▼
USSD prompt sent to customer phone
│
▼
Customer enters PIN on phone
│
▼
Provider confirms → webhook fires
│
▼
Transaction recorded
holdInEscrow = true
EscrowEntity created
│
▼
Order created → kitchen notified
│
▼
Kitchen prepares → packages food
│
▼
Delivery partner picks up
│
▼
Delivery partner confirms delivery
│
▼
Escrow released
Money split:
→ Kitchen earnings
→ Delivery partner paid
→ Platform commission recorded
│
▼
Customer receives food
6.3 Customer — Kiosk Cash Slip
Customer at kiosk machine
│
▼
Customer selects items
│
▼
Customer selects: Pay Cash
│
▼
System creates SLIP session
Inventory held
Slip expires in 15 min
│
▼
Slip printed (frontend handles)
│
▼
Customer walks to cashier with slip
│
▼
Cashier scans slip barcode
Finds session in queue
│
▼
Cashier collects cash
Confirms payment in system
│
▼
Transaction recorded (CASH, no escrow)
Money split immediately
│
▼
Order created → kitchen notified
│
▼
Kitchen prepares food
│
▼
Customer number called
Customer collects food
6.4 Customer — Dine In with Tab (Multiple Rounds)
Customer sits at table
│
▼
Waiter takes order → Round 1
Creates TAB session
New KitchenBillsEntity opened
│
▼
Kitchen ticket printed for Round 1
Kitchen prepares
│
▼
Customer orders more → Round 2
Waiter adds new session to same bill
│
▼
Kitchen ticket printed for Round 2
Kitchen prepares
│
▼
Customer asks for bill
Waiter prints bill (all rounds)
│
▼
Customer pays
Waiter selects payment method(s)
│
▼
Transaction(s) recorded
Money split
│
▼
KitchenBillsEntity closed
Receipt printed
6.5 Kitchen Owner — Request Settlement
Kitchen owner opens earnings screen
Sees available balance
│
▼
Clicks "Request Payout"
Enters amount and destination
│
▼
SettlementEntity created (PENDING)
│
▼
Platform processes
DisbursementEntity created
External transfer initiated
│
▼
Provider confirms
│
▼
SettlementEntity COMPLETED
KitchenEarnings balance updated
│
▼
Kitchen owner receives money
on mobile/bank account
6.6 Admin — Treasury Topup
Platform needs more float
Admin deposits to Selcom
│
▼
Admin records topup in system
TreasuryTopupEntity created
│
▼
JournalEntry:
DEBIT ASSET_FLOAT
CREDIT EQUITY_CAPITAL
│
▼
Platform float increases
Ready for disbursements
6.7 Admin — Profit Withdrawal
Platform has accumulated profits
Super admin requests withdrawal
│
▼
WithdrawalEntity created (PENDING)
Second admin notified for approval
│
▼
Second admin approves
│
▼
JournalEntry recorded
DisbursementEntity created
External transfer initiated
│
▼
WithdrawalEntity COMPLETED
Profits withdrawn
7. Payment Channels
| Channel | External API | Escrow Possible | Notes |
|---|---|---|---|
| CASH | ❌ | ❌ | Physical, always immediate |
| MOBILE_MONEY | ✅ Selcom/Azampay | ✅ | USSD webhook based |
| CARD | ✅ Card gateway | ✅ | Future |
| PLATFORM_WALLET | ❌ Internal | ✅ | Internal debit |
| KITCHEN_WALLET | ❌ Kitchen handles | ❌ | Kitchen's own system |
| KITCHEN_CHANNEL | ❌ Manual confirm | ❌ | Physical payment |
8. Escrow System
When to Hold
Escrow flag (holdInEscrow) is set dynamically at transaction creation based on current business rules. Not hardcoded.
Current default rules:
- DELIVERY fulfillment → hold until delivery confirmed
- All others → no hold (immediate split)
Future rules can be added without code changes — just update the rule engine.
Release Conditions
| Condition | Trigger |
|---|---|
| IMMEDIATE | No hold — split right away |
| ORDER_CONFIRMED | When cashier approves (TABLE_QR) |
| PICKUP_CONFIRMED | When customer collects food |
| DELIVERY_CONFIRMED | When delivery partner confirms |
9. Money Splitting
Splits are dynamic — configured per order based on what services are included.
Split Types
| Split Type | Destination | Example |
|---|---|---|
| KITCHEN_REVENUE | Kitchen earnings | Food items total |
| PACKAGING_FEE | Kitchen earnings | Packaging cost |
| DELIVERY_FEE | Delivery partner | Courier payment |
| PLATFORM_COMMISSION | REVENUE_COMMISSION account | Platform % cut |
| TAX | Tax account | VAT/government tax |
| OFFER_SUBSIDY | EXPENSE_OFFER_SUBSIDY | Platform covers discount |
New split types can be added as new services are introduced — no entity changes needed.
10. Platform Offers
Offer Types
| Type | Description | Platform Pays |
|---|---|---|
| FREE_DELIVERY | Platform covers delivery fee | Delivery fee amount |
| FREE_ORDERS | First N orders free | Full order amount |
| DISCOUNT_PERCENT | % off order | Discount amount |
| FREE_ITEM | Specific item free | Item price |
Offer Validation Rules
- User must be eligible (e.g. first 2 orders check)
- Offer must be active
- Budget must not be exhausted
- Order must meet minimum conditions
- Channel must be APP — offers are app users only
Budget Control
PlatformOfferEntity.budget = TZS 1,000,000 (allocated)
PlatformOfferEntity.budgetUsed = TZS 850,000 (spent so far)
Remaining = TZS 150,000
When budgetUsed >= budget:
→ offer.active = false (auto-deactivated)
→ No more usage allowed
11. Settlements & Withdrawals
Kitchen Settlement Rules
- Kitchen owner can request anytime
- Minimum payout amount (configurable)
- Cannot exceed available KitchenEarnings balance
- Processing time depends on external provider
- Failed settlements → DisbursementEntity FAILED → retry
Admin Withdrawal Rules
- Only SUPER_ADMIN can request
- Requires second SUPER_ADMIN approval
- Cannot withdraw from escrow — those funds belong to customers
- Cannot withdraw more than available ASSET_FLOAT
- Full audit trail — who requested, who approved, when, where it went
12. P&L & Reporting
Revenue Report
Period: April 2026
Commission: TZS 2,500,000
Subscription fees: TZS 1,200,000
Service fees: TZS 300,000
─────────────────────────────────
Total Revenue: TZS 4,000,000
Expense Report
Period: April 2026
Delivery payouts: TZS 800,000
Offer subsidies: TZS 400,000
Refunds: TZS 150,000
─────────────────────────────────
Total Expenses: TZS 1,350,000
Net Profit
Net Profit = TZS 4,000,000 - TZS 1,350,000 = TZS 2,650,000
Balance Sheet
ASSETS
Float: TZS 5,000,000
Escrow: TZS 300,000
Receivables: TZS 200,000
Total Assets: TZS 5,500,000
LIABILITIES
Kitchen settlements due: TZS 2,000,000
Platform wallets: TZS 500,000
Total Liabilities: TZS 2,500,000
EQUITY
Capital: TZS 1,000,000
Retained earnings: TZS 2,000,000
Total Equity: TZS 3,000,000
Projections
Based on historical journal entries:
- Month over month commission growth
- Average order value trend
- Offer subsidy burn rate
- Settlement frequency per kitchen
13. Security & Rules
Immutability
JournalEntryEntity— never updated, never deletedTransactionEntity— status only moves forward (PENDING → COMPLETED → REFUNDED)PlatformOfferUsageEntity— never deleted
Balance Integrity
- Account balance = sum of all credit journal entries - sum of all debit entries
- Running balance maintained AND verifiable by recalculation
- Discrepancy alerts if running balance != calculated balance
Access Control
| Action | Who |
|---|---|
| View treasury | SUPER_ADMIN |
| Request kitchen settlement | Kitchen owner |
| Approve withdrawal | Second SUPER_ADMIN |
| Create offers | SUPER_ADMIN |
| Topup treasury | SUPER_ADMIN |
| View own earnings | Kitchen owner |
| View own wallet | App user |
Audit Trail
Every entity has createdBy, createdAt. Financial entities additionally have:
approvedBywhere applicablereferencelinking to external providernotefor manual operations
QBIT SPARK CO LIMITED | JikoXpress | April 2026
Internal architecture document — confidential
No comments to display
No comments to display