package dto import ( "time" "browser.local/platform/domain" ) type UserCreateRequest struct { ID string `json:"id"` DisplayName string `json:"displayName"` Email string `json:"email,omitempty"` Roles []string `json:"roles,omitempty"` Status domain.UserStatus `json:"status,omitempty"` Password string `json:"password,omitempty"` Profile UserProfileBody `json:"profile,omitempty"` } type UserUpdateRequest struct { DisplayName *string `json:"displayName,omitempty"` Email *string `json:"email,omitempty"` Status *domain.UserStatus `json:"status,omitempty"` Roles []string `json:"roles,omitempty"` Profile *UserProfileBody `json:"profile,omitempty"` } type UserProfileBody struct { DisplayName string `json:"displayName,omitempty"` AvatarURL string `json:"avatarUrl,omitempty"` Phone string `json:"phone,omitempty"` QQ string `json:"qq,omitempty"` ContactNote string `json:"contactNote,omitempty"` } type UserThemePreferenceRequest struct { PaletteID string `json:"paletteId"` BackgroundPresetID string `json:"backgroundPresetId"` BackgroundImage *string `json:"backgroundImage,omitempty"` } type UserThemePreferenceResponse struct { UserID string `json:"userId"` PaletteID string `json:"paletteId"` BackgroundPresetID string `json:"backgroundPresetId"` BackgroundImage string `json:"backgroundImage,omitempty"` Persistence string `json:"persistence"` UpdatedAt time.Time `json:"updatedAt"` } type UserResponse struct { ID string `json:"id"` DisplayName string `json:"displayName"` Email string `json:"email,omitempty"` Status domain.UserStatus `json:"status"` Roles []string `json:"roles"` Profile UserProfileBody `json:"profile,omitempty"` ThemePreference *UserThemePreferenceResponse `json:"themePreference,omitempty"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } type UserListResponse struct { Items []UserResponse `json:"items"` Count int `json:"count"` } type CurrentUserResponse struct { ID string `json:"id"` DisplayName string `json:"displayName"` Email string `json:"email,omitempty"` Status domain.UserStatus `json:"status,omitempty"` Roles []string `json:"roles"` Capabilities []string `json:"capabilities,omitempty"` Profile UserProfileBody `json:"profile,omitempty"` ThemePreference *UserThemePreferenceResponse `json:"themePreference,omitempty"` } type LoginRequest struct { Account string `json:"account"` Password string `json:"password"` } type RegisterRequest struct { DisplayName string `json:"displayName"` Email string `json:"email"` Password string `json:"password"` Phone string `json:"phone,omitempty"` QQ string `json:"qq,omitempty"` } type AuthSessionResponse struct { User CurrentUserResponse `json:"user"` SessionID string `json:"sessionId,omitempty"` Status string `json:"status"` Message string `json:"message,omitempty"` ExpiresAt time.Time `json:"expiresAt,omitempty"` } type AIProviderCreateRequest struct { ID string `json:"id"` Name string `json:"name"` Kind domain.AIProviderKind `json:"kind"` BaseURL string `json:"baseUrl"` APIKeyRef string `json:"apiKeyRef"` Models []string `json:"models"` DefaultModel string `json:"defaultModel,omitempty"` RelayMode domain.AIRelayMode `json:"relayMode"` TimeoutMS int `json:"timeoutMs"` RedactionPolicy string `json:"redactionPolicy"` } type AIProviderUpdateRequest struct { Name string `json:"name"` Kind domain.AIProviderKind `json:"kind"` BaseURL string `json:"baseUrl"` APIKeyRef string `json:"apiKeyRef"` Models []string `json:"models"` DefaultModel string `json:"defaultModel,omitempty"` RelayMode domain.AIRelayMode `json:"relayMode"` TimeoutMS int `json:"timeoutMs"` RedactionPolicy string `json:"redactionPolicy"` } type AIProviderStatusRequest struct { Status domain.AIProviderStatus `json:"status"` } type AIProviderResponse struct { ID string `json:"id"` Name string `json:"name"` Kind domain.AIProviderKind `json:"kind"` BaseURLConfigured bool `json:"baseUrlConfigured"` APIKeyConfigured bool `json:"apiKeyConfigured"` Models []string `json:"models"` DefaultModel string `json:"defaultModel,omitempty"` RelayMode domain.AIRelayMode `json:"relayMode"` TimeoutMS int `json:"timeoutMs"` Status domain.AIProviderStatus `json:"status"` RedactionPolicy string `json:"redactionPolicy"` } type AIProviderListResponse struct { Items []AIProviderResponse `json:"items"` Count int `json:"count"` } type AIProviderTestResponse struct { ProviderID string `json:"providerId"` Mode string `json:"mode"` Success bool `json:"success"` Message string `json:"message"` Violations []string `json:"violations,omitempty"` } type AIProviderModelsResponse struct { ProviderID string `json:"providerId"` DefaultModel string `json:"defaultModel,omitempty"` Models []string `json:"models"` } type PluginPermissionsResponse struct { AI bool `json:"ai"` Logs bool `json:"logs"` Files bool `json:"files"` Jobs bool `json:"jobs"` Artifacts bool `json:"artifacts"` RemoteAccess bool `json:"remoteAccess"` } type PluginLifecycleActionsBody struct { Install string `json:"install"` Start string `json:"start"` Stop string `json:"stop"` Restart string `json:"restart,omitempty"` Status string `json:"status,omitempty"` } type GamePluginPageBody struct { Key string `json:"key"` Title string `json:"title"` Path string `json:"path"` BundleKey string `json:"bundleKey"` BundleVersion string `json:"bundleVersion"` BundleIntegritySHA256 string `json:"bundleIntegritySha256"` Permissions []string `json:"permissions,omitempty"` BridgeActions []string `json:"bridgeActions,omitempty"` FeatureKeys []string `json:"featureKeys,omitempty"` } type PluginLogicalDirectoryBody struct { Key string `json:"key"` Label string `json:"label"` Scope string `json:"scope"` } type PluginLogicalFileBody struct { Key string `json:"key"` DirectoryKey string `json:"directoryKey"` Label string `json:"label"` Kind string `json:"kind"` StreamKey string `json:"streamKey,omitempty"` Editable bool `json:"editable,omitempty"` } type PluginConfigFieldBody struct { Key string `json:"key"` FileKey string `json:"fileKey"` ConfigKey string `json:"configKey"` Label string `json:"label"` Description string `json:"description"` Control string `json:"control"` Minimum int `json:"minimum,omitempty"` Maximum int `json:"maximum,omitempty"` DefaultValue string `json:"defaultValue,omitempty"` RestartImpact string `json:"restartImpact"` } type PluginFileWorkspaceBody struct { DefaultDirectoryKey string `json:"defaultDirectoryKey"` Directories []PluginLogicalDirectoryBody `json:"directories"` Files []PluginLogicalFileBody `json:"files"` ConfigFields []PluginConfigFieldBody `json:"configFields"` } type GamePluginBridgeBody struct { Actions []string `json:"actions"` } type PluginCreateFieldBody struct { Key string `json:"key"` Label string `json:"label"` Type string `json:"type"` Required bool `json:"required,omitempty"` DefaultValue string `json:"defaultValue,omitempty"` Options []string `json:"options,omitempty"` ConfigKey string `json:"configKey,omitempty"` } type GamePluginManifestServerBody struct { Type string `json:"type"` DisplayName string `json:"displayName"` SupportedOS []string `json:"supportedOs,omitempty"` CreateFormSchema string `json:"createFormSchema"` CreateFields []PluginCreateFieldBody `json:"createFields,omitempty"` } type GamePluginManifestAIBody struct { Purposes []string `json:"purposes,omitempty"` Mediation string `json:"mediation,omitempty"` ConfigWritePolicy string `json:"configWritePolicy,omitempty"` } type GamePluginProductionLifecycleBody struct { Operations []string `json:"operations"` DependencyPolicy string `json:"dependencyPolicy"` ApprovalRequired []string `json:"approvalRequired"` } type GamePluginRemoteAccessBody struct { Methods []string `json:"methods,omitempty"` RunCapabilities []string `json:"runCapabilities,omitempty"` DatabaseEngines []string `json:"databaseEngines,omitempty"` RCON bool `json:"rcon,omitempty"` LogTransfer bool `json:"logTransfer,omitempty"` } type GameClientBridgeCommandDeclarationBody struct { Type string `json:"type"` Title string `json:"title"` Permission string `json:"permission"` ApprovalLevel string `json:"approvalLevel"` PayloadSchemaRef string `json:"payloadSchemaRef"` ResultSchemaRef string `json:"resultSchemaRef,omitempty"` TimeoutSeconds int `json:"timeoutSeconds"` MaxPayloadBytes int `json:"maxPayloadBytes"` ProtectedRequest *GameClientBridgeProtectedRequestDeclarationBody `json:"protectedRequest,omitempty"` } type GameClientBridgeProtectedRequestDeclarationBody struct { Kind string `json:"kind"` TransportKey string `json:"transportKey"` TargetKey string `json:"targetKey"` TextField string `json:"textField"` MaxTextBytes int `json:"maxTextBytes"` } type GameClientBridgeSnapshotDeclarationBody struct { Type string `json:"type"` SchemaVersion string `json:"schemaVersion"` SchemaRef string `json:"schemaRef"` KeepForSeconds int `json:"keepForSeconds"` MaxRecords int `json:"maxRecords"` } type GameClientBridgeQueryTemplateDeclarationBody struct { Key string `json:"key"` Title string `json:"title"` Permission string `json:"permission"` Engine string `json:"engine"` TransportKey string `json:"transportKey"` TargetKey string `json:"targetKey"` ParameterSchemaRef string `json:"parameterSchemaRef"` ResultSchemaRef string `json:"resultSchemaRef"` SQLRef string `json:"sqlRef,omitempty"` MaxRows int `json:"maxRows"` TimeoutSeconds int `json:"timeoutSeconds"` RowTarget *PluginDataRowTargetDeclarationBody `json:"rowTarget,omitempty"` } type PluginDataRowTargetDeclarationBody struct { Collection string `json:"collection"` UpsertKeys []string `json:"upsertKeys"` ColumnMappings map[string]string `json:"columnMappings"` } type GameClientBridgeDataPackDeclarationBody struct { Key string `json:"key"` DatabaseUserVersion int `json:"databaseUserVersion"` LogParserRefs []string `json:"logParserRefs"` ConfigMapRefs []string `json:"configMapRefs"` } type GameClientBridgeOperationSafetyBody struct { RequiresApproval bool `json:"requiresApproval,omitempty"` RequiresOfflinePlayer bool `json:"requiresOfflinePlayer,omitempty"` RequiresMaintenanceWindow bool `json:"requiresMaintenanceWindow,omitempty"` RequiresBeforeValue bool `json:"requiresBeforeValue,omitempty"` RequiresConfirmation bool `json:"requiresConfirmation,omitempty"` BackupRequired bool `json:"backupRequired,omitempty"` } type GameClientBridgeOperationMutationDeclarationBody struct { FieldKey string `json:"fieldKey"` TableKey string `json:"tableKey"` IdentityKey string `json:"identityKey"` ValueKey string `json:"valueKey"` ConfirmationQueryKey string `json:"confirmationQueryKey"` AllowedValueType string `json:"allowedValueType"` MinValue float64 `json:"minValue,omitempty"` MaxValue float64 `json:"maxValue,omitempty"` } type GameClientBridgeOperationTemplateDeclarationBody struct { Key string `json:"key"` Title string `json:"title"` Permission string `json:"permission"` ApprovalLevel string `json:"approvalLevel"` Kind string `json:"kind"` TransportKey string `json:"transportKey"` TargetKey string `json:"targetKey"` PayloadSchemaRef string `json:"payloadSchemaRef"` ResultSchemaRef string `json:"resultSchemaRef,omitempty"` ConfirmationSchemaRef string `json:"confirmationSchemaRef,omitempty"` TimeoutSeconds int `json:"timeoutSeconds"` MaxPayloadBytes int `json:"maxPayloadBytes"` MaxRowsAffected int `json:"maxRowsAffected,omitempty"` Mutation GameClientBridgeOperationMutationDeclarationBody `json:"mutation,omitempty"` Safety GameClientBridgeOperationSafetyBody `json:"safety,omitempty"` } type GameClientBridgePageContractBody struct { PageKey string `json:"pageKey"` CommandTypes []string `json:"commandTypes,omitempty"` SnapshotTypes []string `json:"snapshotTypes,omitempty"` QueryTemplateKeys []string `json:"queryTemplateKeys,omitempty"` OperationKeys []string `json:"operationKeys,omitempty"` FeatureKeys []string `json:"featureKeys,omitempty"` } type GameClientBridgeFeatureDeclarationBody struct { Key string `json:"key"` Title string `json:"title"` Permission string `json:"permission"` RequiredHandlers []string `json:"requiredHandlers,omitempty"` RequiredEventProducers []string `json:"requiredEventProducers,omitempty"` } type GameClientBridgeCompanionDeclarationBody struct { ProfileKey string `json:"profileKey"` ConfigTemplateKey string `json:"configTemplateKey"` ConfigSchemaRef string `json:"configSchemaRef"` ConfigFormat string `json:"configFormat"` PlatformBaseURLSource string `json:"platformBaseUrlSource"` RegistrationProof string `json:"registrationProof"` ProofMaterialSource string `json:"proofMaterialSource"` ProofMaterialEnv string `json:"proofMaterialEnv"` SessionMode string `json:"sessionMode"` TLSPolicy string `json:"tlsPolicy"` HeartbeatIntervalSeconds int `json:"heartbeatIntervalSeconds"` CommandPollIntervalSeconds int `json:"commandPollIntervalSeconds"` RequestTimeoutSeconds int `json:"requestTimeoutSeconds"` } type GameClientBridgeManifestBody struct { Commands []GameClientBridgeCommandDeclarationBody `json:"commands"` Snapshots []GameClientBridgeSnapshotDeclarationBody `json:"snapshots"` QueryTemplates []GameClientBridgeQueryTemplateDeclarationBody `json:"queryTemplates,omitempty"` DataPacks []GameClientBridgeDataPackDeclarationBody `json:"dataPacks,omitempty"` OperationTemplates []GameClientBridgeOperationTemplateDeclarationBody `json:"operationTemplates,omitempty"` CommandRetentionSeconds int `json:"commandRetentionSeconds"` MaxCommands int `json:"maxCommands"` Pages []GameClientBridgePageContractBody `json:"pages,omitempty"` Features []GameClientBridgeFeatureDeclarationBody `json:"features,omitempty"` Companion *GameClientBridgeCompanionDeclarationBody `json:"companion,omitempty"` } type GamePluginManifestBody struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description,omitempty"` Version string `json:"version"` Kind string `json:"kind"` Tags []string `json:"tags,omitempty"` Server GamePluginManifestServerBody `json:"server"` Bridge GamePluginBridgeBody `json:"bridge,omitempty"` Capabilities []string `json:"capabilities"` Permissions []string `json:"permissions"` Actions PluginLifecycleActionsBody `json:"actions"` AssetFiles []PluginAssetFileBody `json:"assetFiles,omitempty"` Pages []GamePluginPageBody `json:"pages,omitempty"` FileWorkspace PluginFileWorkspaceBody `json:"fileWorkspace,omitempty"` AI GamePluginManifestAIBody `json:"ai,omitempty"` ProductionLifecycle GamePluginProductionLifecycleBody `json:"productionLifecycle"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesBody `json:"runtimeProfiles,omitempty"` GameClientBridge GameClientBridgeManifestBody `json:"gameClientBridge,omitempty"` } type GamePluginManifestRegistrationRequest struct { ManifestRef string `json:"manifestRef"` Manifest GamePluginManifestBody `json:"manifest"` AssetFiles []PluginAssetFileBody `json:"assetFiles,omitempty"` } type PluginAssetFileBody struct { Path string `json:"path"` Content string `json:"content,omitempty"` Mode int `json:"mode,omitempty"` } type GamePluginCreateRequest struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description,omitempty"` Version string `json:"version"` ServerType string `json:"serverType"` ServerDisplayName string `json:"serverDisplayName,omitempty"` SupportedOS []string `json:"supportedOs,omitempty"` ManifestRef string `json:"manifestRef"` CreateFormSchemaRef string `json:"createFormSchemaRef"` CreateFields []PluginCreateFieldBody `json:"createFields,omitempty"` RequiredRunCapabilities []string `json:"requiredRunCapabilities"` DeclaredPermissions []string `json:"declaredPermissions,omitempty"` Permissions PluginPermissionsResponse `json:"permissions"` LifecycleActions PluginLifecycleActionsBody `json:"lifecycleActions,omitempty"` BridgeActions []string `json:"bridgeActions,omitempty"` Pages []GamePluginPageBody `json:"pages,omitempty"` FileWorkspace PluginFileWorkspaceBody `json:"fileWorkspace,omitempty"` Tags []string `json:"tags,omitempty"` AIPurposes []string `json:"aiPurposes,omitempty"` ProductionLifecycle GamePluginProductionLifecycleBody `json:"productionLifecycle,omitempty"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesBody `json:"runtimeProfiles,omitempty"` GameClientBridge GameClientBridgeManifestBody `json:"gameClientBridge,omitempty"` ValidationViolations []string `json:"validationViolations,omitempty"` } type GamePluginResponse struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description,omitempty"` Version string `json:"version"` ServerType string `json:"serverType"` ServerDisplayName string `json:"serverDisplayName,omitempty"` SupportedOS []string `json:"supportedOs,omitempty"` ManifestRef string `json:"manifestRef"` CreateFormSchemaRef string `json:"createFormSchemaRef"` CreateFields []PluginCreateFieldBody `json:"createFields,omitempty"` RequiredRunCapabilities []string `json:"requiredRunCapabilities"` DeclaredPermissions []string `json:"declaredPermissions"` Permissions PluginPermissionsResponse `json:"permissions"` LifecycleActions PluginLifecycleActionsBody `json:"lifecycleActions"` BridgeActions []string `json:"bridgeActions"` Pages []GamePluginPageBody `json:"pages"` FileWorkspace PluginFileWorkspaceBody `json:"fileWorkspace,omitempty"` Tags []string `json:"tags"` AIPurposes []string `json:"aiPurposes"` ProductionLifecycle GamePluginProductionLifecycleBody `json:"productionLifecycle"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesResponseBody `json:"runtimeProfiles,omitempty"` GameClientBridge GameClientBridgeManifestBody `json:"gameClientBridge,omitempty"` ValidationViolations []string `json:"validationViolations,omitempty"` Status domain.GamePluginStatus `json:"status"` } type GamePluginListResponse struct { Items []GamePluginResponse `json:"items"` Count int `json:"count"` } type MarketplacePluginResponse struct { ID string `json:"id"` Name string `json:"name"` Description string `json:"description,omitempty"` Version string `json:"version"` ServerType string `json:"serverType"` ServerDisplayName string `json:"serverDisplayName,omitempty"` SupportedOS []string `json:"supportedOs,omitempty"` ManifestRef string `json:"manifestRef"` CreateFormSchemaRef string `json:"createFormSchemaRef"` Capabilities []string `json:"capabilities"` DeclaredPermissions []string `json:"declaredPermissions"` Permissions PluginPermissionsResponse `json:"permissions"` LifecycleActions PluginLifecycleActionsBody `json:"lifecycleActions"` BridgeActions []string `json:"bridgeActions"` Pages []GamePluginPageBody `json:"pages"` Tags []string `json:"tags"` AIPurposes []string `json:"aiPurposes"` ProductionLifecycle GamePluginProductionLifecycleBody `json:"productionLifecycle"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesResponseBody `json:"runtimeProfiles,omitempty"` GameClientBridge GameClientBridgeManifestBody `json:"gameClientBridge,omitempty"` ValidationViolations []string `json:"validationViolations,omitempty"` Status domain.GamePluginStatus `json:"status"` Source string `json:"source"` } type MarketplacePluginListResponse struct { Items []MarketplacePluginResponse `json:"items"` Count int `json:"count"` } type MarketplacePluginStateRequest struct { Action domain.PluginMarketplaceStateAction `json:"action"` } type PluginBridgeAuthorizeRequest struct { PluginID string `json:"pluginId"` RouteKey string `json:"routeKey"` ServerInstanceID string `json:"serverInstanceId,omitempty"` Action string `json:"action"` AIPurpose string `json:"aiPurpose,omitempty"` } type PluginBridgeAuthorizeResponse struct { PluginID string `json:"pluginId"` RouteKey string `json:"routeKey"` ServerInstanceID string `json:"serverInstanceId,omitempty"` Action string `json:"action"` Allowed bool `json:"allowed"` RequiredPermissions []string `json:"requiredPermissions"` EffectivePermissions []string `json:"effectivePermissions"` Reason string `json:"reason,omitempty"` } type PluginBridgeExecuteRequest struct { RequestID string `json:"requestId"` PluginID string `json:"pluginId"` RouteKey string `json:"routeKey"` ServerInstanceID string `json:"serverInstanceId,omitempty"` Action string `json:"action"` AIPurpose string `json:"aiPurpose,omitempty"` Payload map[string]string `json:"payload,omitempty"` } type PluginBridgeSafeErrorResponse struct { Code string `json:"code"` Message string `json:"message"` Details []string `json:"details,omitempty"` } type PluginBridgeExecuteResponse struct { RequestID string `json:"requestId"` PluginID string `json:"pluginId"` RouteKey string `json:"routeKey"` ServerInstanceID string `json:"serverInstanceId,omitempty"` Action string `json:"action"` Status string `json:"status"` Result map[string]string `json:"result,omitempty"` Error *PluginBridgeSafeErrorResponse `json:"error,omitempty"` } type ServerInstanceCreateRequest struct { ID string `json:"id"` PluginID string `json:"pluginId"` RunEndpointID string `json:"runEndpointId"` Name string `json:"name"` OwnerUserID string `json:"ownerUserId,omitempty"` AdminUserIDs []string `json:"adminUserIds,omitempty"` State domain.ServerInstanceState `json:"state,omitempty"` } type ServerInstanceUpdateRequest struct { Name *string `json:"name,omitempty"` } type ServerDeletionRequest struct { Password string `json:"password"` Force bool `json:"force,omitempty"` Confirmation string `json:"confirmation,omitempty"` } type ServerMemberRequest struct { UserID string `json:"userId"` } type ServerMemberResponse struct { ID string `json:"id"` DisplayName string `json:"displayName"` Email string `json:"email,omitempty"` Status domain.UserStatus `json:"status"` Roles []string `json:"roles"` Profile UserProfileBody `json:"profile,omitempty"` } type ServerMemberListResponse struct { Items []ServerMemberResponse `json:"items"` Count int `json:"count"` } type ServerInstanceResponse struct { ID string `json:"id"` PluginID string `json:"pluginId"` PluginVersion string `json:"pluginVersion"` DeploymentTargetID string `json:"deploymentTargetId,omitempty"` RunEndpointID string `json:"runEndpointId"` Name string `json:"name"` OwnerUserID string `json:"ownerUserId,omitempty"` AdminUserIDs []string `json:"adminUserIds"` State domain.ServerInstanceState `json:"state"` LifecycleObservedAt *time.Time `json:"lifecycleObservedAt,omitempty"` ConfigVersion int `json:"configVersion"` ConfigKey string `json:"configKey,omitempty"` ConfigChecksum string `json:"configChecksum,omitempty"` ConfigUpdatedAt *time.Time `json:"configUpdatedAt,omitempty"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` DeploymentProjection ServerDeploymentProjectionBody `json:"deploymentProjection,omitempty"` } type ServerInstanceListResponse struct { Items []ServerInstanceResponse `json:"items"` Count int `json:"count"` } type PlatformResourceUsageResponse struct { CPUPercent float64 `json:"cpuPercent"` MemoryPercent float64 `json:"memoryPercent"` DiskPercent float64 `json:"diskPercent"` Source string `json:"source,omitempty"` CollectedAt time.Time `json:"collectedAt"` } type ServerMetricsResponse struct { ServerInstanceID string `json:"serverInstanceId"` Online bool `json:"online"` PlayerCount *int `json:"playerCount,omitempty"` MaxPlayers *int `json:"maxPlayers,omitempty"` TPS *float64 `json:"tps,omitempty"` LatencyMS *float64 `json:"latencyMs,omitempty"` CPUPercent *float64 `json:"cpuPercent,omitempty"` MemoryPercent *float64 `json:"memoryPercent,omitempty"` DiskPercent *float64 `json:"diskPercent,omitempty"` Source string `json:"source,omitempty"` CollectedAt time.Time `json:"collectedAt"` } type ServerMetricsListResponse struct { Items []ServerMetricsResponse `json:"items"` Count int `json:"count"` } type ServerConfigResponse struct { ServerInstanceID string `json:"serverInstanceId"` ConfigVersion int `json:"configVersion"` Format string `json:"format"` Key string `json:"key,omitempty"` Content string `json:"content"` Checksum string `json:"checksum"` Source string `json:"source,omitempty"` UpdatedAt time.Time `json:"updatedAt"` } type ConfigDiffLineResponse struct { Kind string `json:"kind"` OldNumber int `json:"oldNumber,omitempty"` NewNumber int `json:"newNumber,omitempty"` Content string `json:"content"` } type ServerConfigDiffPreviewRequest struct { ExpectedConfigVersion int `json:"expectedConfigVersion"` ExpectedChecksum string `json:"expectedChecksum,omitempty"` Key string `json:"key"` ProposedContent string `json:"proposedContent,omitempty"` ProposedContentInputRef string `json:"proposedContentInputRef,omitempty"` } type ServerConfigDiffPreviewResponse struct { ServerInstanceID string `json:"serverInstanceId"` ConfigVersion int `json:"configVersion"` Checksum string `json:"checksum"` Key string `json:"key"` CurrentContent string `json:"currentContent"` ProposedContent string `json:"proposedContent,omitempty"` ProposedContentInputRef string `json:"proposedContentInputRef,omitempty"` Diff []ConfigDiffLineResponse `json:"diff"` HasChanges bool `json:"hasChanges"` Source string `json:"source"` ReviewedAt time.Time `json:"reviewedAt"` } type ServerConfigWriteApprovalRequest struct { ExpectedConfigVersion int `json:"expectedConfigVersion"` ExpectedChecksum string `json:"expectedChecksum,omitempty"` Key string `json:"key"` ProposedContent string `json:"proposedContent,omitempty"` ProposedContentInputRef string `json:"proposedContentInputRef,omitempty"` IdempotencyKey string `json:"idempotencyKey"` } type ServerConfigWriteDispatchResponse struct { Status string `json:"status"` Preview ServerConfigDiffPreviewResponse `json:"preview"` Job JobResponse `json:"job"` } type FileOperationDispatchRequest struct { ServerInstanceID string `json:"serverInstanceId"` PluginID string `json:"pluginId,omitempty"` Operation domain.FileOperationKind `json:"operation"` Key string `json:"key"` InputRef string `json:"inputRef,omitempty"` Content string `json:"content,omitempty"` ExpectedConfigVersion int `json:"expectedConfigVersion,omitempty"` ExpectedChecksum string `json:"expectedChecksum,omitempty"` IdempotencyKey string `json:"idempotencyKey"` } type FileOperationDispatchResponse struct { Status string `json:"status"` ServerInstanceID string `json:"serverInstanceId"` PluginID string `json:"pluginId,omitempty"` Operation domain.FileOperationKind `json:"operation"` Key string `json:"key"` InputRef string `json:"inputRef,omitempty"` Job JobResponse `json:"job"` } type DeclaredFileReadSnapshotResponse struct { ServerInstanceID string `json:"serverInstanceId"` PluginID string `json:"pluginId"` Key string `json:"key"` State string `json:"state"` Content string `json:"content,omitempty"` Version int `json:"version,omitempty"` Checksum string `json:"checksum,omitempty"` SizeBytes int64 `json:"sizeBytes,omitempty"` JobID string `json:"jobId,omitempty"` ReadAt time.Time `json:"readAt,omitempty"` Reason string `json:"reason,omitempty"` } type RunCapacityResponse struct { MaxJobs int `json:"maxJobs"` RunningJobs int `json:"runningJobs"` QueuedJobs int `json:"queuedJobs"` LogBacklogBatches int `json:"logBacklogBatches,omitempty"` ArtifactBacklogChunks int `json:"artifactBacklogChunks,omitempty"` PressureCodes []string `json:"pressureCodes,omitempty"` Summary string `json:"summary,omitempty"` } type RunEndpointCreateRequest struct { ID string `json:"id"` DisplayName string `json:"displayName"` Version string `json:"version"` Platform string `json:"platform,omitempty"` Architecture string `json:"architecture,omitempty"` Status domain.RunEndpointStatus `json:"status"` Capabilities []string `json:"capabilities"` Capacity RunCapacityResponse `json:"capacity"` LastHeartbeatAt time.Time `json:"lastHeartbeatAt"` } type RunEndpointResponse struct { ID string `json:"id"` DisplayName string `json:"displayName"` Version string `json:"version"` Platform string `json:"platform,omitempty"` Architecture string `json:"architecture,omitempty"` Status domain.RunEndpointStatus `json:"status"` Capabilities []string `json:"capabilities"` Capacity RunCapacityResponse `json:"capacity"` LastHeartbeatAt time.Time `json:"lastHeartbeatAt"` } type RunEndpointListResponse struct { Items []RunEndpointResponse `json:"items"` Count int `json:"count"` } type JobCreateRequest struct { ID string `json:"id"` ServerInstanceID string `json:"serverInstanceId,omitempty"` RunEndpointID string `json:"runEndpointId"` Capability string `json:"capability"` TargetKey string `json:"targetKey,omitempty"` InputRef string `json:"inputRef,omitempty"` IdempotencyKey string `json:"idempotencyKey"` Progress JobProgressBody `json:"progress,omitempty"` } type JobProgressBody struct { Percent int `json:"percent"` Phase string `json:"phase,omitempty"` Message string `json:"message,omitempty"` } type JobRetryPolicyResponse struct { MaxAttempts int `json:"maxAttempts"` InitialBackoffSeconds int `json:"initialBackoffSeconds"` MaxBackoffSeconds int `json:"maxBackoffSeconds"` } type JobResponse struct { ID string `json:"id"` ServerInstanceID string `json:"serverInstanceId,omitempty"` RunEndpointID string `json:"runEndpointId"` Capability string `json:"capability"` TargetKey string `json:"targetKey,omitempty"` InputRef string `json:"inputRef,omitempty"` IdempotencyKey string `json:"idempotencyKey"` State domain.JobState `json:"state"` Progress JobProgressBody `json:"progress"` ResultRef string `json:"resultRef,omitempty"` ExecutionResult JobExecutionResultResponse `json:"executionResult,omitempty"` RetryPolicy JobRetryPolicyResponse `json:"retryPolicy"` Attempt int `json:"attempt"` NextAttemptAt *time.Time `json:"nextAttemptAt,omitempty"` AckDeadlineAt *time.Time `json:"ackDeadlineAt,omitempty"` LeaseExpiresAt *time.Time `json:"leaseExpiresAt,omitempty"` CancelReason string `json:"cancelReason,omitempty"` CancelRequestedAt *time.Time `json:"cancelRequestedAt,omitempty"` CancelCompletedAt *time.Time `json:"cancelCompletedAt,omitempty"` TerminalAt *time.Time `json:"terminalAt,omitempty"` LastReconciledAt *time.Time `json:"lastReconciledAt,omitempty"` ReconcileCount int `json:"reconcileCount"` ReconcileOutcome string `json:"reconcileOutcome,omitempty"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } type JobExecutionResultResponse struct { Kind string `json:"kind,omitempty"` ProcessState string `json:"processState,omitempty"` ExitClassification string `json:"exitClassification,omitempty"` ExitCode int `json:"exitCode,omitempty"` Version int `json:"version,omitempty"` Checksum string `json:"checksum,omitempty"` SizeBytes int64 `json:"sizeBytes,omitempty"` AuditSummary string `json:"auditSummary,omitempty"` ServerDeploymentEvidence *ServerDeploymentEvidenceBody `json:"serverDeploymentEvidence,omitempty"` } type JobListResponse struct { Items []JobResponse `json:"items"` Count int `json:"count"` } type ArtifactCreateRequest struct { ID string `json:"id"` OwnerKind domain.ArtifactOwnerKind `json:"ownerKind"` OwnerID string `json:"ownerId"` SizeBytes int64 `json:"sizeBytes"` Checksum string `json:"checksum"` } type ArtifactResponse struct { ID string `json:"id"` OwnerKind domain.ArtifactOwnerKind `json:"ownerKind"` OwnerID string `json:"ownerId"` SizeBytes int64 `json:"sizeBytes"` Checksum string `json:"checksum"` State domain.ArtifactState `json:"state"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } type ArtifactListResponse struct { Items []ArtifactResponse `json:"items"` Count int `json:"count"` } type LogStreamCreateRequest struct { ID string `json:"id"` ServerInstanceID string `json:"serverInstanceId"` Source domain.LogStreamSource `json:"source"` StreamKey string `json:"streamKey"` StorageBackend domain.LogStorageBackend `json:"storageBackend"` RetentionPolicy string `json:"retentionPolicy"` } type LogStreamResponse struct { ID string `json:"id"` ServerInstanceID string `json:"serverInstanceId"` Source domain.LogStreamSource `json:"source"` StreamKey string `json:"streamKey"` LatestSeq uint64 `json:"latestSeq"` StorageBackend domain.LogStorageBackend `json:"storageBackend"` RetentionPolicy string `json:"retentionPolicy"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } type LogStreamListResponse struct { Items []LogStreamResponse `json:"items"` Count int `json:"count"` } type AuditEventCreateRequest struct { ID string `json:"id"` ActorID string `json:"actorId"` Action string `json:"action"` ResourceKind string `json:"resourceKind"` ResourceID string `json:"resourceId"` Result domain.AuditResult `json:"result"` Summary string `json:"summary"` } type AuditEventResponse struct { ID string `json:"id"` ActorID string `json:"actorId"` Action string `json:"action"` ResourceKind string `json:"resourceKind"` ResourceID string `json:"resourceId"` Result domain.AuditResult `json:"result"` Summary string `json:"summary"` CreatedAt time.Time `json:"createdAt"` } type AuditEventListResponse struct { Items []AuditEventResponse `json:"items"` Count int `json:"count"` } type ErrorResponse struct { Code string `json:"code"` Message string `json:"message"` Details []string `json:"details,omitempty"` } func (request UserCreateRequest) ToDomain() domain.User { return domain.User{ ID: request.ID, DisplayName: request.DisplayName, Email: request.Email, Status: request.Status, Roles: domain.CopyStringSlice(request.Roles), PasswordHash: request.Password, Profile: request.Profile.ToDomain(), } } func (request UserUpdateRequest) ApplyTo(user domain.User) domain.User { if request.DisplayName != nil { user.DisplayName = *request.DisplayName } if request.Email != nil { user.Email = *request.Email } if request.Status != nil { user.Status = *request.Status } if request.Roles != nil { user.Roles = domain.CopyStringSlice(request.Roles) } if request.Profile != nil { user.Profile = request.Profile.ToDomain() } return user } func (profile UserProfileBody) ToDomain() domain.UserProfile { return domain.UserProfile{ AvatarURL: profile.AvatarURL, Phone: profile.Phone, QQ: profile.QQ, ContactNote: profile.ContactNote, } } func UserProfileFromDomain(profile domain.UserProfile) UserProfileBody { return UserProfileBody{ AvatarURL: profile.AvatarURL, Phone: profile.Phone, QQ: profile.QQ, ContactNote: profile.ContactNote, } } func (request UserThemePreferenceRequest) ToDomain(userID string) domain.UserThemePreference { preference := domain.UserThemePreference{ UserID: userID, PaletteID: request.PaletteID, BackgroundPresetID: request.BackgroundPresetID, Persistence: "api", } if request.BackgroundImage != nil { preference.BackgroundImage = *request.BackgroundImage } return preference } func (request LoginRequest) ToDomain() domain.UserLogin { return domain.UserLogin{Account: request.Account, Password: request.Password} } func (request RegisterRequest) ToDomain() domain.UserRegistration { return domain.UserRegistration{ DisplayName: request.DisplayName, Email: request.Email, Password: request.Password, Profile: domain.UserProfile{ Phone: request.Phone, QQ: request.QQ, }, } } func (request AIProviderCreateRequest) ToDomain() domain.AIProvider { return domain.AIProvider{ ID: request.ID, Name: request.Name, Kind: request.Kind, BaseURL: request.BaseURL, APIKeyRef: request.APIKeyRef, Models: domain.CopyStringSlice(request.Models), DefaultModel: request.DefaultModel, RelayMode: request.RelayMode, TimeoutMS: request.TimeoutMS, RedactionPolicy: request.RedactionPolicy, } } func (request AIProviderUpdateRequest) ToDomain(id string, status domain.AIProviderStatus) domain.AIProvider { return domain.AIProvider{ ID: id, Name: request.Name, Kind: request.Kind, BaseURL: request.BaseURL, APIKeyRef: request.APIKeyRef, Models: domain.CopyStringSlice(request.Models), DefaultModel: request.DefaultModel, RelayMode: request.RelayMode, TimeoutMS: request.TimeoutMS, Status: status, RedactionPolicy: request.RedactionPolicy, } } func (request GamePluginManifestRegistrationRequest) ToDomain() domain.GamePluginManifestRegistration { return domain.GamePluginManifestRegistration{ ManifestRef: request.ManifestRef, AssetFiles: pluginAssetFilesToDomain(request.AssetFiles), Manifest: domain.GamePluginManifest{ ID: request.Manifest.ID, Name: request.Manifest.Name, Description: request.Manifest.Description, Version: request.Manifest.Version, Kind: request.Manifest.Kind, Tags: domain.CopyStringSlice(request.Manifest.Tags), Server: request.Manifest.Server.ToDomain(), Bridge: request.Manifest.Bridge.ToDomain(), Capabilities: domain.CopyStringSlice(request.Manifest.Capabilities), Permissions: domain.CopyStringSlice(request.Manifest.Permissions), Actions: request.Manifest.Actions.ToDomain(), AssetFiles: pluginAssetFilesToDomain(request.Manifest.AssetFiles), Pages: pagesToDomain(request.Manifest.Pages), FileWorkspace: fileWorkspaceToDomain(request.Manifest.FileWorkspace), AI: request.Manifest.AI.ToDomain(), ProductionLifecycle: request.Manifest.ProductionLifecycle.ToDomain(), RemoteAccess: request.Manifest.RemoteAccess.ToDomain(), RuntimeProfiles: request.Manifest.RuntimeProfiles.ToDomain(), GameClientBridge: request.Manifest.GameClientBridge.ToDomain(), }, } } func pluginAssetFilesToDomain(files []PluginAssetFileBody) []domain.PluginAssetFile { if files == nil { return nil } out := make([]domain.PluginAssetFile, len(files)) for i, file := range files { out[i] = domain.PluginAssetFile{Path: file.Path, Content: file.Content, Mode: file.Mode} } return out } func fileWorkspaceToDomain(body PluginFileWorkspaceBody) domain.PluginFileWorkspace { workspace := domain.PluginFileWorkspace{DefaultDirectoryKey: body.DefaultDirectoryKey} for _, item := range body.Directories { workspace.Directories = append(workspace.Directories, domain.PluginLogicalDirectory{Key: item.Key, Label: item.Label, Scope: item.Scope}) } for _, item := range body.Files { workspace.Files = append(workspace.Files, domain.PluginLogicalFile{Key: item.Key, DirectoryKey: item.DirectoryKey, Label: item.Label, Kind: item.Kind, StreamKey: item.StreamKey, Editable: item.Editable}) } for _, item := range body.ConfigFields { workspace.ConfigFields = append(workspace.ConfigFields, domain.PluginConfigField{Key: item.Key, FileKey: item.FileKey, ConfigKey: item.ConfigKey, Label: item.Label, Description: item.Description, Control: item.Control, Minimum: item.Minimum, Maximum: item.Maximum, DefaultValue: item.DefaultValue, RestartImpact: item.RestartImpact}) } return workspace } func fileWorkspaceFromDomain(workspace domain.PluginFileWorkspace) PluginFileWorkspaceBody { workspace = domain.CopyPluginFileWorkspace(workspace) body := PluginFileWorkspaceBody{DefaultDirectoryKey: workspace.DefaultDirectoryKey} for _, item := range workspace.Directories { body.Directories = append(body.Directories, PluginLogicalDirectoryBody{Key: item.Key, Label: item.Label, Scope: item.Scope}) } for _, item := range workspace.Files { body.Files = append(body.Files, PluginLogicalFileBody{Key: item.Key, DirectoryKey: item.DirectoryKey, Label: item.Label, Kind: item.Kind, StreamKey: item.StreamKey, Editable: item.Editable}) } for _, item := range workspace.ConfigFields { body.ConfigFields = append(body.ConfigFields, PluginConfigFieldBody{Key: item.Key, FileKey: item.FileKey, ConfigKey: item.ConfigKey, Label: item.Label, Description: item.Description, Control: item.Control, Minimum: item.Minimum, Maximum: item.Maximum, DefaultValue: item.DefaultValue, RestartImpact: item.RestartImpact}) } return body } func (bridge GamePluginBridgeBody) ToDomain() domain.GamePluginBridge { return domain.GamePluginBridge{Actions: domain.CopyStringSlice(bridge.Actions)} } func pluginCreateFieldsToDomain(fields []PluginCreateFieldBody) []domain.PluginCreateField { if fields == nil { return nil } out := make([]domain.PluginCreateField, len(fields)) for i, field := range fields { out[i] = domain.PluginCreateField{Key: field.Key, Label: field.Label, Type: field.Type, Required: field.Required, DefaultValue: field.DefaultValue, Options: domain.CopyStringSlice(field.Options), ConfigKey: field.ConfigKey} } return out } func pluginCreateFieldsFromDomain(fields []domain.PluginCreateField) []PluginCreateFieldBody { if fields == nil { return nil } out := make([]PluginCreateFieldBody, len(fields)) for i, field := range fields { out[i] = PluginCreateFieldBody{Key: field.Key, Label: field.Label, Type: field.Type, Required: field.Required, DefaultValue: field.DefaultValue, Options: domain.CopyStringSlice(field.Options), ConfigKey: field.ConfigKey} } return out } func (server GamePluginManifestServerBody) ToDomain() domain.GamePluginManifestServer { return domain.GamePluginManifestServer{ Type: server.Type, DisplayName: server.DisplayName, SupportedOS: domain.CopyStringSlice(server.SupportedOS), CreateFormSchema: server.CreateFormSchema, CreateFields: pluginCreateFieldsToDomain(server.CreateFields), } } func (ai GamePluginManifestAIBody) ToDomain() domain.GamePluginManifestAI { return domain.GamePluginManifestAI{Purposes: domain.CopyStringSlice(ai.Purposes), Mediation: ai.Mediation, ConfigWritePolicy: ai.ConfigWritePolicy} } func (lifecycle GamePluginProductionLifecycleBody) ToDomain() domain.GamePluginProductionLifecycle { return domain.GamePluginProductionLifecycle{Operations: domain.CopyStringSlice(lifecycle.Operations), DependencyPolicy: lifecycle.DependencyPolicy, ApprovalRequired: domain.CopyStringSlice(lifecycle.ApprovalRequired)} } func (remote GamePluginRemoteAccessBody) ToDomain() domain.GamePluginRemoteAccess { return domain.GamePluginRemoteAccess{ Methods: domain.CopyStringSlice(remote.Methods), RunCapabilities: domain.CopyStringSlice(remote.RunCapabilities), DatabaseEngines: domain.CopyStringSlice(remote.DatabaseEngines), RCON: remote.RCON, LogTransfer: remote.LogTransfer, } } func (body GameClientBridgeManifestBody) ToDomain() domain.GameClientBridgeManifest { commands := make([]domain.GameClientBridgeCommandDeclaration, len(body.Commands)) for index, command := range body.Commands { commands[index] = domain.GameClientBridgeCommandDeclaration{Type: command.Type, Title: command.Title, Permission: command.Permission, ApprovalLevel: domain.GameClientBridgeApprovalLevel(command.ApprovalLevel), PayloadSchemaRef: command.PayloadSchemaRef, ResultSchemaRef: command.ResultSchemaRef, TimeoutSeconds: command.TimeoutSeconds, MaxPayloadBytes: command.MaxPayloadBytes, ProtectedRequest: protectedRequestToDomain(command.ProtectedRequest)} } snapshots := make([]domain.GameClientBridgeSnapshotDeclaration, len(body.Snapshots)) for index, snapshot := range body.Snapshots { snapshots[index] = domain.GameClientBridgeSnapshotDeclaration{Type: snapshot.Type, SchemaVersion: snapshot.SchemaVersion, SchemaRef: snapshot.SchemaRef, Retention: domain.GameClientBridgeRetention{KeepForSeconds: snapshot.KeepForSeconds, MaxRecords: snapshot.MaxRecords}} } queryTemplates := make([]domain.GameClientBridgeQueryTemplateDeclaration, len(body.QueryTemplates)) for index, template := range body.QueryTemplates { var rowTarget *domain.PluginDataRowTargetDeclaration if template.RowTarget != nil { value := domain.PluginDataRowTargetDeclaration{Collection: template.RowTarget.Collection, UpsertKeys: domain.CopyStringSlice(template.RowTarget.UpsertKeys), ColumnMappings: domain.CopyStringMap(template.RowTarget.ColumnMappings)} rowTarget = &value } queryTemplates[index] = domain.GameClientBridgeQueryTemplateDeclaration{Key: template.Key, Title: template.Title, Permission: template.Permission, Engine: template.Engine, TransportKey: template.TransportKey, TargetKey: template.TargetKey, ParameterSchemaRef: template.ParameterSchemaRef, ResultSchemaRef: template.ResultSchemaRef, SQLRef: template.SQLRef, MaxRows: template.MaxRows, TimeoutSeconds: template.TimeoutSeconds, RowTarget: rowTarget} } dataPacks := make([]domain.GameClientBridgeDataPackDeclaration, len(body.DataPacks)) for index, dataPack := range body.DataPacks { dataPacks[index] = domain.GameClientBridgeDataPackDeclaration{Key: dataPack.Key, DatabaseUserVersion: dataPack.DatabaseUserVersion, LogParserRefs: domain.CopyStringSlice(dataPack.LogParserRefs), ConfigMapRefs: domain.CopyStringSlice(dataPack.ConfigMapRefs)} } operationTemplates := make([]domain.GameClientBridgeOperationTemplateDeclaration, len(body.OperationTemplates)) for index, template := range body.OperationTemplates { operationTemplates[index] = domain.GameClientBridgeOperationTemplateDeclaration{Key: template.Key, Title: template.Title, Permission: template.Permission, ApprovalLevel: domain.GameClientBridgeApprovalLevel(template.ApprovalLevel), Kind: domain.GameClientBridgeOperationKind(template.Kind), TransportKey: template.TransportKey, TargetKey: template.TargetKey, PayloadSchemaRef: template.PayloadSchemaRef, ResultSchemaRef: template.ResultSchemaRef, ConfirmationSchemaRef: template.ConfirmationSchemaRef, TimeoutSeconds: template.TimeoutSeconds, MaxPayloadBytes: template.MaxPayloadBytes, MaxRowsAffected: template.MaxRowsAffected, Mutation: domain.GameClientBridgeOperationMutationDeclaration{FieldKey: template.Mutation.FieldKey, TableKey: template.Mutation.TableKey, IdentityKey: template.Mutation.IdentityKey, ValueKey: template.Mutation.ValueKey, ConfirmationQueryKey: template.Mutation.ConfirmationQueryKey, AllowedValueType: template.Mutation.AllowedValueType, MinValue: template.Mutation.MinValue, MaxValue: template.Mutation.MaxValue}, Safety: domain.GameClientBridgeOperationSafety{RequiresApproval: template.Safety.RequiresApproval, RequiresOfflinePlayer: template.Safety.RequiresOfflinePlayer, RequiresMaintenanceWindow: template.Safety.RequiresMaintenanceWindow, RequiresBeforeValue: template.Safety.RequiresBeforeValue, RequiresConfirmation: template.Safety.RequiresConfirmation, BackupRequired: template.Safety.BackupRequired}} } pages := make([]domain.GameClientBridgePageContract, len(body.Pages)) for index, page := range body.Pages { pages[index] = domain.GameClientBridgePageContract{PageKey: page.PageKey, CommandTypes: domain.CopyStringSlice(page.CommandTypes), SnapshotTypes: domain.CopyStringSlice(page.SnapshotTypes), QueryTemplateKeys: domain.CopyStringSlice(page.QueryTemplateKeys), OperationKeys: domain.CopyStringSlice(page.OperationKeys), FeatureKeys: domain.CopyStringSlice(page.FeatureKeys)} } features := make([]domain.GameClientBridgeFeatureDeclaration, len(body.Features)) for index, feature := range body.Features { features[index] = domain.GameClientBridgeFeatureDeclaration{Key: feature.Key, Title: feature.Title, Permission: feature.Permission, RequiredHandlers: domain.CopyStringSlice(feature.RequiredHandlers), RequiredEventProducers: domain.CopyStringSlice(feature.RequiredEventProducers)} } companion := domain.GameClientBridgeCompanionDeclaration{} if body.Companion != nil { companion = domain.GameClientBridgeCompanionDeclaration{ProfileKey: body.Companion.ProfileKey, ConfigTemplateKey: body.Companion.ConfigTemplateKey, ConfigSchemaRef: body.Companion.ConfigSchemaRef, ConfigFormat: body.Companion.ConfigFormat, PlatformBaseURLSource: body.Companion.PlatformBaseURLSource, RegistrationProof: body.Companion.RegistrationProof, ProofMaterialSource: body.Companion.ProofMaterialSource, ProofMaterialEnv: body.Companion.ProofMaterialEnv, SessionMode: body.Companion.SessionMode, TLSPolicy: body.Companion.TLSPolicy, HeartbeatIntervalSeconds: body.Companion.HeartbeatIntervalSeconds, CommandPollIntervalSeconds: body.Companion.CommandPollIntervalSeconds, RequestTimeoutSeconds: body.Companion.RequestTimeoutSeconds} } return domain.GameClientBridgeManifest{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, DataPacks: dataPacks, OperationTemplates: operationTemplates, Retention: domain.GameClientBridgeRetention{KeepForSeconds: body.CommandRetentionSeconds, MaxRecords: body.MaxCommands}, Pages: pages, Features: features, Companion: companion} } func protectedRequestToDomain(value *GameClientBridgeProtectedRequestDeclarationBody) *domain.GameClientBridgeProtectedRequestDeclaration { if value == nil { return nil } return &domain.GameClientBridgeProtectedRequestDeclaration{Kind: value.Kind, TransportKey: value.TransportKey, TargetKey: value.TargetKey, TextField: value.TextField, MaxTextBytes: value.MaxTextBytes} } func (actions PluginLifecycleActionsBody) ToDomain() domain.PluginLifecycleActions { return domain.PluginLifecycleActions{ Install: actions.Install, Start: actions.Start, Stop: actions.Stop, Restart: actions.Restart, Status: actions.Status, } } func (request GamePluginCreateRequest) ToDomain() domain.GamePlugin { return domain.GamePlugin{ ID: request.ID, Name: request.Name, Description: request.Description, Version: request.Version, ServerType: request.ServerType, ServerDisplayName: request.ServerDisplayName, SupportedOS: domain.CopyStringSlice(request.SupportedOS), ManifestRef: request.ManifestRef, CreateFormSchemaRef: request.CreateFormSchemaRef, CreateFields: pluginCreateFieldsToDomain(request.CreateFields), RequiredRunCapabilities: domain.CopyStringSlice(request.RequiredRunCapabilities), DeclaredPermissions: domain.CopyStringSlice(request.DeclaredPermissions), Permissions: permissionsToDomain(request.Permissions), LifecycleActions: request.LifecycleActions.ToDomain(), BridgeActions: domain.CopyStringSlice(request.BridgeActions), Pages: pagesToDomain(request.Pages), FileWorkspace: fileWorkspaceToDomain(request.FileWorkspace), Tags: domain.CopyStringSlice(request.Tags), AIPurposes: domain.CopyStringSlice(request.AIPurposes), ProductionLifecycle: request.ProductionLifecycle.ToDomain(), RemoteAccess: request.RemoteAccess.ToDomain(), RuntimeProfiles: request.RuntimeProfiles.ToDomain(), GameClientBridge: request.GameClientBridge.ToDomain(), ValidationViolations: domain.CopyStringSlice(request.ValidationViolations), } } func (request ServerInstanceCreateRequest) ToDomain() domain.ServerInstance { return domain.ServerInstance{ ID: request.ID, PluginID: request.PluginID, RunEndpointID: request.RunEndpointID, Name: request.Name, OwnerUserID: request.OwnerUserID, AdminUserIDs: domain.CopyStringSlice(request.AdminUserIDs), State: request.State, } } func (request ServerInstanceUpdateRequest) ToDomain() domain.ServerInstanceUpdate { return domain.ServerInstanceUpdate{Name: request.Name} } func (request ServerDeletionRequest) ToDomain() domain.ServerDeletionRequest { return domain.ServerDeletionRequest{Password: request.Password, Force: request.Force, Confirmation: request.Confirmation} } func (request ServerConfigDiffPreviewRequest) ToDomain(serverInstanceID string) domain.ServerConfigDiffRequest { return domain.ServerConfigDiffRequest{ ServerInstanceID: serverInstanceID, ExpectedConfigVersion: request.ExpectedConfigVersion, ExpectedChecksum: request.ExpectedChecksum, Key: request.Key, ProposedContent: request.ProposedContent, ProposedContentInputRef: request.ProposedContentInputRef, } } func (request ServerConfigWriteApprovalRequest) ToDomain(serverInstanceID string) domain.ServerConfigWriteApproval { return domain.ServerConfigWriteApproval{ ServerInstanceID: serverInstanceID, ExpectedConfigVersion: request.ExpectedConfigVersion, ExpectedChecksum: request.ExpectedChecksum, Key: request.Key, ProposedContent: request.ProposedContent, ProposedContentInputRef: request.ProposedContentInputRef, IdempotencyKey: request.IdempotencyKey, } } func (request FileOperationDispatchRequest) ToDomain() domain.FileOperationDispatchRequest { return domain.FileOperationDispatchRequest{ ServerInstanceID: request.ServerInstanceID, PluginID: request.PluginID, Operation: request.Operation, Key: request.Key, InputRef: request.InputRef, Content: request.Content, ExpectedConfigVersion: request.ExpectedConfigVersion, ExpectedChecksum: request.ExpectedChecksum, IdempotencyKey: request.IdempotencyKey, } } func (request RunEndpointCreateRequest) ToDomain() domain.RunEndpoint { return domain.RunEndpoint{ ID: request.ID, DisplayName: request.DisplayName, Version: request.Version, Platform: request.Platform, Architecture: request.Architecture, Status: request.Status, Capabilities: domain.CopyStringSlice(request.Capabilities), Capacity: capacityToDomain(request.Capacity), LastHeartbeatAt: request.LastHeartbeatAt, } } func (request JobCreateRequest) ToDomain() domain.Job { return domain.Job{ ID: request.ID, ServerInstanceID: request.ServerInstanceID, RunEndpointID: request.RunEndpointID, Capability: request.Capability, TargetKey: request.TargetKey, InputRef: request.InputRef, IdempotencyKey: request.IdempotencyKey, Progress: progressToDomain(request.Progress), } } func (request ArtifactCreateRequest) ToDomain() domain.Artifact { return domain.Artifact{ ID: request.ID, OwnerKind: request.OwnerKind, OwnerID: request.OwnerID, SizeBytes: request.SizeBytes, Checksum: request.Checksum, } } func (request LogStreamCreateRequest) ToDomain() domain.LogStream { return domain.LogStream{ ID: request.ID, ServerInstanceID: request.ServerInstanceID, Source: request.Source, StreamKey: request.StreamKey, StorageBackend: request.StorageBackend, RetentionPolicy: request.RetentionPolicy, } } func (request AuditEventCreateRequest) ToDomain() domain.AuditEvent { return domain.AuditEvent{ ID: request.ID, ActorID: request.ActorID, Action: request.Action, ResourceKind: request.ResourceKind, ResourceID: request.ResourceID, Result: request.Result, Summary: request.Summary, } } func UserFromDomain(user domain.User) UserResponse { user = domain.CopyUser(user) return UserResponse{ ID: user.ID, DisplayName: user.DisplayName, Email: user.Email, Status: user.Status, Roles: user.Roles, Profile: UserProfileFromDomain(user.Profile), ThemePreference: UserThemePreferenceFromDomain(user.Theme), CreatedAt: user.CreatedAt, UpdatedAt: user.UpdatedAt, } } func CurrentUserFromDomain(user domain.User) CurrentUserResponse { user = domain.CopyUser(user) return CurrentUserResponse{ ID: user.ID, DisplayName: user.DisplayName, Email: user.Email, Status: user.Status, Roles: user.Roles, Profile: UserProfileFromDomain(user.Profile), ThemePreference: UserThemePreferenceFromDomain(user.Theme), } } func AuthSessionFromDomain(session domain.AuthSession) AuthSessionResponse { return AuthSessionResponse{ User: CurrentUserFromDomain(session.User), SessionID: session.SessionID, Status: session.Status, Message: session.Message, ExpiresAt: session.ExpiresAt, } } func UserThemePreferenceFromDomain(preference domain.UserThemePreference) *UserThemePreferenceResponse { if preference.UserID == "" { return nil } return &UserThemePreferenceResponse{ UserID: preference.UserID, PaletteID: preference.PaletteID, BackgroundPresetID: preference.BackgroundPresetID, BackgroundImage: preference.BackgroundImage, Persistence: preference.Persistence, UpdatedAt: preference.UpdatedAt, } } func UserListFromDomain(users []domain.User) UserListResponse { items := make([]UserResponse, len(users)) for i, user := range users { items[i] = UserFromDomain(user) } return UserListResponse{Items: items, Count: len(items)} } func AIProviderFromDomain(provider domain.AIProvider) AIProviderResponse { provider = domain.CopyAIProvider(provider) return AIProviderResponse{ ID: provider.ID, Name: provider.Name, Kind: provider.Kind, BaseURLConfigured: provider.BaseURL != "", APIKeyConfigured: provider.APIKeyRef != "", Models: provider.Models, DefaultModel: provider.DefaultModel, RelayMode: provider.RelayMode, TimeoutMS: provider.TimeoutMS, Status: provider.Status, RedactionPolicy: provider.RedactionPolicy, } } func AIProviderListFromDomain(providers []domain.AIProvider) AIProviderListResponse { items := make([]AIProviderResponse, len(providers)) for i, provider := range providers { items[i] = AIProviderFromDomain(provider) } return AIProviderListResponse{Items: items, Count: len(items)} } func AIProviderTestFromDomain(result domain.AIProviderTestResult) AIProviderTestResponse { result = domain.CopyAIProviderTestResult(result) return AIProviderTestResponse{ ProviderID: result.ProviderID, Mode: result.Mode, Success: result.Success, Message: result.Message, Violations: result.Violations, } } func AIProviderModelsFromDomain(models domain.AIProviderModels) AIProviderModelsResponse { models = domain.CopyAIProviderModels(models) return AIProviderModelsResponse{ ProviderID: models.ProviderID, DefaultModel: models.DefaultModel, Models: models.Models, } } func GamePluginFromDomain(plugin domain.GamePlugin) GamePluginResponse { plugin = domain.CopyGamePlugin(plugin) return GamePluginResponse{ ID: plugin.ID, Name: plugin.Name, Description: plugin.Description, Version: plugin.Version, ServerType: plugin.ServerType, ServerDisplayName: plugin.ServerDisplayName, SupportedOS: plugin.SupportedOS, ManifestRef: plugin.ManifestRef, CreateFormSchemaRef: plugin.CreateFormSchemaRef, CreateFields: pluginCreateFieldsFromDomain(plugin.CreateFields), RequiredRunCapabilities: plugin.RequiredRunCapabilities, DeclaredPermissions: plugin.DeclaredPermissions, Permissions: permissionsFromDomain(plugin.Permissions), LifecycleActions: lifecycleActionsFromDomain(plugin.LifecycleActions), BridgeActions: plugin.BridgeActions, Pages: pagesFromDomain(plugin.Pages), FileWorkspace: fileWorkspaceFromDomain(plugin.FileWorkspace), Tags: plugin.Tags, AIPurposes: plugin.AIPurposes, ProductionLifecycle: productionLifecycleFromDomain(plugin.ProductionLifecycle), RemoteAccess: remoteAccessFromDomain(plugin.RemoteAccess), RuntimeProfiles: runtimeProfilesFromDomain(plugin.RuntimeProfiles), GameClientBridge: gameClientBridgeManifestFromDomain(plugin.GameClientBridge), ValidationViolations: plugin.ValidationViolations, Status: plugin.Status, } } func (request PluginBridgeAuthorizeRequest) ToDomain() domain.PluginBridgeAuthorizeRequest { return domain.PluginBridgeAuthorizeRequest{ PluginID: request.PluginID, RouteKey: request.RouteKey, ServerInstanceID: request.ServerInstanceID, Action: domain.PluginBridgeAction(request.Action), AIPurpose: request.AIPurpose, } } func (request PluginBridgeExecuteRequest) ToDomain() domain.PluginBridgeExecuteRequest { return domain.PluginBridgeExecuteRequest{ RequestID: request.RequestID, PluginID: request.PluginID, RouteKey: request.RouteKey, ServerInstanceID: request.ServerInstanceID, Action: domain.PluginBridgeAction(request.Action), AIPurpose: request.AIPurpose, Payload: domain.CopyStringMap(request.Payload), } } func PluginBridgeAuthorizeFromDomain(result domain.PluginBridgeAuthorization) PluginBridgeAuthorizeResponse { result = domain.CopyPluginBridgeAuthorization(result) return PluginBridgeAuthorizeResponse{ PluginID: result.PluginID, RouteKey: result.RouteKey, ServerInstanceID: result.ServerInstanceID, Action: string(result.Action), Allowed: result.Allowed, RequiredPermissions: result.RequiredPermissions, EffectivePermissions: result.EffectivePermissions, Reason: result.Reason, } } func PluginBridgeExecuteFromDomain(response domain.PluginBridgeExecuteResponse) PluginBridgeExecuteResponse { response = domain.CopyPluginBridgeExecuteResponse(response) var safeError *PluginBridgeSafeErrorResponse if response.Error != nil { safeError = &PluginBridgeSafeErrorResponse{Code: response.Error.Code, Message: response.Error.Message, Details: response.Error.Details} } return PluginBridgeExecuteResponse{ RequestID: response.RequestID, PluginID: response.PluginID, RouteKey: response.RouteKey, ServerInstanceID: response.ServerInstanceID, Action: string(response.Action), Status: response.Status, Result: domain.CopyStringMap(response.Result), Error: safeError, } } func GamePluginListFromDomain(plugins []domain.GamePlugin) GamePluginListResponse { items := make([]GamePluginResponse, len(plugins)) for i, plugin := range plugins { items[i] = GamePluginFromDomain(plugin) } return GamePluginListResponse{Items: items, Count: len(items)} } func MarketplacePluginFromDomain(plugin domain.PluginMarketplacePlugin) MarketplacePluginResponse { plugin = domain.CopyPluginMarketplacePlugin(plugin) return MarketplacePluginResponse{ ID: plugin.ID, Name: plugin.Name, Description: plugin.Description, Version: plugin.Version, ServerType: plugin.ServerType, ServerDisplayName: plugin.ServerDisplayName, SupportedOS: plugin.SupportedOS, ManifestRef: plugin.ManifestRef, CreateFormSchemaRef: plugin.CreateFormSchemaRef, Capabilities: plugin.Capabilities, DeclaredPermissions: plugin.DeclaredPermissions, Permissions: permissionsFromDomain(plugin.Permissions), LifecycleActions: lifecycleActionsFromDomain(plugin.LifecycleActions), BridgeActions: plugin.BridgeActions, Pages: pagesFromDomain(plugin.Pages), Tags: plugin.Tags, AIPurposes: plugin.AIPurposes, ProductionLifecycle: productionLifecycleFromDomain(plugin.ProductionLifecycle), RemoteAccess: remoteAccessFromDomain(plugin.RemoteAccess), RuntimeProfiles: runtimeProfilesFromDomain(plugin.RuntimeProfiles), GameClientBridge: gameClientBridgeManifestFromDomain(plugin.GameClientBridge), ValidationViolations: plugin.ValidationViolations, Status: plugin.Status, Source: plugin.Source, } } func productionLifecycleFromDomain(lifecycle domain.GamePluginProductionLifecycle) GamePluginProductionLifecycleBody { lifecycle = domain.CopyGamePluginProductionLifecycle(lifecycle) return GamePluginProductionLifecycleBody{Operations: lifecycle.Operations, DependencyPolicy: lifecycle.DependencyPolicy, ApprovalRequired: lifecycle.ApprovalRequired} } func gameClientBridgeManifestFromDomain(value domain.GameClientBridgeManifest) GameClientBridgeManifestBody { value = domain.CopyGameClientBridgeManifest(value) commands := make([]GameClientBridgeCommandDeclarationBody, len(value.Commands)) for index, command := range value.Commands { commands[index] = GameClientBridgeCommandDeclarationBody{Type: command.Type, Title: command.Title, Permission: command.Permission, ApprovalLevel: string(command.ApprovalLevel), PayloadSchemaRef: command.PayloadSchemaRef, ResultSchemaRef: command.ResultSchemaRef, TimeoutSeconds: command.TimeoutSeconds, MaxPayloadBytes: command.MaxPayloadBytes, ProtectedRequest: protectedRequestFromDomain(command.ProtectedRequest)} } snapshots := make([]GameClientBridgeSnapshotDeclarationBody, len(value.Snapshots)) for index, snapshot := range value.Snapshots { snapshots[index] = GameClientBridgeSnapshotDeclarationBody{Type: snapshot.Type, SchemaVersion: snapshot.SchemaVersion, SchemaRef: snapshot.SchemaRef, KeepForSeconds: snapshot.Retention.KeepForSeconds, MaxRecords: snapshot.Retention.MaxRecords} } queryTemplates := make([]GameClientBridgeQueryTemplateDeclarationBody, len(value.QueryTemplates)) for index, template := range value.QueryTemplates { var rowTarget *PluginDataRowTargetDeclarationBody if template.RowTarget != nil { rowTarget = &PluginDataRowTargetDeclarationBody{Collection: template.RowTarget.Collection, UpsertKeys: domain.CopyStringSlice(template.RowTarget.UpsertKeys), ColumnMappings: domain.CopyStringMap(template.RowTarget.ColumnMappings)} } queryTemplates[index] = GameClientBridgeQueryTemplateDeclarationBody{Key: template.Key, Title: template.Title, Permission: template.Permission, Engine: template.Engine, TransportKey: template.TransportKey, TargetKey: template.TargetKey, ParameterSchemaRef: template.ParameterSchemaRef, ResultSchemaRef: template.ResultSchemaRef, SQLRef: template.SQLRef, MaxRows: template.MaxRows, TimeoutSeconds: template.TimeoutSeconds, RowTarget: rowTarget} } dataPacks := make([]GameClientBridgeDataPackDeclarationBody, len(value.DataPacks)) for index, dataPack := range value.DataPacks { dataPacks[index] = GameClientBridgeDataPackDeclarationBody{Key: dataPack.Key, DatabaseUserVersion: dataPack.DatabaseUserVersion, LogParserRefs: domain.CopyStringSlice(dataPack.LogParserRefs), ConfigMapRefs: domain.CopyStringSlice(dataPack.ConfigMapRefs)} } operationTemplates := make([]GameClientBridgeOperationTemplateDeclarationBody, len(value.OperationTemplates)) for index, template := range value.OperationTemplates { operationTemplates[index] = GameClientBridgeOperationTemplateDeclarationBody{Key: template.Key, Title: template.Title, Permission: template.Permission, ApprovalLevel: string(template.ApprovalLevel), Kind: string(template.Kind), TransportKey: template.TransportKey, TargetKey: template.TargetKey, PayloadSchemaRef: template.PayloadSchemaRef, ResultSchemaRef: template.ResultSchemaRef, ConfirmationSchemaRef: template.ConfirmationSchemaRef, TimeoutSeconds: template.TimeoutSeconds, MaxPayloadBytes: template.MaxPayloadBytes, MaxRowsAffected: template.MaxRowsAffected, Mutation: GameClientBridgeOperationMutationDeclarationBody{FieldKey: template.Mutation.FieldKey, TableKey: template.Mutation.TableKey, IdentityKey: template.Mutation.IdentityKey, ValueKey: template.Mutation.ValueKey, ConfirmationQueryKey: template.Mutation.ConfirmationQueryKey, AllowedValueType: template.Mutation.AllowedValueType, MinValue: template.Mutation.MinValue, MaxValue: template.Mutation.MaxValue}, Safety: GameClientBridgeOperationSafetyBody{RequiresApproval: template.Safety.RequiresApproval, RequiresOfflinePlayer: template.Safety.RequiresOfflinePlayer, RequiresMaintenanceWindow: template.Safety.RequiresMaintenanceWindow, RequiresBeforeValue: template.Safety.RequiresBeforeValue, RequiresConfirmation: template.Safety.RequiresConfirmation, BackupRequired: template.Safety.BackupRequired}} } pages := make([]GameClientBridgePageContractBody, len(value.Pages)) for index, page := range value.Pages { pages[index] = GameClientBridgePageContractBody{PageKey: page.PageKey, CommandTypes: page.CommandTypes, SnapshotTypes: page.SnapshotTypes, QueryTemplateKeys: page.QueryTemplateKeys, OperationKeys: page.OperationKeys, FeatureKeys: page.FeatureKeys} } features := make([]GameClientBridgeFeatureDeclarationBody, len(value.Features)) for index, feature := range value.Features { features[index] = GameClientBridgeFeatureDeclarationBody{Key: feature.Key, Title: feature.Title, Permission: feature.Permission, RequiredHandlers: feature.RequiredHandlers, RequiredEventProducers: feature.RequiredEventProducers} } var companion *GameClientBridgeCompanionDeclarationBody if value.Companion.ProfileKey != "" { companion = &GameClientBridgeCompanionDeclarationBody{ProfileKey: value.Companion.ProfileKey, ConfigTemplateKey: value.Companion.ConfigTemplateKey, ConfigSchemaRef: value.Companion.ConfigSchemaRef, ConfigFormat: value.Companion.ConfigFormat, PlatformBaseURLSource: value.Companion.PlatformBaseURLSource, RegistrationProof: value.Companion.RegistrationProof, ProofMaterialSource: value.Companion.ProofMaterialSource, ProofMaterialEnv: value.Companion.ProofMaterialEnv, SessionMode: value.Companion.SessionMode, TLSPolicy: value.Companion.TLSPolicy, HeartbeatIntervalSeconds: value.Companion.HeartbeatIntervalSeconds, CommandPollIntervalSeconds: value.Companion.CommandPollIntervalSeconds, RequestTimeoutSeconds: value.Companion.RequestTimeoutSeconds} } return GameClientBridgeManifestBody{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, DataPacks: dataPacks, OperationTemplates: operationTemplates, CommandRetentionSeconds: value.Retention.KeepForSeconds, MaxCommands: value.Retention.MaxRecords, Pages: pages, Features: features, Companion: companion} } func protectedRequestFromDomain(value *domain.GameClientBridgeProtectedRequestDeclaration) *GameClientBridgeProtectedRequestDeclarationBody { if value == nil { return nil } return &GameClientBridgeProtectedRequestDeclarationBody{Kind: value.Kind, TransportKey: value.TransportKey, TargetKey: value.TargetKey, TextField: value.TextField, MaxTextBytes: value.MaxTextBytes} } func MarketplacePluginListFromDomain(plugins []domain.PluginMarketplacePlugin) MarketplacePluginListResponse { items := make([]MarketplacePluginResponse, len(plugins)) for i, plugin := range plugins { items[i] = MarketplacePluginFromDomain(plugin) } return MarketplacePluginListResponse{Items: items, Count: len(items)} } func ServerInstanceFromDomain(instance domain.ServerInstance) ServerInstanceResponse { instance = domain.CopyServerInstance(instance) adminUserIDs := instance.AdminUserIDs if adminUserIDs == nil { adminUserIDs = []string{} } return ServerInstanceResponse{ ID: instance.ID, PluginID: instance.PluginID, PluginVersion: instance.PluginVersion, DeploymentTargetID: instance.DeploymentTargetID, RunEndpointID: instance.RunEndpointID, Name: instance.Name, OwnerUserID: instance.OwnerUserID, AdminUserIDs: adminUserIDs, State: instance.State, LifecycleObservedAt: optionalTime(instance.LifecycleObservedAt), ConfigVersion: instance.ConfigVersion, ConfigKey: instance.ConfigKey, ConfigChecksum: instance.ConfigChecksum, ConfigUpdatedAt: optionalTime(instance.ConfigUpdatedAt), CreatedAt: instance.CreatedAt, UpdatedAt: instance.UpdatedAt, DeploymentProjection: deploymentProjectionFromDomain(instance.DeploymentProjection), } } func ServerMemberFromDomain(user domain.User) ServerMemberResponse { user = domain.CopyUser(user) return ServerMemberResponse{ ID: user.ID, DisplayName: user.DisplayName, Email: user.Email, Status: user.Status, Roles: user.Roles, Profile: UserProfileFromDomain(user.Profile), } } func ServerMemberListFromDomain(users []domain.User) ServerMemberListResponse { items := make([]ServerMemberResponse, len(users)) for i, user := range users { items[i] = ServerMemberFromDomain(user) } return ServerMemberListResponse{Items: items, Count: len(items)} } func ServerInstanceListFromDomain(instances []domain.ServerInstance) ServerInstanceListResponse { items := make([]ServerInstanceResponse, len(instances)) for i, instance := range instances { items[i] = ServerInstanceFromDomain(instance) } return ServerInstanceListResponse{Items: items, Count: len(items)} } func PlatformResourceUsageFromDomain(usage domain.PlatformResourceUsage) PlatformResourceUsageResponse { usage = domain.CopyPlatformResourceUsage(usage) return PlatformResourceUsageResponse{ CPUPercent: usage.CPUPercent, MemoryPercent: usage.MemoryPercent, DiskPercent: usage.DiskPercent, Source: usage.Source, CollectedAt: usage.CollectedAt, } } func ServerMetricsFromDomain(metrics domain.ServerMetrics) ServerMetricsResponse { metrics = domain.CopyServerMetrics(metrics) return ServerMetricsResponse{ ServerInstanceID: metrics.ServerInstanceID, Online: metrics.Online, PlayerCount: metrics.PlayerCount, MaxPlayers: metrics.MaxPlayers, TPS: metrics.TPS, LatencyMS: metrics.LatencyMS, CPUPercent: metrics.CPUPercent, MemoryPercent: metrics.MemoryPercent, DiskPercent: metrics.DiskPercent, Source: metrics.Source, CollectedAt: metrics.CollectedAt, } } func ServerMetricsListFromDomain(items []domain.ServerMetrics) ServerMetricsListResponse { responses := make([]ServerMetricsResponse, len(items)) for i, item := range items { responses[i] = ServerMetricsFromDomain(item) } return ServerMetricsListResponse{Items: responses, Count: len(responses)} } func ServerConfigFromDomain(config domain.ServerConfig) ServerConfigResponse { config = domain.CopyServerConfig(config) return ServerConfigResponse{ ServerInstanceID: config.ServerInstanceID, ConfigVersion: config.ConfigVersion, Format: config.Format, Key: config.Key, Content: config.Content, Checksum: config.Checksum, Source: config.Source, UpdatedAt: config.UpdatedAt, } } func ServerConfigDiffPreviewFromDomain(preview domain.ServerConfigDiffPreview) ServerConfigDiffPreviewResponse { preview = domain.CopyServerConfigDiffPreview(preview) lines := make([]ConfigDiffLineResponse, len(preview.Diff)) for i, line := range preview.Diff { lines[i] = ConfigDiffLineResponse{ Kind: line.Kind, OldNumber: line.OldNumber, NewNumber: line.NewNumber, Content: line.Content, } } return ServerConfigDiffPreviewResponse{ ServerInstanceID: preview.ServerInstanceID, ConfigVersion: preview.ConfigVersion, Checksum: preview.Checksum, Key: preview.Key, CurrentContent: preview.CurrentContent, ProposedContent: preview.ProposedContent, ProposedContentInputRef: preview.ProposedContentInputRef, Diff: lines, HasChanges: preview.HasChanges, Source: preview.Source, ReviewedAt: preview.ReviewedAt, } } func ServerConfigWriteDispatchFromDomain(dispatch domain.ServerConfigWriteDispatch) ServerConfigWriteDispatchResponse { dispatch = domain.CopyServerConfigWriteDispatch(dispatch) return ServerConfigWriteDispatchResponse{ Status: dispatch.Status, Preview: ServerConfigDiffPreviewFromDomain(dispatch.Preview), Job: JobFromDomain(dispatch.Job), } } func FileOperationDispatchFromDomain(result domain.FileOperationDispatchResult) FileOperationDispatchResponse { result = domain.CopyFileOperationDispatchResult(result) return FileOperationDispatchResponse{ Status: result.Status, ServerInstanceID: result.ServerInstanceID, PluginID: result.PluginID, Operation: result.Operation, Key: result.Key, InputRef: result.InputRef, Job: JobFromDomain(result.Job), } } func DeclaredFileReadSnapshotFromDomain(snapshot domain.DeclaredFileReadSnapshot) DeclaredFileReadSnapshotResponse { return DeclaredFileReadSnapshotResponse{ ServerInstanceID: snapshot.ServerInstanceID, PluginID: snapshot.PluginID, Key: snapshot.Key, State: snapshot.State, Content: snapshot.Content, Version: snapshot.Version, Checksum: snapshot.Checksum, SizeBytes: snapshot.SizeBytes, JobID: snapshot.JobID, ReadAt: snapshot.ReadAt, Reason: snapshot.Reason, } } func RunEndpointFromDomain(endpoint domain.RunEndpoint) RunEndpointResponse { endpoint = domain.CopyRunEndpoint(endpoint) return RunEndpointResponse{ ID: endpoint.ID, DisplayName: endpoint.DisplayName, Version: endpoint.Version, Platform: endpoint.Platform, Architecture: endpoint.Architecture, Status: endpoint.Status, Capabilities: endpoint.Capabilities, Capacity: capacityFromDomain(endpoint.Capacity), LastHeartbeatAt: endpoint.LastHeartbeatAt, } } func RunEndpointListFromDomain(endpoints []domain.RunEndpoint) RunEndpointListResponse { items := make([]RunEndpointResponse, len(endpoints)) for i, endpoint := range endpoints { items[i] = RunEndpointFromDomain(endpoint) } return RunEndpointListResponse{Items: items, Count: len(items)} } func JobFromDomain(job domain.Job) JobResponse { return JobResponse{ ID: job.ID, ServerInstanceID: job.ServerInstanceID, RunEndpointID: job.RunEndpointID, Capability: job.Capability, TargetKey: job.TargetKey, InputRef: job.InputRef, IdempotencyKey: job.IdempotencyKey, State: job.State, Progress: progressFromDomain(job.Progress), ResultRef: job.ResultRef, ExecutionResult: JobExecutionResultResponse{Kind: job.ExecutionResult.Kind, ProcessState: job.ExecutionResult.ProcessState, ExitClassification: job.ExecutionResult.ExitClassification, ExitCode: job.ExecutionResult.ExitCode, Version: job.ExecutionResult.Version, Checksum: job.ExecutionResult.Checksum, SizeBytes: job.ExecutionResult.SizeBytes, AuditSummary: job.ExecutionResult.AuditSummary, ServerDeploymentEvidence: serverDeploymentEvidenceFromDomain(job.ExecutionResult.ServerDeploymentEvidence)}, RetryPolicy: JobRetryPolicyResponse{ MaxAttempts: job.RetryPolicy.MaxAttempts, InitialBackoffSeconds: job.RetryPolicy.InitialBackoffSeconds, MaxBackoffSeconds: job.RetryPolicy.MaxBackoffSeconds, }, Attempt: job.Attempt, NextAttemptAt: optionalTime(job.NextAttemptAt), AckDeadlineAt: optionalTime(job.AckDeadlineAt), LeaseExpiresAt: optionalTime(job.LeaseExpiresAt), CancelReason: job.CancelReason, CancelRequestedAt: optionalTime(job.CancelRequestedAt), CancelCompletedAt: optionalTime(job.CancelCompletedAt), TerminalAt: optionalTime(job.TerminalAt), LastReconciledAt: optionalTime(job.LastReconciledAt), ReconcileCount: job.ReconcileCount, ReconcileOutcome: job.ReconcileOutcome, CreatedAt: job.CreatedAt, UpdatedAt: job.UpdatedAt, } } func optionalTime(value time.Time) *time.Time { if value.IsZero() { return nil } copy := value return © } func JobListFromDomain(jobs []domain.Job) JobListResponse { items := make([]JobResponse, len(jobs)) for i, job := range jobs { items[i] = JobFromDomain(job) } return JobListResponse{Items: items, Count: len(items)} } func ArtifactFromDomain(artifact domain.Artifact) ArtifactResponse { return ArtifactResponse{ ID: artifact.ID, OwnerKind: artifact.OwnerKind, OwnerID: artifact.OwnerID, SizeBytes: artifact.SizeBytes, Checksum: artifact.Checksum, State: artifact.State, CreatedAt: artifact.CreatedAt, UpdatedAt: artifact.UpdatedAt, } } func ArtifactListFromDomain(artifacts []domain.Artifact) ArtifactListResponse { items := make([]ArtifactResponse, len(artifacts)) for i, artifact := range artifacts { items[i] = ArtifactFromDomain(artifact) } return ArtifactListResponse{Items: items, Count: len(items)} } func LogStreamFromDomain(stream domain.LogStream) LogStreamResponse { return LogStreamResponse{ ID: stream.ID, ServerInstanceID: stream.ServerInstanceID, Source: stream.Source, StreamKey: stream.StreamKey, LatestSeq: stream.LatestSeq, StorageBackend: stream.StorageBackend, RetentionPolicy: stream.RetentionPolicy, CreatedAt: stream.CreatedAt, UpdatedAt: stream.UpdatedAt, } } func LogStreamListFromDomain(streams []domain.LogStream) LogStreamListResponse { items := make([]LogStreamResponse, len(streams)) for i, stream := range streams { items[i] = LogStreamFromDomain(stream) } return LogStreamListResponse{Items: items, Count: len(items)} } func AuditEventFromDomain(event domain.AuditEvent) AuditEventResponse { return AuditEventResponse{ ID: event.ID, ActorID: event.ActorID, Action: event.Action, ResourceKind: event.ResourceKind, ResourceID: event.ResourceID, Result: event.Result, Summary: event.Summary, CreatedAt: event.CreatedAt, } } func AuditEventListFromDomain(events []domain.AuditEvent) AuditEventListResponse { items := make([]AuditEventResponse, len(events)) for i, event := range events { items[i] = AuditEventFromDomain(event) } return AuditEventListResponse{Items: items, Count: len(items)} } func permissionsFromDomain(permissions domain.PluginPermissions) PluginPermissionsResponse { return PluginPermissionsResponse{ AI: permissions.AI, Logs: permissions.Logs, Files: permissions.Files, Jobs: permissions.Jobs, Artifacts: permissions.Artifacts, RemoteAccess: permissions.RemoteAccess, } } func permissionsToDomain(permissions PluginPermissionsResponse) domain.PluginPermissions { return domain.PluginPermissions{ AI: permissions.AI, Logs: permissions.Logs, Files: permissions.Files, Jobs: permissions.Jobs, Artifacts: permissions.Artifacts, RemoteAccess: permissions.RemoteAccess, } } func remoteAccessFromDomain(remote domain.GamePluginRemoteAccess) GamePluginRemoteAccessBody { remote = domain.CopyGamePluginRemoteAccess(remote) return GamePluginRemoteAccessBody{ Methods: remote.Methods, RunCapabilities: remote.RunCapabilities, DatabaseEngines: remote.DatabaseEngines, RCON: remote.RCON, LogTransfer: remote.LogTransfer, } } func lifecycleActionsFromDomain(actions domain.PluginLifecycleActions) PluginLifecycleActionsBody { return PluginLifecycleActionsBody{ Install: actions.Install, Start: actions.Start, Stop: actions.Stop, Restart: actions.Restart, Status: actions.Status, } } func pagesToDomain(pages []GamePluginPageBody) []domain.GamePluginPage { if pages == nil { return nil } out := make([]domain.GamePluginPage, len(pages)) for i, page := range pages { out[i] = domain.GamePluginPage{ Key: page.Key, Title: page.Title, Path: page.Path, Bundle: domain.PluginPageBundle{Key: page.BundleKey, Version: page.BundleVersion, IntegritySHA256: page.BundleIntegritySHA256}, Permissions: domain.CopyStringSlice(page.Permissions), BridgeActions: domain.CopyStringSlice(page.BridgeActions), FeatureKeys: domain.CopyStringSlice(page.FeatureKeys), } } return out } func pagesFromDomain(pages []domain.GamePluginPage) []GamePluginPageBody { if pages == nil { return nil } out := make([]GamePluginPageBody, len(pages)) for i, page := range pages { out[i] = GamePluginPageBody{ Key: page.Key, Title: page.Title, Path: page.Path, BundleKey: page.Bundle.Key, BundleVersion: page.Bundle.Version, BundleIntegritySHA256: page.Bundle.IntegritySHA256, Permissions: domain.CopyStringSlice(page.Permissions), BridgeActions: domain.CopyStringSlice(page.BridgeActions), FeatureKeys: domain.CopyStringSlice(page.FeatureKeys), } } return out } func capacityFromDomain(capacity domain.RunCapacity) RunCapacityResponse { return RunCapacityResponse{ MaxJobs: capacity.MaxJobs, RunningJobs: capacity.RunningJobs, QueuedJobs: capacity.QueuedJobs, LogBacklogBatches: capacity.LogBacklogBatches, ArtifactBacklogChunks: capacity.ArtifactBacklogChunks, PressureCodes: domain.CopyStringSlice(capacity.PressureCodes), Summary: capacity.Summary, } } func capacityToDomain(capacity RunCapacityResponse) domain.RunCapacity { return domain.RunCapacity{ MaxJobs: capacity.MaxJobs, RunningJobs: capacity.RunningJobs, QueuedJobs: capacity.QueuedJobs, LogBacklogBatches: capacity.LogBacklogBatches, ArtifactBacklogChunks: capacity.ArtifactBacklogChunks, PressureCodes: domain.CopyStringSlice(capacity.PressureCodes), Summary: capacity.Summary, } } func progressFromDomain(progress domain.JobProgress) JobProgressBody { return JobProgressBody{ Percent: progress.Percent, Phase: progress.Phase, Message: progress.Message, } } func progressToDomain(progress JobProgressBody) domain.JobProgress { return domain.JobProgress{ Percent: progress.Percent, Phase: progress.Phase, Message: progress.Message, } }