Files
boc/landvex-admin/design.md
T
Bernt aee0f09db8 landvex: Fixar och tester klara för alla komponenter
- Datafabrik: Dockerfile fix, agentorkestrering fungerar
- Vision: Identify-modell, FAISS, OCR alla testade
- API: Alla 7 integrationstester passerade
- Upplösare: Entitetsupplösning verifierad
2026-07-05 06:41:32 +00:00

45 KiB

LandveX Enterprise Platform — Admin Backend Design

Overview

A multi-tenant admin backend for LandveX Enterprise Platform serving municipalities (kommuner) and enterprises. Built with FastAPI (Python), PostgreSQL, and React 19.


1. Data Model (PostgreSQL)

Core Tables

-- Tenants (top-level isolation)
CREATE TABLE tenants (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(255) NOT NULL,
    slug VARCHAR(100) UNIQUE NOT NULL,
    type VARCHAR(20) NOT NULL CHECK (type IN ('municipality', 'enterprise', 'partner')),
    org_number VARCHAR(20) UNIQUE,
    billing_email VARCHAR(255) NOT NULL,
    plan_id UUID REFERENCES subscription_plans(id),
    status VARCHAR(20) DEFAULT 'active' CHECK (status IN ('active', 'suspended', 'cancelled', 'trial')),
    settings JSONB DEFAULT '{}',
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Subscription Plans
CREATE TABLE subscription_plans (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100) NOT NULL,
    slug VARCHAR(50) UNIQUE NOT NULL,
    description TEXT,
    price_monthly DECIMAL(10,2) NOT NULL,
    price_yearly DECIMAL(10,2),
    features JSONB NOT NULL DEFAULT '{}',
    limits JSONB NOT NULL DEFAULT '{}', -- {"users": 10, "api_calls": 100000}
    is_public BOOLEAN DEFAULT true,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Users (tenant-scoped)
CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    email VARCHAR(255) NOT NULL,
    password_hash VARCHAR(255) NOT NULL,
    first_name VARCHAR(100),
    last_name VARCHAR(100),
    phone VARCHAR(50),
    avatar_url TEXT,
    status VARCHAR(20) DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'pending', 'locked')),
    last_login_at TIMESTAMPTZ,
    failed_login_attempts INT DEFAULT 0,
    locked_until TIMESTAMPTZ,
    mfa_enabled BOOLEAN DEFAULT false,
    mfa_secret VARCHAR(255),
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, email)
);

-- Roles
CREATE TABLE roles (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE, -- NULL = global role
    name VARCHAR(100) NOT NULL,
    slug VARCHAR(100) NOT NULL,
    description TEXT,
    permissions JSONB NOT NULL DEFAULT '[]',
    is_system BOOLEAN DEFAULT false,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(tenant_id, slug)
);

-- User Roles (many-to-many)
CREATE TABLE user_roles (
    user_id UUID REFERENCES users(id) ON DELETE CASCADE,
    role_id UUID REFERENCES roles(id) ON DELETE CASCADE,
    assigned_by UUID REFERENCES users(id),
    assigned_at TIMESTAMPTZ DEFAULT NOW(),
    PRIMARY KEY (user_id, role_id)
);

