Files
browser/platform/README.md
T

105 lines
7.8 KiB
Markdown

# platform
Backend control plane for the game server management platform.
## Responsibilities
- Users, roles, permissions, and sessions.
- Game management plugin installation metadata and marketplace views.
- Server instance records and lifecycle orchestration.
- AI provider configuration and platform-mediated AI invocation.
- Run registration, capabilities, jobs, artifacts, log stream metadata, and storage adapters.
## Required Directory Plan
Implementation should use dedicated directories for:
- `api/`: route wiring and HTTP/gRPC adapters.
- `dto/`: request and response structures.
- `domain/`: business types and aggregates.
- `model/`: database models only.
- `repo/`: repository interfaces and persistence implementations.
- `service/`: use cases and orchestration.
- `protocol/`: run, plugin, artifact, log, and AI contracts.
- `validator/`: validation rules.
- `config/`: configuration structures and loading.
- `shared/`: small shared helpers.
Do not put DTOs, database models, or protocol structs inside handlers or service functions.
## Development Baseline
Tooling:
- Go 1.25.1.
- Module: `browser.local/platform`.
Commands:
```bash
go test ./...
go run ./cmd/platform
```
Runtime configuration:
- `PLATFORM_ADDR`: local listen address, default `:8080`.
- `PLATFORM_STORAGE_BACKEND`: storage backend, default `file`; use `memory` only for tests or disposable local runs.
- `PLATFORM_MYSQL_DSN`: MySQL DSN used when `PLATFORM_STORAGE_BACKEND=mysql`, for example `platform:platform@tcp(127.0.0.1:3306)/platform?parseTime=true`.
- `PLATFORM_DATA_DIR`: default platform data directory, default `.platform-data`.
- `PLATFORM_METADATA_PATH`: file-backed metadata snapshot path, default `.platform-data/metadata.json`; high-frequency Run endpoint/session state uses a sibling runtime snapshot to avoid rewriting the full metadata file on every heartbeat.
- `PLATFORM_LOG_BODY_BACKEND`: log body backend, default follows metadata backend except MySQL uses `file`; supported values are `file` and `memory`.
- `PLATFORM_LOG_DIR`: segmented log body directory, default `.platform-data/logs`.
- `PLATFORM_ARTIFACT_DIR`: private durable artifact body/transfer directory, default `.platform-data/artifacts`.
- `PLATFORM_BOOTSTRAP_ADMIN_EMAIL`: optional initial platform administrator email.
- `PLATFORM_BOOTSTRAP_ADMIN_PASSWORD`: optional one-time bootstrap password; the platform applies no default and persists only a password verifier.
- `PLATFORM_SECRET_ENVELOPE_KEY`: external secret used to derive the AES-GCM component-key envelope key; use at least 32 random characters and keep it stable across restarts.
- `PLATFORM_BUILDER_DOCKER_BINARY`: Docker-compatible CLI used by the platform builder, default `docker`.
- `PLATFORM_BUILDER_IMAGE`: prebuilt, explicitly versioned or digest-pinned builder image, default `browser-platform-distribution-builder:1.0.0`; floating tags such as `latest` are rejected.
- `PLATFORM_BUILDER_SOURCE_DIR`: persistent Run checkout location used by the platform builder. The checkout may be absent at startup; each Run build creates it when needed, fetches `PLATFORM_BUILDER_SOURCE_REVISION`, exports that revision into the isolated job workspace, injects package configuration, and then compiles.
- `PLATFORM_BUILDER_SOURCE_REPOSITORY`: Run Git repository used when the checkout is absent or needs a build-time refresh.
- `PLATFORM_BUILDER_SOURCE_REVISION`: branch, tag, or commit fetched for each Run build; defaults to `main`.
- `PLATFORM_BUILDER_WORKSPACE_DIR`: private per-plugin/per-job build workspace, default `<PLATFORM_DATA_DIR>/distribution-builds`.
- `PLATFORM_BUILDER_CACHE_DIR`: persistent Go build/module cache, default `<PLATFORM_DATA_DIR>/distribution-build-cache`; it contains no job inputs or component keys.
- `PLATFORM_BUILDER_TIMEOUT_SECONDS`: positive build deadline, default `1800`.
- `PLATFORM_RUN_RELEASE_URL`: public platform URL embedded into generated Run packages, default `https://scum.npc0.com/`. It must be reachable from the target server; loopback and unspecified addresses are rejected.
Build the dedicated toolchain image before enabling distribution generation:
```bash
docker build --pull -t browser-platform-distribution-builder:1.0.0 distribution-builder
export PLATFORM_BUILDER_SOURCE_DIR=/absolute/path/to/run-checkout
export PLATFORM_BUILDER_SOURCE_REPOSITORY=git@git.npc0.com:admin343/run.git
export PLATFORM_BUILDER_SOURCE_REVISION=main
export PLATFORM_BUILDER_IMAGE=browser-platform-distribution-builder:1.0.0
go run ./cmd/platform
```
Each build runs in a separate read-only container. For Run, the platform first exports the fetched revision into a clean per-job source directory; source and per-job input are mounted read-only, only the job build/output directories are writable, and the component auth key is passed through a mode-`0600` input file. The key is not sent through the machine-side job channel or Docker arguments. Production deployments may use an internal-registry `image@sha256:...` reference; the selected image must already exist in the Docker daemon because builds run with `--pull never`.
MySQL configuration example:
```bash
export PLATFORM_STORAGE_BACKEND=mysql
export PLATFORM_MYSQL_DSN='platform:platform@tcp(127.0.0.1:3306)/platform?parseTime=true'
export PLATFORM_LOG_BODY_BACKEND=file
export PLATFORM_LOG_DIR=.platform-data/logs
go run ./cmd/platform
```
MySQL is the platform metadata database here. It stores the platform metadata snapshot table and should later hold normalized users/plugins/servers/jobs/log stream indexes. It is not the high-volume log body store; keep log bodies in segmented files locally, or add a future ClickHouse/Loki/OpenSearch/object-storage `LogBodyStore` adapter for production scale.
For local direct debugging, copy `platform/.env.example` to `platform/.env`, edit the values, and run:
```bash
go run ./cmd/platform
```
The platform process automatically reads root `.env` and `platform/.env` before loading configuration. Explicitly exported process environment values still take precedence over values in those files.
For Docker, the root `docker-compose.yml` sets platform data under `/data/platform` and mounts it through the `platform-data` named volume.
Current executable behavior includes the platform API, durable hashed auth/Run sessions with expiry/revocation/rotation, strict production route authorization, durable file-backed metadata, segmented log bodies, authenticated run control/job/log/artifact routes, plugin bridge dispatch, platform-mediated AI invocation, real typed dependency execution orchestration with reviewed plan digests, and target-fenced transactional Run self-update staging/health/rollback projections.
Validated plugin runtime profiles and per-server runtime bindings are part of durable metadata for advanced logical transports. Server creation requires only the plugin type and server name, and plugin-declared deployment/lifecycle actions must be enough for user-facing start/stop and generated Run package flows without forcing operators through a manual runtime-profile binding screen. Browser and plugin-facing responses expose readiness only, not binding values. Platform-owned Docker builds need no registered Run endpoint with `distribution.build`; component keys remain in platform-held per-job input. This change uses scoped secret references and an injectable AES-GCM component-key envelope. The built-in envelope key is a disposable-development compatibility fallback; deployments must set `PLATFORM_SECRET_ENVELOPE_KEY`. This is not a production vault/KMS or machine-side runtime resolver. Durable scheduling, process supervision, durable log/artifact bodies, bounded metrics/backups, declaration-backed remote adapter envelopes, typed dependency installation, plugin lifecycle dispatch, and transactional Run self-update are implemented. Production signing/fleet rollout, external provider/storage adapters, and real AI-provider integration remain separate tasks.