Dealer Network Expansion¶
Multi-Tenant Whitelabel Platform¶
Status: Planned for Phase 2 (2026 Q3-Q4)
The Dealer Network expansion transforms MORELO Dealer Suite from a single-instance platform into a multi-tenant whitelabel system serving multiple dealers, service partners, and customers worldwide.
Vision¶
From Single to Multi-Tenant¶
graph LR
A[Phase 1:<br/>MORELO Only] --> B[Phase 2:<br/>Dealer Network]
B --> C[Phase 3:<br/>Multi-Industry]
A1[Single tenant] -.-> A
A2[MORELO branding] -.-> A
A3[Internal use] -.-> A
B1[Multi-tenant] -.-> B
B2[Whitelabel] -.-> B
B3[Dealer portals] -.-> B
C1[Cross-industry] -.-> C
C2[Full marketplace] -.-> C
C3[DAO governance] -.-> C
style A fill:#FF6E40
style B fill:#FF9E80
style C fill:#FFCCBC
Architecture Evolution¶
Phase 1: Single Tenant (Current)¶
┌─────────────────────────┐
│ MORELO HQ │
│ admin.morelo.de │
│ ──────────── │
│ • All vehicles │
│ • All dealers │
│ • Central control │
└─────────────────────────┘
Phase 2: Multi-Tenant¶
┌─────────────────────────────────────────────────────────┐
│ MORELO ECOSYSTEM │
├─────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌───────────┐ │
│ │ MORELO HQ │ │ Dealer A │ │ Dealer B │ │
│ │ admin.{{D}} │ │ a.{{D}} │ │ b.{{D}} │ │
│ │ ────────── │ │ ────────── │ │ ──────── │ │
│ │ • Master │ │ • Own │ │ • Own │ │
│ │ • Production│ │ • Sales │ │ • Sales │ │
│ │ • Approvals │ │ • Service │ │ • Rental │ │
│ └──────┬───────┘ └──────┬───────┘ └─────┬─────┘ │
│ │ │ │ │
│ └───────────────────┼──────────────────┘ │
│ │ │
│ ┌─────────┴─────────┐ │
│ │ SHARED BACKEND │ │
│ │ api.{{D}} │ │
│ │ ─────────────── │ │
│ │ • Multi-tenant │ │
│ │ • NFT verify │ │
│ │ • IPFS gateway │ │
│ └───────────────────┘ │
│ │
└─────────────────────────────────────────────────────────┘
Note: {{D}} = Domain placeholder (kept secret)
Key Roles¶
1. MORELO HQ (Master Tenant)¶
Responsibilities: - ✅ Vehicle production - ✅ NFT minting (initial ownership) - ✅ Dealer approval/contracts - ✅ Platform updates - ✅ Compliance oversight
Access: - Full system access - All dealers visible - All vehicles visible - Analytics dashboard
2. Dealers (Standard Tenants)¶
Responsibilities: - ✅ Sales (new & used) - ✅ Rentals - ✅ Service bookings - ✅ Customer support - ✅ Marketing (own brand)
Access:
- Own portal (dealer-a.{{DOMAIN}})
- Own vehicles only
- Own customers only
- Configurable branding
Whitelabel Features: - Custom logo - Custom colors - Custom domain (optional) - Custom email templates
3. Service Partners (Limited Tenants)¶
Responsibilities: - ✅ Parts lookup - ✅ Service logging - ✅ Repair documentation - ✅ Customer communication
Access:
- Service portal (service.{{DOMAIN}})
- Read-only vehicle data
- Parts catalog
- Service history
Limitations: - ❌ No sales access - ❌ No pricing access - ❌ No customer PII (unless approved)
4. Customers (End Users)¶
Responsibilities: - ✅ NFT ownership verification - ✅ Vehicle access - ✅ Service history viewing - ✅ Rental listing (optional)
Access:
- Customer portal (my.{{DOMAIN}})
- NFT-gated login
- Own vehicles only
- Service requests
Core Principles¶
1. Only Active Dealers on Homepage¶
Rule: Only dealers with current, valid contracts can list on MORELO homepage.
Implementation:
interface DealerContract {
dealerId: string;
contractStart: Date;
contractEnd: Date;
status: 'active' | 'suspended' | 'terminated';
// Determines homepage visibility
isActiveForHomepage: boolean;
}
// Logic:
function canListOnHomepage(dealer: Dealer): boolean {
const contract = getActiveContract(dealer.id);
if (!contract) return false;
const now = new Date();
const isValid = contract.status === 'active'
&& now >= contract.contractStart
&& now <= contract.contractEnd;
return isValid && contract.isActiveForHomepage;
}
Benefits: - ✅ Quality control - ✅ Compliance with dealer agreements - ✅ Incentivizes contract renewals
2. No Service Partner Ratings¶
Philosophy: Anyone can make mistakes. No punishment via public ratings.
Rationale: - Bad day ≠ bad service partner - One mistake shouldn't destroy reputation - Humans > metrics - Trust > fear
Alternative Approach:
// Instead of ratings, track service completion
interface ServicePartnerMetrics {
completedJobs: number;
averageTime: number;
certifications: string[];
yearsActive: number;
// NO ratings/reviews from customers!
}
What customers see: - ✅ Certifications - ✅ Years in business - ✅ Services offered - ❌ Star ratings - ❌ Negative reviews
3. NFT ≠ Possession¶
Key Concept: Renting out vehicle does NOT transfer NFT ownership.
Example:
// Owner rents out MORELO for 2 weeks
const rental: RentalTransaction = {
vehicleNftId: "0x123...abc",
ownerId: "user-gunter",
renterId: "user-hans",
period: {
start: "2026-06-01",
end: "2026-06-14"
},
// NFT stays with Gunter!
nftOwnership: {
owner: "user-gunter", // Unchanged
possession: "user-hans" // Temporary
}
};
Implications: - Owner can track vehicle remotely - Owner can end rental if abused - Renter cannot sell vehicle - Renter gets temporary access only
4. Domain Privacy¶
All domains/subdomains as {{DOMAIN}} variable:
Why? - Security through obscurity - Prevent enumeration attacks - Brand protection - Flexibility (can change domains)
Implementation:
// Environment variable
const DOMAIN = process.env.BASE_DOMAIN; // e.g., "morelo-cloud.de"
// Generate subdomains
const adminUrl = `admin.${DOMAIN}`;
const dealerUrl = `${dealerSlug}.${DOMAIN}`;
const apiUrl = `api.${DOMAIN}`;
Transaction Types¶
Sale¶
NFT is transferred to buyer:
sequenceDiagram
participant D as Dealer
participant B as Buyer
participant BC as Blockchain
D->>B: Vehicle delivered
D->>BC: Transfer NFT ownership
BC-->>B: NFT received
B->>D: Payment completed
Result: - Buyer owns NFT - Buyer controls vehicle - Buyer appears on IPFS metadata
Rental¶
NFT stays with owner:
sequenceDiagram
participant O as Owner
participant R as Renter
participant S as System
R->>O: Request rental
O->>S: Approve rental
S->>R: Temporary access granted
Note over O: NFT unchanged
R->>S: Return vehicle
S->>O: Access restored
Result: - Owner keeps NFT - Renter gets temporary access - Rental logged on-chain (optional)
Lease¶
NFT with leasing company or dealer:
sequenceDiagram
participant C as Customer
participant L as Leasing Co.
participant BC as Blockchain
C->>L: Lease agreement
L->>BC: Hold NFT as collateral
BC-->>L: NFT locked
Note over C: Uses vehicle, no ownership
C->>L: Pay off lease
L->>BC: Transfer NFT to customer
BC-->>C: NFT received
Result: - Leasing company holds NFT - Customer has usage rights - NFT transfers after final payment
Used Vehicle Marketplace¶
Dual Model¶
1. Dealer-Owned Listings
Dealers manage their own used inventory:
interface DealerUsedVehicle {
listingId: string;
dealerId: string;
vehicleNftId: string;
pricing: {
askingPrice: number;
negotiable: boolean;
};
visibility: {
ownPortalOnly: boolean; // Only on dealer's site
morelloMarketplace: boolean; // Also on MORELO marketplace
};
}
Benefits: - Dealer controls pricing - Dealer handles negotiations - Dealer keeps commission
2. MORELO Curated Marketplace
Central marketplace with verified listings:
interface MarketplaceListing {
listingId: string;
vehicleNftId: string;
sellerId: string; // Can be dealer or private
verification: {
nftOwnershipVerified: boolean;
serviceHistoryComplete: boolean;
inspectionDate?: Date;
inspectorId?: string;
};
// MORELO takes fee
commission: {
rate: 0.025, // 2.5%
paidBy: 'seller';
};
}
Benefits: - Trust through verification - NFT ownership proven on-chain - Complete service history - MORELO oversight
Data Isolation¶
Tenant Boundaries¶
Each dealer sees only their data:
// Middleware: Tenant isolation
async function getTenantContext(req: Request): Promise<TenantContext> {
const subdomain = req.hostname.split('.')[0];
const dealer = await Dealer.findOne({ subdomain });
if (!dealer) throw new Error('Invalid tenant');
return {
tenantId: dealer.id,
permissions: dealer.permissions,
dataFilter: { dealerId: dealer.id } // Automatic filter on all queries
};
}
// Example query (auto-filtered):
const vehicles = await Vehicle.find();
// Actually executes: Vehicle.find({ dealerId: currentTenantId })
Exceptions: - MORELO HQ sees all (superadmin) - Customers see own vehicles (NFT-verified) - Service partners see allowed vehicles (permission-based)
Whitelabel Configuration¶
Per-Dealer Customization¶
interface WhitelabelConfig {
tenantId: string;
branding: {
logo: string; // URL to logo
primaryColor: string; // Hex color
secondaryColor: string;
fontFamily: string;
};
domain: {
subdomain: string; // e.g., "dealer-a"
customDomain?: string; // Optional: "dealer-a.com"
ssl: boolean;
};
features: {
enableRentals: boolean;
enableUsedSales: boolean;
enableServiceBooking: boolean;
enableKonfigurator: boolean;
};
integrations: {
msBookings?: MSBookingsConfig;
stripe?: StripeConfig;
mobileDe?: MobileDeConfig;
};
}
Example:
const dealerAConfig: WhitelabelConfig = {
tenantId: "dealer-a",
branding: {
logo: "https://cdn.dealer-a.com/logo.svg",
primaryColor: "#FF6E40",
secondaryColor: "#FF9E80",
fontFamily: "Montserrat"
},
domain: {
subdomain: "dealer-a",
customDomain: "shop.dealer-a.de",
ssl: true
},
features: {
enableRentals: true,
enableUsedSales: true,
enableServiceBooking: false, // They use external system
enableKonfigurator: true
}
};
Compliance Framework¶
Dealer Agreement Requirements¶
All dealers must agree to:
- Data privacy (GDPR compliance)
- Service quality standards
- Brand guidelines
- NFT ownership respect (no fake NFTs)
- Customer protection
Inspired by Adobe's partner model:
interface DealerCompliance {
dealerId: string;
agreements: {
gdprCompliance: {
signed: boolean;
date: Date;
version: string;
};
serviceStandards: {
signed: boolean;
minimumResponseTime: number; // hours
minimumSatisfactionScore: number; // 0-5
};
brandGuidelines: {
signed: boolean;
prohibitedActions: string[];
};
};
audits: {
lastAudit: Date;
nextAudit: Date;
findings: string[];
resolved: boolean;
};
}
API Specification¶
Tenant-Aware Endpoints¶
All API calls require tenant context:
// Authentication includes tenant
POST /api/auth/login
{
"email": "dealer@example.com",
"password": "***",
"tenantId": "dealer-a" // Or derived from subdomain
}
// Response includes tenant token
{
"token": "eyJ...",
"tenant": {
"id": "dealer-a",
"name": "Dealer A GmbH",
"permissions": [...]
}
}
// Subsequent requests auto-filtered
GET /api/vehicles
Authorization: Bearer eyJ...
// Returns only vehicles owned by dealer-a
Cross-Tenant Operations¶
Some operations require MORELO HQ approval:
// Dealer wants to sell to another dealer
POST /api/vehicles/transfer
{
"vehicleNftId": "0x123...abc",
"fromDealerId": "dealer-a",
"toDealerId": "dealer-b",
"requiresApproval": true
}
// MORELO HQ reviews and approves
POST /api/admin/approvals/:approvalId/approve
Authorization: Bearer [MORELO_HQ_TOKEN]
{
"approved": true,
"notes": "Transfer approved, check contract terms"
}
Migration Path¶
Phase 1 → Phase 2 Transition¶
Steps:
- Add tenant_id column to all tables
- Set existing data to
tenant_id = 'morelo-hq' - Deploy multi-tenant middleware
- Test with first external dealer (beta)
- Rollout to all dealers (gradual)
No downtime required - backward compatible!
Frequently Asked Questions¶
Can dealers customize everything?¶
No. Core functionality (NFT minting, blockchain integration) remains centralized. UI/branding is customizable.
What if a dealer leaves?¶
Their data stays but portal is suspended. Customers can still access vehicles via main portal.
How do customers find their dealer?¶
NFT ownership records original dealer. Customer portal shows this.
Can service partners become dealers?¶
Yes, but requires new contract and compliance agreement.
Related: - NFT Ownership - D2G2M Vision - Legal Structure