> 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/guida-per-sviluppatori-aggiungere-un-nuovo-applicativo.md).

# Guida per sviluppatori: aggiungere un nuovo applicativo

Questa sezione descrive il processo completo per rendere disponibile un nuovo tipo di applicativo nel Tenant Manager, dalla definizione dello schema di configurazione alla scrittura del workflow Windmill.

***

#### Panoramica del processo

```
1. Aggiungi l'applicativo al catalogo (collezione `apps`)
        │
        ▼
2. Definisci lo schema Form.io (collezione `config_schemas`)
        │
        ▼
3. Configura le transizioni di stato (collezione `windmill_scripts`)
        │
        ▼
4. Scrivi i workflow Windmill (repo `windmill platform`)
        │
        ▼
5. Testa su QA, poi promuovi in produzione
```

***

#### Passo 1 — Aggiungere l'applicativo al catalogo

Accedi al backoffice PocketBase e aggiungi una nuova riga nella collezione `apps`:

| Campo         | Descrizione                        | Esempio                      |
| ------------- | ---------------------------------- | ---------------------------- |
| `name`        | Identificativo tecnico (slug)      | `integrazione-atti-sicraweb` |
| `description` | Nome leggibile mostrato nella UI   | `Integrazione Atti Sicraweb` |
| `icon`        | Icona (nome icona Bootstrap Icons) | `file-earmark-text`          |

> `[SCREENSHOT: Backoffice PocketBase — form di creazione nuova riga in collezione` apps`]`

Il valore di `name` diventa l'`app_name` di tutti i tenant di quel tipo e deve essere stabile: cambiarlo dopo che esistono tenant attivi rompe i riferimenti.

***

#### Passo 2 — Definire lo schema Form.io

Lo schema Form.io determina quali campi di configurazione il team delivery vedrà quando crea o modifica un tenant di questo tipo.

Aggiungi una riga nella collezione `config_schemas`:

| Campo      | Descrizione                                                     |
| ---------- | --------------------------------------------------------------- |
| `app_name` | Deve corrispondere esattamente al `name` dell'app appena creata |
| `version`  | Versione dello schema (es. `1`)                                 |
| `schema`   | Definizione JSON dello schema Form.io                           |

**Come costruire lo schema:**

Il backoffice del Tenant Manager include un editor Form.io drag-and-drop per costruire lo schema visivamente senza scrivere JSON a mano.

> `[SCREENSHOT: Editor Form.io nel backoffice — interfaccia drag-and-drop per aggiungere campi]`

Linee guida per la definizione dei campi:

* Usa `key` stabili e in snake\_case (es. `endpoint_url`, `api_key`) — i workflow Windmill li usano come riferimento
* Marca come `required` solo i campi realmente obbligatori per il funzionamento dell'applicativo
* Raggruppa i campi correlati in pannelli Form.io per migliorare la leggibilità per il team delivery
* Per le credenziali sensibili, usa il tipo campo `password` per mascherarne la visualizzazione
* Testa lo schema compilando il form nella UI del Tenant Manager prima di renderlo disponibile al team delivery

**Versionamento dello schema:**

Se in futuro lo schema deve cambiare in modo incompatibile con le configurazioni esistenti, crea una nuova riga con `version` incrementata invece di sovrascrivere quella corrente. I tenant esistenti mantengono il riferimento alla versione con cui sono stati creati.

***

#### Passo 3 — Configurare le transizioni di stato

Per ogni transizione di stato che deve avviare un workflow Windmill, aggiungi una riga nella collezione `windmill_scripts`:

| Campo           | Descrizione                                | Esempio                                                 |
| --------------- | ------------------------------------------ | ------------------------------------------------------- |
| `app_name`      | Tipo di applicativo                        | `integrazione-atti-sicraweb`                            |
| `from_status`   | Stato di partenza                          | `activation_pending`                                    |
| `to_status`     | Stato target                               | `active`                                                |
| `windmill_path` | Path del workflow nel workspace `platform` | `f/tenant_manager/integrazione_atti_sicraweb_provision` |
| `kind`          | Tipo di operazione                         | `provision` / `deploy` / `archive` / `delete`           |

