> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switchbord.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Architettura della Piattaforma

> Confini dei servizi, topologia del runtime e modello di deployment.

# Architettura della Piattaforma

Switchbord è distribuito come applicazione Next.js multi-tenant su Vercel, supportata da Supabase per persistenza, autenticazione e realtime, con un worker ospitato su Railway per l'elaborazione in background. Non esiste un servizio control-plane separato — quel percorso architetturale è stato ritirato e tutte le responsabilità di runtime sono state consolidate.

## Topologia

* **`apps/app`**: prodotto per l'operatore — inbox, contatti, template, campagne, Margaret AI, impostazioni. Distribuito su Vercel.
* **`apps/web`**: sito marketing, flussi QR/opt-in, landing page con accesso controllato. Distribuito su Vercel.
* **`apps/api`**: superficie API Next.js per l'ingress dei webhook Meta, API REST pubblica v1 (specifica OpenAPI su `/spec`), endpoint di compatibilità e route di health/status. Distribuito su Vercel.
* **`apps/docs`**: documentazione basata su Mintlify. Distribuito su Mintlify.
* **`apps/worker`**: elaborazione delle code, retry, scheduler delle campagne, dispatch dei messaggi, strumenti di replay. Distribuito su Railway.
* **Supabase**: Postgres, Auth, Storage, Realtime, Vault. Fonte unica di verità.

<Note>
  Il servizio `apps/control-plane` è stato rimosso. Tutto il lavoro control-plane orientato ai webhook ora viene eseguito all'interno di `apps/api` e `apps/worker`. Eventuali riferimenti locali alla porta 4000 o a `apps/control-plane/.env.example` sono artefatti legacy.
</Note>

## Percorsi Core del Runtime

1. **Webhook in entrata** — Meta invia un webhook a `apps/api` → firma verificata con `crypto.timingSafeEqual` → busta raw memorizzata in `webhook_events` → Supabase notifica `apps/worker` → il worker instrada verso il processore di messaggi, stato, template o journey.
2. **Invio in uscita** — L'operatore o un'automazione crea un intent di invio → Supabase registra su `outbox_jobs` → `apps/worker` pianifica in base ai limiti di throughput/coppia → la risposta di Meta viene registrata → i webhook di stato aggiornano il ledger.
3. **Broadcast** — Viene creato uno snapshot dell'audience → il worker distribuisce gli outbox job → Supabase Realtime spinge l'avanzamento della campagna alla dashboard dell'operatore.
4. **Margaret AI** — L'operatore attiva la bozza di risposta AI → `apps/app` chiama `/api/ai-assistant` → il provider LLM del workspace viene risolto da `llm_provider_configs` → i dati PII vengono pseudonimizzati prima di qualsiasi prompt → la risposta viene de-pseudonimizzata → la bozza viene mostrata nell'inbox. L'esecuzione tramite agent (BORD-140–143) aggiunge l'uso di strumenti (tool-use) al di sopra.

## Modello di Workspace Multi-Tenant

Ogni tenant è un **workspace** isolato. Le garanzie di isolamento fondamentali:

* Il contesto del workspace viene risolto lato server da `workspace_members` — non da variabili d'ambiente o header forniti dal client.
* Tutte le query sui dati sono ambitate (scoped) da `workspace_id` derivato da tale risoluzione.
* Il dispatch dei messaggi legge le credenziali Meta dai segreti Vault del workspace proprietario — nessuna fuoriuscita di credenziali tra workspace.
* Quattro ruoli RBAC applicati su ogni route: **owner**, **admin**, **developer**, **operator**.

Vedi [Multi-Tenancy e Isolamento dei Workspace](/it/security/multi-tenancy) per il modello di sicurezza completo.

## Livello Margaret AI

Il livello AI introduce tre nuove preoccupazioni di runtime:

