Core
Info
Architectural truth for
Corein theDocumentsfeature. This leaf module contains the root endpoints and operations for theDocumentaggregate root.
Overview
The Documents/Core module provides the root HTTP endpoints for managing the Document entity, which serves as the top-level aggregate root for sections and content blocks. A Document belongs to a Project and contains hierarchical Sections, which contain polymorphic Blocks.
This module is purely synchronous HTTP / Entity Framework Core logic. It handles retrieving and mapping complex object graphs to DTOs for the client, computing summaries, and fetching document-level configurations.
Endpoints
CreateDocumentEndpoint: Directly creates a new Document and attaches it to a Project. Note: this creates an empty document. To create a document from a Template, clients useInstantiateDocumentin theTemplatesfeature.GetDocumentEndpoint: Retrieves a full document with its nested sections and blocks. It explicitly usesAsSplitQuery()to prevent Cartesian explosions when fetching deeply nested tree structures.ListDocumentsEndpoint&ListProjectDocumentsEndpoint: Retrieve a summary of documents, calculating completion statuses (Processing,Pending,Error,Completed) dynamically based on the state of the document’s nested blocks.PreviewDocumentEndpoint: Calls out toIDocumentRenderServiceto render the document’s sections and blocks into an HTML preview string.BrowseRepoFilesEndpoint: Provides an interface for the client to traverse a project’s associated Git repository structure on disk (used for attaching source files to sections).
Business Logic Intent
The main intent of this module is to provide a safe, read-optimized projection of the deeply nested Document -> Section -> Block hierarchy.
Because the system relies on asynchronous generation that alters ContentBlock states, the Document status is a computed projection rather than a stored column. The endpoints dynamically aggregate Pending, Processing, and Error block counts to present an overall document status to the user.
classDiagram class Document { +Guid Id +int ProjectId +string Title +string CategoryLabel +DateTime CreatedAt } class Section { +Guid Id +Guid? ParentSectionId +string Title +int SortOrder } class ContentBlock { +Guid Id +Guid? ParentBlockId +string Type +string Status } Document "1" *-- "many" Section Section "1" *-- "many" Section : nested Section "1" *-- "many" ContentBlock ContentBlock "1" *-- "many" ContentBlock : nested
Mapping & Performance
A significant performance pattern here is the mapping of EF Core query results.
In GetDocumentEndpoint, AsSplitQuery() is crucial:
var doc = await _db.Documents
.Include(d => d.Sections.OrderBy(s => s.SortOrder))
.ThenInclude(s => s.Blocks.OrderBy(b => b.SortOrder))
.ThenInclude(b => b.Children.OrderBy(c => c.SortOrder))
.AsSplitQuery()
.FirstOrDefaultAsync(...)Without AsSplitQuery(), the joins across three levels of one-to-many relationships would duplicate row data exponentially.