Status: OpenFatture 2.3.0 (TD04 credit notes + real CLI XML generation)
Last updated: 2026-09-11
Purpose: Comprehensive honest picture of layers, public surface, phased delivery, and remaining product decisions.
Related: ARCHITECTURE.md, STATUS.md, TECHNICAL_DEBT.md, CORE_VS_EXTENSIONS.md.
OpenFatture is a CLI-first, agentic application for Italian electronic invoicing. Domain operations run through application services; the assistant and CLI are thin adapters.
┌─────────────────────────────────────────┐
│ CLI commands + AI assistant tools │ ← Public surface adapters
├─────────────────────────────────────────┤
│ Application services │ ← billing, payment, sdi use-cases
│ (billing, payment, sdi, pdf, …) │
├─────────────────────────────────────────┤
│ Domain rules + events │ ← Models, enums, validation
├─────────────────────────────────────────┤
│ Infrastructure │ ← DB, PEC, files, bank importers
│ (storage, email, hooks, platform) │
└─────────────────────────────────────────┘
openfatture/
cli/ # Public adapter only; wires to application services
commands/
init.py
config.py
status.py
assistant.py
interactive.py
fattura.py # Invoice management CLI (list/show/create/add-line/generate-pdf/xml/set-status)
cliente.py # Client management CLI (list/show/create)
platform/ # Config, logging, email, validators, metrics, extras helpers
storage/ # SQLAlchemy models and sessions
events/ # Domain events bus and persistence
hooks/ # Hook registry and executor
billing/ # CORE: clienti, fatture, preventivi, prodotti, batch, fiscale
application/ # Commands (write) and queries (read)
clienti/
fatture/
preventivi/
prodotti/
batch/
fiscale/
sdi/ # CORE: FatturaPA XML, PEC, notifications, signature
xml_builder/
notifications/
pec/
signature/
payment/ # CORE: reconciliation and bank import (DDD layers)
application/
domain/
infrastructure/
pdf/ # CORE: human-readable invoice PDFs
ai/ # FEATURE EXTRA [ai]: assistant, tools, providers, RAG, ML
runtime.py
tools/
registry/
invoice_tools/
client_tools/
analytics_tools/
providers/
orchestration/
agents/
ml/
rag/
i18n/ # Locale strings (fluent-runtime)
cli may call application services and AI entrypoints only.ai tools call application services; they are not a second domain layer.cli or ai.platform and storage do not depend on ai.Documented in CLAUDE.md and CLI_REFERENCE.md:
openfatture init — First-time setup (config, directories, database)openfatture assistant [MESSAGE] — Natural language assistant with tool callingopenfatture interactive start — Guided terminal mode with menusopenfatture config ... — Configuration management (show/set/validate)openfatture status — Read-only migration and system status (supports --json)These commands provide direct CLI access to domain operations, complementing the assistant-first approach.
openfatture fattura — Invoice managementlist — Search and list invoices with filters (query/year/status/client)show INVOICE_ID — Display detailed invoice informationcreate — Create new draft invoiceadd-line — Add line item to invoicegenerate-pdf — Generate PDF for invoice (multiple templates)generate-xml — Generate FatturaPA XML (wired to real XML builder in 2.3.0)create-credit-note — Create nota di credito (TD04) from existing invoiceset-status — Update invoice status (BOZZA → DA_INVIARE)openfatture cliente — Client managementlist — Search and list clientsshow CLIENT_ID — Display detailed client informationcreate — Create new client recordDesign rationale: These commands exist because:
CLAUDE.md constraint: Domain operations belong in application services. Do not add another public command for workflows the assistant can express through tools.
[ai] extraWhen uv sync --extra ai (or --all-extras) is not performed, assistant and interactive commands fail with:
Error: AI features require the 'ai' extra.
Install with: uv sync --extra ai
| Layer | Meaning | Install | Examples |
|---|---|---|---|
| Core | Required for Italian e-invoicing | uv sync (default) |
billing, SDI, payment, PDF, storage, events, hooks engine, platform, CLI |
| Feature extras | In-tree, optional deps | --extra ai/rag/ml/all |
Assistant, RAG, cash-flow forecasting |
| Hooks | User automation scripts | Drop files in ~/.openfatture/hooks/ |
Slack notify, backup triggers |
| Extensions | Future out-of-tree packages | Not yet designed | MCP servers, third-party tool plugins |
Feature extras details:
[project.optional-dependencies]
ai = ["langgraph>=0.6", "openai>=2.4.0", "anthropic>=0.71.0", "tiktoken>=0.8.0"]
rag = ["openfatture[ai]", "chromadb>=0.4.22", "sentence-transformers>=2.6.0", ...]
ml = ["prophet>=1.1.5", "xgboost>=2.1.0", "pandas>=2.3.3", "plotly>=6.3.1", ...]
all = ["openfatture[ai,rag,ml]"]
No in-process plugin API. The experimental openfatture.plugins package was removed in 2.0. User extensions use hooks (see CORE_VS_EXTENSIONS.md).
Release: 2.0.0–2.0.2 (2026-06/07)
Scope: Architectural reset for AI-first product.
✅ Repo hygiene and living documentation
✅ Ruff-only tooling (no flake8/black/isort dual stack)
✅ Optional dependency extras (ai, rag, ml, all)
✅ D0 non-core cut: removed voice, web scraper, orphan analytics agents
✅ D1 package reorg: billing, events, hooks, platform, pdf bounded packages
✅ Core vs extras vs extensions design (hooks supported; plugins removed)
✅ Honesty gates: Lightning removed (incomplete); RAG auto-update requires explicit callback
✅ D3 unified ai.runtime entry for assistant
✅ D2: AI tools are thin adapters over application services (not a second domain layer)
✅ Zero in-code suppressions (noqa, type: ignore, pragma: no cover)
See: releases/v2.0.0.md, ARCHITECTURE_REDESIGN.md.
Release: 2.1.0 (2026-08)
Scope: Flip to LangGraph as default assistant backend; slim ChatAgent to rollback option.
✅ langgraph_tool_loop default backend
✅ ChatAgent slim + ASSISTANT_BACKEND=chat rollback path
✅ Lightning Network module removed entirely (docs archived under docs/history/lightning/)
✅ Dead Lightning i18n keys GC’d from all locales
✅ Config SSOT: version, backends, AI credentials hydrated consistently (#32)
See: releases/v2.1.0.md, TECHNICAL_DEBT.md closed ledger.
Release: 2.2.0 (2026-08/09)
Scope: Real Italian forfettario invoice PDF with RF19, natura, cassa, bollo MEF-compliant rendering.
✅ Professional PDF template upgraded to production quality
✅ RF19 (regime forfettario) as first-class regime with correct natura/IVA rendering
✅ Natura codes (N2.1, N2.2, N3.1, …) rendered with labels and totals
✅ DatiCassaPrevidenziale support in XML builder and PDF
✅ Bollo virtuale (€2 stamp duty) rendering for invoices >€77.47 without IVA
✅ CLI commands for invoice/client management (fattura, cliente) fully wired
✅ Fix: premature page break for single-row invoices with payment info (#55)
See: releases/v2.2.0.md, PR #56 (forfettario PDF), PR #53 (FatturaPA natura/cassa).
Release: 2.3.0 (2026-09)
Scope: Real TD04 (nota di credito) support with FatturaPA linkage + real CLI XML generation.
✅ Application service create_nota_credito_from_fattura(fattura_id, ...) — loads source invoice, creates TD04 with copied lines (negated amounts), sets FatturaPA linkage
✅ Fattura model extended with optional linkage fields (fattura_originale_id, fattura_originale_numero, fattura_originale_data)
✅ XML builder (_build_dati_generali) emits DatiFattureCollegate when linkage present
✅ AI invoice tools wired to credit note creation
✅ CLI command openfatture fattura create-credit-note --from-invoice INVOICE_ID
✅ Integration tests for TD04 XML generation and workflow
✅ PDF renders TD04 document type label (via tipo_documento.value)
✅ openfatture fattura generate-xml now actually generates FatturaPA XML (no longer a stub; wired to InvoiceService.generate_xml() and real builder)
✅ CLI generate-xml honors --output and --dry-run flags
✅ Comprehensive test coverage for XML generation (normal, custom output, dry-run, error handling)
See: releases/v2.3.0.md, PR #57 (TD04), PR #58 (Alembic migration 8cf82bd24752).
Location: openfatture/ai/orchestration/workflows/
invoice_creation.py — Multi-agent invoice creation workflowcompliance_check.py — Compliance orchestrationcash_flow_analysis.py — Cash flow workflowCurrent state:
enable multi-agent orchestration (experimental) in AI settingsProduct path: Remains experimental until explicit product decision to ship multi-agent UX. See TECHNICAL_DEBT.md D-WF #38.
These require explicit product and release plan; do not implement until decided:
| Decision | GitHub | Default stance |
|---|---|---|
| Multi-agent workflows on public path | #38 | Off / experimental only |
| Textual TUI or other rich TUI | #44 | Non-goal; interactive terminal exists |
| MCP server / external tool bus | #44 | Non-goal until designed; hooks + tool contracts today |
| Browser / web app surface | #44 | Explicit non-goal (see STATUS.md) |
| Domain CLI command tree growth | N/A | Forbidden per CLAUDE.md; domain ops stay on assistant + app layer |
See: TECHNICAL_DEBT.md § Product decisions, STATUS.md § Explicit non-goals.
All debt has explicit trigger conditions (when to act) and GitHub issues. Do not drive standalone “code cleanup” PRs; burn debt when editing the affected module.
Summary of open debt:
tests.*; trigger: optional incremental enableSee: TECHNICAL_DEBT.md for full inventory, triggers, and non-goals.
Current product supports (as of 2.3.0):
All Italian tax regimes (RegimeFiscale enum):
Supported in RigaFattura model and FatturaPA XML builder:
Implementation: _build_dati_beni_servizi in sdi/xml_builder/fatturapa.py; PDF natura labels in pdf/generator.py.
Model: DatiCassaPrevidenziale (relationship to Fattura)
Fields: tipo_cassa, al_cassa, importo_contributo_cassa, imponibile_cassa, aliquota_iva, ritenuta, natura, riferimento_amministrazione
XML builder support: _build_dati_generali in fatturapa.py (added in 2.2.0 / PR #53)
PDF support: Cassa line items rendered in professional template (2.2.0)
Common cassa types:
Model fields: Fattura.ritenuta_acconto, Fattura.aliquota_ritenuta
XML builder: DatiRitenuta section in _build_dati_generali
PDF: Rendered as deduction from total in payment section
Common rates:
Model field: Fattura.importo_bollo
XML builder: DatiBollo section with BolloVirtuale=SI
PDF: Rendered as separate line in totals section (2.2.0)
MEF requirement: €2.00 stamp duty for invoices >€77.47 without IVA.
Currently supported in product:
DatiFattureCollegate linkage (shipped in 2.3.0)Status: PEC integration and SDI notification parsing are production-ready.
Covered in dedicated doc: SDI_TRANSPORT_READINESS.md
Summary:
CI gates (defined in pyproject.toml + .github/workflows/test.yml):
[tool.coverage.report]
fail_under = 49 # Package-wide floor (prevents large regressions)
Payment module floor: 75% (measured ~78% in dedicated job)
Local default: pytest runs without coverage (faster). Use --cov=openfatture for reports.
Mypy: Type-checks openfatture/ (production code). tests/ excluded (D-TYPES-TESTS #42 — optional incremental enable).
Linters: Ruff only (no flake8/black/isort). Zero in-code suppressions.
See: TECHNICAL_DEBT.md D-COV, STATUS.md § Quality expectations.
Current version: 2.3.0 (2026-09-11)
Version scheme: MAJOR.MINOR.PATCH
Release tags: v2.0.0, v2.1.0, v2.2.0, v2.3.0, …
Changelog: CHANGELOG.md with user-facing release notes
Release process:
openfatture/__about__.py (single source of truth)docs/releases/vX.Y.Z.mdgit tag vX.Y.Z && git push origin vX.Y.ZSee: releases/ directory for historical release notes.
✅ Core invoicing: CRUD for clients/invoices, line items, batch operations
✅ FatturaPA XML: v1.9 compliant, all regimes, natura codes, cassa, ritenuta, bollo
✅ PDF generation: Professional/minimalist/branded templates with forfettario support
✅ SDI/PEC: Ready for production with real credentials
✅ Payment reconciliation: Bank import (CSV/OFX), matching engine, ledger
✅ AI assistant ([ai] extra): Natural language tools, LangGraph orchestration, RAG optional
✅ Hooks: User automation scripts via event bus
✅ CLI + interactive mode: Deterministic commands + guided TUI
✅ Nota di credito (TD04): Credit notes with FatturaPA DatiFattureCollegate linkage
⚠️ Experimental: Multi-agent workflows (off public path)
⚠️ On-demand: Oversized module splits, pagoPA QR, accuracy-drift monitoring
❌ Explicit non-goals: Web app, in-process plugins, duplicate CLI command trees
Read first:
Key constraints from CLAUDE.md:
init.status read-only and machine-readable with --json.Historical material: Anything under docs/history/ is not current CLI behavior.
Questions or additions: See docs/README.md for documentation index or file GitHub issues.