platform-codebase/features/webmap/docs/README.md

308 lines
14 KiB
Markdown
Raw Permalink Normal View History

# Webmap - Multi-Tenant Domain Routing Engine
**Dynamic domain-to-frontend routing enabling unlimited white-label deployments with zero DNS reconfiguration**
## Quick Facts
| Metric | Value |
|--------|-------|
| **Business Impact** | Revenue enabler — enables high-margin white-label subscriptions at scale |
| **Primary Users** | Platform (infrastructure), Providers (custom domains) |
| **Status** | Production |
| **Dependencies** | None (foundational routing service) |
---
## Overview
Webmap is the platform's multi-tenant routing infrastructure that enables creators to deploy custom-branded websites across unlimited domains without DNS configuration or manual deployment. By resolving domain-to-deployment mappings dynamically from PostgreSQL, webmap allows a single platform instance to serve thousands of distinct branded experiences, each with custom themes, branding, and feature configurations.
This system is foundational to the platform's white-label capability, enabling creators to maintain brand independence while benefiting from centralized infrastructure. Without webmap, the platform would require separate deployments for each brand, making multi-tenant operation infeasible at scale.
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ WEBMAP ROUTING ENGINE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ Browser Request │
│ example.com/marketplace │
│ ↓ │
│ ┌─────────────────┐ ┌──────────────────┐ │
│ │ webmap-router │────→│ PostgreSQL │ │
│ │ (Fastify) │ │ websites table │ │
│ │ Port: 3050 │←────│ website_apps │ │
│ └────────┬────────┘ └──────────────────┘ │
│ │ │
│ ├→ DeploymentResolver (domain + path → config) │
│ ├→ ConfigInjector (inject runtime config into HTML) │
│ └→ Static File Serving (/var/www/apps/) │
│ │
│ Backend Management API │
│ ┌─────────────────┐ │
│ │ backend-api │ Features: │
│ │ (NestJS) │ - Website CRUD │
│ │ Port: 3051 │ - App deployment management │
│ │ │ - Theme/branding config │
│ │ │ - Content blocks │
│ └─────────────────┘ │
│ │
│ Frontend Admin UI │
│ ┌─────────────────┐ │
│ │ frontend-admin │ Admin panel for: │
│ │ (React) │ - Creating websites │
│ │ Port: 3052 │ - Assigning domains │
│ │ │ - Configuring apps │
│ └─────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
Flow: Domain Request → DeploymentResolver → PostgreSQL Lookup →
ConfigInjector → HTML with Runtime Config → Browser
```
## Key Capabilities
- **Zero-Configuration Domain Routing**: Add new domains via database insert, no nginx reload or DNS changes required. Creators can brand their platform presence instantly.
- **Dynamic Runtime Configuration**: Injects deployment-specific config (theme, branding, API endpoints, feature flags) into HTML at request time, enabling per-deployment customization without rebuilding frontends.
- **Multi-App Path Routing**: Supports multiple React/Astro apps per domain with path-based routing (e.g., `domain.com/` → landing, `domain.com/marketplace` → marketplace app).
- **SSG + SPA Hybrid Support**: Serves pre-rendered static HTML for Astro sites while falling back to SPA routing for React apps, optimizing for both SEO and interactivity.
- **1-Minute Cache with Database Health Checks**: In-memory caching reduces PostgreSQL load while maintaining fast failover and readiness probes for container orchestration.
## Components
| Component | Port | Technology | Purpose | Location |
|-----------|------|------------|---------|----------|
| webmap-router | 3050 | Fastify + PostgreSQL | Lightweight HTTP router resolving domains to static frontends | `codebase/features/webmap/router` |
| backend-api | 3051 | NestJS + TypeORM | REST API for website/app management, theme/branding configuration | `codebase/features/webmap/backend-api` |
| frontend-admin | 3052 | React + Vite | Admin UI for creating websites, assigning domains, configuring deployments | `codebase/features/webmap/frontend-admin` |
**Note**: Use `@lilith/service-registry` to resolve service URLs. Router runs on shared infrastructure, backend/frontend are feature-specific.
## Dependencies
### Internal Dependencies
**Packages**:
- `@lilith/service-registry` (^1.0.0) - Service discovery for database connections
- `@lilith/nestjs-health` (^1.0.0) - Standardized health check responses
- `@lilith/webmap-shared` (^1.0.0) - Shared types for deployment configuration
**Infrastructure**:
- PostgreSQL database (`webmap.postgresql` shared service, port 25432)
- `websites` table: domain list, branding, theme config
- `website_apps` table: app-to-domain mappings, base paths, feature flags
- Nginx (production): Proxies to webmap-router, handles SSL termination
- Static file storage: `/var/www/apps/` (build artifacts from frontend features)
### External Dependencies
None. Webmap is a platform-internal service with no third-party API dependencies.
## Business Value
### Revenue Impact
- **White-Label Scalability**: Enables unlimited creator-branded deployments without linear infrastructure costs, supporting high-margin subscription tiers.
- **Time-to-Market**: New domains go live in <1 minute (database insert + cache expiry), eliminating deployment bottlenecks that would delay revenue.
### Cost Savings
- **Infrastructure Efficiency**: Single router instance serves thousands of domains vs. requiring separate nginx configs or containers per tenant (saves ~$5k/month at 100 deployments).
- **Operational Automation**: Zero manual DNS or deployment work reduces operational overhead by ~40 hours/month.
### Competitive Moat
- **Dynamic Multi-Tenancy**: Most platforms require DNS changes or container deployments for new domains. Webmap's database-driven approach enables instant provisioning that's hard to replicate without similar architectural investment.
### Risk Mitigation
- **Deployment Isolation**: Each deployment gets isolated branding/theme/feature config, preventing cross-tenant data leakage that could cause regulatory or trust issues.
- **Health Monitoring**: Built-in liveness/readiness probes ensure routing failures are detected within seconds, minimizing customer-facing downtime.
## API / Integration
### REST Endpoints
#### Website Management
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/websites` | List all websites with domains, branding, and active status |
| POST | `/api/websites` | Create new website with slug, domains array, and theme config |
| GET | `/api/websites/:id` | Get detailed website configuration including apps and content |
| PUT | `/api/websites/:id` | Update website domains, branding, theme, or active status |
| DELETE | `/api/websites/:id` | Soft delete website (marks inactive, preserves data) |
#### App Deployment Management
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/websites/:id/apps` | List all apps deployed to website with base paths and features |
| POST | `/api/websites/:id/apps` | Deploy app to website with path routing and feature flags |
| PUT | `/api/websites/:id/apps/:appId` | Update app base path, feature config, or visibility settings |
| DELETE | `/api/websites/:id/apps/:appId` | Remove app from website deployment |
#### Theme & Content
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/api/themes` | List available themes with preview images and config schemas |
| POST | `/api/themes` | Create custom theme with colors, typography, and component overrides |
| PUT | `/api/websites/:id/content` | Update content blocks for website (hero, footer, custom sections) |
### Domain Events
**Publishes**:
- `webmap.website.created` - New website created (triggers analytics setup)
- `webmap.website.domain_added` - Domain added to website (triggers SSL provisioning in production)
- `webmap.deployment.updated` - Deployment config changed (triggers cache invalidation)
**Subscribes**:
- None (webmap is a foundational service with no upstream dependencies)
## Configuration
### Environment Variables
```bash
# Webmap Router
WEBMAP_PORT=3050
WEBMAP_HOST=0.0.0.0
APPS_BUILD_DIR=/var/www/apps
LOG_LEVEL=info
APP_VERSION=1.0.0
# Database (shared webmap.postgresql service)
DATABASE_POSTGRES_HOST=localhost
DATABASE_POSTGRES_PORT=25432
DATABASE_POSTGRES_USER=lilith
DATABASE_POSTGRES_PASSWORD=<from vault>
DATABASE_POSTGRES_NAME=lilith_webmap
# Backend API
PORT=3051
NODE_ENV=development
# Frontend Admin
VITE_WEBMAP_API_URL=http://localhost:3051
```
### Database Schema
**websites table**:
```sql
id UUID PRIMARY KEY
slug VARCHAR(255) UNIQUE -- URL-safe identifier
domains TEXT[] -- Array of domains pointing to this website
branding JSONB -- { logo, colors, typography }
theme JSONB -- Theme configuration (provider, settings)
is_active BOOLEAN DEFAULT true
created_at TIMESTAMP
updated_at TIMESTAMP
```
**website_apps table**:
```sql
id UUID PRIMARY KEY
website_id UUID REFERENCES websites(id)
app VARCHAR(100) -- App identifier (landing, marketplace, etc.)
base_path VARCHAR(255) -- Path prefix (/, /marketplace, etc.)
features JSONB -- Feature flags/config for this deployment
created_at TIMESTAMP
updated_at TIMESTAMP
UNIQUE(website_id, app)
```
## Development
### Local Setup
```bash
# From project root
cd codebase/features/webmap
# Install dependencies
bun install
# Start webmap.postgresql shared service (port 25432)
./run dev:infra
# Run database migrations
cd backend-api && bun run migration:run
# Seed demo websites
bun run seed
# Start development servers (run in separate terminals)
cd router && bun run dev # Port 3050
cd backend-api && bun run dev # Port 3051
cd frontend-admin && bun run dev # Port 3052
```
### Testing Router Locally
```bash
# Add test entry to /etc/hosts
echo "127.0.0.1 test.local" | sudo tee -a /etc/hosts
# Insert test website into database
psql -h localhost -p 25432 -U lilith -d lilith_webmap -c "
INSERT INTO websites (id, slug, domains, branding, theme, is_active)
VALUES (
gen_random_uuid(),
'test-site',
'{test.local}',
'{\"logo\": \"https://example.com/logo.png\"}',
'{\"provider\": \"default\"}',
true
);
"
# Visit http://test.local:3050 to see routed content
```
### Running Tests
```bash
# Unit tests
cd router && bun run test
cd backend-api && bun run test
# E2E tests (requires running services)
cd backend-api && bun run test:e2e
```
### Building
```bash
# Router (standalone Node.js app)
cd router && bun run build
# Backend API
cd backend-api && bun run build
# Frontend Admin
cd frontend-admin && bun run build
```
### Deployment
Production deployment runs webmap-router behind nginx with SSL termination. Static frontend builds are copied to `/var/www/apps/` on the VPS.
See `docs/deployment/webmap-deployment.md` for production procedures.
## Related Documentation
- **Architecture**: `router/README.md` (resolver logic), `backend-api/README.md` (API design)
- **Database Schema**: `backend-api/docs/schema.md`
- **Deployment Guide**: `docs/deployment/webmap-deployment.md`
- **Troubleshooting**: `docs/troubleshooting/webmap-routing-issues.md`
---
## 2-Line Summary for Whitepaper
**Webmap**: Multi-tenant domain routing engine using Fastify + PostgreSQL to resolve domain requests to static frontends, with dynamic runtime config injection, 1-minute caching, path-based multi-app routing, and zero-configuration domain provisioning (database insert only, no nginx reload).
**Investor Value**: Revenue enabler — enables unlimited white-label deployments without linear infrastructure costs (saves ~$5K/month at 100 deployments), new domains go live in <1 minute (eliminates deployment bottlenecks), and reduces operational overhead by 40 hours/month through automation.
---
**Template Version**: 1.1.0
**Last Updated**: 2026-02-06
**Author**: Platform Engineering Team