> For the complete documentation index, see [llms.txt](https://manuale.opencontent.it/manuali/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://manuale.opencontent.it/manuali/manuale-operativo-interno/tenant-manager/riferimenti-tecnici.md).

# Riferimenti tecnici

Questa sezione è rivolta principalmente a sviluppatori e ops. Raccoglie i riferimenti necessari per integrare il Tenant Manager con altri sistemi, configurare nuove istanze e diagnosticare problemi a basso livello.

***

#### Repository

| Repository            | Path GitLab                                     | Descrizione                                                               |
| --------------------- | ----------------------------------------------- | ------------------------------------------------------------------------- |
| **Tenant Manager**    | `opencity-labs/area-personale/tenant-manager`   | Sorgente principale: backend Go, frontend JS, hook PocketBase, migrazioni |
| **Windmill Platform** | `opencity-labs/core-services/windmill-platform` | Workflow di provisioning e deploy per il workspace `platform`             |

***

#### API PocketBase

Il Tenant Manager espone le API standard di PocketBase su tutte le sue collezioni. Le API sono accessibili con autenticazione tramite token Bearer.

**Autenticazione:**

```bash
# Ottenere un token con email + password (account applicativo)
curl -s -X POST https://<TM_URL>/api/collections/users/auth-with-password \
  -H "Content-Type: application/json" \
  -d '{"identity": "<email>", "password": "<password>"}'
# → restituisce {"token": "...", "record": {...}}
```

**Endpoint principali:**

| Operazione          | Metodo | Path                                      |
| ------------------- | ------ | ----------------------------------------- |
| Lista tenant        | GET    | `/api/collections/tenants/records`        |
| Singolo tenant      | GET    | `/api/collections/tenants/records/:id`    |
| Crea tenant         | POST   | `/api/collections/tenants/records`        |
| Aggiorna tenant     | PATCH  | `/api/collections/tenants/records/:id`    |
| Elimina tenant      | DELETE | `/api/collections/tenants/records/:id`    |
| Lista clienti       | GET    | `/api/collections/customers/records`      |
| Lista applicativi   | GET    | `/api/collections/apps/records`           |
| Lista schemi config | GET    | `/api/collections/config_schemas/records` |
| Health check        | GET    | `/api/health`                             |
| Callback Windmill   | PATCH  | `/api/webhook/windmill-callback`          |

**Filtri, ordinamento e expand:**

PocketBase supporta query avanzate tramite parametri URL:

```
# Tenant attivi di tipo Atti Sicraweb
GET /api/collections/tenants/records
    ?filter=(app_name='integrazione-atti-sicraweb' && status='production')
    &expand=customer,organization
    &sort=-created
```

Per la documentazione completa delle API PocketBase: [pocketbase.io/docs/api-records](https://pocketbase.io/docs/api-records)

***

#### Collezioni principali

| Collezione          | Contenuto                               | Note                                                         |
| ------------------- | --------------------------------------- | ------------------------------------------------------------ |
| `tenants`           | Istanze applicative                     | Campo `config` contiene il JSON della configurazione Form.io |
| `customers`         | Anagrafica clienti (enti)               | Relazione 1:N con `tenants`                                  |
| `organizations`     | Anagrafica partner/reseller             | Relazione opzionale con `tenants`                            |
| `apps`              | Catalogo applicativi disponibili        | Gestita dagli sviluppatori nel backoffice                    |
| `config_schemas`    | Schemi Form.io per tipo applicativo     | Versionati per `app_name`                                    |
| `state_transitions` | Definizione macchina a stati            | `from_status`, `to_status`, label                            |
| `windmill_scripts`  | Mapping transizione → workflow Windmill | Per tipo applicativo e transizione                           |
| `users`             | Utenti amministratori e applicativi     | OAuth2 via Authentik + email/password                        |

***

#### Variabili d'ambiente

Le variabili d'ambiente configurano il comportamento del Tenant Manager al deploy. Il file `.env.example` nel repository contiene l'elenco completo con i valori di default.

**Variabili principali:**

| Variabile                | Descrizione                                  | Note                                        |
| ------------------------ | -------------------------------------------- | ------------------------------------------- |
| `PB_URL`                 | URL pubblico dell'istanza TM                 | Usato nella callback URL passata a Windmill |
| `PB_SUPERUSER_EMAIL`     | Email superuser PocketBase                   | Solo per bootstrap iniziale e admin UI      |
| `PB_SUPERUSER_PASSWORD`  | Password superuser PocketBase                | Non usare negli applicativi                 |
| `PB_DEV`                 | Abilita log verbosi                          | `true` in sviluppo, `false` in produzione   |
| `TM_AUTH_DISABLED`       | Disabilita OIDC (dev locale)                 | Mai `true` in produzione                    |
| `TM_OIDC_CLIENT_ID`      | Client ID Authentik                          | —                                           |
| `TM_OIDC_CLIENT_SECRET`  | Client Secret Authentik                      | —                                           |
| `TM_OIDC_AUTH_URL`       | URL authorization endpoint Authentik         | —                                           |
| `TM_OIDC_TOKEN_URL`      | URL token endpoint Authentik                 | —                                           |
| `TM_WINDMILL_BASE_URL`   | URL interno Windmill (server→server)         | —                                           |
| `TM_WINDMILL_PUBLIC_URL` | URL pubblico Windmill (link nella UI)        | —                                           |
| `TM_WINDMILL_TOKEN`      | Token di autenticazione Windmill             | —                                           |
| `TM_WINDMILL_WORKSPACE`  | Workspace Windmill da usare                  | Valore: `platform`                          |
| `KAFKA_BROKERS`          | Broker Kafka (vuoto = Kafka disabilitato)    | —                                           |
| `KAFKA_TOPIC_TENANTS`    | Topic Kafka per gli eventi tenant            | Default: `tenants`                          |
| `FORMIO_VALIDATOR_URL`   | URL del servizio di validazione Form.io      | Vuoto = validazione disabilitata            |
| `TM_KAFKA_WS_URL`        | URL WebSocket per aggiornamenti real-time UI | —                                           |

***

#### Eventi Kafka

Il Tenant Manager pubblica eventi CloudEvents 1.0 sul topic configurato in `KAFKA_TOPIC_TENANTS` a ogni operazione CRUD sui tenant.

**Tipi di evento:**

| `ce_type`                             | Quando viene pubblicato                                   |
| ------------------------------------- | --------------------------------------------------------- |
| `it.opencity.platform.tenant.created` | Creazione di un nuovo tenant                              |
| `it.opencity.platform.tenant.updated` | Aggiornamento di un tenant (incluse transizioni di stato) |
| `it.opencity.platform.tenant.deleted` | Eliminazione di un tenant                                 |

**Struttura del messaggio:**

```json
{
  "entity": {
    "meta": {
      "id": "<uuid>",
      "created": "...",
      "updated": "..."
    },
    "data": {
      "app_name": "...",
      "status": "...",
      "config": { ... },
      ...
    }
  }
}
```

Schema JSON completo pubblicato su: `https://schemas.opencityitalia.it/tenant-manager/tenant/v1.json`

Documentazione AsyncAPI: pubblicata su GitLab Pages del repository Tenant Manager.

***

#### Windmill: workspace platform

I workflow del Tenant Manager risiedono nel workspace `platform` di Windmill. La convenzione di naming per i flow è:

```
f/tenant_manager/<nome_applicativo>_<azione>
```

Esempi:

* `f/tenant_manager/chatbot_provision`
* `f/tenant_manager/integrazione_atti_sicraweb_deploy`
* `f/tenant_manager/pocketbase` *(resource con credenziali TM — non modificare)*

Il subflow condiviso per la callback a PocketBase si trova in:

```
f/tenant_manager/finalize_transition
```

> Tutti i workflow custom devono chiamare questo subflow in coda per finalizzare la transizione di stato. Non reimplementare la logica di callback.