* **Configurazioni provider LLM** — record posseduti dal workspace in `llm_provider_configs` che puntano a OpenAI, Anthropic, OpenRouter, Ollama o vLLM. Le chiavi API sono memorizzate in Supabase Vault tramite `workspace_secret_bindings`.
* **Agent AI** — la tabella `ai_agents` definisce persona, modello, permessi degli strumenti e impostazioni di pseudonimizzazione PII per workspace.
* **Thread AI** — `ai_threads` e `ai_thread_messages` mantengono il contesto di conversazione per le risposte di Margaret. `ai_agent_executions` registra le esecuzioni di tool-use per la tracciabilità (auditability).

## Registro dei Consensi (Consent Ledger)

Il registro dei consensi (BORD-193) fornisce un record durevole e verificabile di ogni evento di opt-in e opt-out per contatto:

* **Tabella `consent_events`** — log append-only delle transizioni di consenso (opt-in / opt-out / revocato). Un trigger `AFTER INSERT` su questa tabella denormalizza lo stato più recente in `contacts.consent_state` per letture rapide.
* **Rilevamento delle parole chiave STOP / START** — `packages/whatsapp` analizza i messaggi in entrata per le parole chiave localizzate di opt-out (`STOP`, `BLOQUEAR`, `FERMA`, `PARAR`) e opt-in (`START`, `INICIO`, `INIZIO`, `COMEÇAR`) in inglese, italiano, portoghese e spagnolo.
* **Gate opt-out del dispatch di campagna** — il motore di broadcast verifica `contacts.consent_state` prima di accodare qualsiasi outbox job. I contatti in stato `opted_out` o `revoked` vengono silenziosamente saltati.
* **Endpoint REST** — `GET /api/v1/contacts/:id/consent` restituisce lo stato attuale e la cronologia degli eventi; `POST /api/v1/contacts/:id/consent` registra una transizione di consenso manuale (solo owner/admin).

## Command Palette

La command palette (BORD-204) è una superficie ⌘K per la navigazione, la ricerca e le azioni nel prodotto per l'operatore:

* **`command-palette.tsx`** — il contenitore della palette, attivato da <kbd>⌘K</kbd> / <kbd>Ctrl+K</kbd>. Renderizza un elenco di comandi ricercabile raggruppato per categoria.
* **`command-palette-provider.tsx`** — contesto React che aggrega i comandi disponibili da ogni modulo (inbox, contatti, campagne, template, journey, impostazioni) e gestisce lo stato apertura/chiusura.
* **`command-palette-hint.tsx`** — badge di suggerimento inline mostrato nella sidebar e nelle intestazioni di pagina per scoprire la scorciatoia.

La palette è estensibile: qualsiasi modulo può registrare comandi tramite il hook `registerCommands` del provider.

## Editor Visivo dei Journey

Un canvas React Flow su `/journeys/[id]` per costruire automazioni multi-step in modo visivo:

* **9 tipi di nodo** — Trigger, Condition, Wait, Send Template, Update Attribute, Add/Remove Tag, Outbound Webhook, AI Agent Step, e Exit.
* **Validazione** — l'editor valida i campi obbligatori, la connettività degli edge e la rilevazione dei cicli prima della pubblicazione. Gli errori vengono mostrati inline su ogni nodo.
* **Pipeline di pubblicazione** — i grafi validati vengono serializzati nella tabella `journeys` come JSON versionato. Una mutation `publish` crea uno snapshot immutabile e attiva il journey per l'esecuzione live da parte di `apps/worker`.

## Costruttore Visivo di Template

Un builder a 3 pannelli su `/templates/new` per comporre template di messaggi WhatsApp:

* **7 editor** — Header, Body, Footer, Buttons, Examples, Language e Category.
* **Colonna `parameter_format`** — memorizzata su `message_templates` per dichiarare il tipo e l'ordine previsti delle variabili del template.
* **Pipeline di invio a Meta** — il builder invia (POST) il template composto alla Meta Business API e traccia lo stato di approvazione tramite i webhook di stato dei template.
* **Renderer a cornice telefono** — un componente di anteprima live rende il template come apparirebbe su un dispositivo, con sostituzione dei placeholder per le variabili.

## Agent con Auto-Trigger

L'agent con auto-trigger (BORD-192) estende Margaret AI per redigere automaticamente risposte sui messaggi WhatsApp in entrata:

