Files
browser/platform/domain/resources.md
T

193 lines
13 KiB
Markdown

# Platform Domain Resources
This file defines the first platform resource contracts. Concrete Go domain structs are implemented in `platform/domain/resources.go`; API DTO projections live in `platform/dto/resources.go`; database model projections live in `platform/model/resources.go`. Do not define these resource shapes inside handlers or service functions.
## Implemented Boundaries
- Domain constants centralize allowed status, state, provider kind, relay mode, artifact owner, storage backend, and result summary values.
- DTO responses expose AI-provider secret presence only (`apiKeyConfigured`), never the stored reference or raw key material.
- Model structs include JSON/database tags and explicit `TableName()` mappings for future persistence work.
- `platform/repo.NewFileStore` provides durable local metadata snapshots for platform startup, while `platform/repo.NewMemoryStore` provides deterministic in-memory repository behavior for unit tests and disposable local runs.
- Log stream metadata records the selected body backend. The current durable local body backend uses `local-segments`; future production adapters should target log-optimized stores such as `clickhouse`, `loki`, `opensearch`, or `elasticsearch` rather than row-per-line relational tables.
- `platform/service.Core` enforces create/list/get workflows and cross-resource invariants before resources are persisted.
## User
- `id`: stable user ID.
- `displayName`: visible user name.
- `email`: optional login email.
- `status`: `active`, `disabled`, or `pending`.
- `roles`: role keys assigned to the user.
- `createdAt`: creation time.
- `updatedAt`: last update time.
## AIProvider
- `id`: stable provider ID.
- `name`: display name.
- `kind`: `openai-compatible`, `openai`, `claude`, `gemini`, `ollama`, or `custom`.
- `baseUrl`: provider or relay base URL.
- `apiKeyRef`: platform-owned secret reference accepted on writes and never returned by response DTOs.
- `apiKeyConfigured`: response-only presence flag.
- `models`: allowed model IDs.
- `defaultModel`: optional default model.
- `relayMode`: `direct`, `relay`, or `local`.
- `timeoutMs`: request timeout.
- `status`: `active`, `disabled`, or `error`.
- `redactionPolicy`: policy key for prompt/input/output redaction.
## GamePlugin
- `id`: plugin ID such as `game.example`.
- `name`: display name.
- `description`: bounded marketplace/registry summary.
- `version`: installed version.
- `serverType`: game/server type key.
- `serverDisplayName`: visible server type name.
- `supportedOs`: operating systems declared by the plugin manifest.
- `manifestRef`: immutable manifest artifact reference.
- `createFormSchemaRef`: create form schema reference.
- `requiredRunCapabilities`: run capabilities required by this plugin.
- `declaredPermissions`: scoped manifest permission keys used by plugin bridge and marketplace views.
- `permissions`: aggregate platform ability declarations for AI, logs, files, jobs, artifacts, and remote access.
- `lifecycleActions`: manifest action contract references for install/start/stop and optional restart/status.
- `pages`: plugin-local page metadata with scoped permission requirements.
- `tags`: bounded catalog tags.
- `aiPurposes`: platform-mediated AI purposes such as config suggestions or log diagnosis.
- `remoteAccess`: plugin-declared remote access methods (`ftp`, `rsync`, `run`), run capabilities, database engines, RCON, and log transfer flags.
- `validationViolations`: safe validation findings for invalid plugin records.
- `status`: `installed`, `disabled`, `invalid`, or `updating`.
Manifest registration uses `GamePluginManifestRegistrationRequest` at `POST /api/v1/game-plugins/register-manifest`. Platform validation repeats plugin workspace safety checks and rejects raw host paths, direct run sockets, raw credentials, and raw AI/provider keys before metadata reaches the registry.
Remote access jobs are enabled only when both the selected run endpoint reports the capability and the server instance's installed plugin declares it. Plugin pages must use `remote.access.request` with `server.remote.access`; platform rejects undeclared database, RCON, log transfer, or remote file capabilities before creating jobs.
Runtime profile and distribution permissions are declared by plugins, then gated again by platform routes and services. `server.run.distribution` enables run package generation/download/reset/update operations, and `server.dependencies.manage` enables dependency check/install jobs. Plugin metadata stores only declarations and safe refs; raw run keys and transport credentials are stored through platform secret resources, never in plugin records.
## ServerInstance
- `id`: server instance ID.
- `pluginId`: installed game management plugin ID.
- `pluginVersion`: plugin version used to create or last reconcile the instance.
- `runEndpointId`: selected run endpoint.
- `name`: server display name.
- `state`: `draft`, `installing`, `ready`, `running`, `stopped`, `failed`, or `deleted`.
- `configVersion`: optimistic concurrency version for platform-managed config.
- `createdAt`: creation time.
- `updatedAt`: last update time.
## RunEndpoint
- `id`: run endpoint ID.
- `displayName`: visible executor name.
- `version`: run binary version.
- `status`: `online`, `offline`, `degraded`, or `disabled`.
- `capabilities`: current capability keys.
- `capacity`: current queue and resource summary.
- `lastHeartbeatAt`: last control heartbeat time.
Run control hello can include server/component identity from a generated package config. When `serverInstanceId`, `pluginId`, `componentKind`, `componentKey`, and `keyGeneration` are present, platform authenticates the provided key against the current encrypted component key before issuing a session token. Stale generations after reset are rejected without returning raw key material.
Run sessions persist only a token hash, generation, status, expiry, capability fingerprint, signed-request policy, and bounded replay nonce history. Component-authenticated Run sessions require HMAC-SHA256 HTTP envelopes over method, path, timestamp, nonce, and request-body hash; timestamps outside five minutes and repeated nonces are rejected.
## AuthSessionRecord
- `tokenHash`: SHA-256 verifier; raw bearer tokens are never persisted.
- `userId`: owning user.
- `status`: `active` or `revoked`.
- `generation`: monotonically increasing user session generation.
- `issuedAt`, `expiresAt`, `lastSeenAt`, `revokedAt`: durable lifecycle timestamps.
## RuntimeBinding
- `id`: runtime binding ID.
- `serverInstanceId`: server instance using the binding.
- `pluginId` and `pluginVersion`: installed plugin contract that declared the logical runtime profile.
- `profileKey`: declared lifecycle/runtime profile key.
- `mode`: runtime mode such as `local-process`, `hosted-ftp-rcon`, `ftp-only`, or `custom-client`.
- `bindings`: logical binding keys to operator-provided settings.
- `missingKeys`: logical keys that must be completed before dependent actions are available.
- `status`: `complete` or `incomplete`.
Installed `GamePlugin` records persist the validated manifest `runtimeProfiles` contract, including discovery, lifecycle, dependency/install, log, and transport declarations. One server binding selects one declared lifecycle profile. Platform derives allowed and required logical keys; clients cannot assert `missingKeys` or `status`.
Plugin lifecycle assets are registered as manifest-declared files plus a
content-bearing registration payload. Platform packages those assets into
generated Run workspaces so plugin action refs such as `actions/install.json`
and helper refs such as `bin/scum-install-update.cmd` are available before the
first bootstrap job. Guided deployments whose selected lifecycle profile
supports `process.start` may bootstrap through the plugin-owned start action so
the script can install-if-missing and then launch the supervised process whose
stdout/stderr feed the live terminal. Game-specific install/update/start policy,
including SCUM SteamCMD app IDs and launch flags, stays in the plugin asset
bundle rather than in platform services or Run executors.
Bindings are used for action gating and future run-side profile resolution. File and MySQL metadata snapshots include them so a platform restart does not make a configured server appear complete or lose its selected profile. API responses expose only logical key names, configured/secret-backed flags, missing keys, and safe reasons. They never expose stored binding values, raw host paths, direct sockets, FTP/RCON passwords, SQL DSNs, component auth keys, or internal secret locations.
## Runtime Component Keys And Distributions
- `EncryptedComponentKey`: stores exactly one active encrypted key per server/component plus hash, fingerprint, redacted secret ref, generation, status, and reset time.
- `RunDistribution`: records a generated run package for one server, target OS/architecture, package format, artifact ID, checksum, key generation, secret ref, and status.
- `RunUpdateJob`: records platform-created Run self-update orchestration with server, endpoint, artifact ID/checksum, target and previous release, job/idempotency identity, `queued/downloading/staged/restart-requested/activating/succeeded/rolled-back/failed` phase, bounded message, rollback flag, and timestamps. Platform only projects success after a signed current-session post-reconciliation health report; terminal staging alone remains `restart-requested`.
Run keys are isolated singleton credentials. Reset replaces the encrypted database value, increments generation, marks older distributions revoked, and requires regenerating and redeploying that component. API DTOs may expose key generation, fingerprint, status, artifact ID, checksum, job ID, and `secret://runtime-keys/.../current` refs, but never the raw key.
## DependencyStatus
- `id`: dependency status ID.
- `serverInstanceId`: server instance checked by run.
- `pluginId`: plugin that declared the probe.
- `probeKey`: logical dependency probe key.
- `targetOs`, `targetArch`: target platform metadata.
- `state`: dependency state such as present, missing, failed, or unknown.
- `required`: whether the probe is required for the runtime profile.
- `installPlanKey`: optional typed install plan key.
- `message`: bounded safe status.
- `planDigest`: deterministic SHA-256 digest of the declared target-specific probe/plan and logical binding generation; install approval must match it exactly.
- `evidence`, `completedSteps`, `jobId`: bounded terminal execution projection; no command output, path, credential, or private binding is stored in the projection.
- `checkedAt`, `updatedAt`: observation times.
Dependency checks and installs are queued as run jobs with logical `dependencies/...` or `dependencies/install/...` target keys. Install jobs must use typed plugin-declared plans and must not carry arbitrary shell snippets.
## Job
- `id`: job ID.
- `serverInstanceId`: optional target server.
- `runEndpointId`: target run endpoint.
- `capability`: requested capability key.
- `idempotencyKey`: duplicate detection key.
- `state`: `queued`, `accepted`, `running`, `succeeded`, `failed`, or `cancelled`.
- `progress`: bounded progress summary.
- `resultRef`: optional terminal result reference.
Lifecycle workflow jobs use fixed capabilities:
- `process.install`: dispatched by install bootstrap workflows and projects successful terminal results to `ready`.
- `process.start`: dispatched by server start workflow or guided supervised bootstrap and projects successful terminal results to `running`.
- `process.stop`: dispatched by server stop workflow and projects successful terminal results to `stopped`.
- `run.self-update`: dispatched by runtime distribution APIs with an approved artifact ref and checksum.
- `dependencies.check`: dispatched by dependency check APIs for a declared probe key.
- `dependencies.install`: dispatched by dependency install APIs for a declared typed install plan.
- `logs.backfill`: dispatched by historical log APIs for a declared source key and checkpoint ref.
Failed or cancelled lifecycle jobs project the server instance to `failed`. Active start/stop jobs are visible through job metadata; this change does not add separate `starting` or `stopping` server states.
## Artifact
- `id`: artifact ID.
- `ownerKind`: `platform`, `plugin`, `server-instance`, or `job`.
- `ownerId`: owning resource ID.
- `sizeBytes`: expected or final size.
- `checksum`: final checksum.
- `state`: `uploading`, `available`, `expired`, or `failed`.
## LogStream
- `id`: log stream ID.
- `serverInstanceId`: target server.
- `source`: `process`, `file`, `plugin`, or custom source.
- `streamKey`: stable stream key.
- `latestSeq`: latest accepted sequence.
- `storageBackend`: `local-segments`, `loki`, `clickhouse`, `opensearch`, or `elasticsearch`.
- `retentionPolicy`: retention key.