# Plan: Multi-Tenancy & SaaS Mode

**Status**: Draft
**Author**: Prism Core Team
**Created**: 2026-02-06
**Updated**: 2026-02-06

## Overview

Add first-class multi-tenancy support to Prism so that a single generated codebase can serve multiple isolated tenants (customers, organizations, workspaces). This transforms Prism from a "generate a CRUD app" tool into a "generate a SaaS product" platform.

## Goals

- Define tenancy model in spec (`tenancy:` section) with zero ambiguity
- Support three isolation strategies: **row-level security (RLS)**, **schema-per-tenant**, and **database-per-tenant**
- Auto-generate tenant-aware middleware, services, and queries
- Generate tenant onboarding flows (signup, provisioning, billing hooks)
- Provide tenant-scoped admin dashboard with usage metrics
- Generate tenant-aware API routes (subdomain-based or header-based resolution)

## Non-Goals

- Billing/payment processing (integrates with Priority 2: Email and future Stripe plan)
- Cross-tenant analytics or reporting (deferred to a BI feature)
- Tenant data export/migration tooling (future follow-up)

## Design

### Specification Extensions

```yaml
tenancy:
  enabled: true
  strategy: rls          # rls | schema | database
  resolver: subdomain    # subdomain | header | path
  tenant_model: Organization
  tenant_id_field: org_id
  shared_models:         # Models NOT scoped to a tenant
    - User
    - Plan
    - GlobalConfig
  onboarding:
    auto_provision: true
    default_plan: free
    trial_days: 14
```

### Technical Approach

#### 1. Row-Level Security (RLS) — Default Strategy

- Add `tenant_id` column to all tenant-scoped models (auto-generated FK)
- Generate PostgreSQL RLS policies (`CREATE POLICY`) in Alembic migrations
- Set `current_setting('app.tenant_id')` via middleware on every request
- All queries automatically filtered — no application-level filtering needed
- Superadmin bypass via `SET ROLE` for cross-tenant operations

#### 2. Schema-per-Tenant Strategy

- Generate `create_tenant_schema(tenant_slug)` utility
- Alembic migrations run per-schema using `include_schemas` config
- SQLAlchemy `schema_translate_map` in session factory
- Middleware resolves tenant → sets schema search path
- Shared tables remain in `public` schema

#### 3. Database-per-Tenant Strategy

- Generate database provisioning scripts (CREATE DATABASE)
- Connection pool per tenant with lazy initialization
- Middleware resolves tenant → selects connection pool
- Alembic multi-database migration support

#### 4. Tenant Resolution Middleware

```python
# Generated middleware
class TenantMiddleware:
    async def __call__(self, request, call_next):
        tenant = await self.resolve_tenant(request)
        request.state.tenant = tenant
        # RLS: SET app.tenant_id
        # Schema: SET search_path
        # Database: select connection pool
        return await call_next(request)
```

Resolution strategies:
- **Subdomain**: `acme.myapp.com` → tenant "acme"
- **Header**: `X-Tenant-ID: acme`
- **Path**: `/api/acme/items`

#### 5. Generated Tenant Admin Pages

- `/admin/tenants` — list all tenants with usage metrics
- `/admin/tenants/:id` — tenant detail, plan, limits, users
- `/admin/tenants/new` — provision new tenant
- Tenant-scoped admin at `/dashboard` — tenant's own view

### API Changes

- All tenant-scoped API routes automatically include tenant context
- New routes: `POST /api/tenants` (provision), `GET /api/tenants/:id/usage`
- GraphQL: `tenant` field on all scoped types, `createTenant` mutation

### Database Changes

- `tenants` table: id, slug, name, plan, created_at, limits (JSONB)
- `tenant_id` FK on all scoped models
- RLS policies on all scoped tables
- `tenant_invitations` table for team member invites

## Implementation Steps

1. **Spec model** — Add `TenancyConfig` to spec models, parser, validation
2. **Migration generator** — Generate RLS policies, tenant_id columns, tenant table
3. **Middleware generator** — Tenant resolution middleware (subdomain/header/path)
4. **Service layer** — Tenant-aware base service with automatic scoping
5. **Frontend** — Tenant selector, onboarding wizard, tenant admin pages
6. **CLI** — `prism tenant create`, `prism tenant list`, `prism tenant migrate`
7. **Tests** — Tenant isolation tests, RLS policy tests, cross-tenant leak detection

## Testing Strategy

- **Unit tests**: Tenant resolution, RLS policy application, schema switching
- **Integration tests**: Multi-tenant CRUD operations, cross-tenant isolation verification
- **Security tests**: Verify no data leaks between tenants (automated cross-tenant query attempts)
- **Performance tests**: RLS overhead benchmarks, connection pool scaling

## Rollout Plan

1. Ship RLS strategy first (simplest, most common)
2. Schema-per-tenant as opt-in follow-up
3. Database-per-tenant as advanced option

## Complexity & Effort

**Effort Estimate**: 6-8 weeks (1-2 senior developers)
**Complexity**: HIGH — touches every layer of generated code

## Dependencies

- Enterprise Auth (P12) — already complete, provides user/role system
- Admin Panel (P19) — already complete, provides admin UI foundation

## Risk Assessment

**High Risks**:
- RLS policy correctness is critical — a bug = data leak between tenants
- Migration complexity increases significantly with schema/database strategies
- Performance overhead of RLS on high-throughput queries

**Mitigation**:
- Auto-generated security tests that attempt cross-tenant access
- RLS policy linting in CI
- Benchmark suite for tenant-aware queries

## Open Questions

- Should tenant billing/usage limits be enforced at the middleware level or service level?
- How should tenant deletion work — soft delete with grace period or immediate purge?
- Should we support tenant-level feature flags?
