Files
vtuber-awards/docs/ARCHITECTURE.md
T
AzuTear fc5c13a4fd Add project documentation and update workflow plan
Adds AGENTS.md, DESIGN.md, and docs/* covering architecture,
conventions, decisions, checklists, branching, release process,
and prompts. Updates README and workflow-feedback-plan to reflect
the decoupled GroupName nomination model.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-28 23:31:13 +02:00

207 lines
7.2 KiB
Markdown

# Architecture
This document describes the structure, boundaries, flows, and technical rules of
the VTuber Star Awards system. For project facts, see [PROJECT.md](PROJECT.md).
For coding standards, see [CONVENTIONS.md](CONVENTIONS.md).
For recorded trade-offs, see [DECISIONS.md](DECISIONS.md).
## High-Level Overview
VTuber Star Awards is a production monorepo with a Vue/Vite frontend, an
ASP.NET Core 8 minimal API backend, and a PostgreSQL database managed by EF Core
migrations.
```mermaid
flowchart LR
Public["Public users"]
Team["Team/admin users"]
Frontend["Vue/Vite frontend"]
Api["ASP.NET Core API"]
Domain["Domain models and services"]
Database["PostgreSQL"]
Twitch["Twitch OAuth"]
CI["Gitea Actions"]
Public --> Frontend
Team --> Frontend
Frontend --> Api
Api --> Domain
Domain --> Database
Api --> Twitch
CI --> Api
CI --> Frontend
CI --> Database
```
The frontend is the user interface. The backend is the source of truth for
season state, content, team permissions, moderation, workflow rules, and public
overview data.
## Architecture Style
| Field | Value |
| --- | --- |
| Style | Layered modular monolith |
| Runtime shape | One frontend app, one backend API, one PostgreSQL database |
| Primary reason | Keep deployment simple while preserving clearer internal feature boundaries. |
| Main trade-off | Boundaries depend on code organization and review discipline rather than service isolation. |
## Repository Structure
```text
VTubeAwards/
frontend/
src/
views/
components/
stores/
lib/
types/
Backend/
Common/
Configuration/
Contracts/
Data/
Domain/
Endpoints/
Extensions/
Migrations/
Repositories/
Security/
Services/
docs/
.gitea/workflows/
```
| Folder | Responsibility |
| --- | --- |
| `frontend/src/views` | Route-level Vue views. |
| `frontend/src/components` | Reusable public/admin UI components and composables. |
| `frontend/src/lib` | API clients, HTTP helpers, formatting, and shared frontend utilities. |
| `frontend/src/types` | TypeScript contract and payload types. |
| `Backend/Endpoints` | Minimal API endpoint groups and endpoint-specific mapping helpers. |
| `Backend/Contracts` | Request and response DTOs. |
| `Backend/Domain` | Persistent domain entities and core business concepts. |
| `Backend/Data` | EF Core `DbContext`, seed/bootstrap code, and design-time setup. |
| `Backend/Repositories` | Domain-specific persistence boundaries. |
| `Backend/Services` | Use-case, audit, session, risk, and workflow services. |
| `Backend/Security` | Session filters, role/permission catalog, and security middleware. |
| `docs` | Durable project, architecture, workflow, and decision documentation. |
## Backend Flow
```mermaid
sequenceDiagram
participant Client as Frontend or API client
participant Endpoint as Minimal API endpoint
participant Filter as Admin/session filter
participant Service as Service or repository
participant Db as EF Core/PostgreSQL
Client->>Endpoint: HTTP request
Endpoint->>Filter: Auth and permission checks when required
Endpoint->>Service: Validate intent and execute use case
Service->>Db: Query or persist through DbContext/repository
Db-->>Service: Domain data
Service-->>Endpoint: Contract DTO
Endpoint-->>Client: JSON response or problem result
```
Endpoint files should stay focused on transport concerns, authorization,
mapping, and orchestration. Domain rules and cross-endpoint behavior belong in
services, repositories, or domain-specific helpers.
## Frontend Flow
```mermaid
flowchart TD
Route["Vue route/view"]
Components["Focused components"]
Composables["Composables and stores"]
ApiClient["frontend/src/lib/api"]
Backend["Backend API"]
Route --> Components
Components --> Composables
Composables --> ApiClient
ApiClient --> Backend
```
Public pages should render backend/admin truth. Admin pages should favor clear
workspace structure, permission-aware controls, explicit loading/error states,
and smaller Vue files split by feature.
## Data Ownership
| Data | Owner | Notes |
| --- | --- | --- |
| Seasons, categories, candidates, winners | Backend | Public and admin views read from canonical backend state. |
| Nominations and clip submissions | Backend | Public writes are validated and reviewed through admin workflows. |
| Site settings, landing content, footer links, showacts, sponsors | Backend | Content hub/admin settings own public presentation data. |
| Team members, roles, permissions, sessions | Backend | UI may hide controls, but API authorization is authoritative. |
| Risk flags and audit entries | Backend | Used for admin review, diagnostics, and accountability. |
| Frontend interaction state | Frontend | Local state is allowed only for view state and unsaved form state. |
## Persistence Boundary
The backend uses EF Core with PostgreSQL. Domain-specific repositories exist for
session, risk flag, and audit behavior. Direct `AwardsDbContext` use is still
acceptable inside endpoint groups or services when the operation is simple and
local to one feature, but repeated or cross-feature persistence behavior should
move behind a repository or focused service.
Production migrations are applied by the Gitea deploy workflow. Development can
auto-apply migrations during API startup.
## Authentication And Authorization
- Team/admin authentication is session-based.
- Twitch OAuth is handled through backend auth endpoints.
- Admin endpoints use session/permission checks at the trusted backend boundary.
- The frontend should reflect permissions to improve UX, but never be the only
authorization layer.
- `creator` is not a normal assignable role in team management.
## Security Posture
| Area | Policy |
| --- | --- |
| CORS | Non-development environments require explicit configured frontend origins. |
| Public writes | Rate-limited and validated server-side. |
| Secrets | Environment variables only; no checked-in production credentials. |
| Demo data | Controlled by seed/demo environment flags. Production defaults must remain safe. |
| Headers | Security headers are applied by backend middleware. |
| Audit | Admin-relevant changes should emit useful audit records where supported. |
## Deployment Flow
```mermaid
flowchart LR
Push["Push to main or manual dispatch"]
Verify["Build, typecheck, hygiene"]
Sync["Sync code to production host"]
Backup["Predeploy PostgreSQL backup"]
Migrate["Apply EF Core migrations"]
Restart["Recreate api and web services"]
Smoke["Health, database, and asset checks"]
Push --> Verify
Verify --> Sync
Sync --> Backup
Backup --> Migrate
Migrate --> Restart
Restart --> Smoke
```
The production deploy path is encoded in `.gitea/workflows/ci.yaml`.
## Known Constraints
- There is no dedicated checked-in test project yet.
- Build/type checks and targeted manual verification are currently required for
most changes.
- Production database migration rollback must be considered before risky schema
changes; the pipeline writes backups but does not make destructive migrations
automatically safe.
- Large admin and public Vue surfaces should continue to be split as they grow.