# Docker Infrastructure and Casdoor Setup

# Docker Infrastructure and Casdoor Setup

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [infra/docker-compose.postgres.yml](infra/docker-compose.postgres.yml)
- [infra/init-db/01-create-casdoor-db.sql](infra/init-db/01-create-casdoor-db.sql)
- [scripts/check-casdoor-db.ts](scripts/check-casdoor-db.ts)
- [scripts/fix-casdoor-admin.ts](scripts/fix-casdoor-admin.ts)
- [scripts/fix-missing-audit-records.ts](scripts/fix-missing-audit-records.ts)
- [scripts/setup-casdoor.ts](scripts/setup-casdoor.ts)
- [src/modules/auth/avatar-svg-generator.ts](src/modules/auth/avatar-svg-generator.ts)
- [src/modules/auth/config-repo.ts](src/modules/auth/config-repo.ts)
- [src/modules/auth/config.ts](src/modules/auth/config.ts)
- [src/modules/customers/list-config.ts](src/modules/customers/list-config.ts)
- [src/openapi/openapi.ts](src/openapi/openapi.ts)

</details>



This section describes the containerized infrastructure and the automated bootstrap process for the Identity Provider (IdP) integration. The Primebrick backend relies on a multi-service Docker stack and a specialized orchestration script to synchronize credentials between Casdoor and the local PostgreSQL instance.

## 1. Docker Services Overview

The local development environment is managed via `infra/docker-compose.postgres.yml` [infra/docker-compose.postgres.yml:1-112](). It defines three primary services and utilizes named volumes for persistence.

### Service Definitions

| Service | Image | Role | Persistence Volume |
| :--- | :--- | :--- | :--- |
| `postgres` | `postgres:18-bookworm` | Primary DB (Primebrick & Casdoor) | `primebrick_pg18_data` |
| `casdoor` | `casbin/casdoor:3.75.0` | OIDC Identity Provider | `primebrick_casdoor_data` |
| `nats` | `nats:latest` | Message Broker (JetStream enabled) | `primebrick_nats_data` |

### PostgreSQL Customization
The `postgres` service includes a custom `entrypoint` to install and enable `pg_partman`, which is required for database partitioning [infra/docker-compose.postgres.yml:46-52](). It binds to `127.0.0.1:${PG_HOST_PORT:-5432}` to avoid port conflicts and IPv6 resolution issues on some host systems [infra/docker-compose.postgres.yml:37-40]().

### Casdoor Database Initialization
Casdoor is configured to use the same PostgreSQL instance but targets a separate database named `casdoor` [infra/docker-compose.postgres.yml:64-68](). The `casdoor` database is created via the SQL script `infra/init-db/01-create-casdoor-db.sql` [infra/init-db/01-create-casdoor-db.sql:1-3]() and the Casdoor flag `--createDatabase=true` [infra/docker-compose.postgres.yml:76]().

**Sources:**
- [infra/docker-compose.postgres.yml:1-112]()
- [infra/init-db/01-create-casdoor-db.sql:1-3]()

---

## 2. Casdoor Bootstrap Logic (`setup-casdoor.ts`)

The `scripts/setup-casdoor.ts` script is a critical maintenance tool that ensures the Identity Provider is correctly configured for the Primebrick API. It bypasses common API limitations by performing direct SQL updates on the Casdoor internal tables before using the HTTP API for entity creation.

### Execution Flow

1.  **Credential Discovery**: It connects to the `casdoor` database and retrieves the `client_id` and `client_secret` for the internal `app-built-in` application [scripts/setup-casdoor.ts:49-56](). These are used to authenticate subsequent API calls.
2.  **SQL Patching**: It updates the `application` table in the `casdoor` database to enable `password`, `authorization_code`, and `client_credentials` grant types for the `primebrick-api` application [scripts/setup-casdoor.ts:44-47]().
3.  **App Provisioning**: If the `primebrick-api` application does not exist, it inserts it directly into the `application` table [scripts/setup-casdoor.ts:82-88]().
4.  **API Synchronization**: It uses the discovered master credentials to call Casdoor's `/api/add-organization` and `/api/add-user` endpoints [scripts/setup-casdoor.ts:131-138]().
5.  **Local Sync**: Finally, it creates a matching record in the Primebrick `public.organizations` table to ensure the local DB recognizes the IdP organization [scripts/setup-casdoor.ts:141-160]().

