# Multitenancy Runtime Design

## Goals
- Keep tenant config validation and header resolution in one reusable internal crate.
- Keep Axum-to-auth request dispatch conversion in one place.
- Let one AthenaAuth server host multiple tenant runtimes (DB URL + search path + schema mapping) with strict typed boundaries.

## Component UML

```mermaid
flowchart LR
    A["config.yaml"] --> B["ServerConfigFile"]
    B --> C["athena-auth-multitenancy::ParsedMultiTenancyConfig"]
    C --> D["HeaderTenantResolver"]
    C --> E["TenantDatabaseRuntimeConfig"]
    E --> F["SqlxAdapter (per tenant)"]
    F --> G["AthenaAuth (per tenant)"]
    G --> H["TenantRuntimeRegistry<Arc<AthenaAuth<SqlxAdapter>>>" ]
    I["Axum Request"] --> J["dispatch_auth_request"]
    J --> H
    H --> K["Selected tenant runtime"]
    K --> L["dispatch_auth_axum_request"]
    L --> M["AthenaAuth::handle_request"]
    M --> N["Axum Response + x-athena-tenant"]
```

## Sequence UML

```mermaid
sequenceDiagram
    participant Client
    participant Axum as Axum Router
    participant Dispatch as dispatch_auth_request
    participant Registry as TenantRuntimeRegistry
    participant Shared as dispatch_auth_axum_request
    participant Auth as AthenaAuth Runtime

    Client->>Axum: HTTP /api/auth/* + tenant header
    Axum->>Dispatch: route(any)
    Dispatch->>Registry: resolve_tenant_from_headers(...)
    Registry-->>Dispatch: TenantId
    Dispatch->>Registry: runtime(TenantId)
    Registry-->>Dispatch: Arc<AthenaAuth>
    Dispatch->>Shared: dispatch_auth_axum_request(auth, req)
    Shared->>Auth: handle_request(AuthRequest)
    Auth-->>Shared: AuthResponse / AuthError
    Shared-->>Dispatch: Axum Response
    Dispatch-->>Client: Response + x-athena-tenant
```

## Design Choices
- New crate `crates/multitenancy` owns tenant ID/header/search-path validation and runtime registry typing.
- `src/handlers/axum.rs` now exposes `dispatch_auth_axum_request`, so request conversion/error mapping is no longer duplicated in `src/bin/server.rs`.
- `src/bin/server.rs` remains responsible for deployment/runtime concerns: env lookup, SQL pool creation, plugin composition, and observability.
- Tenant `schema_mapping` is now first-class config state (default + per-tenant override merge), so schema-object remapping can evolve without changing route dispatch internals.
