- Kotlin 72.6%
- Svelte 16.8%
- TypeScript 9.1%
- HTML 0.6%
- JavaScript 0.4%
- Other 0.4%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| backend | ||
| deploy | ||
| docs | ||
| frontend | ||
| review-findings | ||
| .gitignore | ||
| CLAUDE.md | ||
| CLAUDE_CODE_PROMPT.md | ||
| docker-compose.yml | ||
| PLAN.md | ||
| README.md | ||
| renovate.json | ||
gptiers
If I pay for Ultimate instead of Premium, what games do I actually get?
A self-hosted web app that answers exactly that question. Compares Xbox Game
Pass tiers (Essential / Premium / Ultimate / PC Game Pass) against the live
catalogs at catalog.gamepass.com and displaycatalog.mp.microsoft.com,
keeps a history per (game, tier, market), and exposes the diff via REST and
a Svelte UI.
For 2026-04 NL, the headline answer is: upgrading from Premium to Ultimate unlocks 139 additional games. That's the kind of thing this app exists for.
Quickstart (local)
You need Docker, Java 21+, Node 20+, Maven 3.9+.
# 1. Postgres
docker run -d --name gptiers-pg \
-e POSTGRES_PASSWORD=devpw -e POSTGRES_USER=gptiers -e POSTGRES_DB=gptiers \
-p 127.0.0.1:5433:5432 postgres:16-alpine
# 2. Backend
DB_URL=jdbc:postgresql://localhost:5433/gptiers \
DB_USERNAME=gptiers DB_PASSWORD=devpw \
GPTIERS_ADMIN_USERNAME=admin \
GPTIERS_ADMIN_PASSWORD=local-dev-password-1234 \
mvn -B -f backend/pom.xml spring-boot:run
# 3. Frontend (separate terminal — Vite proxies /api to localhost:8080)
cd frontend && npm install && npm run dev
# 4. Visit http://localhost:5173, navigate to /login, and sign in
# with username 'admin' + the GPTIERS_ADMIN_PASSWORD you set above.
# The Admin page has buttons to trigger syncs.
Layout
backend/ Spring Boot 3.4 + Kotlin 2.1 + Spring Security 6 + JPA + Liquibase
frontend/ Svelte 5 + Vite + Tailwind 4 (SPA, login + admin pages included)
deploy/ docker-compose.yml runbook + Caddy snippet (see deploy/README.md)
docs/ Cowork-produced API discovery notes
.forgejo/workflows/ CI: build and push both images on develop / main
docker-compose.yml Production stack at the repo root
renovate.json Dependency updater config
PLAN.md Phase-by-phase project plan
CLAUDE_CODE_PROMPT.md Kickoff prompt for the agent that built this
Endpoints
Public read API
GET /api/tiers tier+benefit catalog with current counts
GET /api/tiers/{tier}/games paginated, filter by category/publisher/first-party
GET /api/tiers/{tier}/categories distinct categories for a tier
GET /api/tiers/{tier}/publishers publisher groups for a tier
GET /api/benefits/{benefit}/games same shape as tier games, for EA Play / Ubisoft+
GET /api/benefits/{benefit}/categories distinct categories for a benefit
GET /api/benefits/{benefit}/publishers publisher groups for a benefit
GET /api/diff?from=premium&to=ultimate games in `to` but not in `from`
GET /api/games/{bigId} detail + full membership history
GET /api/recent?tier=ultimate&days=30 recently added to a tier or benefit (use ?benefit=)
GET /api/stats/history?tier=ultimate&days=90 snapshot count over time (or ?benefit=)
GET /api/version git sha + build time of the running image
GET /actuator/health uptime check
GET /v3/api-docs OpenAPI 3.1 spec
GET /swagger-ui.html Swagger UI
Admin (Spring Security form-login)
POST /admin/login username + password, sets JSESSIONID
POST /admin/logout clears the session
GET /admin/me current authentication
GET /admin/sync-runs paginated audit log
POST /admin/sync?tier=… sync one tier
POST /admin/sync/benefit?benefit=… sync one benefit (unions console + PC)
POST /admin/sync/run the full daily job, on demand
Easiest path is the SPA admin page at /admin — sign in at /login with
the configured username/password and the page exposes one-click triggers
for all of the above plus a recent-runs table. The deploy doc has a curl
fallback if you really need it.
Tests
mvn -B -f backend/pom.xml test # full backend suite (Testcontainers)
cd frontend && npx svelte-check # frontend type-check
JaCoCo report after mvn test is at backend/target/site/jacoco/index.html.
Deploy
The runbook for putting this on an Oracle VPS behind Caddy is in
deploy/README.md. Short version: pull the two images
from the Forgejo registry, set .env (DB password + admin password +
optional username override), docker compose up -d, append the Caddy
snippet (one reverse_proxy line — the frontend nginx handles the
/api and /admin split internally), point DNS, done.
Project plan
See PLAN.md for the phase-by-phase plan and the conventions
the code follows. All six phases are complete and the stack runs on the
VPS; ongoing work is incremental polish on top.