Documents Feature (Document Factory)
The Documents Feature is the core component of MILTON. It handles the lifecycle of documents, dynamic sections, block instantiation, templates, traceability, and AI-powered text generation.
Overview
The “Document Factory” uses a robust hierarchical data model to build complex system documentation formats like SRS (Software Requirements Specification), SVD (Software Version Description), STD (Software Test Description), and STR (Software Test Report).
Endpoints
Document Endpoints (DocumentEndpoints.cs)
GET /api/documents- Lists all documents with summaries (statuses, block counts).GET /api/documents/blocks/{BlockId}/tracelinks- Retrieves traceability link data for a given block.
Template Endpoints (TemplateEndpoints.cs)
POST /api/documents/templates- Creates a new reusable document template.POST /api/documents/templates/instantiate- Instantiates a document from a defined template and triggers the processing saga.
Client L1 Cache
The frontend wraps the document and template read paths in a scoped L1 cache so the same project payloads are reused across multiple routed pages.
DocumentStoreinMILTON.Client/StateContainer/DocumentStore.cscaches document summary lists by project ID and document editor payloads by document ID.TemplateStoreinMILTON.Client/StateContainer/TemplateStore.cscaches template lists by project ID.ProjectDashboard.razor,DocumentsList.razor,CreateTemplate.razor, andEditTemplate.razorreadGET /api/projects/{projectId}/documentsonly when the per-project document entry is missing.Templates.razorandProjectDashboard.razorreadGET /api/projects/{projectId}/templatesonly when the per-project template entry is missing.EditTemplate.razorfirst tries to resolve the requested template fromTemplateStore; if it is absent, it fetchesGET /api/documents/templates/{templateId}and inserts the result into the cached project list.DocumentEditor.razorcachesGET /api/documents/{id}responses inDocumentStore.DocumentDetails.
Write paths explicitly invalidate the relevant cache scope:
CreateTemplate.razorclears the project’s template cache afterPOST /api/documents/templates.EditTemplate.razorclears the project’s template cache afterPUT /api/documents/templates/{templateId}.InstantiateTemplateDialog.razorclears the project’s document-summary cache afterPOST /api/documents/templates/instantiate.
Note: The current document-detail cache is independent from the per-project document list cache.
DocumentStoreexposesClearForProject(projectId)for summary lists, but it does not currently expose a matching clear operation forDocumentDetails.
See Client application for the complete client-side cache map.
Component Handlers (The “Workers”)
Block processing handlers form the executable units of the document pipeline:
- RepoScannerHandler (The “Exploder”): Scans repository filesystems for source files, clusters them using AI or directory heuristics, and spawns structured sub-sections.
- RequirementGeneratorHandler (The “Leaf Worker”): Validates and enriches Requirement blocks utilizing AI contexts mapped against specific source code sections.
- TestCaseGeneratorHandler (The “Test Generator”): Iterates over Requirement blocks to generate matching test cases and auto-links them for absolute traceability.
Rendering & Export
The Document Factory also integrates deeply with the rendering pipeline:
- Complex document blocks are transpiled into a robust HTML structure using the
IDocumentRenderService. - Global and localized styling constraints are managed natively inside the document templates via
DocumentStyleJsonand individual blockLayoutJsonpayload elements. - The compiled document structures can be fully exported using isolated Gotenberg sidecar containers pointing exactly to
IPdfGenerationService. - S3 synchronization is built directly into generation flows tracking endpoints to valid object bucket repositories locally referencing via
PdfStorageKey.
Orchestration
The instantiation and AI generation of documents is extremely state-dependent. Thus, it operates heavily with Wolverine Sagas.
When a template is instantiated, InstantiateDocumentHandler breaks out the blueprint into a materialized PostgreSQL hierarchy, publishing the DocumentCreatedEvent, which is ingested by the background saga engine (DocumentProcessingSaga) to start recursive, methodical block processing.