* **Trigger di esecuzione dell'agent** — quando arriva un messaggio in entrata e il workspace ha configurato un agent con auto-trigger, `agent.run` viene invocato automaticamente dal worker.
* **API di accettazione/rifiuto della bozza** — `POST /api/v1/contacts/:id/drafts/:draftId/accept` e `POST /api/v1/contacts/:id/drafts/:draftId/reject` permettono agli operatori di approvare o scartare le bozze generate dall'AI.
* **Banner della bozza nell'inbox** — un banner prominente nella vista della conversazione avvisa gli operatori quando una bozza è in attesa, con azioni di accettazione/rifiuto a un clic.

## Storage degli Asset

Lo storage degli asset (BORD-187) fornisce upload di file ambitati per workspace per template, journey e asset di knowledge base:

* **Tabella `asset_files`** — registra i metadati del file (nome, tipo MIME, dimensione, ambito workspace) e punta all'oggetto memorizzato.
* **Pipeline compatibile con S3** — gli upload passano attraverso una pipeline con URL prefirmato verso qualsiasi object store compatibile con S3. Il worker recupera gli oggetti al momento del dispatch per gli invii di media.
* **Isolamento del workspace** — ogni file è ambitato da `workspace_id`; l'accesso cross-workspace viene rifiutato a livello di API.

## Alert sull'Account

Gli alert sull'account (BORD-189) mostrano agli operatori i problemi a livello di account Meta:

* **Handler del webhook** — `apps/api` elabora gli eventi webhook `account_alerts` di Meta e li memorizza in `account_alert_events`.
* **Pannello UI per l'operatore** — un pannello dedicato nelle impostazioni mostra gli alert attivi (ad es. violazioni delle policy, avvisi sui rate limit, scadenza delle credenziali) con gravità e passaggi di risoluzione.

## Log di Audit

I log di audit (BORD-158) registrano le azioni degli operatori per conformità e analisi forense:

* **Tabella `audit_logs`** — log append-only ambitato per workspace di attore, azione, risorsa di destinazione e payload diff.
* **`writeAuditLog()`** — un helper lato server che ogni route di mutazione chiama prima di eseguire il commit. Garantisce una struttura coerente e previene omissioni accidentali.

## Conservazione dei Dati GDPR

La conservazione dei dati GDPR (BORD-165 / BORD-167) applica limiti di conservazione per workspace:

* **`data_retention_days`** — un'impostazione a livello di workspace (default 365). Controlla per quanto tempo vengono conservate le buste dei webhook, il contenuto dei messaggi e gli eventi di consenso.
* **Job `retention_sweep`** — un job del worker pianificato che elimina i record più vecchi della finestra di conservazione del workspace. Viene eseguito giornalmente; registra le metriche di sweep in `audit_logs`.

## Generazione delle Chiavi API

La generazione delle chiavi API (BORD-178) consente ai proprietari del workspace di fornire chiavi API di lunga durata:

* **Chiavi con prefisso `swb_`** — generate lato server con un segreto casuale crittograficamente sicuro di 32 byte. Il prefisso consente un'identificazione visiva rapida e il rilevamento programmatico nei log.
* **Metadati della chiave** — memorizzati in `api_keys` con timestamp di creazione, timestamp di ultimo utilizzo e descrizione opzionale. Le chiavi sono sottoposte a hash a riposo; il segreto completo viene mostrato solo una volta alla creazione.

## Wizard Guidato

Il wizard guidato (BORD-194) fornisce un flusso di onboarding dal primo avvio al primo messaggio:

* **Sequenza di step** — collega il numero WhatsApp → configura il provider LLM → crea il primo template → invia il primo messaggio.
* **Tracciamento dell'avanzamento** — memorizzato in `workspace_onboarding_state`. Il wizard avanza automaticamente ed è ignorabile dopo il completamento.
* **Punto di ingresso** — i workspace appena creati vengono reindirizzati a `/welcome` al primo login. Il wizard è anche accessibile dalle Impostazioni.

## Primitive del Design System

Nuove primitive del design system rilasciate in `packages/design-system`:

* **Design token** — token semantici di colore, spaziatura e tipografia in `tokens.css`, utilizzati da tutti i componenti shadcn/ui.
* **Motion** — utility di transizione e animazione coerenti in `motion.ts` (durate, easing, preset di enter/exit).
* **Skeleton** — componente `Skeleton` con animazione pulse, utilizzato come placeholder di caricamento in tutto il prodotto per l'operatore.

## Aggiornamenti al Brand

* **Wordmark trasparente** — il logo della sidebar espansa ora utilizza un wordmark SVG con sfondo trasparente per un rendering pulito su qualsiasi superficie.
* **Favicon con sfondo nero** — `favicon.ico` aggiornato a una variante con sfondo nero per una maggiore visibilità nelle tab del browser.

## Principi di Dati e Sicurezza

* Ogni busta di webhook è immutabile; il corpo raw + i metadati vengono conservati con controlli di conservazione configurabili.
* La cronologia di consegna è append-only (`outbox_jobs`, `message_status_events`) — non viene mai sovrascritta.
* RBAC, feature flag e segreti del provider rimangono solo lato server.
* Topic Broadcast privati di Supabase Realtime alimentano i feed realtime dell'operatore; nessun broadcast di Postgres Changes per evitare problemi di scalabilità.
* Log di audit su ogni azione dell'operatore e rotazione delle credenziali.
* Il registro dei consensi applica l'opt-out prima di qualsiasi dispatch di campagna o automazione.
* Gli sweep di conservazione dei dati applicano le tempistiche di eliminazione GDPR per workspace.

Vedi [Panoramica sulla Sicurezza](/it/security/overview) per lo stato completo di implementazione dei controlli.

## UI Operatore — Sidebar e Navigazione

L'UI dell'operatore (`apps/app`) utilizza una sidebar costruita sulle primitive `Sidebar` di shadcn/ui.

### Componente

* **File**: `apps/app/components/operator-sidebar.tsx` (\~165 righe)
* **Pattern**: `collapsible='icon'` — si collassa in una barra solo icone; si espande al passaggio del mouse o al toggle. L'interfaccia delle prop è stabile.
* **Layout**: Ogni pagina che necessita della sidebar avvolge il proprio contenuto con `SidebarProvider`.

### Struttura di navigazione

* **Sezione superiore (nav piatta)**: Inbox / Contatti / Broadcast / Template / Operazioni
* **Sezione inferiore (footer)**: Impostazioni / Documentazione / Account utente

### Theming

La sidebar utilizza i valori predefiniti standard delle variabili CSS chiare di shadcn — non c'è un tema scuro personalizzato né `className='dark'` applicato all'elemento sidebar.

Variabili rilevanti (definite sotto `:root` in `packages/design-system/styles/globals.css`):

* `--sidebar`: sfondo quasi bianco
* `--sidebar-foreground`: testo quasi nero

Il tema scuro personalizzato quasi-nero della sidebar precedente alla PR #270 è stato rimosso. La sidebar ora eredita dai token standard del design system chiaro del workspace.

### Logo

* **Espanso**: wordmark completo
* **Collassato**: solo il marchio icona

## Monitoraggio + Deployment

* Endpoint di health: `/health`, `/ready`, `/internal/runtime`.
* Endpoint operativi: `/internal/webhooks`, `/internal/webhook-rejections`, `/internal/webhooks/:id/replay`.
* Specifica OpenAPI + explorer Scalar: `/spec`.
* Distribuisci `apps/app`, `apps/web`, `apps/api` e `apps/docs` su Vercel/Mintlify. Distribuisci `apps/worker` su Railway. Tutte le superfici condividono lo stesso progetto Supabase.
* La CI valida build, migrazioni, lint della documentazione e scansioni dei segreti. Vedi [CI/CD](/it/operations/cicd).

## Leggi anche

* [Panoramica sulla Sicurezza](/it/security/overview)
* [Multi-Tenancy e Isolamento dei Workspace](/it/security/multi-tenancy)
* [Modello dei Dati](/it/platform/data-model)
* [Matrice delle Funzionalità](/it/platform/feature-matrix)
* [Runbook Operativo](/it/operations/runbook)