-- API Keys
CREATE TABLE api_keys (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    name VARCHAR(100) NOT NULL,
    key_hash VARCHAR(255) NOT NULL,
    key_prefix VARCHAR(8) NOT NULL,
    scopes JSONB NOT NULL DEFAULT '[]',
    rate_limit INT DEFAULT 1000,
    expires_at TIMESTAMPTZ,
    last_used_at TIMESTAMPTZ,
    created_by UUID REFERENCES users(id),
    status VARCHAR(20) DEFAULT 'active' CHECK (status IN ('active', 'revoked', 'expired')),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Audit Log
CREATE TABLE audit_logs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID REFERENCES tenants(id),
    user_id UUID REFERENCES users(id),
    action VARCHAR(50) NOT NULL,
    resource_type VARCHAR(50) NOT NULL,
    resource_id UUID,
    details JSONB DEFAULT '{}',
    ip_address INET,
    user_agent TEXT,
    severity VARCHAR(20) DEFAULT 'info' CHECK (severity IN ('info', 'warning', 'critical')),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Invoices
CREATE TABLE invoices (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants(id),
    invoice_number VARCHAR(50) UNIQUE NOT NULL,
    period_start DATE NOT NULL,
    period_end DATE NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    tax_amount DECIMAL(10,2) NOT NULL,
    total_amount DECIMAL(10,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'SEK',
    status VARCHAR(20) DEFAULT 'draft' CHECK (status IN ('draft', 'sent', 'paid', 'overdue', 'cancelled')),
    paid_at TIMESTAMPTZ,
    stripe_invoice_id VARCHAR(100),
    pdf_url TEXT,
    due_date DATE NOT NULL,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Invoice Line Items
CREATE TABLE invoice_items (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    invoice_id UUID NOT NULL REFERENCES invoices(id) ON DELETE CASCADE,
    description VARCHAR(255) NOT NULL,
    quantity DECIMAL(10,2) NOT NULL,
    unit_price DECIMAL(10,2) NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    metadata JSONB DEFAULT '{}'
);

-- Plugins
CREATE TABLE plugins (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100) NOT NULL,
    slug VARCHAR(100) UNIQUE NOT NULL,
    description TEXT,
    version VARCHAR(20) NOT NULL,
    author VARCHAR(100),
    config_schema JSONB DEFAULT '{}',
    is_system BOOLEAN DEFAULT false,
    status VARCHAR(20) DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'deprecated')),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Tenant Plugins (installed plugins)
CREATE TABLE tenant_plugins (
    tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
    plugin_id UUID REFERENCES plugins(id) ON DELETE CASCADE,
    config JSONB DEFAULT '{}',
    installed_by UUID REFERENCES users(id),
    installed_at TIMESTAMPTZ DEFAULT NOW(),
    status VARCHAR(20) DEFAULT 'active',
    PRIMARY KEY (tenant_id, plugin_id)
);

-- Reports
CREATE TABLE reports (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    tenant_id UUID NOT NULL REFERENCES tenants(id) ON DELETE CASCADE,
    name VARCHAR(255) NOT NULL,
    type VARCHAR(50) NOT NULL,
    config JSONB NOT NULL DEFAULT '{}',
    schedule VARCHAR(50), -- cron expression or null for one-time
    last_run_at TIMESTAMPTZ,
    next_run_at TIMESTAMPTZ,
    created_by UUID REFERENCES users(id),
    created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Report Runs
CREATE TABLE report_runs (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    report_id UUID NOT NULL REFERENCES reports(id) ON DELETE CASCADE,
    status VARCHAR(20) DEFAULT 'running' CHECK (status IN ('running', 'completed', 'failed')),
    result_url TEXT,
    error_message TEXT,
    started_at TIMESTAMPTZ DEFAULT NOW(),
    completed_at TIMESTAMPTZ
);

-- Indexes for performance
CREATE INDEX idx_users_tenant_email ON users(tenant_id, email);
CREATE INDEX idx_audit_logs_tenant_created ON audit_logs(tenant_id, created_at DESC);
CREATE INDEX idx_audit_logs_user ON audit_logs(user_id, created_at DESC);
CREATE INDEX idx_invoices_tenant_status ON invoices(tenant_id, status);
CREATE INDEX idx_api_keys_tenant ON api_keys(tenant_id, status);

2. API Specification (FastAPI + OpenAPI)

Base URL

https://api.landvex.com/v1

Authentication

  • JWT Bearer for user sessions
  • API Key (X-API-Key header) for service-to-service

Common Headers

X-Tenant-ID: <tenant-uuid>  # Required for all tenant-scoped endpoints

Endpoints

Authentication

POST   /auth/login
POST   /auth/logout
POST   /auth/refresh
POST   /auth/mfa/setup
POST   /auth/mfa/verify
POST   /auth/forgot-password
POST   /auth/reset-password

Tenants

GET    /tenants                    # List (superadmin)
POST   /tenants                    # Create (superadmin)
GET    /tenants/{id}
PATCH  /tenants/{id}
DELETE /tenants/{id}               # Soft delete
GET    /tenants/{id}/stats         # Usage statistics
GET    /tenants/{id}/billing       # Billing summary

Users

GET    /users
POST   /users
GET    /users/{id}
PATCH  /users/{id}
DELETE /users/{id}
PATCH  /users/{id}/status          # Activate/deactivate/lock
POST   /users/{id}/roles           # Assign roles
DELETE /users/{id}/roles/{role_id}
GET    /users/me                   # Current user profile
PATCH  /users/me

Roles & Permissions

GET    /roles
POST   /roles
GET    /roles/{id}
PATCH  /roles/{id}
DELETE /roles/{id}
GET    /permissions                # List all available permissions

API Keys

GET    /api-keys
POST   /api-keys                   # Returns key once (not stored plaintext)
GET    /api-keys/{id}
PATCH  /api-keys/{id}
DELETE /api-keys/{id}
POST   /api-keys/{id}/revoke

Billing & Subscriptions

GET    /billing/plans
GET    /billing/subscription
POST   /billing/subscribe
POST   /billing/cancel
POST   /billing/upgrade
GET    /billing/invoices
GET    /billing/invoices/{id}
GET    /billing/invoices/{id}/pdf
POST   /billing/payment-method

Audit Logs

GET    /audit-logs
GET    /audit-logs/export          # CSV/JSON export
GET    /audit-logs/stats           # Summary statistics

Reports

GET    /reports
POST   /reports
GET    /reports/{id}
PATCH  /reports/{id}
DELETE /reports/{id}
POST   /reports/{id}/run
GET    /reports/{id}/runs
GET    /reports/{id}/runs/{run_id}/download

Plugins

GET    /plugins                    # Available plugins
GET    /plugins/installed
POST   /plugins/{id}/install
PATCH  /plugins/{id}/config
DELETE /plugins/{id}/uninstall
POST   /plugins/{id}/enable
POST   /plugins/{id}/disable

Dashboard & Analytics

GET    /dashboard/summary
GET    /dashboard/activity
GET    /dashboard/usage
GET    /analytics/users
GET    /analytics/api-usage
GET    /analytics/revenue

Response Format

{
  "success": true,
  "data": {},
  "meta": {
    "page": 1,
    "per_page": 20,
    "total": 100,
    "total_pages": 5
  }
}

Error Format

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input data",
    "details": [
      {"field": "email", "message": "Invalid email format"}
    ]
  }
}

