Core

Info

Architectural truth for Core in the Documents feature. This leaf module contains the root endpoints and operations for the Document aggregate 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 use InstantiateDocument in the Templates feature.
  • GetDocumentEndpoint: Retrieves a full document with its nested sections and blocks. It explicitly uses AsSplitQuery() 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 to IDocumentRenderService to 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.

0 items under this folder.