9.6 KiB
9.6 KiB
HexaHost GameCloud — Implementation Status
Last updated: 2026-06-26
Current phase: WHMCS Addon Dashboard ✅
WHMCS Addon module completed
| Area | Status | Notes |
|---|---|---|
| Addon PHP module | Done | Dashboard, events, reconciliation UI |
| Module tables | Done | mod_hexagamecloud_* on activation |
| Event poller | Done | Manual + daily cron hook |
| Dashboard API | Done | GET /integrations/whmcs/dashboard/stats |
| Cron hook | Done | integrations/whmcs/hooks/hexagamecloud.php |
| Docs | Done | docs/integrations/whmcs/addon-module.md |
Billing providers
| Provider | Status | Notes |
|---|---|---|
| WHMCS | Done | Production default (BILLING_PROVIDER=whmcs) |
| Internal | Done | Dev / free tier credits |
| Stripe | Stub | Optional fallback webhook — inactive unless BILLING_PROVIDER=stripe |
See docs/billing/providers.md.
Abnahmekriterium Addon
- WHMCS admin dashboard shows API health and sync stats
- Event poll + ack from addon UI and cron hook
- Reconciliation dry-run from addon UI
- Manual E2E: activate addon on WHMCS host
WHMCS Phase E + F — Sync & Usage Billing ✅
WHMCS Phase E completed
| Area | Status | Notes |
|---|---|---|
| ListAccounts API | Done | GET /integrations/whmcs/accounts |
| Service import | Done | POST .../services/import |
| Reconciliation | Done | Full + per-service, severity classification |
| Integration events | Done | Cursor poll + ack/dead-letter |
| Worker daily sync | Done | 03:00 UTC reconciliation tick |
| WHMCS PHP | Done | ListAccounts, reconcile/import client |
| Docs | Done | docs/integrations/whmcs/reconciliation.md |
WHMCS Phase F completed
| Area | Status | Notes |
|---|---|---|
| Usage metrics API | Done | GET .../services/:id/usage |
| Usage adjustments | Done | POST .../usage/adjustments |
| Export audit | Done | WhmcsUsageExport + content hash |
| Test mode | Done | testMode=true → DRAFT exports |
| WHMCS PHP | Done | MetricProvider, UsageUpdate |
| Docs | Done | docs/integrations/whmcs/usage-billing.md |
Abnahmekriterium Phase E
- ListAccounts liefert alle verknüpften Services
- Reconciliation erkennt Status-, Plan- und Orphan-Drift
- Events cursorbasiert mit Ack/Dead-Letter
- Import bestehender Server möglich
- Manual E2E: WHMCS Server-Sync + Reconcile-Button
Abnahmekriterium Phase F
- Metriken aus
usage_recordsaggregiert (UTC-Perioden) - Idempotente Exporte mit Hash
- Adjustments ohne Rohdaten-Mutation
- WHMCS MetricProvider + UsageUpdate
- Manual E2E: WHMCS Usage Metrics Abrechnungslauf
WHMCS Phase D — SSO ✅
WHMCS Phase D completed
| Area | Status | Notes |
|---|---|---|
SsoTicket model |
Done | Hashed token, 60s TTL, single use |
| Impersonation sessions | Done | UserSession.isImpersonation + audit |
| API create SSO | Done | POST .../services/:id/sso |
| API consume SSO | Done | POST /auth/sso/consume → session cookie |
| Path allowlist | Done | Server panel routes only |
| Web SSO page | Done | /auth/sso?ticket= + impersonation banner |
| WHMCS PHP SSO | Done | ServiceSingleSignOn, AdminSingleSignOn |
| Docs | Done | docs/integrations/whmcs/sso.md |
Abnahmekriterium Phase D
- WHMCS „Server verwalten“ erzeugt einmaliges SSO-Ticket
- Ticket-Einlösung setzt Session-Cookie und leitet auf Server-Panel weiter
- Admin-SSO markiert Impersonation-Session sichtbar im Panel
- Gesperrte/beendete Services erhalten kein SSO-Ticket
- Manual E2E: WHMCS client area → panel → server detail
Local SSO test
pnpm db:migrate && pnpm db:seed(includeslocal-dev-whmcs)- Provision a service via WHMCS API (
PUT .../clients/1,POST .../services) POST /api/v1/integrations/whmcs/services/{externalServiceId}/sso(signed)- Open
{APP_URL}/auth/sso?ticket={token}→ redirects to/servers/{id} - Admin SSO: same flow with
kind=admin→ impersonation banner visible
See docs/integrations/whmcs/sso.md.
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
- WHMCS can provision/suspend/unsuspend/terminate via signed API
- Production DNS provider abstraction with RFC2136
- Documented control plane + two-node deployment path
- Billing suspension enforced on panel and edge gateway
- Manual E2E: WHMCS order → GameCloud server → suspend/unsuspend
Local WHMCS API test
pnpm db:migrate && pnpm db:seed(createslocal-dev-whmcsinstallation)- Set
BILLING_PROVIDER=whmcsoptional for credit-bypass mode - Sign requests with
WHMCS_API_SECRETfrom seed output PUT /api/v1/integrations/whmcs/clients/1thenPOST .../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 |
| 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
- Stable join hostname per server (
slug.play.example.net) - DNS metadata stored (A + SRV for Java)
- Edge gateway resolves slug and can start stopped servers
- Rate limiting on join-to-start (3/min per slug, 10/min per IP)
- Credits/tariff checks on edge-triggered start
- Manual E2E: connect via fixed hostname while server stopped
Local test
pnpm db:migrate && pnpm db:seed- Set in
.env:EDGE_GATEWAY_ENABLED=true, matchingEDGE_INTERNAL_API_KEY pnpm dev(API + worker) andcd apps/edge-gateway && go run ./cmd/gateway- Provision server → note
joinHostnameon dashboard - Stop server → connect with Minecraft client to join hostname (or
slug.play.localhostwith hosts file) - Edge starts server and proxies connection when
RUNNING
Edge env defaults (.env.example)
GAME_BASE_DOMAIN=play.example.netEDGE_LISTEN_ADDR=:25565EDGE_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
- Empty running server triggers idle countdown and auto-stop
- Player connection cancels countdown (via
listpoll) - Usage debited to credit wallet with ledger + usage records
- Free plan grants credits on signup
- Server quota per plan enforced
- Manual E2E: start server, wait idle, verify stop + usage
Local test
pnpm db:migrate && pnpm db:seed- Register/login → dashboard shows 5000 credits (free plan)
- Create & start server → credits decrease while running
- Leave server empty → after ~10 min idle + 60s countdown → auto-stop
GET /account/usageshows RAM-GB-minute records
Free plan defaults (seed)
idleTimeoutMinutes: 10idleCountdownSeconds: 60monthlyCreditGrant: 5000maxServersPerUser: 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
- Penetration test, product mapping UI in addon, mTLS for integration API