3. UI Sketches (React 19)

Layout Structure

┌─────────────────────────────────────────────────────────┐
│  🏠 LandveX          🔍 Search    🔔 👤 Profile  ▼     │  ← TopBar
├──────────┬──────────────────────────────────────────────┤
│          │                                              │
│  Dashboard│     Main Content Area                        │
│  ├── Overview                                         │
│  ├── Analytics                                        │
│  Tenants   │                                              │
│  ├── All Tenants                                      │
│  ├── Pending                                          │
│  Users     │                                              │
│  ├── All Users                                        │
│  ├── Roles                                            │
│  API Keys  │                                              │
│  Billing   │                                              │
│  ├── Invoices                                         │
│  ├── Plans                                            │
│  ├── Subscriptions                                    │
│  Audit Logs│                                              │
│  Reports   │                                              │
│  Plugins   │                                              │
│  Settings  │                                              │
│          │                                              │
└──────────┴──────────────────────────────────────────────┘
     Sidebar              Content

Key Screens

Dashboard Overview

┌─────────────────────────────────────────────────────────┐
│ Dashboard                                    [Refresh]  │
├─────────────────────────────────────────────────────────┤
│  ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐      │
│  │ Active  │ │  Total  │ │ API Calls│ │ Revenue │      │
│  │ Tenants │ │  Users  │ │  Today  │ │  (MTD)  │      │
│  │   42    │ │   156   │ │  1.2M   │ │ 45,000  │      │
│  │  ↑ 12%  │ │  ↑ 8%   │ │  ↑ 23%  │ │  ↑ 15%  │      │
│  └─────────┘ └─────────┘ └─────────┘ └─────────┘      │
├─────────────────────────────────────────────────────────┤
│  Recent Activity                    API Usage (7d)     │
│  ─────────────────                  ──────────────     │
│  • New tenant: Stockholm Kommun    ┌──────────────┐   │
│  • User locked: admin@example.com  │    📈        │   │
│  • Invoice paid: #INV-2024-001     │   Chart      │   │
│  • API key revoked: prod-key       │              │   │
│                                    └──────────────┘   │
├─────────────────────────────────────────────────────────┤
│  Recent Invoices          Recent Audit Logs             │
│  ───────────────          ─────────────────             │
│  #INV-001   5,000 SEK     admin@x  DELETE user   2m   │
│  #INV-002   2,500 SEK     api@x    CREATE key    5m   │
│  #INV-003  12,000 SEK     sys      UPDATE tenant 1h   │
└─────────────────────────────────────────────────────────┘