### Natural Language to Code Entity Mapping: Casdoor Setup

The following diagram maps the logical setup steps to the specific functions and SQL operations in `setup-casdoor.ts`.

```mermaid
graph TD
    subgraph "Natural Language Space"
        A["Bootstrap Casdoor"]
        B["Enable Grant Types"]
        C["Sync Org to API DB"]
    end

    subgraph "Code Entity Space"
        A --> |"calls"| F1["scripts/setup-casdoor.ts:main()"]
        F1 --> |"SQL UPDATE"| Q1["UPDATE application SET grant_types..."]
        B --> |"implemented in"| Q1
        F1 --> |"SQL INSERT"| Q2["INSERT INTO public.organizations"]
        C --> |"implemented in"| Q2
    end
```

**Sources:**
- [scripts/setup-casdoor.ts:31-160]()
- [src/modules/auth/config-repo.ts:23-47]()

---

## 3. Credential Consolidation and Auth Configuration

The system supports two authentication modes: `STANDALONE` and `GATEWAY` [src/modules/auth/config.ts:4-15](). Configuration is loaded via `getAuthConfig`, which prioritizes database settings over environment variables [src/modules/auth/config.ts:93-110]().

### Auth Configuration Hierarchy

| Setting | DB Key (auth_configurations) | Env Variable |
| :--- | :--- | :--- |
| Issuer URL | `oidc_issuer_url` | `OIDC_ISSUER_URL` |
| Client ID | `oidc_client_id` | `OIDC_CLIENT_ID` |
| Roles Path | N/A | `AUTH_ROLES_PATH` |

The `loadAuthConfigFromDb` function in `src/modules/auth/config-repo.ts` [src/modules/auth/config-repo.ts:23-47]() fetches these values from the `auth_configurations` table. If the database is unavailable or the keys are missing, it falls back to defaults (e.g., `http://localhost:8000` for Casdoor) [src/modules/auth/config-repo.ts:34-40]().

**Sources:**
- [src/modules/auth/config.ts:1-157]()
- [src/modules/auth/config-repo.ts:1-66]()

---

## 4. Maintenance and Fix Scripts

### `fix-missing-audit-records.ts`
Because the initial bootstrap of the admin user and organization happens outside the standard API flow, they often lack audit trails. This script backfills the `organizations_audit` and `user_profiles_audit` tables [scripts/fix-missing-audit-records.ts:7-113]().

-   **Action**: `INSERT` [scripts/fix-missing-audit-records.ts:42]()
-   **Delta**: Captures the initial state of fields like `idp_code`, `email`, and `display_name` [scripts/fix-missing-audit-records.ts:46-52]().

### `fix-casdoor-admin.ts`
A utility to force-update the admin user in Casdoor. It ensures the user has `isAdmin: true`, `isVerified: true`, and `emailVerified: true` [scripts/fix-casdoor-admin.ts:162-164](). It attempts to locate the user using multiple ID formats: `org/user`, `admin/user`, and `user` [scripts/fix-casdoor-admin.ts:84-88]().

### Infrastructure Component Interaction

The following diagram illustrates how the Docker services and setup scripts interact to establish the system state.

```mermaid
sequenceDiagram
    participant D as Docker Compose
    participant S as setup-casdoor.ts
    participant C as Casdoor Container
    participant P as Postgres (casdoor DB)
    participant PB as Postgres (primebrick DB)

    D->>P: Initialize schema
    D->>C: Start service
    S->>P: Update 'app-built-in' grant_types
    S->>P: Provision 'primebrick-api' app
    S->>C: API: Create Organization (ACME)
    S->>C: API: Create Admin User
    S->>PB: INSERT INTO public.organizations
    Note over S,PB: Ensures IDP/API sync
```

**Sources:**
- [scripts/fix-missing-audit-records.ts:1-126]()
- [scripts/fix-casdoor-admin.ts:1-175]()
- [infra/docker-compose.postgres.yml:76-85]()

---
