Files
HexaHost-GameCloud/docs/IMPLEMENTATION_STATUS.md
smueller ed8334328e
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 9s
CI / Go — node-agent tests (push) Failing after 8s
CI / Go — edge-gateway build (push) Successful in 17s
Phase9
2026-06-26 13:46:25 +02:00

160 lines
5.6 KiB
Markdown

# HexaHost GameCloud — Implementation Status
Last updated: 2026-06-26
## Current phase: Phase 9 — WHMCS integration and production hardening ✅
### Phase 9 completed
| Area | Status | Notes |
|------|--------|-------|
| WHMCS Prisma models | Done | Installations, client/service links, idempotent operations |
| `@hexahost/integration-auth` | Done | HMAC-SHA256 request signing |
| WHMCS Integration API | Done | `/api/v1/integrations/whmcs/*` with nonce replay protection |
| Billing suspension | Done | `billingSuspendedAt`, blocks start/join-to-start |
| Billing provider mode | Done | `BILLING_PROVIDER=internal\|whmcs` |
| RFC2136 DNS provider | Done | `nsupdate` + worker DNS sync tick |
| WHMCS PHP module | Done | Create/Suspend/Unsuspend/Terminate/ChangePackage |
| Ansible playbooks | Done | `site.yml`, `control-plane.yml`, `game-node.yml` |
| Operations docs | Done | `dns.md`, `control-plane.md`, `game-node.md` |
### Abnahmekriterium Phase 9
- [x] WHMCS can provision/suspend/unsuspend/terminate via signed API
- [x] Production DNS provider abstraction with RFC2136
- [x] Documented control plane + two-node deployment path
- [x] Billing suspension enforced on panel and edge gateway
- [ ] Manual E2E: WHMCS order → GameCloud server → suspend/unsuspend
### Local WHMCS API test
1. `pnpm db:migrate && pnpm db:seed` (creates `local-dev-whmcs` installation)
2. Set `BILLING_PROVIDER=whmcs` optional for credit-bypass mode
3. Sign requests with `WHMCS_API_SECRET` from seed output
4. `PUT /api/v1/integrations/whmcs/clients/1` then `POST .../services`
### WHMCS module install
Copy `integrations/whmcs/modules/servers/hexagamecloud` to `/modules/servers/hexagamecloud` on your WHMCS host.
Server entry fields:
- Hostname: `https://api.example.net`
- Username: integration ID (`WHMCS_INTEGRATION_ID`)
- Password: API secret (`WHMCS_API_SECRET`)
---
## 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: Post-MVP hardening
- Stripe webhooks, SSO (WHMCS Phase D), reconciliation dashboard, penetration test