> `[SCREENSHOT: Backoffice PocketBase — collezione` windmill\_scripts `con le righe di un applicativo esistente come riferimento]`

Non tutte le transizioni devono necessariamente avere un workflow associato. Se per una certa transizione non è richiesta alcuna automazione infrastrutturale, lascia la transizione senza riga corrispondente: il Tenant Manager avanzerà lo stato direttamente.

***

#### Passo 4 — Scrivere i workflow Windmill

I workflow vanno aggiunti nel repository `opencity-labs/integrations/windmill`, nel workspace `platform`.

**Convenzione di naming:**

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

Esempi:

```
f/tenant_manager/integrazione_atti_sicraweb_provision
f/tenant_manager/integrazione_atti_sicraweb_deploy
f/tenant_manager/integrazione_atti_sicraweb_archive
```

**Parametri in ingresso:**

Il Tenant Manager passa automaticamente al workflow i seguenti parametri:

```typescript
{
  tenant_id: string,        // UUID del tenant
  app_name: string,         // tipo di applicativo
  app_id: string,           // slug dell'applicativo
  customer: string,         // nome del cliente
  cluster: string,          // cluster di destinazione
  environment: string,      // "qa" o "prod"
  from_status: string,      // stato corrente
  to_status: string,        // stato target
  config: Record<string, any>, // tutti i campi del form di configurazione
  callback_url: string      // URL pre-autenticato per finalizzare la transizione
}
```

I campi in `config` corrispondono esattamente alle `key` definite nello schema Form.io.

**Struttura consigliata di un workflow:**

```
1. Leggi i parametri in ingresso (incluso callback_url)
2. Esegui le operazioni infrastrutturali
   (crea DB, bucket S3, deploy stack, configura risorse, ecc.)
3. In caso di errore: gestisci e termina con errore
   (la callback NON viene chiamata → il tenant rimane in stato transitorio
    per permettere il debug)
4. Chiama il subflow condiviso per finalizzare la transizione
```

**Subflow condiviso per la callback:**

Non reimplementare la logica di callback. Alla fine del workflow, chiama:

```
f/tenant_manager/finalize_transition
```

passandogli `callback_url` e lo stato target. Questo subflow si occupa di:

* Chiamare il Tenant Manager via API
* Avanzare il tenant allo stato target
* Liberare lo stato transitorio

**Workflow multi-tenant (pattern orchestratore):**

Per i workflow che devono operare su tutti i tenant attivi di un tipo (es. sincronizzazione periodica), usa il pattern orchestratore:

```typescript
// 1. Query al Tenant Manager per ottenere i tenant attivi
const tenants = await fetch(
  `${TM_URL}/api/collections/tenants/records` +
  `?filter=(app_name='${APP_NAME}'&&status='production')`
)

// 2. Per ciascun tenant, avvia il workflow di integrazione
for (const tenant of tenants.items) {
  await runFlow('f/integrations/<app>_sync', {
    config: tenant.config,
    tenant_id: tenant.id,
    ...
  })
}
```

Questo elimina la necessità di hardcodare la lista dei tenant nel workflow.

***

#### Passo 5 — Test e promozione in produzione

1. Fai merge del workflow nel branch `develop` del repo `windmill platform` → viene deployato automaticamente su Windmill QA
2. Crea un tenant di test nel TM QA con il nuovo applicativo
3. Percorri l'intero ciclo di vita: crea → attiva → configura → metti in produzione → archivia
4. Verifica che ogni transizione completi correttamente e che il tenant avanzi allo stato atteso
5. Verifica i log del job Windmill per ogni transizione
6. Se tutti i test passano, fai merge su `main` → promozione a Windmill Produzione

> **Prima di rendere disponibile il nuovo applicativo al team delivery**, assicurati che:
>
> * Lo schema Form.io sia completo e validato
> * Tutte le transizioni previste abbiano il workflow corrispondente o siano esplicitamente documentate come manuali
> * Il team delivery abbia una scheda nella sezione [Applicativi supportati](/manuali/manuale-operativo-interno/tenant-manager/applicativi-supportati.md) aggiornata con i campi di configurazione richiesti