Tenant Management

┌─────────────────────────────────────────────────────────┐
│ Tenants                              [+ New Tenant]     │
├─────────────────────────────────────────────────────────┤
│ [🔍 Search...] [Type ▼] [Status ▼] [Plan ▼] [Export]  │
├─────────────────────────────────────────────────────────┤
│ Name              Type        Plan       Users  Status  │
│ ─────────────────────────────────────────────────────── │
│ Stockholm Kommun  Municipality  Enterprise  12   🟢 Active│
│ Volvo Group       Enterprise   Business    45   🟢 Active│
│ Malmö Stad        Municipality  Starter     8   🟡 Trial │
│ Ericsson          Enterprise   Enterprise  89   🟢 Active│
│ ...                                                     │
│                                                         │
│ [← Prev] Page 1 of 5 [Next →]    Showing 1-10 of 42    │
└─────────────────────────────────────────────────────────┘

User Management with Roles

┌─────────────────────────────────────────────────────────┐
│ Users                                  [+ Invite User]  │
├─────────────────────────────────────────────────────────┤
│ [🔍 Search...] [Role ▼] [Status ▼]                     │
├─────────────────────────────────────────────────────────┤
│ Name              Email           Role        Status    │
│ ─────────────────────────────────────────────────────── │
│ Anna Svensson    anna@x.com      Admin       🟢 Active │
│ Erik Johansson   erik@x.com      Editor      🟢 Active │
│ Maria Lind       maria@x.com     Viewer      🟡 Pending│
│ [Locked] Johan   johan@x.com     Editor      🔴 Locked │
│                                                         │
│ Actions: [Edit] [Reset PW] [Lock] [Delete] [Assign Role]│
└─────────────────────────────────────────────────────────┘

Role Editor

┌─────────────────────────────────────────────────────────┐
│ Edit Role: Admin                              [Save]    │
├─────────────────────────────────────────────────────────┤
│ Name: [Admin                    ]                       │
│ Description: [Full system access...              ]      │
│                                                         │
│ Permissions                                             │
│ ─────────────────────────────────────────────────────── │
│ ☑ Users    ☑ Create  ☑ Read  ☑ Update  ☑ Delete       │
│ ☑ Tenants  ☐ Create  ☑ Read  ☑ Update  ☐ Delete       │
│ ☑ Billing  ☑ Read    ☑ Manage Invoices                │
│ ☑ API Keys ☑ Create  ☑ Read  ☑ Revoke                 │
│ ☑ Reports  ☑ Create  ☑ Run   ☑ Export                 │
│ ☐ Plugins  ☐ Install ☐ Configure ☐ Uninstall          │
│                                                         │
│ Members (12)                                            │
│ ─────────────────────────────────────────────────────── │
│ Anna Svensson, Erik Johansson, ... [+ Add Member]       │
└─────────────────────────────────────────────────────────┘

API Key Management

┌─────────────────────────────────────────────────────────┐
│ API Keys                               [+ Generate Key] │
├─────────────────────────────────────────────────────────┤
│ ⚠️ Only show key once on creation!                      │
├─────────────────────────────────────────────────────────┤
│ Name           Prefix    Scopes          Last Used      │
│ ─────────────────────────────────────────────────────── │
│ Production     prod_***  read,write      2 min ago      │
│ Integration    int_***   read            1 hour ago     │
│ Backup Script  back_***  read            3 days ago     │
│                                                         │
│ [Revoke] [Regenerate] [Edit Scopes]                     │
└─────────────────────────────────────────────────────────┘

Billing & Invoices

