Skip to content

Commit 041c4bf

Browse files
committed
refactor: Update table of contents by removing and re-adding API Documentation entry
1 parent 9f1d40a commit 041c4bf

2 files changed

Lines changed: 35 additions & 22 deletions

File tree

docs/architecture.md

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ graph TD
1515
Admin[Admin Endpoints]
1616
System[System Endpoints]
1717
end
18-
18+
1919
subgraph Handlers [Command Handlers / Aggregates]
2020
Book[Book]
2121
Author[Author]
@@ -37,10 +37,10 @@ graph TD
3737
Public --> Handlers
3838
Admin --> Handlers
3939
System --> Handlers
40-
40+
4141
Handlers -- Events --> EventStore
4242
EventStore -- Async Projections --> Projections
43-
43+
4444
EventStore -- PostgreSQL Protocol --> Postgres
4545
Projections -- PostgreSQL Protocol --> Postgres
4646
```
@@ -61,6 +61,7 @@ Instead of storing current state, we store all changes as immutable events.
6161
- Natural fit for distributed systems
6262

6363
**Implementation**:
64+
6465
```csharp
6566
// Events are immutable records
6667
public record BookAdded(
@@ -89,12 +90,14 @@ See [Marten Guide](guides/marten-guide.md) for implementation details.
8990
Separate models for writes (commands) and reads (queries).
9091

9192
**Write Side** (Commands):
93+
9294
- Commands routed through Wolverine message bus
9395
- Handlers execute business logic
9496
- Events are appended to streams
9597
- Optimized for consistency
9698

9799
**Read Side** (Queries):
100+
98101
- Projections denormalize data
99102
- Optimized for specific queries
100103
- Eventually consistent
@@ -104,7 +107,7 @@ Separate models for writes (commands) and reads (queries).
104107
Commands are routed through Wolverine's message bus to handlers that execute business logic.
105108

106109
**Command Flow**:
107-
**Command Flow**:
110+
108111
```mermaid
109112
graph LR
110113
HTTP[HTTP Request] --> Endpoint
@@ -117,12 +120,14 @@ graph LR
117120
```
118121

119122
**Benefits**:
123+
120124
- Clean separation of concerns
121125
- Automatic transaction management
122126
- Easy to test (pure functions)
123127
- Foundation for async messaging
124128

125129
**Example**:
130+
126131
```csharp
127132
// Endpoint: Just routing
128133
private static Task<IResult> CreateBook(request, IMessageBus bus)
@@ -143,6 +148,7 @@ public static IResult Handle(CreateBook cmd, IDocumentSession session)
143148
The system implements **Enterprise-grade Multi-tenancy** using Marten's Conjoined Tenancy model.
144149

145150
**Key Components**:
151+
146152
- **Tenant Resolution**: `TenantResolutionMiddleware` extracts tenant ID from `X-Tenant-ID` header.
147153
- **Data Isolation**: All Marten documents and events are partitioned by `tenant_id`.
148154
- **Service Scoping**: `IDocumentSession` and `IQuerySession` are scoped to the current tenant.
@@ -171,44 +177,48 @@ The application automatically sends SSE notifications whenever projections are u
171177
> For implementation details, flow diagrams, and client integration examples, see the [Real-time Notifications Guide](guides/real-time-notifications.md).
172178
173179
**Key Features**:
180+
174181
- **Automatic**: Tied to projection updates, not API calls.
175182
- **Reliable**: Notifications only fire if the data is successfully committed.
176183
- **Integrated**: Handles cache invalidation and notification in a single unit of work.
177-
```
178184

179185
## Domain Model
180186

181187
### Aggregates
182188

183189
**Book Aggregate**:
190+
184191
- Root entity for book management
185192
- Enforces business rules
186193
- Emits events: `BookAdded`, `BookUpdated`, `BookSoftDeleted`, `BookRestored`
187194

188195
**Author Aggregate**:
196+
189197
- Manages author information
190198
- Tracks biography and metadata
191199

192200
**Category Aggregate**:
201+
193202
- Supports multi-language translations
194203
- Manages category hierarchy
195204

196205
**Publisher Aggregate**:
206+
197207
- Publisher information management
198208

199209
### Events
200210

201211
All events include:
212+
202213
- Domain data (title, ISBN, etc.)
203214
- Marten metadata (correlation ID, causation ID, timestamp)
204215

205216
Example event flow:
206-
```
217+
207218
1. User creates book → BookAdded event
208219
2. Event stored in mt_events table
209220
3. Async projection updates BookSearchProjection
210221
4. Read model available for queries
211-
```
212222

213223
## Event Modeling
214224

@@ -294,14 +304,13 @@ sequenceDiagram
294304

295305
### Write Path (Command)
296306

297-
```
298307
```mermaid
299308
sequenceDiagram
300309
participant Client
301310
participant API as API Endpoint
302311
participant Domain as Domain Model
303312
participant Marten as Marten Event Store
304-
313+
305314
Client->>API: 1. HTTP Request
306315
API->>Domain: 2. Load Aggregate
307316
Domain->>Domain: 3. Business Logic
@@ -310,28 +319,24 @@ sequenceDiagram
310319
Marten->>Marten: 6. SaveChanges
311320
API->>Client: 7. Return Response
312321
```
313-
```
314322

315323
### Read Path (Query)
316324

317-
```
318325
```mermaid
319326
sequenceDiagram
320327
participant Client
321328
participant API as API Endpoint
322329
participant DB as Read Model DB
323-
330+
324331
Client->>API: 1. HTTP Request
325332
API->>DB: 2. Query Projection
326333
DB->>API: 3. Return Data (DTOs)
327334
API->>API: 4. Apply Filters/Pagination
328335
API->>Client: 5. Return Results
329336
```
330-
```
331337

332338
### Projection Update (Async)
333339

334-
```
335340
```mermaid
336341
sequenceDiagram
337342
participant EventStore as Marten Event Store
@@ -345,11 +350,11 @@ sequenceDiagram
345350
Builder->>DB: 4. Update Read Model
346351
DB-->>Daemon: 5. Commit Checkpoint
347352
```
348-
```
349353

350354
## Technology Stack
351355

352356
### Backend
357+
353358
- **ASP.NET Core 10** - Web framework
354359
- **Minimal APIs** - Endpoint definition
355360
- **Wolverine** - Command/handler pattern and message bus
@@ -359,6 +364,7 @@ sequenceDiagram
359364
- **Scalar** - API documentation
360365

361366
### Features
367+
362368
- **Event Sourcing** - Marten event store
363369
- **CQRS** - Separate read/write models
364370
- **Real-time Notifications** - Server-Sent Events (SSE) for all mutations
@@ -372,6 +378,7 @@ sequenceDiagram
372378
- **Soft Deletion** - Logical deletes with restore
373379

374380
### Infrastructure
381+
375382
- **Docker** - Container runtime
376383
- **PgAdmin** - Database management
377384
- **OpenTelemetry** - Distributed tracing
@@ -386,20 +393,23 @@ sequenceDiagram
386393

387394
### 1. Event Sourcing with Marten
388395

389-
**Why**:
396+
**Why**:
397+
390398
- Built-in event store on PostgreSQL
391399
- No additional infrastructure needed
392400
- Strong .NET integration
393401
- Async projection support
394402

395403
**Trade-offs**:
404+
396405
- Learning curve for event sourcing
397406
- Eventually consistent reads
398407
- More complex than CRUD
399408

400409
### 2. Minimal APIs
401410

402411
**Why**:
412+
403413
- Less boilerplate than controllers
404414
- Better performance
405415
- Cleaner endpoint definition
@@ -408,18 +418,21 @@ sequenceDiagram
408418
### 3. Async Projections
409419

410420
**Why**:
421+
411422
- Decouples write and read models
412423
- Optimized read models for specific queries
413424
- Scalable (can run on separate processes)
414425

415426
**Trade-offs**:
427+
416428
- Eventually consistent
417429
- Projection lag possible
418430
- More complex than direct queries
419431

420432
### 4. Soft Deletion
421433

422434
**Why**:
435+
423436
- Preserve data integrity
424437
- Support undo/restore
425438
- Maintain referential integrity
@@ -428,6 +441,7 @@ sequenceDiagram
428441
### 5. ETags for Concurrency
429442

430443
**Why**:
444+
431445
- Standard HTTP mechanism
432446
- Works with any client
433447
- Natural fit with stream versions
@@ -437,12 +451,14 @@ sequenceDiagram
437451
### 6. Identity Stored as Documents (Not Event Sourced)
438452

439453
**Why**:
454+
440455
- **Standardization**: ASP.NET Core Identity provides robust, battle-tested security.
441456
- **Compliance**: GDPR "Right to be Forgotten" is easier to implement with mutable documents than immutable event streams.
442457
- **Simplicity**: Authentication state (current password hash, lock status) is more critical than the history of changes.
443458
- **Performance**: High-frequency read path (login) benefits from simple index lookups.
444459

445460
**Trade-offs**:
461+
446462
- **Audit Trail**: Account changes (password reset, email change) are not automatically event-sourced (must use separate audit logs).
447463
- **Consistency**: Auth data lives outside the primary event stream (though still in Postgres/Marten).
448464

@@ -471,8 +487,6 @@ sequenceDiagram
471487

472488
### Authentication & Authorization
473489

474-
### Authentication & Authorization
475-
476490
The application implements a **Token-based authentication system**:
477491

478492
- **JWT Bearer Tokens** - Primary authentication method
@@ -489,7 +503,7 @@ The application implements a **Token-based authentication system**:
489503
- **Role-Based Authorization** - Admin endpoints protected
490504
- Admin role for full access
491505
- Extensible for additional roles
492-
506+
493507
See [Authentication Guide](guides/authentication-guide.md) and [Passkey Guide](guides/passkey-guide.md) for details.
494508

495509
### Data Protection

docs/toc.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,6 @@
22
href: getting-started.md
33
- name: Architecture
44
href: architecture.md
5-
items:
6-
- name: Api Documentation
7-
href: api/index.md
85
- name: Guides
96
items:
107
- name: Event Sourcing
@@ -63,3 +60,5 @@
6360
items:
6461
- name: Analyzer Rules
6562
href: guides/analyzer-rules.md
63+
- name: Api Documentation
64+
href: api/index.md

0 commit comments

Comments
 (0)