# Sistema Documentale — Design Master > Sistema documentale multi-wiki (personale, aziendale, scalabile a N) come > vault Git di markdown, sincronizzato su Gitea (VPS), pubblicato in sola > lettura via Quartz, accessibile da desktop (Obsidian + Claude Code), > Android (Obsidian) e browser mobile, integrato con `mcp-docgen` per > documenti formali e predisposto per pipeline di ingest futura > (STT di riunioni, bot Telegram). --- ## Indice 1. [Panoramica e scopo](#1-panoramica-e-scopo) 2. [Componenti del sistema](#2-componenti-del-sistema) 3. [Struttura di un singolo wiki](#3-struttura-di-un-singolo-wiki) 4. [Configurazione multi-wiki](#4-configurazione-multi-wiki) 5. [Flusso Git end-to-end](#5-flusso-git-end-to-end) 6. [Integrazione con `mcp-docgen`](#6-integrazione-con-mcp-docgen) 7. [Pubblicazione web — Quartz multi-site](#7-pubblicazione-web--quartz-multi-site) 8. [Accesso da Android](#8-accesso-da-android) 9. [Storage degli asset binari](#9-storage-degli-asset-binari) 10. [Autenticazione e sicurezza](#10-autenticazione-e-sicurezza) 11. [Backup e disaster recovery](#11-backup-e-disaster-recovery) 12. [Setup iniziale — fasi implementative](#12-setup-iniziale--fasi-implementative) 13. [Estensioni future pianificate](#13-estensioni-future-pianificate) 14. [Decisioni e rationale](#14-decisioni-e-rationale) --- ## 1. Panoramica e scopo ### Cosa stiamo costruendo Un sistema documentale che: - **Archivia** documenti (relazioni, preventivi, note commercialista, idee, verbali riunione, ecc.) in più **wiki separati per dominio** (personale, aziendale, altri futuri) — tutti come file Markdown - **Versiona** ogni wiki in un **repo Git separato** su Gitea self-hosted (VPS) - **Pubblica** ogni wiki in sola lettura su **un sotto-dominio dedicato** (Quartz statico), con auth unificata - **Integra** un generatore di documenti formali (`mcp-docgen`, già progettato) condiviso da tutti i wiki - **Resta editabile** principalmente da desktop (Obsidian + Claude Code) e occasionalmente da Android (Obsidian mobile + Git plugin) - **È predisposto** per estensioni future di ingest automatico: trascrizione riunioni via STT, bot Telegram per note vocali/testuali inviate da mobile ### Principi cardine **Un wiki, un dominio, un repo, un ciclo di vita.** Wiki personale e wiki aziendale sono **fisicamente separati**: repo diversi, vault Obsidian diversi, siti Quartz diversi, asset separati, backup indipendenti. Una compromissione o un errore su uno non tocca l'altro. Un eventuale hand-off di un wiki (es. condivisione di `aziendale` con un collaboratore o commercialista) è possibile senza sforzo. **Pattern riusabile.** Tutti i wiki seguono la stessa struttura interna (sezione 3), la stessa convenzione di frontmatter, lo stesso workflow Git. Aggiungere un terzo wiki (`wiki-`) è una replica meccanica. **Infrastruttura condivisa.** Gitea, Quartz, nginx, Authelia, `mcp-docgen` sono servizi orizzontali usati da tutti i wiki. Una sola istanza di ciascuno. **Flat-file + Git + Claude Code + Obsidian.** Niente database applicativo nel percorso di produzione del contenuto. ### Cosa NON fa - Non è un DMS con workflow di approvazione / firma digitale integrata - Non sostituisce il gestionale contabile - Non fa OCR né ricerca semantica (eventualmente integrabili in futuro) - Non supporta edit concorrente multi-utente (un operatore, Adriano) - Non espone interfaccia di editing da browser (edit solo da Obsidian/Claude Code) --- ## 2. Componenti del sistema ### Mappa macro-componenti ``` ┌─────────────────────────────────────────────────────────────────────────┐ │ DESKTOP (questa macchina, Linux Ubuntu) │ │ │ │ /home/adriano/Documenti/Git_XYZ/Documentale/ │ │ │ │ ├─ wiki-personale/ ← vault locale (clone git Gitea) │ │ ├─ wiki-aziendale/ ← vault locale (clone git Gitea) │ │ ├─ wiki-/ ← futuri wiki, stessa struttura │ │ │ │ │ ├─ wiki-personale-assets/ ← binari fuori git, rsync → VPS │ │ ├─ wiki-aziendale-assets/ ← idem │ │ │ │ │ └─ mcp-docgen/ ← sorgente MCP server (repo separato) │ │ │ │ Strumenti: │ │ • Obsidian: un vault per ogni wiki (switch-vault funzione nativa) │ │ • Claude Code: opera su cartelle del wiki selezionato │ │ • Obsidian Git plugin: auto-push per ciascun vault │ │ • systemd timer: rsync asset → VPS │ └─────────────────────────────────────────────────────────────────────────┘ │ ▲ │ ▲ │ ▲ │ git │ │ git │ │ rsync │ ▼ │ ▼ │ ▼ │ ┌─────────────────────────────────────────────────────────────────────────┐ │ VPS Hostinger │ │ │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ Gitea (un'istanza, più repo) │ │ │ │ • adriano/wiki-personale.git + post-receive hook │ │ │ │ • adriano/wiki-aziendale.git + post-receive hook │ │ │ │ ↓ (hook → quartz build per ciascun wiki) │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ Quartz build pipeline (una config per wiki) │ │ │ │ /opt/quartz-personale/ → build → /var/www/personale/ │ │ │ │ /opt/quartz-aziendale/ → build → /var/www/aziendale/ │ │ │ └───────────────────────────────────────────────────────────────────┘ │ │ │ │ ┌─────────────────────┐ ┌─────────────────────┐ │ │ │ /var/www/assets/ │ │ mcp-docgen (Docker) │ │ │ │ ├─ personale/ │ │ condiviso tra wiki │ │ │ │ └─ aziendale/ │ │ FastMCP HTTP │ │ │ └─────────────────────┘ │ OpenRouter LLM │ │ │ └─────────────────────┘ │ │ │ │ ┌───────────────────────────────────────────────────────────────────┐ │ │ │ nginx + Authelia (SSO unico) │ │ │ │ personale. → /var/www/personale/ │ │ │ │ aziendale. → /var/www/aziendale/ │ │ │ │ ./assets/ → /var/www/assets// │ │ │ │ gitea. → Gitea web UI │ │ │ │ docgen. → mcp-docgen (solo API key, no SSO) │ │ │ └───────────────────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────────────────┘ ▲ │ HTTPS + SSO (TOTP 2FA) ┌─────────────────────────────────────────────────────────────────────────┐ │ MOBILE Android │ │ • Obsidian app + Git plugin → un vault per ciascun wiki │ │ • Chrome/Firefox → consultazione siti sotto-dominio │ └─────────────────────────────────────────────────────────────────────────┘ ``` ### Ruoli sintetici | Componente | Dove vive | Ruolo | Molteplicità | Stato | |---|---|---|---|---| | `wiki-/` | Desktop + Gitea VPS | Vault markdown versionato | **Per wiki** | Da creare | | `wiki--assets/` | Desktop + `/var/www/assets//` | Binari | **Per wiki** | Da creare | | `mcp-docgen` | VPS Docker | Generazione documenti formali | **Condiviso** | Design pronto | | Gitea | VPS | Git remote | Unica istanza, più repo | Da installare | | Quartz | VPS | SSG per wiki | **Un'istanza per wiki** (config + output separati) | Da configurare | | nginx | VPS | Reverse proxy | Unico | Da configurare | | Authelia | VPS | SSO 2FA | Unico | Da configurare | --- ## 3. Struttura di un singolo wiki Tutti i wiki (personale, aziendale, futuri) seguono **identica struttura interna**. Schema isomorfico a `Cerbero_Brain` (raw immutabile + wiki LLM-managed), esteso con `documents/` per output prodotti e `areas/` come MOC tematiche. ``` wiki-/ ├── CLAUDE.md # schema e regole del vault ├── README.md # intro human-readable ├── index.md # catalogo content-oriented ├── log.md # timeline append-only │ ├── raw/ # IMMUTABILE │ ├── comunicazioni_in/ # mail ricevute, PEC, lettere │ ├── documenti_ricevuti/ # markdown ricevuti, allegati testuali │ ├── notes/ # appunti grezzi, voice-to-text (manual) │ └── riunioni/ # trascrizioni riunioni grezze (STT futuro) │ └── wiki/ # LLM-managed ├── documents/ # documenti prodotti da Adriano │ ├── preventivi/ # (prevalente in wiki-aziendale) │ ├── relazioni/ │ ├── verbali_riunione/ # note sintetiche strutturate da raw/riunioni/ │ └── comunicazioni_out/ │ ├── entities/ # clienti, fornitori, persone, studi │ ├── concepts/ # procedure, template, framework │ ├── areas/ # MOC tematici │ └── syntheses/ # analisi trasversali ``` ### Contenuto tipico per wiki | Wiki | Contenuto prevalente | |---|---| | **wiki-personale** | Idee, note personali, journal, documentazione privata (salute, famiglia, viaggi), inventari personali, consapevolezza finanziaria personale (distinta da Milito/Cerbero) | | **wiki-aziendale** | Clienti, preventivi, relazioni, fatturazione, commercialista, fornitori, procedure aziendali, contratti, verbali riunione con clienti | ### Convenzioni comuni Frontmatter, naming, wikilink, log.md append-only, index content-oriented: **identici** per tutti i wiki. Vedi esempi completi in §5 e §6. Ogni wiki ha il **proprio `CLAUDE.md`** locale al suo root, che specifica: - Identità del wiki (es. "wiki personale di Adriano") - Dominio applicativo (cosa ci va, cosa non ci va) - Eventuali regole peculiari (es. wiki-aziendale richiede che ogni `documents/preventivi/` menzioni un `entities/cliente`) Claude Code, quando opera dentro un wiki, carica il suo `CLAUDE.md` contestuale (comportamento nativo). --- ## 4. Configurazione multi-wiki ### Registro dei wiki File di riferimento: `/home/adriano/Documenti/Git_XYZ/Documentale/wikis.yaml` ```yaml wikis: - name: personale local_path: wiki-personale assets_path: wiki-personale-assets remote: git@gitea.:adriano/wiki-personale.git publish_domain: personale. quartz_source: /opt/quartz-personale quartz_output: /var/www/personale vps_assets_path: /var/www/assets/personale - name: aziendale local_path: wiki-aziendale assets_path: wiki-aziendale-assets remote: git@gitea.:adriano/wiki-aziendale.git publish_domain: aziendale. quartz_source: /opt/quartz-aziendale quartz_output: /var/www/aziendale vps_assets_path: /var/www/assets/aziendale ``` Questo file è la **single source of truth** per scripting (sync, backup, provisioning nuovo wiki). ### Aggiungere un terzo wiki Procedura meccanica: 1. Aggiungi voce a `wikis.yaml` 2. `gitea` web UI → crea repo privato `adriano/wiki-` 3. Script di provisioning (da scrivere in Fase 2): `./tools/new-wiki.sh ` che: - Crea struttura cartelle locale - Inizializza git, primo commit, push - Installa plugin Obsidian Git nel nuovo vault - Crea config Quartz per il nuovo sotto-dominio - Aggiunge virtual host nginx + cert Let's Encrypt - Registra hook post-receive Gitea ### Scripting condiviso Gli script operativi (backup, sync asset, provisioning) iterano su `wikis.yaml`, zero duplicazione. --- ## 5. Flusso Git end-to-end ### Remote e branch - **Gitea self-hosted**: un server, più repo (uno per wiki) - **Branch unico `main`** per repo (no PR, uso personale) - **Commit strategy**: piccoli e frequenti, messaggi descrittivi (`doc(acme): preventivo v1`, `ingest: PEC 2026-04-15`, `refactor: split concepts/procedura-x`) ### Flusso desktop → Gitea (per ciascun wiki) 1. Edit markdown (Obsidian o Claude Code) nella cartella del wiki 2. **Obsidian Git plugin** in quel vault (configurato per-wiki): - Auto-commit + push ogni 10 min - Messaggio commit: `auto: {{date}}` 3. Gitea riceve push sul repo del wiki 4. Hook `post-receive` triggera **`quartz build` specifico di quel wiki** → `/var/www//` 5. nginx serve la nuova versione di `.` ### Flusso mobile Android → Gitea Per ciascun vault (un vault per wiki) su Obsidian mobile: 1. Apri vault → pull manuale (bottone Git plugin) 2. Edita 3. Commit & Push manuale ### Fallback systemd timer (desktop) Sotto `~/.config/systemd/user/`, un timer + service generici parametrizzati per-wiki: ```ini # vault-sync@.service (template unit) [Service] Type=oneshot WorkingDirectory=/home/adriano/Documenti/Git_XYZ/Documentale/%i ExecStart=/usr/bin/git add -A ExecStart=/bin/sh -c 'git diff --cached --quiet || git commit -m "auto: $(date -Iseconds)"' ExecStart=/usr/bin/git pull --rebase --autostash ExecStart=/usr/bin/git push ``` Abilita per wiki: `systemctl --user enable vault-sync@wiki-personale.timer`, `vault-sync@wiki-aziendale.timer`. ### Asset sync (per wiki) Un timer rsync per wiki: ```bash rsync -az --delete \ /home/adriano/Documenti/Git_XYZ/Documentale/wiki--assets/ \ adriano@vps:/var/www/assets// ``` Script unico che itera `wikis.yaml` e lancia rsync per ciascuno. --- ## 6. Integrazione con `mcp-docgen` `mcp-docgen` è **condiviso** tra tutti i wiki. Il template selezionato determina il formato; la destinazione di archiviazione la scegli (o la suggerisce Claude Code) al momento della generazione. ### Tool MCP | Tool | Uso | |---|---| | `template_create/update/delete/list/get` | Gestione template | | `document_generate` | Genera markdown formale | ### Configurazione Claude Code `~/.claude/.mcp.json`: ```json { "mcpServers": { "docgen": { "type": "http", "url": "https://docgen./mcp", "headers": { "Authorization": "Bearer " } } } } ``` ### Template iniziali (condivisi, taggati per wiki di provenienza tipica) | Template | Wiki tipico | Uso | |---|---|---| | `preventivo-commerciale` | aziendale | Preventivi clienti | | `relazione-audit` | aziendale | Relazioni tecniche | | `lettera-formale` | aziendale o personale | Comunicazioni ufficiali | | `nota-commercialista` | aziendale | Comunicazioni al commercialista | | `verbale-riunione` | aziendale | Verbali post-riunione (anche da STT futuro) | | `journal-entry` | personale | Entry diario personale strutturato | I template hanno `tags: [wiki:aziendale]` o `[wiki:personale]` nel frontmatter per filtrarli in `template_list`, ma nulla impedisce di usarli cross-wiki se serve. ### Flusso "draft → formal → archivio in wiki corretto" ``` 1. Adriano: "Prepara preventivo per Acme in wiki-aziendale" 2. Claude Code (contesto wiki-aziendale): a) Legge wiki-aziendale/wiki/entities/Acme_SRL.md b) Legge wiki-aziendale/wiki/concepts/Template_Preventivo.md c) Prepara bozza grezza d) Invoca mcp__docgen__document_generate: template = "preventivo-commerciale" content = bozza variables = {cliente: "Acme SRL", piva: "...", ...} e) Salva output in wiki-aziendale/wiki/documents/preventivi/YYYY-MM-DD_Acme_v1.md f) Aggiorna wiki-aziendale/wiki/entities/Acme_SRL.md (storico preventivi) g) Aggiorna wiki-aziendale/index.md e log.md 3. Adriano rivede in Obsidian (vault aziendale) 4. Finale → export PDF in wiki-aziendale-assets/clienti/Acme_SRL/ → aggiorna status: sent → rsync asset → VPS → Git auto-push → Quartz rebuild → visibile su aziendale. ``` ### Quando NON usare `mcp-docgen` - Note grezze, appunti, idee → markdown diretto - Ingest di materiale ricevuto (va in `raw/` as-is) - Template operativi interni (scritti manualmente in `concepts/`) --- ## 7. Pubblicazione web — Quartz multi-site ### Approccio **Un'istanza Quartz per wiki.** Stessa versione del codice sorgente Quartz, configurazione separata, output separato, sotto-dominio separato. ### Layout VPS ``` /opt/quartz-personale/ ├── quartz.config.ts # title: "Wiki Personale", baseUrl: "personale." ├── content/ # git checkout di wiki-personale (pull nel hook) └── ... /opt/quartz-aziendale/ ├── quartz.config.ts # title: "Wiki Aziendale", baseUrl: "aziendale." ├── content/ └── ... /var/www/personale/ # output Quartz personale /var/www/aziendale/ # output Quartz aziendale /var/www/assets/ ├── personale/ └── aziendale/ ``` ### Hook `post-receive` (per repo) ```bash #!/bin/bash # hooks/post-receive di wiki-.git set -e WIKI_NAME= WORKDIR=/opt/quartz-$WIKI_NAME cd $WORKDIR/content git pull --rebase cd $WORKDIR npx quartz build --output /var/www/$WIKI_NAME/ nginx -t && systemctl reload nginx ``` ### nginx per wiki Un virtual host per sotto-dominio: ```nginx server { listen 443 ssl http2; server_name personale.; include /etc/nginx/authelia-location.conf; location / { include /etc/nginx/authelia-authrequest.conf; root /var/www/personale; try_files $uri $uri/ $uri.html =404; } location /assets/ { include /etc/nginx/authelia-authrequest.conf; alias /var/www/assets/personale/; } ssl_certificate /etc/letsencrypt/live//fullchain.pem; ssl_certificate_key /etc/letsencrypt/live//privkey.pem; } # Stesso identico schema per aziendale., sostituendo "personale" con "aziendale" ``` ### CSS print condiviso Custom media-query `@media print` in un file `print.scss` copiato in entrambe le config Quartz, o mantenuto in un submodule Git condiviso. --- ## 8. Accesso da Android Consultazione (90%) via browser sui sotto-domini. Edit occasionale via Obsidian mobile con **un vault separato per wiki**. ### Obsidian mobile multi-vault Obsidian mobile supporta N vault. Ciascun vault è una cartella separata (che clona il repo Gitea del wiki corrispondente). Setup per wiki: 1. Aggiungi vault in Obsidian Android (crea cartella locale, es. `/storage/emulated/0/Obsidian/wiki-personale/`) 2. Installa community plugin "Obsidian Git" 3. Clone via plugin: URL `https://gitea./adriano/wiki-personale.git` + **token personale Gitea** (scope: repo read/write) 4. Configurazione plugin: - Auto-pull on load: on - Auto-push: off - Commit message: `mobile: {{date}}` Ripeti per `wiki-aziendale`. ### Switch vault Dalla home di Obsidian Android, icona a destra → lista vault → tap per switchare. Comodo e veloce. ### Limiti - Android non supporta sync in background → azione manuale pull/commit/push - Asset binari: via browser sotto-dominio, non Obsidian - Evitare edit contemporaneo mobile vs desktop (pull sempre prima di editare) --- ## 9. Storage degli asset binari ### Struttura per wiki (identica) ``` wiki--assets/ ├── clienti/ # (prevalente in aziendale) ├── commercialista/ # (prevalente in aziendale) ├── personale/ # (prevalente in personale) └── ... ``` ### Sync Systemd timer desktop, uno script, itera `wikis.yaml`: ```bash for wiki in $(yq e '.wikis[].name' wikis.yaml); do src="$HOME/Documenti/Git_XYZ/Documentale/wiki-$wiki-assets/" dst="adriano@vps:/var/www/assets/$wiki/" rsync -az --delete "$src" "$dst" done ``` ### Referenziazione dal markdown Link assoluto al sotto-dominio del wiki: ```markdown PDF firmato: [preventivo v1](https://aziendale./assets/clienti/Acme_SRL/2026-04-22_preventivo_v1_firmato.pdf) ``` --- ## 10. Autenticazione e sicurezza ### Authelia SSO condiviso **Una sola istanza Authelia** protegge tutti i sotto-domini dei wiki e gli asset: - `personale.`, `aziendale.`, `.` - Session cookie valido cross-subdomain (`Domain=`) - Utente unico `adriano` con TOTP 2FA (Aegis/Google Authenticator) - Una login per aprire qualsiasi wiki ### Eccezioni - `gitea.` → login Gitea separato (con 2FA) - `docgen.` → solo API key header, non per browser umano ### ACL per wiki Se in futuro vuoi dare accesso a `aziendale.` a un collaboratore senza dare accesso a `personale.`: Authelia configurable ACL: ```yaml access_control: rules: - domain: personale. policy: two_factor subject: "user:adriano" - domain: aziendale. policy: two_factor subject: ["user:adriano", "user:collaboratore"] ``` Nessun lavoro extra nell'architettura — feature already-there. ### TLS Let's Encrypt con cert SAN per tutti i sotto-domini, rinnovo automatico `certbot` + `systemd timer`. --- ## 11. Backup e disaster recovery ### Cosa salvare (per wiki) | Asset | Criticità | Strategia | |---|---|---| | Repo Git Gitea (per wiki) | **Alta** | Clone desktop + Gitea VPS + snapshot settimanale | | Asset binari (per wiki) | **Alta** (legale in aziendale) | Desktop + VPS + backup offsite weekly | | `mcp-docgen` template + SQLite | Media | Snapshot volume Docker | | Config VPS (nginx, Authelia, Quartz, Gitea) | Media | Repo `ops-vps` versionato | ### Strategia 3-2-1 (per wiki) Ogni wiki ha la sua catena 3-2-1 indipendente. Script che itera `wikis.yaml` su VPS: ```bash # systemd timer offsite-backup.timer, weekly for wiki in $(yq e '.wikis[].name' /etc/documentale/wikis.yaml); do rsync -az --delete \ /var/www/$wiki/ /var/www/assets/$wiki/ \ /var/opt/gitea/repositories/adriano/wiki-$wiki.git/ \ offsite:backups/documentale/$wiki/$(date +%Y-W%V)/ done ``` ### Retention differenziabile per wiki Potenzialmente (configurabile in `wikis.yaml`): - `aziendale`: retention 10+ anni (documentazione legale) - `personale`: retention 3 anni rotating (ok da revisione) Implementabile con policy distinte per destinazione offsite (non critico al MVP). ### DR procedure Documentata per ciascun wiki in `wiki-/wiki/concepts/DR_Procedure.md`. Procedura standard: 1. Repo perduto → clone da Gitea, riparti 2. Gitea VPS perduta → restore volume da offsite, repush da desktop 3. Tutto perduto → restore da offsite (perdita max 1 settimana) --- ## 12. Setup iniziale — fasi implementative **Strategia:** porta **un solo wiki** fino in fondo (pipeline completa funzionante) prima di clonare la configurazione per il secondo. Così validi il modello end-to-end, poi replichi. **Scelta del wiki pilota:** raccomando `wiki-aziendale` perché: - Ha esigenze più concrete e immediate (preventivi, commercialista) - Forza a testare `mcp-docgen` (template formali) - Il pattern è più impegnativo, quindi se funziona lì il personale è banale ### Fase 1 — `wiki-aziendale` locale funzionante **Deliverable:** vault locale usabile, Claude Code e Obsidian felici, commit git a repo locale. 1. Crea `Documentale/wikis.yaml` con solo `aziendale` 2. Crea struttura `wiki-aziendale/` (raw/ + wiki/{documents,entities,concepts,areas,syntheses}) 3. Scrivi `wiki-aziendale/CLAUDE.md` (regole wiki aziendale) 4. `README.md`, `index.md`, `log.md` iniziali 5. `git init` + primo commit 6. Crea `wiki-aziendale-assets/` 7. Apri in Obsidian come vault, verifica rendering 8. Documento di prova (cliente fittizio + preventivo prova) ### Fase 2 — Gitea su VPS + sync wiki-aziendale **Deliverable:** vault sincronizzato desktop ↔ Gitea. 1. Docker Gitea su VPS, `gitea.` (TLS) 2. Crea repo `adriano/wiki-aziendale` (privato) 3. SSH key desktop → Gitea, token mobile Gitea 4. `git remote add` dal desktop, primo push 5. Plugin Obsidian Git → configura auto-push 10 min 6. Test round-trip 7. Systemd timer fallback ### Fase 3 — `mcp-docgen` su VPS + integrazione Claude Code **Deliverable:** workflow "bozza → formale → archivio" in wiki-aziendale. 1. Implementa `mcp-docgen` (vedi suo design doc in `mcp-docgen/`) 2. Deploy Docker su `docgen.` 3. Aggiungi a `~/.claude/.mcp.json` 4. Crea template: `preventivo-commerciale`, `relazione-audit`, `lettera-formale`, `nota-commercialista`, `verbale-riunione` 5. Test end-to-end dal wiki-aziendale ### Fase 4 — Quartz + nginx + TLS per wiki-aziendale **Deliverable:** `aziendale.` consultabile via HTTPS (senza auth stringente ancora, o basic auth temporanea). 1. Node su VPS, clone Quartz in `/opt/quartz-aziendale/` 2. Config Quartz (title, baseUrl) 3. CSS print 4. Hook `post-receive` in `wiki-aziendale.git` → `quartz build` 5. nginx virtual host + cert Let's Encrypt 6. Test da browser desktop + mobile ### Fase 5 — Authelia SSO + protezione **Deliverable:** `aziendale.` privato, login con TOTP. 1. Docker Authelia su VPS 2. Utente `adriano` con password + TOTP 3. nginx `auth_request` per dominio wiki e `/assets/` 4. Verifica login desktop + mobile ### Fase 6 — Asset sync + backup offsite (wiki-aziendale) **Deliverable:** asset sync, backup 3-2-1 attivo. 1. Systemd timer rsync asset → VPS 2. nginx serve `/var/www/assets/aziendale/` (con auth) 3. Test link dai markdown 4. Backup offsite weekly (Hetzner Storagebox / B2) ### Fase 7 — Obsidian Android per wiki-aziendale **Deliverable:** edit mobile funzionante. 1. Obsidian app + plugin Obsidian Git 2. Clone repo via plugin, token Gitea 3. Test edit mobile → push → verifica desktop ### Fase 8 — Replica per `wiki-personale` **Deliverable:** secondo wiki operativo end-to-end. Usando script `tools/new-wiki.sh` (scritto in Fase 2 o qui): 1. Aggiungi `personale` a `wikis.yaml` 2. Crea struttura locale 3. Crea repo Gitea 4. Provisioning Quartz + nginx + cert (wildcard o nuova SAN) 5. Clone vault Obsidian desktop + mobile 6. Testa ciclo completo Replica banale — se Fasi 1-7 hanno validato il modello. --- ## 13. Estensioni future pianificate Funzionalità **non** implementate in Fasi 1-8 ma già predisposte nell'architettura. Vengono sviluppate in fasi successive con i propri design + implementation doc. ### 13.1 Pipeline STT — trascrizione riunioni **Scenario:** hai una riunione con cliente Acme, registri audio (Zoom, dittafono, registratore telefono). Vuoi che l'audio diventi automaticamente una bozza di verbale nel `wiki-aziendale`, pronta per revisione. **Architettura prevista:** ``` ┌─────────────────┐ ┌─────────────────┐ ┌──────────────────┐ │ Registrazione │ │ Upload a VPS │ │ STT service VPS │ │ (mobile, │─────▶│ (curl / web │─────▶│ (Whisper.cpp │ │ registratore, │ │ form / SFTP) │ │ faster-whisper │ │ Zoom export) │ │ │ │ Docker) │ └─────────────────┘ └─────────────────┘ └────────┬─────────┘ │ ▼ ┌─────────────────────────────────────────┐ │ Inbox Service (nuovo microservizio VPS)│ │ │ │ ├─ Riceve trascrizione grezza │ │ ├─ Normalizza a markdown + frontmatter │ │ │ (source: stt, target_wiki: ?) │ │ ├─ Salva in /var/lib/inbox/drafts/ │ │ └─ Espone API: │ │ GET /drafts │ │ GET /drafts/{id} │ │ DELETE /drafts/{id} (consume) │ └────────────────┬────────────────────────┘ │ ▼ ┌────────────────────────────────────────┐ │ Claude Code desktop │ │ (comando /ingest-inbox o cron locale) │ │ │ │ ├─ GET /drafts │ │ ├─ Per ciascun draft: │ │ │ • Identifica target wiki │ │ │ (euristica + conferma Adriano) │ │ │ • Eventuale mcp-docgen format │ │ │ con template verbale-riunione │ │ │ • Commit in wiki/ │ │ │ documents/verbali_riunione/ │ │ │ • DELETE /drafts/{id} │ │ └─ Push git │ └────────────────────────────────────────┘ ``` **Componenti nuovi da creare:** - **`stt-service`**: container Docker con `faster-whisper` o `whisper.cpp`, API FastAPI minimale (`POST /transcribe` con audio → text). Modello `large-v3` per italiano. - **`inbox-service`**: microservizio FastAPI che: - Riceve audio (multipart) o testo - Orchestra STT se audio - Salva draft markdown in `/var/lib/inbox/drafts/.md` - Espone API REST protetta da API key - **Claude Code skill `/ingest-inbox`**: comando che pollicia l'inbox, ingeriste nel wiki corretto con conferma utente **Predisposizione nell'architettura corrente:** - La cartella `raw/riunioni/` è **già prevista** nella struttura wiki (§3) - Il template `verbale-riunione` è **già previsto** tra i template iniziali `mcp-docgen` (§6) - nginx può ospitare `inbox.` a un sottodomino aggiuntivo (Authelia o API key) - Nessuna ristrutturazione necessaria quando arriva — è un'aggiunta pulita **Fase stimata:** Fase 9 dopo completamento di Fase 8 e uso reale per qualche settimana. ### 13.2 Bot Telegram — ingest da mobile **Scenario:** sei in giro, hai un'idea o vuoi registrare una nota vocale. Mandi messaggio (audio o testo) al tuo bot Telegram → finisce nel wiki corretto. **Architettura prevista:** ``` ┌─────────────┐ ┌─────────────────┐ ┌───────────────┐ │ Telegram │────────▶│ Bot Telegram │──────▶│ Inbox Service │ │ (tu, mobile│ message │ (python-tele- │ POST │ (stessa API │ │ vocale o │ │ gram-bot su │ │ di §13.1) │ │ testo) │ │ VPS Docker) │ └───────────────┘ └─────────────┘ └─────────────────┘ │ ▼ (stessa pipeline STT se audio, poi drafts/, poi Claude Code desktop ingerisce) ``` **Logica minima del bot:** - Riceve messaggio da chat autorizzata (whitelist per telegram ID) - Se audio → forward a `stt-service`, poi `inbox-service` - Se testo → forward diretto a `inbox-service` come markdown con `source: telegram` - Risponde a Adriano: "Draft creato: ID xxx, target wiki non specificato" - Opzionale: comandi slash tipo `/wiki aziendale` prima del messaggio per hint di targeting **Predisposizione nell'architettura corrente:** - È già disponibile il server MCP `cerbero-telegram` (vedi `~/.claude/.mcp.json` nel progetto Cerbero). Può essere riutilizzato o duplicato per questo uso, o si scrive un bot dedicato - `inbox-service` previsto in §13.1 è la colonna portante di entrambe le integrazioni - Nessuna ristrutturazione necessaria **Fase stimata:** Fase 10 dopo §13.1. ### 13.3 Principio comune Entrambe le estensioni seguono il pattern **"sorgente esterna → inbox VPS → Claude Code desktop ingerisce"**. Questo mantiene: - **Single point of ingest** — `inbox-service` è l'unico che parla col VPS per contenuti nuovi - **Claude Code resta autorevole** — decide target wiki, applica format, scrive il commit, mantiene coerenza - **Evita commit diretti al wiki da VPS** — la VPS non ha mai bisogno di scrivere nei repo (solo leggerli per Quartz build e Gitea) ### 13.4 Altre estensioni meno urgenti Tracciato qui per non dimenticarle: - **OCR automatico** di scansioni ricevute (Tesseract + preprocessing, spinge output in inbox) - **Ricerca semantica** del vault (integrazione con `claude-mem` o sistema embedding dedicato) - **Auto-export PDF** per ogni `wiki/documents/` con status `final` (tramite pandoc + template LaTeX/typst) - **Firma digitale** integrata in workflow preventivi (via CADES o firma semplice qualificata) - **Collaboratore** su `wiki-aziendale` (già supportato da ACL Authelia §10) --- ## 14. Decisioni e rationale ### Perché separazione forte (repo per wiki) - Separazione netta di ciclo di vita, backup, retention, ACL - Possibilità di hand-off di un wiki senza esporre l'altro - Un wiki rotto / corrotto non tocca gli altri - Tradeoff accettato: niente wikilink cross-wiki — si duplica volentieri quando un soggetto è davvero rilevante per entrambi ### Perché Quartz e non SilverBullet/Wiki.js - Nessun runtime app su VPS per il publish → zero superficie d'attacco extra - Wikilink Obsidian nativi + backlinks + graph - Velocità: pagine statiche - Tradeoff: no edit da browser — accettato perché edit è da Obsidian/Claude Code ### Perché asset fuori git - Git si gonfia con binari senza delta utili - rsync separato → repo leggero per sempre ### Perché Authelia SSO unificato - Una login per tutti i sotto-domini (cookie cross-subdomain) - 2FA nativo - ACL configurabili future (multi-utente parziale) ### Perché portare un wiki fino in fondo prima di replicare - Valida l'intero stack end-to-end (meno rischio) - Script di provisioning (`new-wiki.sh`) nasce dall'esperienza del primo setup - Replica in Fase 8 è meccanica ### Perché `inbox-service` come hub per STT e Telegram - Un solo endpoint normalizza l'ingest (API, storage, retention) - Ogni sorgente futura (email-to-wiki, web-clipper, ecc.) riutilizza lo stesso hub - Claude Code desktop resta il solo autorizzato a scrivere nei repo wiki ### Cose lasciate fuori scope (consapevolmente, MVP) - OCR automatico - Ricerca semantica / embeddings - Auto-export PDF - Firma digitale integrata - Workflow di approvazione multi-step - Multi-utente pieno --- ## Note finali Design **incrementale** e **decomponibile**: - Fase 1 sola → vault locale usabile (valore immediato) - Fasi 1-4 → vault sincronizzato + pubblicato - Fasi 1-7 → wiki-aziendale completo end-to-end - Fase 8 → secondo wiki operativo - Fase 9-10 → STT + Telegram (estensioni future) Ogni fase è stop accettabile. Ogni fase avrà il proprio implementation plan prodotto da **writing-plans** quando ci arriveremo. Cuore concettuale invariato: flat markdown + git + Claude Code + Obsidian + Quartz. Multi-wiki è replica di questo cuore, isolata per dominio. Estensioni future (STT, Telegram) sono aggiunte senza riarchitettura.