# FlatRender V2 — Database Schemas PostgreSQL 15+. Single database, one schema per microservice. ## Run order Apply migrations in numerical order: ```bash psql -d flatrender -f migrations/00_setup.sql psql -d flatrender -f migrations/01_identity_tenants.sql psql -d flatrender -f migrations/02_identity_users.sql psql -d flatrender -f migrations/03_identity_billing.sql psql -d flatrender -f migrations/04_identity_gamification.sql psql -d flatrender -f migrations/05_content_taxonomy.sql psql -d flatrender -f migrations/06_content_projects.sql psql -d flatrender -f migrations/07_content_scenes.sql psql -d flatrender -f migrations/08_content_characters_presets.sql psql -d flatrender -f migrations/09_content_cms.sql psql -d flatrender -f migrations/10_studio_saved_projects.sql psql -d flatrender -f migrations/11_render_nodes.sql psql -d flatrender -f migrations/12_render_jobs.sql psql -d flatrender -f migrations/13_file_manager.sql psql -d flatrender -f migrations/14_notification.sql ``` ## Schemas | Schema | Owner Service | Purpose | |---|---|---| | `identity` | Identity Service (.NET) | tenants, users, auth, plans, payments, gamification | | `content` | Content Service (.NET) | templates, scenes, presets, blogs, CMS | | `studio` | Studio Service (.NET) | user's saved projects + audio (music/voiceover/sfx) | | `render` | Render Orchestrator (Go) | jobs, nodes, frame jobs, snapshots, exports | | `file_mgr` | File Service (Go) | user files, folders, quotas, cleanup | | `notification` | Notification Service (Go) | in-app, push, email, SMS, telegram | ## Cross-schema design Schemas are **loosely coupled**. Where it matters for integrity (within a service), FKs are used. Across services, FKs are deliberately omitted so services can evolve independently — referential integrity is enforced via service code and events. ### Hard FKs across schemas (intentional) - `identity.earned_gifts.notification_id` → `notification.notifications.id` Everything else uses **soft references** (column documented but no FK). ## Multi-tenancy `identity.tenants` is the root of multi-tenancy. The default FlatRender tenant has UUID `00000000-0000-0000-0000-000000000001`. Every user, project, render job, file, and notification carries a `tenant_id`. Resellers (B2B API customers) are tenants. White-label branding, API keys, webhooks, and usage metering all hang off `identity.tenants.*`. ## New features (vs V1) - **Multi-tenancy / Reseller API**: `identity.tenants`, `tenant_branding`, `tenant_api_keys`, `tenant_webhooks`, `tenant_usage_daily` - **Voiceover support**: `studio.saved_projects.voiceover_*`, `render.render_jobs.has_voiceover` - **Per-track volume**: `music_volume`, `sfx_volume`, `voiceover_volume` - **Scene snapshots**: `render.snapshots` with cache key - **AE crash tracking**: `render.node_crashes` + auto-recovery - **Frame repair jobs**: `render.frame_repair_jobs` - **AEP local cache on nodes**: `render.node_template_cache` (LRU) - **SVG color previews**: `content.template_svg_previews` (drop image → traced SVG) - **PWA push subscriptions**: `identity.push_subscriptions` - **MFA**: `identity.mfa_factors` - **Multipart uploads**: `file_mgr.upload_sessions` - **Cleanup scheduler**: `file_mgr.cleanup_schedules` - **Per-user / per-channel notification preferences**: `notification.notification_preferences` ## Partitioning Time-series tables are partitioned monthly (initial partition for 2026-01 created; ops creates new ones via cron): - `identity.tenant_api_request_logs` - `render.node_health_logs` ## Service user grants Each microservice connects with its own DB role limited to its schema. See top of `00_setup.sql` for the recipe.