# 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.