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:

  1. UplineRequestService creates an upline_requests record
  2. Ends tenancy (tenancy()->end())
  3. Runs UplineRequestJob::handle() directly in central context
  4. Job calls callInTenant(parentId, ...) from central (null source = passes validation)
  5. Result written back to requesting tenant via TenantContextManager::runInTenant()
  6. 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 cache
  • ResellerAdmin.reseller.deactivated → log + invalidate cache
  • ResellerAdmin.reseller.subtree_frozen → log + mark frozen
  • ResellerCatalog.catalog.pricing.updated → log
  • ResellerOrders.chain_order.status_changed → log
  • ResellerOrders.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