6b3b0360e7
Deliver the demo-ready feature set and seed data so the live site can be presented end to end: - Winner archive: ArchivedWinner domain, admin CRUD endpoints/view/manager and public archive surface, backed by AddArchivedWinners migration. - Host presentation: host image upload and artist name on SiteSettings with public image endpoint and supporting migrations. - Clip submissions: idempotent table-ensure migration plus current-season demo clips for review workflows. - Demo seed data: sponsors, share links and 2025 archived winners, with a guarded RemoveDemoSeasons cleanup; all seeds guard against real data. - EnsureRuntimeSchemaParity migration to align runtime schema defensively. - Admin/home UI refinements; remove unused team role permissions modal and dead share-quick-links code. All seed and schema migrations are idempotent (IF NOT EXISTS / ON CONFLICT) and skip when real season data is present. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
207 lines
7.3 KiB
Markdown
207 lines
7.3 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, 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.
|