204 lines
5.1 KiB
Markdown
204 lines
5.1 KiB
Markdown
# System architecture
|
|
|
|
## Decision summary
|
|
|
|
The first release is a **modular monolith** deployed as one application container plus
|
|
PostgreSQL.
|
|
|
|
The production application contains:
|
|
|
|
- ASP.NET Core API and authentication;
|
|
- compiled React static assets;
|
|
- application/use-case modules;
|
|
- background hosted services;
|
|
- filesystem attachment adapter;
|
|
- import/export and backup orchestration.
|
|
|
|
This topology minimizes operational overhead on Unraid while retaining internal
|
|
boundaries that can be tested and evolved.
|
|
|
|
## Context
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
User[Browser user] -->|HTTPS| Proxy[Reverse proxy]
|
|
Proxy --> App[ItWorx Knowledge Hub]
|
|
ApiClient[Scoped API client] -->|HTTPS /api/v1| Proxy
|
|
App --> Db[(PostgreSQL)]
|
|
App --> Files[(Attachments / imports / backups)]
|
|
Leaf[Read-only LeafWiki snapshot] -->|Read-only import mount| App
|
|
FutureMCP[Future separate MCP server] -.->|HTTPS /api/v1| Proxy
|
|
```
|
|
|
|
The future MCP server is shown only as an external client. It is not built or deployed by
|
|
this repository.
|
|
|
|
## Production containers
|
|
|
|
```text
|
|
knowledge-hub
|
|
postgres
|
|
```
|
|
|
|
Development may run the React Vite server separately for fast refresh. Production serves
|
|
its built files through ASP.NET Core.
|
|
|
|
## Logical projects
|
|
|
|
```text
|
|
ItWorx.KnowledgeHub.Domain
|
|
Pure domain concepts and invariants
|
|
|
|
ItWorx.KnowledgeHub.Application
|
|
Use cases, authorization requirements, ports and orchestration
|
|
|
|
ItWorx.KnowledgeHub.Contracts
|
|
Stable request/response and event contracts
|
|
|
|
ItWorx.KnowledgeHub.Infrastructure
|
|
EF Core, PostgreSQL, files, hashing, import adapters, jobs
|
|
|
|
ItWorx.KnowledgeHub.Api
|
|
HTTP, auth/session transport, middleware, static SPA hosting
|
|
|
|
src/frontend
|
|
React application
|
|
|
|
tests/backend/*
|
|
tests/e2e
|
|
```
|
|
|
|
Allowed dependency direction:
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
Api --> Application
|
|
Api --> Contracts
|
|
Api --> Infrastructure
|
|
Infrastructure --> Application
|
|
Infrastructure --> Domain
|
|
Infrastructure --> Contracts
|
|
Application --> Domain
|
|
Application --> Contracts
|
|
```
|
|
|
|
Forbidden:
|
|
|
|
- Domain → Application/Infrastructure/API/UI
|
|
- Application → Infrastructure/API/UI
|
|
- Contracts → Infrastructure/API/UI
|
|
- Frontend → database/filesystem
|
|
|
|
Architecture tests must enforce this.
|
|
|
|
## Application modules
|
|
|
|
Initial module boundaries:
|
|
|
|
- Identity
|
|
- Workspaces
|
|
- Knowledge
|
|
- Search
|
|
- Attachments
|
|
- Projects
|
|
- Decisions
|
|
- Runbooks
|
|
- Imports
|
|
- Exports
|
|
- Audit
|
|
- Integration
|
|
- Operations
|
|
|
|
Modules may share infrastructure composition but must not mutate each other's tables
|
|
through ad hoc DbContext access. Cross-module operations use application contracts and a
|
|
single transaction boundary where required.
|
|
|
|
## Data flow: publish page
|
|
|
|
```mermaid
|
|
sequenceDiagram
|
|
participant UI
|
|
participant API
|
|
participant App as Application
|
|
participant DB as PostgreSQL
|
|
participant Outbox
|
|
|
|
UI->>API: PUT page + If-Match
|
|
API->>App: PublishPage command
|
|
App->>DB: Load page + authorization
|
|
App->>App: Validate version, Markdown and links
|
|
App->>DB: Update current page
|
|
App->>DB: Insert immutable revision
|
|
App->>DB: Replace derived link/search records
|
|
App->>DB: Insert audit event
|
|
App->>Outbox: Insert page.updated event
|
|
DB-->>App: Commit
|
|
App-->>API: DTO + new ETag
|
|
API-->>UI: 200 OK
|
|
```
|
|
|
|
## Data flow: attachment upload
|
|
|
|
Uploads use a bounded streaming pipeline:
|
|
|
|
1. authenticate and authorize;
|
|
2. stream to a quarantined temporary file with a hard size limit;
|
|
3. calculate SHA-256;
|
|
4. inspect signature and type;
|
|
5. reject active/unsafe inline behavior;
|
|
6. atomically move to content-addressed storage;
|
|
7. commit blob/reference metadata;
|
|
8. schedule safe preview generation where supported;
|
|
9. remove temporary data on failure.
|
|
|
|
No ordinary upload is executed or automatically extracted.
|
|
|
|
## Data flow: import
|
|
|
|
1. Discover source in read-only mode.
|
|
2. Fingerprint all relevant source items.
|
|
3. Select a versioned adapter.
|
|
4. Produce a preflight plan with conflicts/ambiguities.
|
|
5. Persist the plan.
|
|
6. Execute in bounded transactional batches with import provenance.
|
|
7. Resolve stable internal relations.
|
|
8. Validate counts, tree, links and file hashes.
|
|
9. Re-fingerprint the source.
|
|
10. Mark complete only when source is unchanged and validation passes.
|
|
|
|
## Background jobs
|
|
|
|
Use database-backed jobs/leases rather than a mandatory external broker.
|
|
|
|
Initial job types:
|
|
|
|
- search projection repair;
|
|
- attachment preview;
|
|
- orphan blob cleanup;
|
|
- import execution and validation;
|
|
- export generation;
|
|
- backup creation and verification;
|
|
- retention purge;
|
|
- outbox dispatch/retention;
|
|
- integrity scan.
|
|
|
|
Jobs require idempotency, bounded retries, backoff, cancellation and administrator-visible
|
|
status.
|
|
|
|
## Configuration
|
|
|
|
Configuration precedence:
|
|
|
|
1. secure mounted secret/file where applicable;
|
|
2. environment variables;
|
|
3. `appsettings.Production.json`;
|
|
4. compiled safe defaults.
|
|
|
|
Database credentials and key material are not stored in repository configuration.
|
|
|
|
## Future evolution
|
|
|
|
Possible later extraction candidates are backup/export workers or an MCP adapter, but only
|
|
after measured pressure. The domain and API boundaries must not assume extraction is
|
|
required.
|