docs: initialize engineering starter kit

This commit is contained in:
AzuTear
2026-06-28 09:40:40 +02:00
commit ed8efda692
23 changed files with 3131 additions and 0 deletions
+158
View File
@@ -0,0 +1,158 @@
# 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.
```mermaid
flowchart LR
User["Support User"]
Browser["Vue SPA"]
API["ASP.NET Core API"]
Modules["Application Modules"]
Domain["Domain Model"]
Database["PostgreSQL"]
IdP["Identity Provider"]
User --> Browser
Browser --> API
API --> Modules
Modules --> Domain
Modules --> Database
API --> IdP
```
## 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
```text
atlas-desk/
backend/
src/
Requests/
Users/
Reporting/
Shared/
tests/
frontend/
src/
features/
shared/
tests/
docs/
```
| 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.
## Request Flow
```mermaid
sequenceDiagram
participant Browser
participant API
participant Auth
participant Requests
participant Database
Browser->>API: POST /api/requests/{id}/assign
API->>Auth: Check Manager or Agent policy
API->>Requests: AssignRequest command
Requests->>Database: Save assignment and audit event
Database-->>Requests: Commit result
Requests-->>API: Updated request summary
API-->>Browser: 200 OK
```
## 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. |
+93
View File
@@ -0,0 +1,93 @@
# Atlas Desk Conventions
## Naming
- Use support-domain language: request, assignment, note, queue, audit event.
- Use `Async` suffix for asynchronous backend methods.
- Name Vue components by feature and purpose, such as `RequestDetailPanel`.
- Name authorization policies by action, such as `CanAssignRequest`.
## File Organization
- Keep backend files under their owning module.
- Keep Vue components below 250 lines when practical.
- Co-locate component tests with feature components.
- Keep generated API types in `frontend/src/shared/api/generated`.
## Folder Organization
| Folder | Rule |
| --- | --- |
| `backend/src/Requests` | Owns request workflow commands, queries, and domain rules. |
| `backend/src/Shared` | Contains cross-cutting primitives only. |
| `frontend/src/features/requests` | Owns request screens and feature-specific components. |
| `frontend/src/shared` | Contains reusable UI primitives and API utilities. |
## Dependency Injection
- Register backend services by module.
- Inject clocks, email clients, database contexts, and external gateways.
- Do not inject primitive configuration values directly into domain classes.
## Logging
- Use structured logs with `requestId` and `userId` where available.
- Log workflow transitions at information level.
- Log authorization denials at warning level only when they indicate suspicious behavior.
- Do not log customer message bodies.
## Validation
- Validate API DTO shape at the API boundary.
- Validate workflow invariants inside request commands.
- Validate authorization before loading sensitive detail views.
## Error Handling
- Use stable problem codes for client-visible API errors.
- Return validation errors as field-level responses.
- Include correlation IDs in error responses.
- Do not expose stack traces outside local development.
## DTO Rules
- API DTOs are separate from persistence entities.
- Request detail DTOs must not include internal audit metadata unless the user has manager or auditor access.
- Public API changes require a changelog entry.
## Repository Rules
- Keep queries explicit, such as `FindOpenRequestsForQueue`.
- Do not add generic repository abstractions over the database context.
- Write operations that can be retried must be idempotent or transactionally protected.
## Service Rules
- Application services coordinate commands and queries.
- Domain services contain request workflow rules only when the rule spans entities.
- External email delivery is behind an interface.
## Testing
- Unit test request state transitions.
- Integration test authorization and database persistence.
- End-to-end test create, assign, comment, and close workflows.
- Add regression tests for production defects.
## Git Workflow
- Branch names use `feature/`, `fix/`, `refactor/`, `docs/`, or `hotfix/`.
- Squash merge pull requests into `main`.
- Commit messages use imperative summaries.
## Pull Requests
- Include summary, validation, risk, and screenshots for UI changes.
- Include migration notes when database schema changes.
- Keep unrelated refactors in separate pull requests.
## Code Reviews
- Block on correctness, security, data integrity, missing validation, or unclear ownership.
- Prefer suggestions for style issues that are not covered by tooling.
- Ask for ADR updates when a decision changes system structure.
+150
View File
@@ -0,0 +1,150 @@
# Atlas Desk Decisions
## ADR-001: Start With A Modular Monolith
### Status
Accepted
### Date
2026-06-28
### Context
Atlas Desk is new, the team is small, and the request workflow domain is still
evolving. The system needs clear boundaries, but it does not yet need
independent service deployments.
### Problem
The team must choose an architecture that supports maintainability without
adding unnecessary operational complexity.
### Alternatives
| Alternative | Summary |
| --- | --- |
| Layered monolith | Simple, but feature ownership can blur over time. |
| Modular monolith | Clear module boundaries with one deployable unit. |
| Microservices | Strong service isolation but adds network, deployment, and data consistency cost. |
### Pros
- Keeps deployment simple.
- Supports explicit module ownership.
- Allows future service extraction if boundaries prove stable.
### Cons
- Requires discipline to maintain module boundaries.
- Scaling is initially at the application level, not module level.
### Decision
Use a modular monolith for the first production release.
### Consequences
- Module dependency rules are documented in the architecture guide.
- Cross-module writes are not allowed without an application-level command.
- Microservice extraction will be reconsidered only after measured pressure.
## ADR-002: Use PostgreSQL As The Primary Data Store
### Status
Accepted
### Date
2026-06-28
### Context
Atlas Desk needs transactional consistency for request state, assignment, notes,
and audit events.
### Problem
The team needs a reliable primary database that supports relational queries,
transactions, and reporting-friendly indexes.
### Alternatives
| Alternative | Summary |
| --- | --- |
| PostgreSQL | Strong relational database with good operational support. |
| Document database | Flexible schema but weaker fit for transactional queue workflows. |
| Embedded database | Simple locally but not suitable for shared production usage. |
### Pros
- Strong transactions.
- Mature indexing and query capabilities.
- Good fit for reporting queries.
- Broad hosting support.
### Cons
- Schema changes require migration discipline.
- Query performance must be monitored as data grows.
### Decision
Use PostgreSQL as the primary data store.
### Consequences
- Migrations must be reviewed before release.
- Integration tests should run against PostgreSQL, not an incompatible in-memory substitute.
- Backup and restore procedures are production readiness requirements.
## ADR-003: Require Backend Authorization For All Sensitive Actions
### Status
Accepted
### Date
2026-06-28
### Context
The frontend hides actions based on role, but API clients cannot be trusted to
enforce authorization.
### Problem
Sensitive actions such as assignment, closure, and audit viewing must be
protected even if a user bypasses the UI.
### Alternatives
| Alternative | Summary |
| --- | --- |
| Frontend-only checks | Better user experience but not a security boundary. |
| Backend policy checks | Trusted enforcement point. |
| Database row-level security | Strong but more complex than needed initially. |
### Pros
- Keeps authorization in a trusted boundary.
- Makes behavior testable through API integration tests.
- Supports multiple clients later.
### Cons
- Requires explicit policy coverage for each sensitive endpoint.
- UI and API authorization rules can drift without tests.
### Decision
Enforce authorization in backend policies for all sensitive actions.
### Consequences
- Frontend checks remain usability hints only.
- Authorization tests are required for each protected workflow.
- Policy changes must be reviewed as security-sensitive changes.
+93
View File
@@ -0,0 +1,93 @@
# Feature: Request Assignment
## Objective
Allow agents and managers to assign an open support request to an active agent.
## User Or System Value
Support teams can see clear ownership for every active request and reduce
duplicate work.
## Requirements
- Agents can assign unowned requests to themselves.
- Managers can assign requests to any active agent.
- Assignment creates an audit event.
- Closed requests cannot be reassigned.
## Non-Goals
- Automated assignment rules.
- Workload balancing.
- External notifications beyond a basic assignment event.
## Acceptance Criteria
- [ ] An agent can assign an unowned open request to themselves.
- [ ] A manager can assign an open request to another active agent.
- [ ] A non-manager cannot assign a request to another user.
- [ ] Closed requests return a domain error when assignment is attempted.
- [ ] Every successful assignment writes an audit event.
## Architecture Notes
- Affected modules: Requests, Users.
- Dependency concerns: Requests queries Users through a user lookup interface.
- Data ownership: Requests owns assignments and audit events.
- Related ADRs: ADR-001, ADR-003.
## API Or Interface Changes
```http
POST /api/requests/{requestId}/assignment
Content-Type: application/json
{
"assigneeUserId": "usr_123"
}
```
Successful response:
```json
{
"requestId": "req_456",
"assigneeUserId": "usr_123",
"status": "open"
}
```
## Data Changes
- Add `assigned_to_user_id` to requests if not already present.
- Add `RequestAssigned` audit event type.
- Index active requests by assigned user for queue views.
## Security And Authorization
- Authenticated agents can assign requests to themselves.
- Managers can assign requests to any active agent.
- Backend policies enforce assignment permissions.
- Frontend controls are not considered a security boundary.
## Testing Plan
- Unit: request assignment state transitions and closed-request rejection.
- Integration: authorization cases and audit event persistence.
- End-to-end: create request, assign, and confirm queue ownership changes.
- Manual: verify manager and agent UI states.
## Rollout Plan
Deploy backend and frontend together. Run a smoke test that assigns a staging
request as an agent and as a manager.
## Risks
- Authorization drift between UI and API.
- Assignment race when two users assign the same request at the same time.
## Open Questions
- Should assignment notify the assignee immediately in the first release?
+167
View File
@@ -0,0 +1,167 @@
# Atlas Desk
Atlas Desk is a fictional internal support workflow system for small operations
teams.
## Vision
Give support teams one reliable place to triage customer requests, assign work,
track status, and understand operational bottlenecks without relying on shared
mailboxes or spreadsheets.
## Goals
- Reduce average request triage time by 40 percent.
- Make ownership and status visible for every support request.
- Provide an audit trail for customer-impacting decisions.
## Non-Goals
- Replace the billing system.
- Provide public customer self-service in the first release.
- Support multi-region deployment before usage requires it.
## Functional Requirements
| ID | Requirement | Priority | Status |
| --- | --- | --- | --- |
| FR-001 | Agents can create, assign, and close support requests. | Must | Accepted |
| FR-002 | Managers can view queue health and overdue work. | Must | Accepted |
| FR-003 | Users can add internal notes to requests. | Should | Proposed |
| FR-004 | The system sends notifications when ownership changes. | Should | Proposed |
## Non-Functional Requirements
| Category | Requirement | Measurement |
| --- | --- | --- |
| Availability | Available during support hours. | 99.5 percent monthly uptime. |
| Performance | Common list and detail views feel immediate. | P95 API latency below 300 ms for core endpoints. |
| Security | Only authorized users can view or mutate requests. | Authorization tests cover each role. |
| Privacy | Customer contact data is minimized and auditable. | Sensitive fields are excluded from debug logs. |
| Maintainability | New queue workflows can be added without rewriting the core model. | Feature modules own their workflows. |
## Users And Roles
| Role | Description | Key Permissions |
| --- | --- | --- |
| Agent | Handles support requests. | Create, update, assign, comment, close. |
| Manager | Oversees queue health. | All agent permissions plus reporting and reassignment. |
| Auditor | Reviews historical activity. | Read-only access to requests and audit events. |
## Tech Stack
| Area | Choice | Notes |
| --- | --- | --- |
| Language | C# and TypeScript | Backend and frontend use separate type systems. |
| Framework | ASP.NET Core and Vue | Conventional web application stack. |
| Frontend | Vue 3 | Single-page application. |
| Backend | ASP.NET Core | Modular monolith API. |
| Database | PostgreSQL | Primary transactional store. |
| Messaging | None initially | Reconsider if notification volume grows. |
| Search | PostgreSQL full-text search | Sufficient for initial request search. |
| Cache | None initially | Add only after measured pressure. |
## Runtime
| Environment | Purpose | URL or Entry Point | Notes |
| --- | --- | --- | --- |
| Local | Development | `https://localhost:5173` | Frontend talks to local API. |
| Test | Automated validation | CI service containers | Uses ephemeral PostgreSQL. |
| Staging | Release verification | `https://staging.atlas-desk.example` | Mirrors production config. |
| Production | Live system | `https://atlas-desk.example` | Single-region deployment. |
## Infrastructure
| Component | Provider | Responsibility | Notes |
| --- | --- | --- | --- |
| Hosting | Managed container platform | Run API and frontend assets. | One service initially. |
| Storage | PostgreSQL managed database | Store requests, users, audit events. | Daily backups. |
| Network | Managed load balancer | TLS and routing. | Internal admin access restricted. |
## Database
| Field | Value |
| --- | --- |
| Database engine | PostgreSQL |
| Migration tool | Entity Framework Core migrations |
| Backup strategy | Daily automated backup with 14-day retention |
| Restore strategy | Restore to staging monthly as a drill |
| Data retention | Closed requests retained for 3 years |
## CI/CD
| Pipeline | Trigger | Required Checks | Notes |
| --- | --- | --- | --- |
| CI | Pull request and push to main | Build, unit tests, integration tests, lint | Blocks merge. |
| Deploy staging | Push to main | CI success | Automatic. |
| Deploy production | Manual approval | Staging smoke test | Release owner approves. |
## Deployment
| Area | Policy |
| --- | --- |
| Deployment strategy | Rolling container deployment |
| Rollback strategy | Redeploy previous image and disable feature flags |
| Release owner | Support platform maintainer |
| Change window | Weekdays before 15:00 local support time |
## Authentication
| Field | Value |
| --- | --- |
| Authentication method | OpenID Connect |
| Identity provider | Company identity provider |
| Session model | Secure HTTP-only cookie |
| Token lifetime | 8-hour workday session |
## Authorization
| Field | Value |
| --- | --- |
| Authorization model | Role-based access with policy checks |
| Role source | Identity provider group claims synchronized at login |
| Policy location | Backend authorization policies |
| Audit requirements | Assignment and close actions generate audit events |
## Logging
| Field | Value |
| --- | --- |
| Logging library | Structured backend logging |
| Log sink | Central log service |
| Correlation ID | Created at API edge and returned in responses |
| Sensitive data policy | Do not log customer email bodies or tokens |
## Monitoring
| Signal | Tool | Alert Policy |
| --- | --- | --- |
| Availability | Health checks | Alert after 3 failed checks. |
| Errors | Error tracking | Alert on elevated 5xx rate. |
| Performance | API metrics | Alert when P95 exceeds 500 ms for 15 minutes. |
| Business metrics | Queue dashboard | Alert managers when overdue work exceeds threshold. |
## Testing
| Test Type | Tooling | Required When |
| --- | --- | --- |
| Unit | Backend and frontend test runners | Domain rules, view logic, formatters. |
| Integration | API tests with PostgreSQL | Persistence, auth, and queue workflows. |
| End-to-end | Browser automation | Critical request lifecycle. |
| Performance | Scripted API checks | Before major queue or reporting changes. |
| Security | Dependency audit and auth tests | Each release candidate. |
## Roadmap
| Milestone | Target | Outcome |
| --- | --- | --- |
| M1 | Q1 | Request intake, assignment, and closure. |
| M2 | Q2 | Reporting dashboard and overdue alerts. |
| M3 | Q3 | Customer-visible request status page. |
## Open Questions
| Question | Owner | Needed By | Status |
| --- | --- | --- | --- |
| Should notification delivery use email only or chat integration too? | Product | M2 planning | Open |
| Is audit export required for compliance reviews? | Operations | M1 release | Open |