┌─────────────────────────────────────────────────────────┐
│ Billing                                                 │
├─────────────────────────────────────────────────────────┤
│ Current Plan: Enterprise                                │
│ Next billing: 2024-08-01 (15 days)                      │
│ Amount: 12,000 SEK/month                                │
│ [Upgrade] [Cancel Subscription]                         │
├─────────────────────────────────────────────────────────┤
│ Payment Methods                            [+ Add Card] │
│ 💳 •••• 4242  Exp: 12/25  [Default]  [Remove]           │
├─────────────────────────────────────────────────────────┤
│ Invoices                                                │
│ ─────────────────────────────────────────────────────── │
│ #INV-2024-007   12,000 SEK   Paid   Jul 1    [PDF]      │
│ #INV-2024-006   12,000 SEK   Paid   Jun 1    [PDF]      │
│ #INV-2024-005   12,000 SEK   Paid   May 1    [PDF]      │
└─────────────────────────────────────────────────────────┘

Audit Log Viewer

┌─────────────────────────────────────────────────────────┐
│ Audit Logs                              [Export CSV]    │
├─────────────────────────────────────────────────────────┤
│ [🔍 Search] [Action ▼] [User ▼] [Date Range] [Severity]│
├─────────────────────────────────────────────────────────┤
│ Time      User        Action    Resource      IP        │
│ ─────────────────────────────────────────────────────── │
│ 14:32:05  admin@x     DELETE    user/abc      10.0.0.1 │
│ 14:30:22  api@x       CREATE    api_key/xyz  10.0.0.2 │
│ 14:15:00  system      UPDATE    tenant/123   internal  │
│ 13:45:10  erik@x      LOGIN     session/xxx  192.168.1 │
│                                                         │
│ [View Details] for each row                             │
└─────────────────────────────────────────────────────────┘

Report Builder

┌─────────────────────────────────────────────────────────┐
│ Reports                                [+ New Report]   │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Report: Monthly API Usage                           │ │
│ │ Type: Bar Chart    Schedule: Monthly (1st)          │ │
│ │                                                     │ │
│ │ Filters:                                            │ │
│ │ Date Range: [2024-01-01] to [2024-06-30]            │ │
│ │ Tenant: [All ▼]    Endpoint: [/api/v1/users ▼]      │ │
│ │                                                     │ │
│ │ [Run Now] [Schedule] [Export PDF]                   │ │
│ └─────────────────────────────────────────────────────┘ │
│                                                         │
│ Recent Runs                                             │
│ ─────────────────────────────────────────────────────── │
│ Jul 1, 2024   Completed   [Download PDF] [Download CSV] │
│ Jun 1, 2024   Completed   [Download PDF]                │
│ May 1, 2024   Failed      [View Error]                  │
└─────────────────────────────────────────────────────────┘

Plugin Marketplace

┌─────────────────────────────────────────────────────────┐
│ Plugins                                                 │
├─────────────────────────────────────────────────────────┤
│ [🔍 Search...] [Installed] [Available] [Updates]        │
├─────────────────────────────────────────────────────────┤
│ ┌─────────────┐  ┌─────────────┐  ┌─────────────┐      │
│ │ 📊 Analytics│  │ 🗺️ GIS     │  │ 📄 PDF Gen  │      │
│ │ v2.1.0      │  │ v1.5.2      │  │ v3.0.0      │      │
│ │ By LandveX  │  │ By LandveX  │  │ By LandveX  │      │
│ │             │  │             │  │             │      │
│ │ [Installed] │  │ [Install]   │  │ [Update]    │      │
│ │ [Configure] │  │ [Details]   │  │ [Details]   │      │
│ └─────────────┘  └─────────────┘  └─────────────┘      │
│                                                         │
│ ┌─────────────┐  ┌─────────────┐  ┌─────────────┐      │
│ │ 🔗 Webhook  │  │ 📧 Email   │  │ 🤖 AI Assist│      │
│ │ v1.0.0      │  │ v2.0.1      │  │ v0.9.0      │      │
│ │ By Acme     │  │ By LandveX  │  │ By OpenAI   │      │
│ │             │  │             │  │             │      │
│ │ [Install]   │  │ [Installed] │  │ [Install]   │      │
│ │ [Details]   │  │ [Configure] │  │ [Details]   │      │
│ └─────────────┘  └─────────────┘  └─────────────┘      │
└─────────────────────────────────────────────────────────┘

