Skip to content

πŸ—οΈ G100 Architecture

Multi-Tenancy with Self-Sufficient Instances


🎯 Architecture Principles

1. Option B: Self-Sufficient Instances

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    SHARED CORE MODULES                          β”‚
β”‚              (NPM Packages / Shared Library)                    β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   AUTH   β”‚ β”‚ CONTRACT β”‚ β”‚ PAYMENT  β”‚ β”‚ DOCUMENT GEN     β”‚   β”‚
β”‚  β”‚  Module  β”‚ β”‚  Module  β”‚ β”‚  Module  β”‚ β”‚ (Adobe/PDF)      β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚  β”‚   CRM    β”‚ β”‚ BOOKING  β”‚ β”‚   NFT    β”‚ β”‚    i18n          β”‚   β”‚
β”‚  β”‚ Module   β”‚ β”‚  Module  β”‚ β”‚  Module  β”‚ β”‚   Module         β”‚   β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚               β”‚               β”‚
              β–Ό               β–Ό               β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚  FLO Instance   β”‚ β”‚ MORELO Instance β”‚ β”‚ Future Instance β”‚
    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
    β”‚ β€’ Own DB        β”‚ β”‚ β€’ Own DB        β”‚ β”‚ β€’ Own DB        β”‚
    β”‚ β€’ Own Frontend  β”‚ β”‚ β€’ Own Frontend  β”‚ β”‚ β€’ Own Frontend  β”‚
    β”‚ β€’ Own Domain    β”‚ β”‚ β€’ Own Domain    β”‚ β”‚ β€’ Own Domain    β”‚
    β”‚                 β”‚ β”‚                 β”‚ β”‚                 β”‚
    β”‚ πŸ”Œ API Client   β”‚ β”‚ πŸ”Œ API Client   β”‚ β”‚ πŸ”Œ API Client   β”‚
    β”‚ (Optional)      β”‚ β”‚ (Optional)      β”‚ β”‚ (Optional)      β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚               β”‚               β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                              β–Ό
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚  UNIFIED CONTRACT API       β”‚
                β”‚  (Optional Central Hub)     β”‚
                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

2. Why Self-Sufficient?

Benefit Description
Independence Jede Instance kann offline arbeiten
Scalability Kein Single Point of Failure
Flexibility Eigene Tech-Stack Entscheidungen
Performance Keine API-Latenz fΓΌr lokale Operationen
Privacy Daten bleiben in Instance (GDPR)

3. Shared vs Local

// SHARED (NPM Package)
import { createContract } from '@contractplattform/core';

// LOCAL (Instance-specific)
const contract = await createContract({
  type: 'kfz_kaufvertrag',
  instance: 'morelo',
  ...
});

// Wird lokal in Instance-DB gespeichert
await db.contracts.insert(contract);

// Optional: Sync to Master API
if (config.syncToMaster) {
  await api.contracts.sync(contract);
}

πŸ—„οΈ Database Strategy

Option: Separate D1 per Instance

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Cloudflare D1                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚                                                         β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”‚
β”‚  β”‚   flo-db     β”‚  β”‚  morelo-db   β”‚  β”‚ bavaria-db   β”‚  β”‚
β”‚  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€  β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€  β”‚
β”‚  β”‚ users        β”‚  β”‚ users        β”‚  β”‚ users        β”‚  β”‚
β”‚  β”‚ contracts    β”‚  β”‚ contracts    β”‚  β”‚ contracts    β”‚  β”‚
β”‚  β”‚ memberships  β”‚  β”‚ vehicles     β”‚  β”‚ yachts       β”‚  β”‚
β”‚  β”‚ properties   β”‚  β”‚ dealers      β”‚  β”‚ marinas      β”‚  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Advantages:

  • βœ… Complete data isolation
  • βœ… Instance-specific schema
  • βœ… Independent scaling
  • βœ… GDPR compliance easier

