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.

  • DocumentStore in MILTON.Client/StateContainer/DocumentStore.cs caches document summary lists by project ID and document editor payloads by document ID.
  • TemplateStore in MILTON.Client/StateContainer/TemplateStore.cs caches template lists by project ID.
  • ProjectDashboard.razor, DocumentsList.razor, CreateTemplate.razor, and EditTemplate.razor read GET /api/projects/{projectId}/documents only when the per-project document entry is missing.
  • Templates.razor and ProjectDashboard.razor read GET /api/projects/{projectId}/templates only when the per-project template entry is missing.
  • EditTemplate.razor first tries to resolve the requested template from TemplateStore; if it is absent, it fetches GET /api/documents/templates/{templateId} and inserts the result into the cached project list.
  • DocumentEditor.razor caches GET /api/documents/{id} responses in DocumentStore.DocumentDetails.

Write paths explicitly invalidate the relevant cache scope:

  • CreateTemplate.razor clears the project’s template cache after POST /api/documents/templates.
  • EditTemplate.razor clears the project’s template cache after PUT /api/documents/templates/{templateId}.
  • InstantiateTemplateDialog.razor clears the project’s document-summary cache after POST /api/documents/templates/instantiate.

Note: The current document-detail cache is independent from the per-project document list cache. DocumentStore exposes ClearForProject(projectId) for summary lists, but it does not currently expose a matching clear operation for DocumentDetails.

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 DocumentStyleJson and individual block LayoutJson payload 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.