Files
ArcaSuite/docs/sistema-documentale.md
T
Adriano 7b169fb8db chore: organize repo as uv workspace multi-MCP monorepo
Layout stile CerberoSuite/Cerbero:
- services/ per MCP workspace members (futuri: mcp-docugen, mcp-convert, mcp-inbox)
- docs/ flat con design+implementation per componente
- scripts/, secrets/ placeholder
- pyproject.toml root (uv workspace vuoto + ruff + pytest)
- .gitignore, .env.example, .mcp.json.example, README.md

Rinominate le doc: Docs/<comp>/2026-04-21-*.md -> docs/<comp>-*.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:06:38 +02:00

39 KiB

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
  2. Componenti del sistema
  3. Struttura di un singolo wiki
  4. Configurazione multi-wiki
  5. Flusso Git end-to-end
  6. Integrazione con mcp-docgen
  7. Pubblicazione web — Quartz multi-site
  8. Accesso da Android
  9. Storage degli asset binari
  10. Autenticazione e sicurezza
  11. Backup e disaster recovery
  12. Setup iniziale — fasi implementative
  13. Estensioni future pianificate
  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-<nome>) è 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-<altro>/         ← 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.<dominio>    → /var/www/personale/                   │  │
│  │    aziendale.<dominio>    → /var/www/aziendale/                   │  │
│  │    <w>.<dominio>/assets/  → /var/www/assets/<w>/                  │  │
│  │    gitea.<dominio>        → Gitea web UI                          │  │
│  │    docgen.<dominio>       → 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-<nome>/ Desktop + Gitea VPS Vault markdown versionato Per wiki Da creare
wiki-<nome>-assets/ Desktop + /var/www/assets/<nome>/ 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-<nome>/
├── 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

wikis:
  - name: personale
    local_path: wiki-personale
    assets_path: wiki-personale-assets
    remote: git@gitea.<dominio>:adriano/wiki-personale.git
    publish_domain: personale.<dominio>
    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.<dominio>:adriano/wiki-aziendale.git
    publish_domain: aziendale.<dominio>
    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-<nuovo>
  3. Script di provisioning (da scrivere in Fase 2): ./tools/new-wiki.sh <nome> 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/<wiki>/
  5. nginx serve la nuova versione di <wiki>.<dominio>

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:

# 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:

rsync -az --delete \
  /home/adriano/Documenti/Git_XYZ/Documentale/wiki-<nome>-assets/ \
  adriano@vps:/var/www/assets/<nome>/

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:

{
  "mcpServers": {
    "docgen": {
      "type": "http",
      "url": "https://docgen.<dominio>/mcp",
      "headers": { "Authorization": "Bearer <API_KEY>" }
    }
  }
}

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.<dominio>

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.<dominio>"
  ├── content/             # git checkout di wiki-personale (pull nel hook)
  └── ...

/opt/quartz-aziendale/
  ├── quartz.config.ts     # title: "Wiki Aziendale", baseUrl: "aziendale.<dominio>"
  ├── content/
  └── ...

/var/www/personale/        # output Quartz personale
/var/www/aziendale/        # output Quartz aziendale
/var/www/assets/
  ├── personale/
  └── aziendale/

Hook post-receive (per repo)

#!/bin/bash
# hooks/post-receive di wiki-<nome>.git
set -e
WIKI_NAME=<nome>
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:

server {
    listen 443 ssl http2;
    server_name personale.<dominio>;

    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/<dominio>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<dominio>/privkey.pem;
}
# Stesso identico schema per aziendale.<dominio>, 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.<dominio>/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-<nome>-assets/
├── clienti/         # (prevalente in aziendale)
├── commercialista/  # (prevalente in aziendale)
├── personale/       # (prevalente in personale)
└── ...

Sync

Systemd timer desktop, uno script, itera wikis.yaml:

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:

PDF firmato: [preventivo v1](https://aziendale.<dominio>/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.<dominio>, aziendale.<dominio>, <nuovo>.<dominio>
  • Session cookie valido cross-subdomain (Domain=<dominio>)
  • Utente unico adriano con TOTP 2FA (Aegis/Google Authenticator)
  • Una login per aprire qualsiasi wiki

Eccezioni

  • gitea.<dominio> → login Gitea separato (con 2FA)
  • docgen.<dominio> → solo API key header, non per browser umano

ACL per wiki

Se in futuro vuoi dare accesso a aziendale.<dominio> a un collaboratore senza dare accesso a personale.<dominio>:

Authelia configurable ACL:

access_control:
  rules:
    - domain: personale.<dominio>
      policy: two_factor
      subject: "user:adriano"
    - domain: aziendale.<dominio>
      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:

# 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-<nome>/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.<dominio> (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.<dominio>
  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.<dominio> 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.gitquartz build
  5. nginx virtual host + cert Let's Encrypt
  6. Test da browser desktop + mobile

Fase 5 — Authelia SSO + protezione

Deliverable: aziendale.<dominio> 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/<uuid>.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.<dominio> 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 ingestinbox-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.