Disadvantages:

  • ⚠️ Cross-instance queries harder
  • ⚠️ Data duplication (users)

Alternative: Shared Users + Separate Assets

-- SHARED: master-db
CREATE TABLE users (
  id TEXT PRIMARY KEY,
  email TEXT UNIQUE,
  name TEXT,
  instance_id TEXT  -- 'flo', 'morelo', 'bavaria'
);

-- INSTANCE: morelo-db
CREATE TABLE vehicles (
  id TEXT PRIMARY KEY,
  user_id TEXT,     -- Reference to master-db
  vin TEXT,
  model TEXT,
  ...
);

πŸ“¦ NPM Package Structure

@contractplattform/
β”œβ”€β”€ core/              # Shared Logic
β”‚   β”œβ”€β”€ contracts/
β”‚   β”œβ”€β”€ auth/
β”‚   └── types/
β”‚
β”œβ”€β”€ ui/                # Shared UI Components
β”‚   β”œβ”€β”€ ContractForm/
β”‚   β”œβ”€β”€ SignatureField/
β”‚   └── DocumentViewer/
β”‚
β”œβ”€β”€ integrations/      # External APIs
β”‚   β”œβ”€β”€ stripe/
β”‚   β”œβ”€β”€ adobe/
β”‚   β”œβ”€β”€ salesforce/
β”‚   └── ms-graph/
β”‚
└── cli/               # Instance Generator
    └── create-instance

Usage in Instance

{
  "name": "morelo-dealer-suite",
  "dependencies": {
    "@contractplattform/core": "^1.0.0",
    "@contractplattform/ui": "^1.0.0",
    "@contractplattform/integrations": "^1.0.0"
  }
}

πŸ”Œ API Connection (Optional)

Instances kΓΆnnen optional mit Master API verbinden:

Scenario 1: Full Independence

// FLO Instance - Komplett eigenstΓ€ndig
const contract = await db.contracts.create({
  type: 'membership',
  ...
});

// Keine API-Verbindung nΓΆtig

Scenario 2: Sync to Master

// MORELO Instance - Sync fΓΌr Analytics
const contract = await db.contracts.create({
  type: 'kfz_kaufvertrag',
  ...
});

// Optional: Push to Master fΓΌr Cross-Instance Analytics
if (config.features.centralAnalytics) {
  await api.contracts.sync({
    instance_id: 'morelo',
    contract: contract,
  });
}

Scenario 3: Shared Services

// Bavaria Instance - Nutzt Shared Document Generation
const contract = await db.contracts.create({
  type: 'yacht_kaufvertrag',
  ...
});

// Document Generation via Master API (Adobe Express)
const pdf = await api.documents.generate({
  contract_id: contract.id,
  template: 'yacht_kaufvertrag_de',
  instance_id: 'bavaria',
});

🌐 Tech Stack per Instance

FLO

Frontend:  SwiftUI (iOS Native)
Backend:   TBD (Node.js / Cloudflare Workers?)
Database:  D1 / PostgreSQL
Auth:      Firebase Auth / Custom
Payments:  Stripe
Booking:   MS Bookings

MORELO

Frontend:  SvelteKit (PWA)
Backend:   Hono (Cloudflare Workers)
Database:  Cloudflare D1
Auth:      JWT (Custom)
Payments:  Stripe + Leasing APIs
CRM:       Salesforce
Hardware:  ESP32 (MQTT)

ContractPlattform

Frontend:  SvelteKit
Backend:   SvelteKit API Routes
Database:  Prisma + PostgreSQL / D1
Auth:      MS Graph OAuth
Payments:  Stripe
CRM:       Custom

Future (Bavaria, Porsche, etc.)

Template:  Copy from MORELO
Adjust:    Asset Type, Vocabulary, Integrations
Deploy:    Independent Cloudflare Workers

πŸ” Authentication Strategy

Per-Instance Auth

