# 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, archived winners | Backend | Public and admin views read from canonical backend state; historical archive winners are managed separately from current season winner publication. |
| 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.
