Appearance
Backend Architecture Overview
Tech Stack
| Component | Choice | Notes |
|---|---|---|
| Language | C# / .NET | Team's strongest backend language |
| Database | PostgreSQL | With EF Core ORM |
| API Style | REST + custom endpoints | Custom graph endpoints for relationship maps |
| Real-time | SignalR | From Phase 1 for activity feed notifications |
| ID Strategy | UUIDv7 (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| Type | Entities |
|---|---|
| Aggregate Roots | Project, Character, Faction, TimelineUpdate |
| Entities | Section, Item, ProjectMember, FactionMembership, Relationship, FactionRelationship, ChangelogEntry |
| Value Objects | Theme, 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 ... RETURNINGto 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
IPermissionServiceinterface - Phase 1: Fixed role-based implementation (
RoleBasedPermissionService) - Future: Designed to be swappable for configurable per-project permissions without rewriting feature code
Roles and Access
| Action | Owner | Storyteller | Co-Creator | Player | Viewer |
|---|---|---|---|---|---|
| Manage project settings | Yes | - | - | - | - |
| Manage members | Yes | - | - | - | - |
| Create/edit timeline | Yes | Yes | Yes | - | - |
| Create NPC characters | Yes | Yes | Yes | - | - |
| Create own PC character | Yes | Yes | Yes | Yes | - |
| Create relationships | Yes | Yes | Yes | Own only | - |
| Moderate content | Yes | Yes | - | - | - |
| View content | Yes | Yes | Yes | Published | Published |
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.
Related Documents
- Data Model
- API Endpoints
- Architecture Decision Records
- [Team Discussion Items](/Team Discussion Items.md)