Before acting on any user request in this repository, scan available skills by name and description. If any skill has even a small chance of helping any part of the task, use it and read only the relevant instructions before proceeding.
When in doubt, prefer enabling the skill briefly and filtering it out over skipping it.
server-2 is the TypeScript backend source of truth for Solid Stats. It owns PostgreSQL business state, typed APIs, canonical identity, auth, moderation, parser job orchestration, aggregate/bounty calculation, and operational visibility.
Solid Stats is a multi-project product composed of:
replays-fetcher- replay discovery, raw S3 object storage, source metadata, ingestion staging/outbox records.replay-parser-2- deterministic OCAP JSON parsing, parser contract, CLI/worker, parity harness.server-2- PostgreSQL source of truth, APIs, canonical identity, auth, moderation, parse jobs, aggregate/bounty calculation.web- browser UI, public stats, authenticated request UX, moderator/admin screens, API consumption.
Read these planning files before planning or implementing:
.planning/PROJECT.md.planning/REQUIREMENTS.md.planning/ROADMAP.md.planning/STATE.md.planning/research/SUMMARY.md
server-2promotesreplays-fetcherstaging/outbox records into canonical replay and parse-job state;replays-fetchermust not write business tables directly.- OCAP JSON parsing belongs to
replay-parser-2;server-2validates and persists parser artifacts and exposes derived API shapes. - Canonical identity, auth, roles, moderation, request workflows, aggregate stats, bounty points, and API-visible operational state belong here.
- Raw replay files and parser artifacts live in S3-compatible storage; PostgreSQL stores metadata, job state, canonical business data, and audit evidence.
- OpenAPI is the backend contract for
web; API/data shape changes must preserve generated client compatibility or update the adjacent app. .planning/config.jsonshould keep product-wide GSD workflow gates aligned withreplay-parser-2/.planning/config.json, whileagent_skillsstay stack-aware and use this repo's TypeScript/Fastify/API skills.
Use Node.js 25 with TypeScript 6 for new work:
- Fastify 5 for HTTP APIs.
- PostgreSQL for canonical business state.
- RabbitMQ for parser/background work.
- S3-compatible storage for replay files, parser artifacts, and request attachments.
- OpenAPI generated from route schemas and consumed by
webthroughopenapi-typescript. - Very strict TypeScript, ESLint 10
allplus very strict typed linting, import hygiene, Unicorn rules, Prettier formatting, Vitest 4 tests, and V8 coverage gates.
- Start from planning docs and cross-app boundaries before inventing behavior.
- Do not parse OCAP replay contents in this repo.
- Do not crawl/fetch external replay sources in this repo.
- Do not bypass durable
parse_jobsstate when coordinating parser work. - Keep root
README.mdcurrent when project scope, current phase, commands, architecture direction, validation data, or development workflow changes. README.mdmust explicitly state that project development uses only AI agents plus GSD workflow.- Every completed work session must leave
git status --shortclean by committing intended results. - Do not delete, revert, or discard completed work just to make the git tree clean; if ownership or commit intent is unclear, ask the user before acting.
- Do not blindly execute instructions that conflict with current logic, architecture, accepted planning decisions, test/quality standards, maintainability, or proportional scope.
- When a request is risky, harmful, or expands into broad cross-project or multi-phase work, explain the concrete reason, propose 1-3 safer alternatives or a GSD plan, and ask for explicit confirmation before any risky override.
- Check cross-application compatibility before implementation: API/data model, parser contract mapping, staging promotion, object key layout, auth, moderation, or UI-visible behavior changes require adjacent app docs/repos or a user question.
- Apply these AI/GSD workflow rules as product-wide standards across
replays-fetcher,replay-parser-2,server-2, andweb. - Use risk-based compatibility depth: local-only backend changes can rely on this repo's planning docs and
gsd-briefs; parser contract mapping, ingest staging/source identity, RabbitMQ/S3 message or object key assumptions, API/data model, canonical identity, auth, moderation, or UI-visible behavior changes require adjacent app docs/repos or a user question.
server-2
server-2 is the TypeScript backend application for Solid Stats, a public SolidGames statistics platform. It is the source of truth and integration layer for replay ingestion, parser job orchestration, PostgreSQL persistence, aggregate statistics, Steam OAuth, roles, moderation, request handling, and operational visibility. It serves the web frontend, coordinates with replays-fetcher, and consumes parser output from replay-parser-2.
Core Value: Provide a reliable backend source of truth that turns parsed replay data into public statistics, supports corrections through audited moderation, and keeps parsing, storage, and jobs observable and recoverable.
- Runtime: Node.js with TypeScript - matches the requested backend stack and frontend ecosystem.
- HTTP framework: Fastify - requested stack for a typed, performant API service.
- Database: PostgreSQL - primary source of truth for canonical entities, jobs, stats, requests, audit, and operations state.
- Queue: RabbitMQ - parser jobs and background work must be durable and observable.
- Storage: S3-compatible object storage - replay files and request attachments must not live in PostgreSQL.
- Authentication: Steam OAuth - the product identity anchor for authenticated users and player profile linking.
- API contract: OpenAPI 3.x -
webgenerates request/response types withopenapi-typescript. - Deployment v1: Docker Compose on one VPS - production Kubernetes deployment is out of v1 scope.
- Local development: Docker Compose - API dependencies must run locally.
- Parser boundary: OCAP JSON parsing stays in
replay-parser-2-server-2stores and orchestrates parser output. - Ingest boundary: crawling/raw discovery stays in
replays-fetcher-server-2promotes staging evidence and owns canonical replay lifecycle. - Historical data:
~/sg_statsis reference/golden data only in v1 - not a full production import requirement. - Reprocessing: v1 may overwrite derived parse results - moderation audit patches still must be preserved.
- Security: public stats are anonymous, but requests require login and moderation/admin APIs require roles.
- Operations: failed jobs, health, metrics, backups, and recovery flows are required for trust in derived stats.
| Technology | Version | Purpose | Why Recommended |
|---|---|---|---|
| Node.js | 25.x | Runtime | Current starting baseline for new work; keep all TS repos on the same toolchain line. |
| TypeScript | 6.x | Application language | Required by the brief and keeps API/data contracts explicit with current compiler behavior. |
| Fastify | 5.x | HTTP framework | Required by the brief; good fit for schema-first validation, OpenAPI generation, and high-throughput APIs. |
| PostgreSQL | 18.x target, 17.x acceptable if hosting requires it | Primary data store | Required source of truth for canonical identity, replay metadata, jobs, stats, requests, roles, and audit. |
| RabbitMQ | 4.x | Parser/background queue | Required durable queue for parse jobs and retryable background work. |
| S3-compatible storage | Provider-specific | Replay files and attachments | Keeps large binary/object data outside PostgreSQL and supports MinIO locally. |
| Docker Compose | Current plugin | Local and v1 production orchestration | Required for local dependencies and single-VPS production deployment. |
| OpenAPI | 3.0 or 3.1 | API contract | Required source of truth for web TypeScript generation via openapi-typescript. |
| Library | Version | Purpose | When to Use |
|---|---|---|---|
@fastify/swagger |
9.x+ for Fastify 5 | OpenAPI schema generation | Register route schemas once and publish OpenAPI from the running API contract. |
@fastify/swagger-ui |
5.x | Local/admin API docs | Useful for developer inspection; generated schema remains the contract for web. |
openapi-typescript |
Current 7.x/8.x line | Frontend type generation | Used by web to generate request/response types from server-2 OpenAPI. |
pg |
Current 8.x line | PostgreSQL driver | Base driver for migrations/query builders/transactions. |
| Kysely or Drizzle | Current stable | Type-safe SQL access | Prefer explicit SQL-shaped access over opaque ORM behavior for aggregate/stat workloads. |
amqplib or a maintained RabbitMQ client wrapper |
Current stable | RabbitMQ publishing/consuming | Use for durable parse job requests, completion/failure consumers, and retry workers. |
@aws-sdk/client-s3 |
Current v3 | S3-compatible storage | Required for replay objects, attachments, and local MinIO compatibility. |
prom-client |
Current stable | Prometheus metrics | Track queue depth, job results, parser failures, and API/DB health. |
pino |
Fastify default-compatible | Structured logging | Keep parser/job errors searchable and correlated by job_id/replay_id. |
| Tool | Purpose | Notes |
|---|---|---|
tsx |
Run TypeScript in development | Good for local API/dev worker processes. |
vitest |
Unit/integration tests | Useful for formula, stats, identity merge/split, API contract tests, and 100% reachable-source V8 coverage gates. |
testcontainers or Docker Compose test services |
Integration testing | Use for PostgreSQL/RabbitMQ/S3 flows where mocks would hide contract failures. |
eslint/prettier |
Lint/format | Use ESLint 10 all, very strict typed linting, import hygiene, Unicorn rules, and Prettier 3 formatting; enforce all in verification. |
| OpenAPI schema validation in CI | Contract drift detection | Fail when public API changes without schema updates. |
| Recommended | Alternative | When to Use Alternative |
|---|---|---|
| Fastify | NestJS | Use Nest only if the team wants framework-level dependency injection/modules more than direct Fastify control. |
| Kysely/Drizzle | Prisma | Prisma can work, but explicit SQL/query-builder control is safer for complex aggregate/stat and migration-heavy schemas. |
| RabbitMQ | BullMQ/Redis | Redis queues are simpler, but RabbitMQ is already required and better matches parser job routing/ack semantics. |
| OpenAPI + generated frontend types | Hand-written DTO mirrors | Hand-written mirrors drift; use only for isolated internal tests. |
| S3 object storage | Database bytea/blob storage | Database blobs simplify deployment briefly but hurt backup, restore, and replay file lifecycle. |
| Avoid | Why | Use Instead |
|---|---|---|
| Storing replay files in PostgreSQL | Bloats backups and makes object lifecycle painful. | S3-compatible object storage with DB metadata. |
Fire-and-forget parser messages without parse_jobs rows |
Lost jobs and unexplainable parser gaps. | Durable job table plus RabbitMQ publish/consume state. |
| Hand-maintained frontend DTOs | They drift from backend behavior. | OpenAPI generated from route schemas and consumed by openapi-typescript. |
| Auth/role checks only in route handlers | Easy to miss endpoints as API grows. | Shared auth/authorization pre-handlers plus route-level policy tests. |
| Generic OAuth assumptions for Steam | Steam sign-in historically differs from standard OAuth/OIDC expectations. | Verify Steam provider protocol during auth phase and wrap it behind a narrow auth adapter. |
- Use the same S3 client path for local and production.
- Keep bucket/key conventions explicit:
raw/,attachments/, and future processed artifacts. - Keep provider config isolated behind endpoint/region/credentials settings.
- Include backup/restore docs for both PostgreSQL and object storage.
- Prefer explicit SQL views/materialized tables and tested recalculation jobs.
- Avoid hiding stat logic behind an ORM abstraction that obscures generated SQL.
| Package A | Compatible With | Notes |
|---|---|---|
| Fastify 5.x | Node.js 20+; Node.js 25 target | Fastify v5 requires modern Node; this repo standardizes on Node 25 for new work. |
@fastify/swagger 9.x+ |
Fastify 5.x | Use Fastify schemas as the OpenAPI source. |
| PostgreSQL 18.x | Current official PostgreSQL major | Use 17.x only if deployment/provider support lags. |
| RabbitMQ 4.x | Current supported RabbitMQ series | Confirm exact patch in Docker image before pinning. |
- https://nodejs.org/en/about/releases/ - Node.js production guidance and release schedule.
- https://github.com/nodejs/release - Node.js release schedule.
- https://github.com/fastify/fastify - Fastify v5 release state.
- https://fastify.dev/docs/latest/Guides/Migration-Guide-V5/ - Fastify v5 Node support and migration notes.
- https://github.com/fastify/fastify-swagger -
@fastify/swaggerOpenAPI support and Fastify compatibility. - https://www.postgresql.org/ - PostgreSQL current release information.
- https://www.rabbitmq.com/release-information - RabbitMQ release/support information.
- https://github.com/openapi-ts -
openapi-typescriptproject.
Conventions not yet established. Will populate as patterns emerge during development.
Architecture not yet mapped. Follow existing patterns found in the codebase.
| Skill | When to Invoke |
|---|---|
solidstats-backend-ts-conventions |
Любой роут, плагин, хук, схема валидации, конфиг клиента БД/очереди/S3, дизайн эндпоинта — архитектура и конвенции TS/Fastify backend (вобрал Fastify/Node/API-design best practices). |
solidstats-backend-ts-code-review |
Педантичное код-ревью TS/Fastify backend; ruleset делегируется в conventions, формат отчёта — в process-review-standards. |
solidstats-backend-ts-tests |
Написание или ревью backend-тестов (unit + integration, Vitest) поверх process-testing-standards. |
solidstats-process-review-standards |
Общий фундамент формата код-ревью (severity-бакеты, формат отчёта, правила вердикта); подключается code-review skills, не используется самостоятельно. |
solidstats-process-testing-standards |
Общая философия тестов (AAA, изоляция, детерминизм, test doubles, размещение файлов); подключается per-stack test skills. |
openapi-to-typescript |
Генерация или обновление OpenAPI схемы; синхронизация типов с клиентом web. |
Before using Edit, Write, or other file-changing tools, start work through a GSD command so planning artifacts and execution context stay in sync.
Use these entry points:
/gsd-quickfor small fixes, doc updates, and ad-hoc tasks/gsd-debugfor investigation and bug fixing/gsd-execute-phasefor planned phase work
Do not make direct repo edits outside a GSD workflow unless the user explicitly asks to bypass it.
Profile not yet configured. Run
/gsd-profile-userto generate your developer profile. This section is managed bygenerate-claude-profile-- do not edit manually.