Three channels, one Commerce Core.
App, Web and Admin differ in experience, but they do not own separate commerce rules. Pricing, stock, delivery, capacity, coupons, wallet, payment methods and final outcomes remain server-authoritative.
The platform at a glance
The Modular Monolith is intentional: Checkout needs strong consistency across inventory, slots, Characters, wallet, coupons, payment and orders. Domains stay logically separated without introducing distributed-transaction complexity too early.
Each domain owns its data and rules
A module must not update another module's critical tables through ad-hoc SQL. Clear boundaries are what make the platform maintainable and extensible.
What Flutter or the JavaScript storefront must never decide
The client owns presentation, local validation and UX improvements. It does not become the source of truth for critical financial or operational decisions.
If the Admin exposes an option that the APIs and apps ignore, or a field has no persistence or required audit trail, the capability is incomplete.
Locked technical decisions
The stack supports App, Web and Admin over the same commerce source, with queues, caching, observability and versioned APIs.
Canonical catalog
There is no separate English Product and Arabic Product as two commercial entities.
One SKU · brand/category relations · age model · stock · price · delivery profile · AR/EN translations.
Historical order snapshots
A historical order never re-reads the product's current name or price.
Each order line keeps the name, price, discount, services, fees and required commercial facts as they were at purchase time.