FLO:     Firebase Auth (Social Login)
MORELO:  JWT (Dealer Login)
Contract: MS Graph OAuth (Office 365)

Shared User Pool (Optional)

// Master Auth Service (Optional)
POST /api/v1/auth/login
{
  "email": "max@example.com",
  "password": "...",
  "instance_id": "morelo"
}

Response:
{
  "token": "eyJhbGc...",
  "user": {
    "id": "usr_123",
    "email": "max@example.com",
    "instances": ["morelo", "bavaria"]  // Multi-Instance Access
  }
}

πŸ“Š Data Flow Example

MORELO: Fahrzeugkauf End-to-End

sequenceDiagram
    participant Kunde
    participant Frontend
    participant Backend
    participant D1 Database
    participant Salesforce
    participant Adobe
    participant Blockchain

    Kunde->>Frontend: Konfiguriert Fahrzeug
    Frontend->>Backend: POST /konfigurator
    Backend->>D1 Database: Save Configuration

    Kunde->>Frontend: Erstellt Angebot
    Frontend->>Backend: POST /contracts
    Backend->>D1 Database: Create Contract (Draft)
    Backend->>Adobe: Generate PDF
    Adobe-->>Backend: PDF URL
    Backend->>D1 Database: Update Contract
    Backend-->>Frontend: Contract + PDF

    Kunde->>Frontend: Unterschreibt
    Frontend->>Backend: POST /contracts/{id}/sign
    Backend->>D1 Database: Update Status (Signed)
    Backend->>Salesforce: Create Opportunity
    Salesforce-->>Backend: Opportunity ID
    Backend->>D1 Database: Link to Salesforce

    Note over Backend: Bei Fahrzeug-Auslieferung
    Backend->>Blockchain: Mint NFT
    Blockchain-->>Backend: Token ID
    Backend->>D1 Database: Update Contract (NFT)
    Backend-->>Frontend: Contract Complete

πŸš€ Deployment Strategy

Per Instance

# wrangler.toml (MORELO)
name = "morelo-dealer-suite"
main = "src/index.ts"
compatibility_date = "2024-01-01"

[[d1_databases]]
binding = "DB"
database_name = "morelo-db"
database_id = "xxx"

[vars]
INSTANCE_ID = "morelo"
API_URL = "https://api.contractplattform.dev"  # Optional
# wrangler.toml (FLO)
name = "flo-backend"
main = "src/index.ts"

[[d1_databases]]
binding = "DB"
database_name = "flo-db"
database_id = "yyy"

[vars]
INSTANCE_ID = "flo"
API_URL = "https://api.contractplattform.dev"  # Optional

Domains

morelo.contractplattform.dev    β†’ MORELO Instance
flo.contractplattform.dev       β†’ FLO Instance
bavaria.contractplattform.dev   β†’ Bavaria Instance
api.contractplattform.dev       β†’ Master API (Optional)

πŸ”„ Migration Path

Phase 1: Independent Instances (NOW)

  • βœ… MORELO lΓ€uft eigenstΓ€ndig
  • βœ… FLO lΓ€uft eigenstΓ€ndig
  • βœ… ContractPlattform lΓ€uft eigenstΓ€ndig
  • ❌ Keine Verbindung untereinander

Phase 2: Shared Modules (Q2 2026)

  • πŸ”„ Extract common code to NPM packages
  • πŸ”„ Refactor Instances to use @contractplattform/core
  • βœ… Instances bleiben eigenstΓ€ndig

Phase 3: Optional API (Q3 2026)

  • πŸ”Œ Deploy Master API
  • πŸ”Œ Instances kΓΆnnen optional syncen
  • βœ… Weiterhin full independence

Phase 4: Cross-Instance Features (Q4 2026)

  • 🌐 User can have accounts in multiple instances
  • πŸ“Š Shared Analytics Dashboard
  • πŸ”” Cross-Instance Notifications

Next: i18n & Vocabulary β†’