Splits AdminSeasonsView into AdminSeasonOverviewCard and AdminSeasonWorkflowCard for cleaner separation of concerns. Adds SeedSponsorsBootstrapper with demo sponsor SVG assets and extends SeedCatalog with sponsor seed entries. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend
PostgreSQL
The API targets PostgreSQL through EF Core 8 and Npgsql.EntityFrameworkCore.PostgreSQL.
Local development is aligned with ../docker-compose.dev.yml and appsettings.Development.json:
Host=localhost;Port=5433;Database=vtuber_star_awards_dev;Username=vtsa_dev;Password=change-me-local-only
For production or shared deployments, keep checked-in appsettings empty and provide your own value through:
VTSA_POSTGRES
ConnectionStrings__Postgres
The API reads its connection string from:
- environment variable
VTSA_POSTGRES - environment variable
ConnectionStrings__Postgres
Presentation/demo data is controlled separately:
VTSA_SEED_MODE=demo
demo,presentationorsample: seed local presentation data.none,off,disabledor an unset value in Production: do not seed presentation data.Backend/appsettings.Development.jsondefaults todemo;Backend/appsettings.jsondefaults tonone.
If Docker is available locally, start a dev database from the repository root with:
docker compose -f docker-compose.dev.yml up -d
Commands
Restore and build:
dotnet restore
dotnet build
Create a migration:
dotnet ef migrations add InitialCreate
Generate a SQL migration script:
dotnet ef migrations script 0 20260617060000_InitialCreate --output Migrations/InitialCreate.sql
Apply migrations once PostgreSQL is running:
dotnet ef database update
Fallback bootstrap if dotnet ef is not usable in the current environment:
psql "$VTSA_POSTGRES" -f Migrations/InitialCreate.manual.sql
Run the API:
ASPNETCORE_ENVIRONMENT=Development dotnet run --urls http://127.0.0.1:5084
Check the API and database wiring:
curl http://127.0.0.1:5084/api/health
curl http://127.0.0.1:5084/api/health/database
Development auth/session:
curl -X POST http://localhost:5084/api/auth/dev-login \
-H "Content-Type: application/json" \
-d '{"twitchUserId":"jayuhime_admin","displayName":"Jayuhime Admin","role":"admin"}'
Demo admin login for public presentations:
VTSA_DEMO_LOGIN_ENABLED=true
VTSA_DEMO_ADMIN_LOGIN=jayuhime_admin
VTSA_DEMO_ADMIN_EMAIL=admin@example.local
VTSA_DEMO_ADMIN_PASSWORD=<set-secure-demo-password>
VTSA_DEMO_ADMIN_TWITCH_ID=jayuhime_admin
VTSA_DEMO_ADMIN_DISPLAY_NAME=Jayuhime Admin
The frontend route is /login. VTSA_DEMO_ADMIN_LOGIN may be a username or an email-style identifier; the backend also accepts the configured email, Twitch ID, and display name for admin flexibility. Disable the demo login for release with VTSA_DEMO_LOGIN_ENABLED=false.
Team owner bootstrap credentials are separate from demo login credentials:
VTSA_TEAM_OWNER_PASSWORD=<set-secure-owner-password>
VTSA_TEAM_CREATOR_PASSWORD=<set-secure-creator-password>
These fixed owner/creator credentials are authoritative on API startup. If a personal team account gets locked out after an admin reset, redeploying with the configured environment password restores the login.
Frontend app-wide demo gate:
VITE_DEMO_GATE_ENABLED=true
true: if/api/public/site-statusis unavailable, the Vue app still starts at/loginuntil a session exists.- unset or
false: if/api/public/site-statusis unavailable, public pages such as/remain visible without the initial demo login.
When /api/public/site-status is reachable, the backend demoLoginEnabled flag is authoritative.