Skip to content

Backend Architecture Overview

Tech Stack

ComponentChoiceNotes
LanguageC# / .NETTeam's strongest backend language
DatabasePostgreSQLWith EF Core ORM
API StyleREST + custom endpointsCustom graph endpoints for relationship maps
Real-timeSignalRFrom Phase 1 for activity feed notifications
ID StrategyUUIDv7 (internal) + project-scoped sequences (public)Public IDs like VNO-42

Pending team decisions: Hosting, Authentication, File Storage, Search Implementation.


Solution Structure

Modular monolith - shared infrastructure with separate feature projects.

KnowledgeBase.sln
├── src/
│   ├── Shared/
│   │   ├── KnowledgeBase.Domain/              # Shared base classes, enums, interfaces
│   │   ├── KnowledgeBase.Infrastructure/      # DbContext, shared services, SignalR, auth
│   │   └── KnowledgeBase.Common/              # Pagination, error handling, permissions
│   │
│   ├── Features/
│   │   ├── KnowledgeBase.Projects/            # Project CRUD, membership, invitations
│   │   │   ├── Commands/
│   │   │   ├── Queries/
│   │   │   ├── DTOs/
│   │   │   ├── Entities/
│   │   │   └── Controllers/
│   │   │
│   │   ├── KnowledgeBase.Timelines/           # Timeline updates, sections, items
│   │   │   ├── Commands/
│   │   │   ├── Queries/
│   │   │   ├── DTOs/
│   │   │   ├── Entities/
│   │   │   └── Controllers/
│   │   │
│   │   ├── KnowledgeBase.Characters/          # Characters + character relationships
│   │   │   └── ...
│   │   │
│   │   ├── KnowledgeBase.Factions/            # Factions + faction relationships + memberships
│   │   │   └── ...
│   │   │
│   │   └── KnowledgeBase.Collaboration/       # Comments, activity feed, version history
│   │       └── ...
│   │
│   └── KnowledgeBase.API/                     # Thin host - wires everything together
│       ├── Program.cs
│       └── Middleware/

└── tests/
    ├── KnowledgeBase.Projects.Tests/
    ├── KnowledgeBase.Timelines.Tests/
    ├── KnowledgeBase.Characters.Tests/
    ├── KnowledgeBase.Factions.Tests/
    └── KnowledgeBase.Collaboration.Tests/

Design Principles

  • Feature isolation: Each feature is its own project with its own entities, logic, endpoints, and tests
  • Shared foundation: Domain base classes, Infrastructure (DbContext, auth), and Common utilities are shared across features
  • Feature projects reference shared projects but not each other (unless necessary, e.g., Characters references Projects for membership checks)
  • DDD patterns: Aggregate roots, entities, and value objects with proper encapsulation

DDD Base Classes

Entity (base)
├── Id: Guid (UUIDv7)
├── CreatedAt: DateTime
├── CreatedBy: Guid
├── UpdatedAt: DateTime
└── UpdatedBy: Guid

AggregateRoot : Entity
├── SequenceNumber: int (project-scoped public ID)
└── Domain events collection
TypeEntities
Aggregate RootsProject, Character, Faction, TimelineUpdate
EntitiesSection, Item, ProjectMember, FactionMembership, Relationship, FactionRelationship, ChangelogEntry
Value ObjectsTheme, RelationshipType, DevelopmentStatus

Public ID System

Internal database IDs (UUIDv7) are never exposed to users. Instead, each project has a unique key (e.g., VNO) and each aggregate root gets a project-scoped sequence number.

  • Public identifier format: {ProjectKey}-{SequenceNumber} (e.g., VNO-42)
  • Sequence counter: Stored on the Project entity, incremented atomically at the database level
  • Atomic increment: Uses PostgreSQL UPDATE ... RETURNING to prevent race conditions under concurrent requests
sql
UPDATE "Projects" SET "NextSequenceNumber" = "NextSequenceNumber" + 1
WHERE "Id" = @projectId
RETURNING "NextSequenceNumber";

Permission System

Architecture

  • Permission checks live in the Application layer behind an IPermissionService interface
  • Phase 1: Fixed role-based implementation (RoleBasedPermissionService)
  • Future: Designed to be swappable for configurable per-project permissions without rewriting feature code

Roles and Access

ActionOwnerStorytellerCo-CreatorPlayerViewer
Manage project settingsYes----
Manage membersYes----
Create/edit timelineYesYesYes--
Create NPC charactersYesYesYes--
Create own PC characterYesYesYesYes-
Create relationshipsYesYesYesOwn only-
Moderate contentYesYes---
View contentYesYesYesPublishedPublished

Visibility Filtering

  • Timeline items: Players/Viewers only see items with Published status
  • Relationships: Private relationships are omitted entirely from API responses for anyone except the creator + Storyteller/Owner
  • Characters: Private characters visible only to creator + Storyteller/Owner

No "hidden but hinted" partial visibility - private content simply does not exist in the response.


Real-time Strategy

SignalR is included from Phase 1 for basic activity feed notifications (e.g., "Alex added a new character"). Full collaborative editing features expand in Phase 3.