# HexaHost GameCloud — Implementation Status Last updated: 2026-06-26 ## Current phase: Phase 8 — DNS and join-to-start ✅ ### Phase 8 completed | Area | Status | Notes | |------|--------|-------| | Prisma join/DNS | Done | `joinSlug`, `joinToStartEnabled`, `ServerDnsRecord`, node port ranges | | `@hexahost/dns` | Done | Slug builder, DNS record sync (DB metadata), join address assignment | | API internal edge | Done | `GET/POST /internal/edge/v1/resolve|start/:slug` with API key + rate limits | | Join-to-start start | Done | Edge triggers `startServerInternal` with billing/queue checks | | Worker provision hook | Done | Assigns join slug + DNS after provision completes | | Edge gateway (Go) | Done | TCP listener, Minecraft handshake, proxy + join-to-start | | Web | Done | Join hostname on server card | | Contracts | Done | `join.ts` edge resolve/start schemas, server join fields | ### Abnahmekriterium Phase 8 - [x] Stable join hostname per server (`slug.play.example.net`) - [x] DNS metadata stored (A + SRV for Java) - [x] Edge gateway resolves slug and can start stopped servers - [x] Rate limiting on join-to-start (3/min per slug, 10/min per IP) - [x] Credits/tariff checks on edge-triggered start - [ ] Manual E2E: connect via fixed hostname while server stopped ### Local test 1. `pnpm db:migrate && pnpm db:seed` 2. Set in `.env`: `EDGE_GATEWAY_ENABLED=true`, matching `EDGE_INTERNAL_API_KEY` 3. `pnpm dev` (API + worker) and `cd apps/edge-gateway && go run ./cmd/gateway` 4. Provision server → note `joinHostname` on dashboard 5. Stop server → connect with Minecraft client to join hostname (or `slug.play.localhost` with hosts file) 6. Edge starts server and proxies connection when `RUNNING` ### Edge env defaults (`.env.example`) - `GAME_BASE_DOMAIN=play.example.net` - `EDGE_LISTEN_ADDR=:25565` - `EDGE_INTERNAL_API_KEY=local-dev-edge-key-change-me-32chars` --- ## Phase 7 — Idle shutdown and free tier ✅ ### Phase 7 completed | Area | Status | Notes | |------|--------|-------| | `@hexahost/metering` | Done | RAM-GB-minute credits, Minecraft `list` parser | | Prisma billing models | Done | `CreditWallet`, `CreditTransaction`, `UsageRecord` | | Plan idle/quota fields | Done | Timeouts, countdown, `maxServersPerUser`, `queuePriority` | | Idle controller (worker) | Done | Player poll, countdown, auto-stop | | Usage metering (worker) | Done | 60s tick debits wallet, writes `UsageRecord` | | API billing | Done | `GET /account/wallet`, `GET /account/usage` | | API idle | Done | `GET /servers/:id/idle`, `POST .../idle/extend` | | Quotas & credits | Done | Server create/start guards | | Web | Done | Credit balance on dashboard, idle countdown on server card | ### Abnahmekriterium Phase 7 - [x] Empty running server triggers idle countdown and auto-stop - [x] Player connection cancels countdown (via `list` poll) - [x] Usage debited to credit wallet with ledger + usage records - [x] Free plan grants credits on signup - [x] Server quota per plan enforced - [ ] Manual E2E: start server, wait idle, verify stop + usage ### Local test 1. `pnpm db:migrate && pnpm db:seed` 2. Register/login → dashboard shows **5000 credits** (free plan) 3. Create & start server → credits decrease while running 4. Leave server empty → after ~10 min idle + 60s countdown → auto-stop 5. `GET /account/usage` shows RAM-GB-minute records ### Free plan defaults (seed) - `idleTimeoutMinutes`: 10 - `idleCountdownSeconds`: 60 - `monthlyCreditGrant`: 5000 - `maxServersPerUser`: 3 --- ## Phase 6 — Multi-Node and queue ✅ --- ## Phase 5 — Software & add-ons ✅ --- ## Phase 4 — Worlds & backups ✅ --- ## Phase 3 — Console, files, settings ✅ --- ## Phase 2 — Single-Node Vertical Slice ✅ --- ## Phase 1 — Authentication ✅ --- ## Phase 0 — Monorepo foundation ✅ ### Next phase: Phase 9 — WHMCS integration and production hardening - Billing provider hooks, WHMCS module, production DNS (RFC2136)