4. Security Architecture

Authentication Flow

┌─────────┐     ┌─────────────┐     ┌─────────────┐     ┌─────────┐
│  Client │────▶│  FastAPI    │────▶│  PostgreSQL │────▶│  Redis  │
│         │◄────│   Backend   │◄────│   (users)   │◄────│ (sessions)
└─────────┘     └─────────────┘     └─────────────┘     └─────────┘
                      │
                      ▼
               ┌─────────────┐
               │  Argon2id   │  ← Password hashing
               │   (pwd)     │
               └─────────────┘

Multi-Tenant Isolation

┌─────────────────────────────────────────┐
│           API Gateway / WAF             │
│    (Rate limiting, DDoS protection)     │
└─────────────────────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────┐
│         Authentication Layer            │
│    (JWT validation, API key check)      │
└─────────────────────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────┐
│         Tenant Resolution               │
│  • Header: X-Tenant-ID                  │
│  • JWT claim: tenant_id                 │
│  • API key → lookup tenant              │
└─────────────────────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────┐
│      Row-Level Security (RLS)           │
│  All queries filtered by tenant_id      │
│  Users can only access their tenant     │
└─────────────────────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────┐
│         PostgreSQL Database             │
│  • RLS policies on all tenant tables    │
│  • Separate schemas optional            │
│  • Encrypted at rest (AES-256)          │
└─────────────────────────────────────────┘

Authorization (RBAC)

# Permission hierarchy
permissions = {
    "users": ["create", "read", "update", "delete", "impersonate"],
    "tenants": ["create", "read", "update", "delete", "manage"],
    "roles": ["create", "read", "update", "delete", "assign"],
    "api_keys": ["create", "read", "revoke", "rotate"],
    "billing": ["read", "manage", "invoices", "subscribe"],
    "audit_logs": ["read", "export"],
    "reports": ["create", "read", "run", "export", "delete"],
    "plugins": ["install", "configure", "uninstall", "enable"],
    "settings": ["read", "update"]
}

# Role examples
roles = {
    "superadmin": "*",  # All permissions
    "admin": ["users.*", "roles.read", "billing.read", "settings.*"],
    "editor": ["users.read", "users.update", "reports.*"],
    "viewer": ["*.read"],
    "api": ["api_keys.read", "api_keys.create"]  # Service account
}

API Key Security

# Key format: lv_<prefix>_<random>
# Example: lv_prod_abc123def456

# Storage: Only hash is stored
key_hash = argon2.hash(full_key)
key_prefix = full_key[:8]  # For identification

# Scopes restrict access
scopes = ["read:users", "write:reports"]

# Rate limiting per key
rate_limit = 1000  # requests per hour

Audit Logging

# All actions logged automatically
@audit_log(action="user.update", resource_type="user")
async def update_user(user_id: UUID, data: UserUpdate):
    # ... update logic
    # Automatically logged with:
    # - who (user_id)
    # - what (action)
    # - when (timestamp)
    # - where (IP, user_agent)
    # - changes (before/after diff)

Data Protection

1. Encryption at Rest
   - PostgreSQL: AES-256 (AWS RDS encryption / LUKS)
   - Backups: Encrypted with tenant-specific keys

2. Encryption in Transit
   - TLS 1.3 for all API communications
   - mTLS for service-to-service

3. Secrets Management
   - AWS Secrets Manager / HashiCorp Vault
   - API keys: Hashed with Argon2id
   - JWT: RS256 with key rotation

4. PII Handling
   - Email encryption for sensitive tenants
   - GDPR-compliant data export/deletion
   - Automatic PII redaction in logs

Security Headers

Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Security-Policy: default-src 'self'
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: geolocation=(), microphone=(), camera=()

5. Project Structure

