ResellerNetwork Module
The ResellerNetwork module is installed on every reseller tenant. It acts as the local control plane, orchestrating the three supply-chain modules (Catalog, Orders, Finance) and managing communication with the reseller chain.
Features
- Dashboard — aggregated stats from all 3 modules
- Downline Tree — view and manage sub-resellers recursively
- Referral Codes — generate codes for sub-resellers (via upline to super_admin)
- Performance — aggregate downline metrics
- Activity Feed — unified event log from all modules
- Settings — configure auto-forwarding, notifications, margins
Inter-Tenant Communication
Downline (parent → child) — Direct calls
$this->apiBus->callInTenant($childId, 'ResellerCatalog', 'catalog.getAvailableCatalog', [$child]);
Allowed by TenantContextManager::validateCrossTenantAccess() (ancestor→descendant).
Upline (child → parent) — Via UplineRequestJob
Child→parent calls are blocked by the TenantContextManager. The pattern:
UplineRequestServicecreates anupline_requestsrecord- Ends tenancy (
tenancy()->end()) - Runs
UplineRequestJob::handle()directly in central context - Job calls
callInTenant(parentId, ...)from central (null source = passes validation) - Result written back to requesting tenant via
TenantContextManager::runInTenant() - Tenancy restored
Same-Tenant (module → module) — Direct calls
$this->apiBus->call('ResellerCatalog', 'catalog.getAvailableCatalog', [$tenant], 'ResellerNetwork');
Data Isolation
All ResellerNetwork tables (upline_requests, network_cache, network_activity_feed, network_settings) live in the central database with owner_tenant_id columns. Global scopes on each model automatically filter by tenant()->getTenantKey() and auto-set the tenant ID on creation.
ModuleBus APIs
| Alias | Description | CrossTenant |
|---|---|---|
network.getDashboard |
Aggregated stats from 3 modules | Yes |
network.getDownlineTree |
Recursive sub-reseller tree | Yes |
network.getChildSummary |
Summary for a specific child | Yes |
Events
Subscribes to:
ResellerAdmin.reseller.approved→ log + invalidate cacheResellerAdmin.reseller.deactivated→ log + invalidate cacheResellerAdmin.reseller.subtree_frozen→ log + mark frozenResellerCatalog.catalog.pricing.updated→ logResellerOrders.chain_order.status_changed→ logResellerOrders.chain_order.delivered→ log
API Endpoints
All routes require auth:api + EnsureTenantMember middleware.
| Method | Path | Description |
|---|---|---|
| GET | /reseller-network/dashboard |
Aggregated dashboard |
| GET | /reseller-network/activity |
Activity feed |
| GET | /reseller-network/downline/tree |
Sub-reseller tree |
| GET | /reseller-network/downline/{id} |
Child detail |
| GET | /reseller-network/downline/performance |
Aggregate metrics |
| GET | /reseller-network/downline/health |
Chain health status |
| POST | /reseller-network/referrals |
Generate referral code |
| GET | /reseller-network/referrals |
List generated codes |
| GET/PUT | /reseller-network/settings |
Network settings |
| POST | /reseller-network/upline/request |
Generic upline request |
| GET | /reseller-network/upline/request/{id} |
Poll request status |