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"` BaseURL string `json:"baseUrl"` 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"` Permissions []string `json:"permissions,omitempty"` BridgeActions []string `json:"bridgeActions,omitempty"` } type GamePluginBridgeBody struct { Actions []string `json:"actions"` } type GamePluginManifestServerBody struct { Type string `json:"type"` DisplayName string `json:"displayName"` SupportedOS []string `json:"supportedOs,omitempty"` CreateFormSchema string `json:"createFormSchema"` } type GamePluginManifestAIBody struct { Purposes []string `json:"purposes,omitempty"` } 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 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"` Pages []GamePluginPageBody `json:"pages,omitempty"` AI GamePluginManifestAIBody `json:"ai,omitempty"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesBody `json:"runtimeProfiles,omitempty"` } type GamePluginManifestRegistrationRequest struct { ManifestRef string `json:"manifestRef"` Manifest GamePluginManifestBody `json:"manifest"` } 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"` 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"` Tags []string `json:"tags,omitempty"` AIPurposes []string `json:"aiPurposes,omitempty"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesBody `json:"runtimeProfiles,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"` RequiredRunCapabilities []string `json:"requiredRunCapabilities"` 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"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesBody `json:"runtimeProfiles,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"` RemoteAccess GamePluginRemoteAccessBody `json:"remoteAccess,omitempty"` RuntimeProfiles GamePluginRuntimeProfilesBody `json:"runtimeProfiles,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 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"` RunEndpointID string `json:"runEndpointId"` Name string `json:"name"` OwnerUserID string `json:"ownerUserId,omitempty"` AdminUserIDs []string `json:"adminUserIds"` State domain.ServerInstanceState `json:"state"` 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"` } 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 RunCapacityResponse struct { MaxJobs int `json:"maxJobs"` RunningJobs int `json:"runningJobs"` QueuedJobs int `json:"queuedJobs"` 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"` 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"` } 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, 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(), Pages: pagesToDomain(request.Manifest.Pages), AI: request.Manifest.AI.ToDomain(), RemoteAccess: request.Manifest.RemoteAccess.ToDomain(), RuntimeProfiles: request.Manifest.RuntimeProfiles.ToDomain(), }, } } func (bridge GamePluginBridgeBody) ToDomain() domain.GamePluginBridge { return domain.GamePluginBridge{Actions: domain.CopyStringSlice(bridge.Actions)} } func (server GamePluginManifestServerBody) ToDomain() domain.GamePluginManifestServer { return domain.GamePluginManifestServer{ Type: server.Type, DisplayName: server.DisplayName, SupportedOS: domain.CopyStringSlice(server.SupportedOS), CreateFormSchema: server.CreateFormSchema, } } func (ai GamePluginManifestAIBody) ToDomain() domain.GamePluginManifestAI { return domain.GamePluginManifestAI{Purposes: domain.CopyStringSlice(ai.Purposes)} } 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 (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, 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), Tags: domain.CopyStringSlice(request.Tags), AIPurposes: domain.CopyStringSlice(request.AIPurposes), RemoteAccess: request.RemoteAccess.ToDomain(), RuntimeProfiles: request.RuntimeProfiles.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 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, BaseURL: 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, RequiredRunCapabilities: plugin.RequiredRunCapabilities, DeclaredPermissions: plugin.DeclaredPermissions, Permissions: permissionsFromDomain(plugin.Permissions), LifecycleActions: lifecycleActionsFromDomain(plugin.LifecycleActions), BridgeActions: plugin.BridgeActions, Pages: pagesFromDomain(plugin.Pages), Tags: plugin.Tags, AIPurposes: plugin.AIPurposes, RemoteAccess: remoteAccessFromDomain(plugin.RemoteAccess), RuntimeProfiles: runtimeProfilesFromDomain(plugin.RuntimeProfiles), 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, RemoteAccess: remoteAccessFromDomain(plugin.RemoteAccess), RuntimeProfiles: runtimeProfilesFromDomain(plugin.RuntimeProfiles), ValidationViolations: plugin.ValidationViolations, Status: plugin.Status, Source: plugin.Source, } } 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, RunEndpointID: instance.RunEndpointID, Name: instance.Name, OwnerUserID: instance.OwnerUserID, AdminUserIDs: adminUserIDs, State: instance.State, ConfigVersion: instance.ConfigVersion, ConfigKey: instance.ConfigKey, ConfigChecksum: instance.ConfigChecksum, ConfigUpdatedAt: optionalTime(instance.ConfigUpdatedAt), CreatedAt: instance.CreatedAt, UpdatedAt: instance.UpdatedAt, } } 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 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}, 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, Permissions: domain.CopyStringSlice(page.Permissions), BridgeActions: domain.CopyStringSlice(page.BridgeActions), } } 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, Permissions: domain.CopyStringSlice(page.Permissions), BridgeActions: domain.CopyStringSlice(page.BridgeActions), } } return out } func capacityFromDomain(capacity domain.RunCapacity) RunCapacityResponse { return RunCapacityResponse{ MaxJobs: capacity.MaxJobs, RunningJobs: capacity.RunningJobs, QueuedJobs: capacity.QueuedJobs, Summary: capacity.Summary, } } func capacityToDomain(capacity RunCapacityResponse) domain.RunCapacity { return domain.RunCapacity{ MaxJobs: capacity.MaxJobs, RunningJobs: capacity.RunningJobs, QueuedJobs: capacity.QueuedJobs, Summary: capacity.Summary, } } func progressFromDomain(progress domain.JobProgress) JobProgressBody { return JobProgressBody{ Percent: progress.Percent, Message: progress.Message, } } func progressToDomain(progress JobProgressBody) domain.JobProgress { return domain.JobProgress{ Percent: progress.Percent, Message: progress.Message, } }