Platform Architecture
Auto Commerce is built on a modular, plugin-based architecture where a minimal core system provides multi-tenancy, authentication, and module orchestration — while all business features are implemented as self-contained modules.
Design Philosophy
- Plugin-based — Tenants enable only the modules they need. No bloat.
- Event-driven — Modules communicate through a typed event bus, not direct coupling.
- Multi-tenant first — Database-per-tenant isolation from day one.
- API-first — Every feature is accessible through REST APIs.
Tech Stack
| Layer | Technologies |
|---|---|
| Backend | Laravel 11, PHP 8.4, PostgreSQL 16, Redis 7 |
| Frontend | Next.js 14 (App Router), React 18, TypeScript, Tailwind CSS |
| Mobile | Expo SDK 55, React Native 0.83, React 19 |
| Real-Time | Laravel Reverb (WebSockets), Laravel Horizon (Queues) |
| Auth | Laravel Passport (OAuth2), spatie/permission (RBAC) |
| Infra | Docker, Kubernetes (k3s), Nginx |
System Architecture
┌─────────────────────────────────────────────────────────┐
│ Clients │
│ Next.js Frontend │ Expo Mobile App │ External API │
└──────────┬──────────┴────────┬──────────┴───────┬───────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────┐
│ Nginx (Reverse Proxy) │
│ SSL termination, rate limiting │
└──────────┬──────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Laravel API (PHP-FPM) │
│ ┌───────────┐ ┌───────────┐ ┌─────────────────────┐ │
│ │ Tenant │ │ Auth │ │ Module Loader │ │
│ │ Resolver │→ │ (Passport)│→ │ (discovers & boots) │ │
│ └───────────┘ └───────────┘ └─────────┬───────────┘ │
│ │ │
│ ┌────────────────────────────────────────┼───────────┐ │
│ │ Module API Bus (events + RPC) │ │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │Products│ │ Orders │ │Shopify │ │Delhvry │ ... │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ └────────────────────────────────────────────────────┘ │
└──────────┬──────────────────────────┬───────────────────┘
│ │
▼ ▼
┌──────────────────┐ ┌──────────────────────────┐
│ PostgreSQL │ │ Redis │
│ ┌────────────┐ │ │ Cache, Sessions, Queues │
│ │ Landlord DB│ │ └──────────────────────────┘
│ ├────────────┤ │
│ │ Tenant DB 1│ │ ┌──────────────────────────┐
│ ├────────────┤ │ │ Laravel Reverb │
│ │ Tenant DB 2│ │ │ WebSocket Server │
│ └────────────┘ │ └──────────────────────────┘
└──────────────────┘
Multi-Tenancy
Auto Commerce uses database-per-tenant isolation via stancl/tenancy:
| Database | Purpose | Contains |
|---|---|---|
| Landlord | Central/system database | Tenant records, billing, module registry, user accounts |
| Tenant | One per organization | Orders, products, customers, settings, module data |
Tenant Identification
Tenants are resolved through:
- Subdomain:
acme.autocom.com→ tenantacme - Header:
X-Tenant: acme(for API clients) - Path:
/api/v1/...with tenant context from auth token
What's Shared vs. Isolated
| Shared (Landlord) | Isolated (Per-Tenant) |
|---|---|
| User accounts | Orders, Products, Customers |
| Tenant membership & roles | Module settings & data |
| Available modules registry | Dashboards & widgets |
| Billing & plans | Files & media |
Module System
Modules are self-contained feature packages in /modules/. Each module has its own backend (Laravel) and frontend (React) code.
Module Types
| Type | Contract | Examples |
|---|---|---|
core |
— | Orders, Products, Customers, Dashboard |
store |
StoreProviderContract |
Shopify, WooCommerce |
shipping |
ShippingProviderContract |
Delhivery, Shiprocket, BlueDart |
channel |
ChannelProviderContract |
WhatsApp, SMS, Email |
payment |
PaymentProviderContract |
Razorpay, Cashfree |
ai |
AIProviderContract |
OpenAI, Claude |
Module Communication
Modules never call each other directly. All communication flows through the Module API Bus:
Module A Module B
│ │
├── Bus::call('B', 'method', $data) ──► handles request
│ │
├── Bus::publish('event.name', $payload)
│ │
│ ◄── subscribes to event ┤
This means:
- Modules can be installed/removed without breaking other modules
- Events are published even if no subscriber exists (graceful degradation)
- New modules can subscribe to existing events without code changes
Module Lifecycle
Registered → Installed → Enabled → Active
↓
Disabled → Uninstalled
Directory Structure
autocom/
├── backend/ # Laravel API
│ ├── app/
│ │ ├── Core/ # Contracts, base services, module loader
│ │ ├── Http/Controllers/ # System controllers (auth, tenants)
│ │ └── Models/ # System models (User, Tenant)
│ ├── config/ # Laravel config files
│ ├── database/
│ │ └── migrations/
│ │ ├── *.php # Landlord (system) migrations
│ │ └── tenant/ # Tenant-scoped migrations
│ └── routes/
│ ├── api.php # System API routes
│ └── tenant.php # Tenant-scoped routes
│
├── frontend/ # Next.js Web App
│ ├── app/ # App Router pages
│ ├── components/ # Shared UI components
│ ├── contexts/ # React contexts (auth, modules, theme)
│ └── lib/ # API client, module loader, utilities
│
├── app/ # Expo Mobile App
│ ├── app/ # Expo Router pages
│ ├── components/ # React Native components
│ └── contexts/ # Mobile contexts
│
├── docs/ # Documentation (this site)
│
└── modules/ # Feature Modules (HMVC)
├── Core/ # Shared models, contracts, base classes
├── Products/ # Product catalog
├── Customers/ # Customer management
├── Orders/ # Order lifecycle
├── CoreDashboard/ # Dashboard & widgets
├── Workflows/ # Visual workflow builder
├── StoreShopify/ # Shopify integration
├── ShippingDelhivery/ # Delhivery shipping
├── ChannelWhatsApp/ # WhatsApp messaging
└── [YourModule]/ # Each has: module.json + backend/ + frontend/
Request Lifecycle
A typical authenticated API request flows through:
- Nginx receives request, forwards to PHP-FPM
- Tenant Resolver identifies tenant from subdomain or
X-Tenantheader - Auth Middleware validates Passport token
- Permission Middleware checks RBAC permissions (
orders.view, etc.) - Tenancy Bootstrap switches database connection to tenant DB
- Controller handles the request using module services
- Events are published to the Module API Bus
- Queue Jobs are dispatched for async work (notifications, webhooks)
Data Flow Example
An order flowing from Shopify to delivery notification:
Shopify webhook → StoreShopify module
│
├── Bus::call('Orders', 'orders.createOrUpdate', $data)
│ │
│ ├── OrderIngestService validates & creates order
│ ├── Publishes: order.created
│ │
│ ├── Orders module self-subscribes → reserves inventory
│ ├── Workflows module subscribes → triggers automations
│ ├── ResellerOrders subscribes → forwards to chain
│ │
│ └── Notification rules → Bus::call('ChannelWhatsApp', 'send', ...)
│ │
│ └── WhatsApp API → Customer
Next Steps
- Installation — Get Auto Commerce running
- Module Development — Build custom modules
- Module Structure — Understand module file organization
- Module API Bus — Inter-module communication details