Atlas Desk Architecture
Atlas Desk uses a modular monolith with a Vue frontend, ASP.NET Core API, and
PostgreSQL database.
High-Level Overview
The system is deployed as one backend service and one frontend artifact. The
backend owns authentication integration, authorization, request workflows, audit
events, and persistence. The frontend renders queue workflows and calls the API.
Architecture Style
| Field |
Value |
| Style |
Modular monolith |
| Primary reason |
Small team, shared database, evolving domain boundaries. |
| Main trade-off |
Requires discipline to prevent module coupling. |
| Related decision |
ADR-001 in DECISIONS.example.md. |
Folder Structure
| Folder |
Responsibility |
backend/src/Requests |
Request lifecycle, assignment, notes, and closure. |
backend/src/Users |
User profile and role synchronization. |
backend/src/Reporting |
Queue health and manager dashboards. |
frontend/src/features |
User-facing feature modules. |
frontend/src/shared |
Reusable UI and API utilities. |
Module Responsibilities
| Module |
Responsibility |
Owned Data |
Public Interface |
| Requests |
Support request workflow. |
Requests, notes, assignments, audit events. |
Request commands and query endpoints. |
| Users |
Local user profile and role cache. |
Users and role snapshots. |
User lookup service. |
| Reporting |
Aggregated queue health views. |
Read models derived from requests. |
Reporting queries. |
Dependency Rules
- Feature modules may depend on
Shared.
Reporting reads request data through query interfaces, not direct mutation.
- Domain rules do not depend on HTTP, Vue, or database APIs.
- Infrastructure implementations depend inward on application contracts.
Persistence Boundary
Atlas Desk uses the repository pattern for persistence boundaries.
- Repository interfaces live in the owning backend module.
- Repository implementations live in the module's infrastructure or persistence
folder.
- Repositories are domain-specific, such as
RequestRepository and
UserRepository.
- Application services coordinate transactions for workflows that write multiple
records, such as assignment plus audit event creation.
- Generic CRUD repositories are not used because they hide workflow intent.
Request Flow
Data Flow
| Data |
Source |
Owner |
Storage |
Consumers |
| Support request |
Agent or imported email |
Requests module |
PostgreSQL |
Agents, managers, reporting. |
| User role |
Identity provider |
Users module |
PostgreSQL role snapshot |
Authorization policies. |
| Queue metrics |
Request state changes |
Reporting module |
Materialized query table |
Manager dashboard. |
Domain Model
| Concept |
Meaning |
Invariants |
| Request |
A customer support item requiring work. |
Must have status, priority, creator, and audit history. |
| Assignment |
Ownership of a request by a user. |
Only active users can own open requests. |
| Audit Event |
Immutable record of important workflow action. |
Cannot be edited after creation. |
Integration Points
| Integration |
Direction |
Protocol |
Reliability Expectations |
| Identity provider |
Outbound |
OpenID Connect |
Login must fail closed if identity cannot be verified. |
| Email notifications |
Outbound |
SMTP or provider API |
Retry transient failures; never block core assignment transaction. |
Security
| Area |
Policy |
| Authentication |
All application routes require authenticated users. |
| Authorization |
Backend policies enforce role and ownership checks. |
| Secrets |
Secrets are environment-provided and never committed. |
| Input validation |
API validates DTO shape before command execution. |
| Output encoding |
Frontend renders user content safely through framework escaping. |
| Audit logging |
Assignment, closure, and role changes create audit events. |
| Dependency security |
CI runs dependency audit before release. |
Error Handling
| Error Type |
Handling Policy |
User/Client Response |
| Validation error |
Return field-level errors. |
400 with validation details. |
| Domain error |
Return stable problem code. |
409 or 422 with safe message. |
| Infrastructure error |
Log with correlation ID and retry if safe. |
503 for transient failures. |
| Unexpected error |
Log, alert if elevated, hide details. |
500 with correlation ID. |
Performance
| Concern |
Expectation |
Measurement |
| Latency |
P95 below 300 ms for core endpoints. |
API metrics. |
| Throughput |
100 concurrent active users. |
Load test before production launch. |
| Resource usage |
Single service fits standard container profile. |
Runtime metrics. |
Scalability
| Dimension |
Current Strategy |
Future Strategy |
| Traffic |
Single API service with horizontal scaling. |
Split reporting read model if dashboards become expensive. |
| Data volume |
PostgreSQL indexes for active queue queries. |
Archive closed requests older than retention threshold. |
| Team size |
Module ownership within one repo. |
Extract services only after boundaries and ownership stabilize. |