landvex-admin/
├── backend/
│   ├── app/
│   │   ├── __init__.py
│   │   ├── main.py                 # FastAPI app entry
│   │   ├── config.py               # Settings & env vars
│   │   ├── database.py             # DB connection & session
│   │   ├── models/                 # SQLAlchemy models
│   │   │   ├── __init__.py
│   │   │   ├── tenant.py
│   │   │   ├── user.py
│   │   │   ├── role.py
│   │   │   ├── api_key.py
│   │   │   ├── billing.py
│   │   │   ├── audit.py
│   │   │   ├── report.py
│   │   │   └── plugin.py
│   │   ├── schemas/                # Pydantic models
│   │   │   ├── __init__.py
│   │   │   ├── tenant.py
│   │   │   ├── user.py
│   │   │   └── ...
│   │   ├── api/
│   │   │   ├── __init__.py
│   │   │   ├── deps.py             # Dependencies (auth, tenant)
│   │   │   ├── v1/
│   │   │   │   ├── __init__.py
│   │   │   │   ├── auth.py
│   │   │   │   ├── tenants.py
│   │   │   │   ├── users.py
│   │   │   │   ├── roles.py
│   │   │   │   ├── api_keys.py
│   │   │   │   ├── billing.py
│   │   │   │   ├── audit.py
│   │   │   │   ├── reports.py
│   │   │   │   ├── plugins.py
│   │   │   │   └── dashboard.py
│   │   ├── services/               # Business logic
│   │   │   ├── __init__.py
│   │   │   ├── auth_service.py
│   │   │   ├── tenant_service.py
│   │   │   ├── user_service.py
│   │   │   ├── billing_service.py
│   │   │   └── audit_service.py
│   │   ├── core/
│   │   │   ├── __init__.py
│   │   │   ├── security.py         # Password, JWT, crypto
│   │   │   ├── permissions.py      # RBAC logic
│   │   │   ├── tenant_resolver.py  # Tenant isolation
│   │   │   └── exceptions.py       # Custom exceptions
│   │   └── utils/
│   │       ├── __init__.py
│   │       ├── pagination.py
│   │       └── validators.py
│   ├── alembic/                    # Database migrations
│   ├── tests/
│   ├── Dockerfile
│   ├── requirements.txt
│   └── pyproject.toml
│
├── frontend/
│   ├── src/
│   │   ├── main.tsx                # Entry point
│   │   ├── App.tsx
│   │   ├── components/
│   │   │   ├── layout/
│   │   │   │   ├── Sidebar.tsx
│   │   │   │   ├── TopBar.tsx
│   │   │   │   └── Layout.tsx
│   │   │   ├── ui/                 # Reusable UI components
│   │   │   │   ├── DataTable.tsx
│   │   │   │   ├── Modal.tsx
│   │   │   │   ├── Form.tsx
│   │   │   │   └── Charts.tsx
│   │   │   └── features/
│   │   │       ├── tenants/
│   │   │       ├── users/
│   │   │       ├── billing/
│   │   │       └── reports/
│   │   ├── pages/
│   │   │   ├── Dashboard.tsx
│   │   │   ├── Tenants/
│   │   │   │   ├── List.tsx
│   │   │   │   └── Detail.tsx
│   │   │   ├── Users/
│   │   │   ├── Billing/
│   │   │   └── Settings/
│   │   ├── hooks/
│   │   │   ├── useAuth.ts
│   │   │   ├── useTenant.ts
│   │   │   ├── useApi.ts
│   │   │   └── usePermissions.ts
│   │   ├── stores/
│   │   │   ├── authStore.ts        # Zustand/Jotai
│   │   │   ├── tenantStore.ts
│   │   │   └── uiStore.ts
│   │   ├── lib/
│   │   │   ├── api.ts              # API client (axios/fetch)
│   │   │   ├── utils.ts
│   │   │   └── constants.ts
│   │   └── types/
│   │       └── index.ts
│   ├── public/
│   ├── index.html
│   ├── package.json
│   ├── tsconfig.json
│   ├── vite.config.ts
│   └── tailwind.config.js
│
├── docker-compose.yml
├── Makefile
└── README.md

6. Key Implementation Details

FastAPI Dependencies (Tenant Isolation)

# app/api/deps.py
from fastapi import Depends, HTTPException, Header
from fastapi.security import HTTPBearer

security = HTTPBearer()

async def get_current_user(token: str = Depends(security)):
    """Validate JWT and return user"""
    pass

async def get_current_tenant(
    x_tenant_id: UUID = Header(...),
    user: User = Depends(get_current_user)
):
    """Validate user belongs to tenant"""
    if not user.has_access_to(x_tenant_id):
        raise HTTPException(403, "Access denied to tenant")
    return x_tenant_id

