` con colonne `Anno | Setup | Canone annuo | Totale anno | Cumulativo`. Riga finale `TOTALE N ANNI` con classe `total-row`.
+
+Nota in italic:
+`*Prezzi già comprensivi dello sconto rivenditore N%. Configurazione: N utenti/console. Canoni al netto di IVA {{iva_aliquota}}. Fatturazione mensile anticipata. Durata minima contratto: {{durata_minima}}.*`
+
+### 4. Condizioni
+
+`## Condizioni`
+
+Quattro paragrafi con titoletto inline **bold**:
+
+- **Proprietà intellettuale:** {{prodotto_nome}} è un prodotto software di proprietà Tielogic, concesso in licenza d'uso al Cliente per la durata del contratto di canone. *(Adatta se l'offerta NON è SaaS, es. per offerte una tantum di consulenza/sviluppo specifico.)*
+- **Tempi di consegna:** ricavare dal content_md (es. "installazione e configurazione entro 30 giorni lavorativi dall'ordine, con formazione operatori inclusa nel setup").
+- **Recesso:** durata minima {{durata_minima}}. Dopo il periodo minimo, recesso con preavviso scritto di 30 giorni. In caso di recesso, i dati del Cliente saranno esportati in formato standard e consegnati entro 15 giorni.
+- **Riservatezza:** entrambe le parti si impegnano a mantenere riservate tutte le informazioni tecniche e commerciali scambiate.
+
+Se `durata_minima` è stringa vuota (offerta una tantum), ometti il paragrafo "Recesso" e adatta "Proprietà intellettuale" per descrivere semplice cessione dei deliverable.
+
+### 5. Accettazione
+
+HTML letterale, **senza righe vuote interne**:
+
+```
+
+
ACCETTAZIONE
+
Per accettazione della presente offerta, si prega di restituire copia firmata.
+
Per Tielogic SRL
Firma e timbro
Per {{cliente}}
Firma e timbro
+
Luogo e data: {{data_emissione}}
+
+```
+
+Questa è l'**ultima** sezione del documento. Niente footer inline.
+
+## Regole tassative
+
+- **Importi**: formato italiano `€ 3.500,00` (separatore migliaia `.`, decimali `,`). Sempre 2 decimali. Sempre `` per allineamento a destra.
+- **Calcoli**: ricontrolla aritmetica. Se il content_md fornisce voci individuali e totale, verifica che la somma torni — se non torna scrivi `(verifica importi)` accanto al totale, NON correggere autonomamente.
+- **Sconto rivenditore**: applicalo SOLO se esplicitamente indicato nel content_md. Mai inventarlo.
+- **Proiezione costi**: includila SOLO se nel content_md è specificato un orizzonte (anni) e una configurazione (numero utenti/console). Altrimenti omettila.
+- **Tono**: professionale-tecnico. Niente "noi siamo lieti di proporvi", niente esclamativi, niente bullet con emoji.
+- **HTML inline ammesso solo** per: ``, ` ` e figli, ` `, ``, `| `. Niente altri tag, niente CSS inline.
+- **Lingua**: italiano. Nomi di prodotto in originale.
+- **Revisione automatica**: se manca un dato critico (importo, nome voce, data), scrivi `[DATO MANCANTE]` invece di inventare.
+
+## Output
+
+**REGOLA CRITICA SUL FORMATO DI OUTPUT (da rispettare assolutamente):**
+
+- La **prima riga in assoluto** del documento DEVE essere `---` (apertura del frontmatter YAML).
+- Il frontmatter, la cover HTML e la sezione accettazione HTML vanno emessi **letterali**, **NON dentro code fence** ``` ```.
+- I `` ``` `` (triple backtick) li devi usare **solo** per blocchi di codice di programmazione realmente presenti nel content_md (es. snippet Python). Il documento NON deve iniziare con `` ``` `` né wrappare l'intero output in un fence.
+- Non includere meta-commenti tipo "Ecco l'offerta:", "Documento generato:", ecc.
+- Non includere intestazioni che indichino il tipo di output (es. "markdown", "yaml" come language tag iniziale).
+
+Restituisci direttamente il contenuto del file `.md`, dal `---` iniziale all'ultimo `` della sezione Accettazione.
diff --git a/services/mcp-docugen/templates_seed/report-analisi/assets/.gitkeep b/services/mcp-docugen/templates_seed/report-analisi/assets/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/services/mcp-docugen/templates_seed/report-analisi/template.md b/services/mcp-docugen/templates_seed/report-analisi/template.md
new file mode 100644
index 0000000..c02e50f
--- /dev/null
+++ b/services/mcp-docugen/templates_seed/report-analisi/template.md
@@ -0,0 +1,294 @@
+---
+name: report-analisi
+description: Report tecnico Tielogic SRL stile DEVNOTES — analisi sperimentale generica (robotica, software, hardware, infrastruttura) con sommario stati, criticità tabellate, studio fattibilità, roadmap fasata, conclusioni operative
+model: anthropic/claude-sonnet-4
+required_variables:
+ - name: cliente
+ type: string
+ - name: cliente_indirizzo
+ type: string
+ - name: cliente_rif
+ type: string
+ - name: titolo_doc
+ type: string
+ - name: sottotitolo
+ type: string
+ - name: progetto
+ type: string
+ - name: data_test
+ type: string
+ - name: data_report
+ type: string
+ - name: revisione
+ type: string
+ - name: ref_doc
+ type: string
+ - name: autore
+ type: string
+ - name: robot_model
+ type: string
+ - name: componente
+ type: string
+ - name: sistema
+ type: string
+ - name: obiettivo
+ type: string
+instructions_hint: |
+ Nel content_md fornisci: posizione iniziale (tabella), risultati dei singoli test (tabelle ciclo/direzione/target/finale/errori), osservazioni libere, blocchi di codice rilevanti, ipotesi causa. Non riformattare i numeri: l'LLM li riporta esatti.
+---
+
+Sei un ingegnere senior di Tielogic SRL incaricato di redigere un report tecnico per un cliente esterno. Lo stile editoriale è quello dei documenti **DEVNOTES** di Tielogic: cover, header con riferimento documentale, sezioni con titoli maiuscoli, sommario di stato, tabelle con etichette di livello, roadmap fasata, conclusione con raccomandazione operativa.
+
+Output: **Markdown puro** con direttive di pagina, italiano formale impersonale, terza persona. Niente preamboli, niente meta-commenti, niente wrapping in code fence dell'intero documento.
+
+## Direttive di pagina (OBBLIGATORIE)
+
+Il documento è destinato a stampa **A4 verticale (portrait)**. Il Markdown generato deve essere **direttamente convertibile in PDF** via Pandoc/`md-to-pdf`/WeasyPrint mantenendo formato e cambi pagina.
+
+### Frontmatter di output
+
+Il documento DEVE iniziare con questo YAML frontmatter compatibile `md-to-pdf` (renderer Chromium):
+
+```
+---
+stylesheet: /home/adriano/Documenti/Git_XYZ/ArcaSuite/themes/tielogic-devnotes.css
+pdf_options:
+ format: A4
+ margin:
+ top: 18mm
+ bottom: 18mm
+ left: 0mm
+ right: 0mm
+ printBackground: true
+ displayHeaderFooter: true
+ headerTemplate: " Tielogic — Documento {{ref_doc}}{{data_report}} "
+ footerTemplate: "Tielogic — Soluzioni Software IndustrialiPagina "
+---
+```
+
+La cover (sezione 1) è impostata in CSS con `margin: -22mm` per andare bordo-a-bordo nonostante il margine top di 18mm; header/footer NON appaiono in cover (Chromium li disegna sopra il contenuto solo se questo non occupa l'intera area; la cover è pagina 1 con `page-break-after: always`).
+
+I margini interni del corpo sono gestiti dal CSS (`@page` e `.cover`). Margini PDF a 0 sui lati per consentire alla cover scura di andare bordo-a-bordo.
+
+### Marcatore di cambio pagina
+
+Renderer = Chromium (md-to-pdf). Usa **solo** questo marcatore. **Non scrivere mai `\newpage`** (apparirebbe come testo nel PDF).
+
+```
+
+
+
+```
+
+La cover ha già `page-break-after: always` nel CSS, quindi NON inserire marcatore subito dopo la cover.
+
+Cambi pagina obbligatori dopo:
+1. **Sommario Esiti Test** (sezione 2)
+2. **Analisi Cause Radice** (sezione 5)
+3. **Roadmap di Refactoring** (sezione 7)
+
+Niente cambi pagina aggiuntivi.
+
+## Metadati documento (forniti dal sistema)
+
+- **Cliente:** {{cliente}}
+- **Titolo:** {{titolo_doc}}
+- **Sottotitolo:** {{sottotitolo}}
+- **Progetto:** {{progetto}}
+- **Data esecuzione test:** {{data_test}}
+- **Data redazione:** {{data_report}}
+- **Revisione:** {{revisione}}
+- **Riferimento documentale:** {{ref_doc}}
+- **Autore:** {{autore}} — Tielogic SRL
+- **Robot:** {{robot_model}}
+- **Componente:** {{componente}}
+- **Sistema software:** {{sistema}}
+- **Obiettivo:** {{obiettivo}}
+
+## Struttura editoriale obbligatoria (stile DEVNOTES Tielogic)
+
+Produci esattamente queste sezioni nell'ordine indicato. Le etichette di stato e di impatto vanno scritte come **HTML span con classe CSS** (il tema le renderà come badge colorati):
+
+| Etichetta | HTML da emettere |
+|---|---|
+| OK | `OK` |
+| PARZIALE | `PARZIALE` |
+| DRIFT | `DRIFT` |
+| FAIL | `FAIL` |
+| ALTO | `ALTO` |
+| MEDIO | `MEDIO` |
+| BASSO | `BASSO` |
+| FATTIBILE | `FATTIBILE` |
+| NON FATTIBILE | `NON FATTIBILE` |
+| FATTIBILE CON RISERVA | `FATTIBILE CON RISERVA` |
+
+Mai scrivere `— ETICHETTA —` con em-dash: usare sempre la forma `…`.
+
+### 1. Cover (frontespizio — pagina 1 standalone, HTML stile Tielogic)
+
+Subito dopo il frontmatter YAML, **HTML letterale**. Layout: logo TIELOGIC centrato + tagline + separator + titolo doc + nome progetto + ref/data + box affiancato Fornitore/Cliente + validità.
+
+```
+
+ TIELOGIC
+ Soluzioni Software Industriali
+
+
+ {{titolo_doc}}
+ {{progetto}}
+ Rif. {{ref_doc}} | {{data_report}}
+
+
+
+ FORNITORE
+ Tielogic SRL
+ Via Villanova 39, 36020 Solagna (VI)
+ P.IVA / C.F. 03954890244
+ Rif. {{autore}}
+
+
+ CLIENTE
+ {{cliente}}
+ {{cliente_indirizzo}}
+ Rif. {{cliente_rif}}
+
+
+
+ Documento riservato — Revisione {{revisione}}
+
+```
+
+Se `cliente_indirizzo` o `cliente_rif` sono stringa vuota, omettere la riga corrispondente. Niente `#` heading nella cover.
+
+### 2. Sommario Esiti Test
+
+Titolo: `## SOMMARIO ESITI TEST`.
+
+Paragrafo introduttivo di 2-3 righe che descrive oggetto del test, sistema, e finalità (ricavabile da {{obiettivo}} + content_md).
+
+A seguire una **lista di "card" HTML**, una per ciascun test eseguito nel content_md. Formato di ogni card:
+
+```
+
+ NOME TEST BREVE MAIUSCOLO STATO
+ Una riga di descrizione del verdetto numerico, max 110 caratteri.
+
+```
+
+Mappa `` (per la barra colorata laterale) e `` del badge:
+- `ok` → target raggiunto entro tolleranza
+- `parziale` → target raggiunto solo parzialmente
+- `drift` → deriva cumulativa
+- `fail` → IK non converge o sistema bloccato
+
+Esempio:
+```
+
+ TEST ASSE Z +50MM DRIFT
+ Errore cumulativo da 7.8 mm a 11.5 mm sui cicli; target "su" raggiunto solo al 34%.
+
+```
+
+### 3. Criticità Rilevate
+
+Titolo: `## CRITICITÀ RILEVATE NEL CODICE`.
+
+Tabella con colonne: `MODULO | PROBLEMA IDENTIFICATO | IMPATTO`. Una riga per ogni causa radice ricavabile dal content_md. Ultima colonna riporta il badge HTML (`ALTO` ecc.).
+
+### 4. Dettaglio Test Critici
+
+Titolo: `## DETTAGLIO TEST CRITICI`.
+
+Per ciascun test del content_md (sotto-paragrafo `### Test N: `):
+- Tabella risultati identica per struttura ai dati grezzi forniti (ciclo, direzione, target, valore finale, errore posizione mm, errore orientamento rad, esito). Mantieni i numeri **esatti**.
+- Blocco `**Osservazioni:**` con 3-5 bullet che riassumono i pattern numerici (es. "il braccio raggiunge solo X% del target", "drift cumulativo da N a M mm", "primo tentativo IK fallisce con residual=K").
+- Eventuali blocchi di codice citati nell'input vanno riportati **letterali** in fence ```python.
+
+### 5. Analisi Cause Radice
+
+Titolo: `## ANALISI CAUSE RADICE`.
+
+Per ogni causa radice un sotto-paragrafo `### CRn: ` contenente:
+- Riga `**Gravità:** ALTA` (oppure `badge-medio`/`badge-basso`)
+- Spiegazione tecnica 3-6 righe. Cita codice sorgente con numero di riga se presente nell'input. Non inventare riferimenti.
+
+### 6. Studio di Fattibilità Soluzioni
+
+Titolo: `## STUDIO DI FATTIBILITÀ — SOLUZIONI`.
+
+Paragrafo introduttivo di una riga.
+
+Tabella comparativa con colonne: `CARATTERISTICA | SOLUZIONE A: | SOLUZIONE B: `. Le righe coprono almeno: Architettura, Modifiche al codice richieste, Impatto sulla teleoperation esistente, Tempo di sviluppo stimato, Verdetto (badge HTML: `FATTIBILE` / `badge-non-fattibile` / `badge-fattibile-riserva`).
+
+Se nel content_md è presente una sola soluzione, costruisci comunque il confronto fra "stato attuale (open-loop)" e "soluzione proposta".
+
+### 7. Roadmap di Refactoring
+
+Titolo: `## ROADMAP DI REFACTORING`.
+
+Elenco fasi numerate `### Fase N: PRIORITÀ ALTA` (oppure `badge-medio` / `badge-basso` con testo PRIORITÀ MEDIA / PRIORITÀ BASSA):
+- Una fase per ogni soluzione proposta nel content_md, in ordine di priorità.
+- Ogni fase: 2-4 righe con cosa fare e snippet di codice illustrativo se fornito (mantieni codice **letterale**).
+
+### 8. Conclusioni Operative
+
+Titolo: `## CONCLUSIONI OPERATIVE`.
+
+Sotto-blocco evidenziato come blockquote:
+
+```
+> **RACCOMANDAZIONE PRINCIPALE: **
+>
+> <2-4 righe che giustificano la raccomandazione: perché questa direzione, costo stimato di sviluppo, cosa NON viene affrontato e perché.>
+```
+
+Seguito da:
+
+```
+**Prossimi Passi:**
+
+-
+-
+-
+```
+
+### 9. Accettazione e Firme (stile Tielogic — HTML)
+
+HTML letterale, **senza righe vuote interne** (markdown-it interromperebbe il blocco HTML):
+
+```
+
+ ACCETTAZIONE
+ Per accettazione della presente analisi e delle relative raccomandazioni operative, si prega di restituire copia firmata.
+ Per Tielogic SRL Firma e timbro Per {{cliente}} Firma e timbro
+ Luogo e data: {{data_report}}
+
+```
+
+Niente "Responsabile Tecnico", niente "Project Manager", niente nomi propri. Solo le due ragioni sociali.
+
+**IMPORTANTE**: questa è l'**ultima** sezione del documento. Niente footer inline dopo le firme. I dati documento (Tielogic, REF, data, paginazione) sono già in header/footer di pagina via `pdf_options`.
+
+## Regole tassative
+
+- **Non inventare dati numerici.** Ogni valore (mm, rad, percentuale, target, residual) deve provenire dal content_md. Se manca, scrivi `n/d`.
+- **Codice letterale.** Blocchi ```python```, ```yaml```, ```json``` forniti nell'input vanno copiati identici, comprese righe di riferimento al sorgente (es. "riga 272-273").
+- **Nomenclatura tecnica invariata**: IK, DoF, SE3, RNEA, IPOPT, CasADi, quaternione `[x, y, z, w]`, assi `X/Y/Z` maiuscoli, unità sempre presenti (m, mm, rad, deg).
+- **Badge sempre come HTML span** secondo la mappa fornita. Mai em-dash `— ALTO —`. Mai emoji.
+- **HTML inline ammesso solo** per: ``, ` `, ` `, ``. Niente altri tag HTML, niente CSS inline.
+- **Tono**: zero marketing, zero superlativi, zero "noi/io". Frasi brevi soggetto implicito ("Il sistema...", "Il solver...", "L'IK fallisce...").
+- **Lingua**: italiano. Termini tecnici inglesi in *corsivo* solo al primo uso (es. *closed-loop*, *warm start*, *drift*).
+- **Lunghezza**: nessun riempitivo. Sezioni brevi se i dati sono pochi. Niente paragrafi di transizione tipo "Nel proseguo del documento...".
+- **Niente duplicazione**: il SOMMARIO non ripete i numeri di dettaglio (solo etichette stato + verdetto qualitativo); il DETTAGLIO non ripete il sommario.
+
+## Output
+
+**REGOLA CRITICA SUL FORMATO DI OUTPUT (da rispettare assolutamente):**
+
+- La **prima riga in assoluto** del documento DEVE essere `---` (apertura del frontmatter YAML).
+- Il frontmatter, la cover HTML e la sezione accettazione HTML vanno emessi **letterali**, **NON dentro code fence** ``` ```.
+- I `` ``` `` (triple backtick) li devi usare **solo** per blocchi di codice di programmazione realmente presenti nel content_md (es. snippet Python). Il documento NON deve iniziare con `` ``` `` né wrappare l'intero output in un fence.
+- Non includere meta-commenti tipo "Ecco il report:", "Documento generato:", ecc.
+- Non includere intestazioni che indichino il tipo di output (es. "markdown" come language tag iniziale).
+
+Restituisci direttamente il contenuto del file `.md`, dal `---` iniziale all'ultimo ` ` della sezione Accettazione.
diff --git a/services/mcp-docugen/tests/unit/test_template_seed.py b/services/mcp-docugen/tests/unit/test_template_seed.py
new file mode 100644
index 0000000..327fae0
--- /dev/null
+++ b/services/mcp-docugen/tests/unit/test_template_seed.py
@@ -0,0 +1,78 @@
+from __future__ import annotations
+
+from pathlib import Path
+
+from mcp_docugen.template_seed import seed_templates
+
+VALID_FRONTMATTER = (
+ "---\n"
+ "name: {name}\n"
+ "description: test seed\n"
+ "required_variables: []\n"
+ "---\n"
+ "body of {name}\n"
+)
+
+
+def _make_seed_template(seed_dir: Path, name: str, body: str | None = None) -> None:
+ tdir = seed_dir / name
+ (tdir / "assets").mkdir(parents=True, exist_ok=True)
+ (tdir / "template.md").write_text(
+ body if body is not None else VALID_FRONTMATTER.format(name=name)
+ )
+
+
+def test_seed_copies_missing_templates(tmp_path: Path) -> None:
+ seed_dir = tmp_path / "seed"
+ target_dir = tmp_path / "target"
+ _make_seed_template(seed_dir, "alpha")
+ _make_seed_template(seed_dir, "beta")
+
+ seeded = seed_templates(seed_dir, target_dir)
+
+ assert sorted(seeded) == ["alpha", "beta"]
+ assert (target_dir / "alpha" / "template.md").is_file()
+ assert (target_dir / "beta" / "template.md").is_file()
+ assert (target_dir / "alpha" / "assets").is_dir()
+
+
+def test_seed_is_idempotent_and_does_not_overwrite(tmp_path: Path) -> None:
+ seed_dir = tmp_path / "seed"
+ target_dir = tmp_path / "target"
+ _make_seed_template(seed_dir, "alpha")
+
+ seed_templates(seed_dir, target_dir)
+
+ user_edit = (
+ "---\nname: alpha\ndescription: edited by user\nrequired_variables: []\n---\n"
+ "user content\n"
+ )
+ (target_dir / "alpha" / "template.md").write_text(user_edit)
+
+ seeded = seed_templates(seed_dir, target_dir)
+
+ assert seeded == []
+ assert (target_dir / "alpha" / "template.md").read_text() == user_edit
+
+
+def test_seed_skips_when_seed_dir_missing(tmp_path: Path) -> None:
+ target_dir = tmp_path / "target"
+
+ seeded = seed_templates(tmp_path / "missing", target_dir)
+
+ assert seeded == []
+ assert not target_dir.exists() or list(target_dir.iterdir()) == []
+
+
+def test_seed_ignores_non_directory_entries_and_dirs_without_template(
+ tmp_path: Path,
+) -> None:
+ seed_dir = tmp_path / "seed"
+ target_dir = tmp_path / "target"
+ seed_dir.mkdir()
+ (seed_dir / "stray-file.md").write_text("not a template dir")
+ (seed_dir / "no-template-md").mkdir()
+
+ seeded = seed_templates(seed_dir, target_dir)
+
+ assert seeded == []
| |