- Docs/sistema-documentale/: master architettura multi-wiki - Docs/docugen-mcp/: design + implementation plan MCP server Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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-docgenper documenti formali e predisposto per pipeline di ingest futura (STT di riunioni, bot Telegram).
Indice
- Panoramica e scopo
- Componenti del sistema
- Struttura di un singolo wiki
- Configurazione multi-wiki
- Flusso Git end-to-end
- Integrazione con
mcp-docgen - Pubblicazione web — Quartz multi-site
- Accesso da Android
- Storage degli asset binari
- Autenticazione e sicurezza
- Backup e disaster recovery
- Setup iniziale — fasi implementative
- Estensioni future pianificate
- 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 unentities/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:
- Aggiungi voce a
wikis.yaml giteaweb UI → crea repo privatoadriano/wiki-<nuovo>- 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
mainper 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)
- Edit markdown (Obsidian o Claude Code) nella cartella del wiki
- Obsidian Git plugin in quel vault (configurato per-wiki):
- Auto-commit + push ogni 10 min
- Messaggio commit:
auto: {{date}}
- Gitea riceve push sul repo del wiki
- Hook
post-receivetriggeraquartz buildspecifico di quel wiki →/var/www/<wiki>/ - nginx serve la nuova versione di
<wiki>.<dominio>
Flusso mobile Android → Gitea
Per ciascun vault (un vault per wiki) su Obsidian mobile:
- Apri vault → pull manuale (bottone Git plugin)
- Edita
- 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:
- Aggiungi vault in Obsidian Android (crea cartella locale, es.
/storage/emulated/0/Obsidian/wiki-personale/) - Installa community plugin "Obsidian Git"
- Clone via plugin: URL
https://gitea.<dominio>/adriano/wiki-personale.git+ token personale Gitea (scope: repo read/write) - 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
adrianocon 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:
- Repo perduto → clone da Gitea, riparti
- Gitea VPS perduta → restore volume da offsite, repush da desktop
- 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.
- Crea
Documentale/wikis.yamlcon soloaziendale - Crea struttura
wiki-aziendale/(raw/ + wiki/{documents,entities,concepts,areas,syntheses}) - Scrivi
wiki-aziendale/CLAUDE.md(regole wiki aziendale) README.md,index.md,log.mdinizialigit init+ primo commit- Crea
wiki-aziendale-assets/ - Apri in Obsidian come vault, verifica rendering
- Documento di prova (cliente fittizio + preventivo prova)
Fase 2 — Gitea su VPS + sync wiki-aziendale
Deliverable: vault sincronizzato desktop ↔ Gitea.
- Docker Gitea su VPS,
gitea.<dominio>(TLS) - Crea repo
adriano/wiki-aziendale(privato) - SSH key desktop → Gitea, token mobile Gitea
git remote adddal desktop, primo push- Plugin Obsidian Git → configura auto-push 10 min
- Test round-trip
- Systemd timer fallback
Fase 3 — mcp-docgen su VPS + integrazione Claude Code
Deliverable: workflow "bozza → formale → archivio" in wiki-aziendale.
- Implementa
mcp-docgen(vedi suo design doc inmcp-docgen/) - Deploy Docker su
docgen.<dominio> - Aggiungi a
~/.claude/.mcp.json - Crea template:
preventivo-commerciale,relazione-audit,lettera-formale,nota-commercialista,verbale-riunione - 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).
- Node su VPS, clone Quartz in
/opt/quartz-aziendale/ - Config Quartz (title, baseUrl)
- CSS print
- Hook
post-receiveinwiki-aziendale.git→quartz build - nginx virtual host + cert Let's Encrypt
- Test da browser desktop + mobile
Fase 5 — Authelia SSO + protezione
Deliverable: aziendale.<dominio> privato, login con TOTP.
- Docker Authelia su VPS
- Utente
adrianocon password + TOTP - nginx
auth_requestper dominio wiki e/assets/ - Verifica login desktop + mobile
Fase 6 — Asset sync + backup offsite (wiki-aziendale)
Deliverable: asset sync, backup 3-2-1 attivo.
- Systemd timer rsync asset → VPS
- nginx serve
/var/www/assets/aziendale/(con auth) - Test link dai markdown
- Backup offsite weekly (Hetzner Storagebox / B2)
Fase 7 — Obsidian Android per wiki-aziendale
Deliverable: edit mobile funzionante.
- Obsidian app + plugin Obsidian Git
- Clone repo via plugin, token Gitea
- 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):
- Aggiungi
personaleawikis.yaml - Crea struttura locale
- Crea repo Gitea
- Provisioning Quartz + nginx + cert (wildcard o nuova SAN)
- Clone vault Obsidian desktop + mobile
- 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 confaster-whisperowhisper.cpp, API FastAPI minimale (POST /transcribecon audio → text). Modellolarge-v3per 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 inizialimcp-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, poiinbox-service - Se testo → forward diretto a
inbox-servicecome markdown consource: telegram - Risponde a Adriano: "Draft creato: ID xxx, target wiki non specificato"
- Opzionale: comandi slash tipo
/wiki aziendaleprima del messaggio per hint di targeting
Predisposizione nell'architettura corrente:
- È già disponibile il server MCP
cerbero-telegram(vedi~/.claude/.mcp.jsonnel progetto Cerbero). Può essere riutilizzato o duplicato per questo uso, o si scrive un bot dedicato inbox-serviceprevisto 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-memo sistema embedding dedicato) - Auto-export PDF per ogni
wiki/documents/con statusfinal(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.