async def require_permission(permission: str):
    """Dependency factory for permission checking"""
    async def checker(user: User = Depends(get_current_user)):
        if not user.has_permission(permission):
            raise HTTPException(403, f"Missing permission: {permission}")
    return checker

# Usage:
@router.get("/users", dependencies=[Depends(require_permission("users.read"))])
async def list_users(tenant_id: UUID = Depends(get_current_tenant)):
    pass

React 19 + Server Components Pattern

// Using React 19 features
// Server Components for data fetching
async function TenantListPage() {
  const tenants = await api.tenants.list(); // Server-side fetch
  
  return (
    <DataTable 
      data={tenants} 
      columns={tenantColumns}
      // React 19: actions for mutations
      onDelete={deleteTenantAction}
    />
  );
}

// Client Components for interactivity
'use client';
function TenantActions({ tenantId }: { tenantId: string }) {
  const { hasPermission } = usePermissions();
  
  return (
    <div>
      {hasPermission('tenants.update') && (
        <Button onClick={() => editTenant(tenantId)}>Edit</Button>
      )}
      {hasPermission('tenants.delete') && (
        <Button variant="danger" onClick={() => deleteTenant(tenantId)}>
          Delete
        </Button>
      )}
    </div>
  );
}

Audit Log Middleware

# Automatically log all state-changing operations
@app.middleware("http")
async def audit_middleware(request: Request, call_next):
    response = await call_next(request)
    
    if request.method in ["POST", "PUT", "PATCH", "DELETE"]:
        await audit_service.log(
            action=f"{request.method.lower()}.{request.url.path}",
            user=get_current_user_from_request(request),
            tenant=get_tenant_from_request(request),
            ip=request.client.host,
            user_agent=request.headers.get("user-agent"),
            details={"path": str(request.url), "status": response.status_code}
        )
    
    return response

7. Deployment Architecture

┌─────────────────────────────────────────────────────────┐
│                      CDN (CloudFront)                   │
│              Static assets, DDoS protection             │
└─────────────────────────────────────────────────────────┘
                           │
┌─────────────────────────────────────────────────────────┐
│                   Load Balancer (ALB)                   │
│              SSL termination, health checks             │
└─────────────────────────────────────────────────────────┘
                           │
           ┌───────────────┼───────────────┐
           ▼               ▼               ▼
    ┌────────────┐  ┌────────────┐  ┌────────────┐
    │  Frontend  │  │  Backend   │  │  Backend   │
    │  (React)   │  │  (FastAPI) │  │  (FastAPI) │
    │  Container │  │  Container │  │  Container │
    └────────────┘  └────────────┘  └────────────┘
           │               │               │
           └───────────────┼───────────────┘
                           ▼
    ┌─────────────────────────────────────────────────┐
    │              PostgreSQL (RDS/Aurora)            │
    │         Primary → Replica (Multi-AZ)            │
    │              Automated backups                  │
    └─────────────────────────────────────────────────┘
                           │
           ┌───────────────┼───────────────┐
           ▼               ▼               ▼
    ┌────────────┐  ┌────────────┐  ┌────────────┐
    │   Redis    │  │   S3       │  │  Stripe    │
    │  (ElastiCache)│ (Backups) │  │  (Billing) │
    │  Sessions  │  │  Reports   │  │            │
    │  Cache     │  │  Exports   │  │            │
    └────────────┘  └────────────┘  └────────────┘

8. Summary

Component Technology Purpose
Backend API FastAPI (Python) REST API, async request handling
Database PostgreSQL 15+ Primary data store with RLS
Cache Redis Sessions, rate limiting, cache
Frontend React 19 + TypeScript Admin UI with modern patterns
Styling Tailwind CSS Utility-first CSS
State Zustand/Jotai Client state management
Auth JWT + Argon2id Token-based authentication
Payments Stripe Subscription billing
Monitoring Prometheus + Grafana Metrics and alerting
Logs ELK Stack / CloudWatch Centralized logging

This design provides a secure, scalable, and maintainable admin backend for the LandveX Enterprise Platform with full multi-tenant isolation, comprehensive audit logging, and flexible plugin architecture.