Integrate SCUM real ops workflows
This commit is contained in:
+60
-12
@@ -302,11 +302,50 @@ type GameClientBridgeQueryTemplateDeclarationBody struct {
|
||||
TimeoutSeconds int `json:"timeoutSeconds"`
|
||||
}
|
||||
|
||||
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"`
|
||||
}
|
||||
|
||||
@@ -335,14 +374,15 @@ type GameClientBridgeCompanionDeclarationBody struct {
|
||||
}
|
||||
|
||||
type GameClientBridgeManifestBody struct {
|
||||
Commands []GameClientBridgeCommandDeclarationBody `json:"commands"`
|
||||
Snapshots []GameClientBridgeSnapshotDeclarationBody `json:"snapshots"`
|
||||
QueryTemplates []GameClientBridgeQueryTemplateDeclarationBody `json:"queryTemplates,omitempty"`
|
||||
CommandRetentionSeconds int `json:"commandRetentionSeconds"`
|
||||
MaxCommands int `json:"maxCommands"`
|
||||
Pages []GameClientBridgePageContractBody `json:"pages,omitempty"`
|
||||
Features []GameClientBridgeFeatureDeclarationBody `json:"features,omitempty"`
|
||||
Companion *GameClientBridgeCompanionDeclarationBody `json:"companion,omitempty"`
|
||||
Commands []GameClientBridgeCommandDeclarationBody `json:"commands"`
|
||||
Snapshots []GameClientBridgeSnapshotDeclarationBody `json:"snapshots"`
|
||||
QueryTemplates []GameClientBridgeQueryTemplateDeclarationBody `json:"queryTemplates,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 GameMapTrajectoryDeclarationBody struct {
|
||||
MapID string `json:"mapId"`
|
||||
@@ -1167,9 +1207,13 @@ func (body GameClientBridgeManifestBody) ToDomain() domain.GameClientBridgeManif
|
||||
for index, template := range body.QueryTemplates {
|
||||
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, MaxRows: template.MaxRows, TimeoutSeconds: template.TimeoutSeconds}
|
||||
}
|
||||
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), FeatureKeys: domain.CopyStringSlice(page.FeatureKeys)}
|
||||
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 {
|
||||
@@ -1179,7 +1223,7 @@ func (body GameClientBridgeManifestBody) ToDomain() domain.GameClientBridgeManif
|
||||
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, Retention: domain.GameClientBridgeRetention{KeepForSeconds: body.CommandRetentionSeconds, MaxRecords: body.MaxCommands}, Pages: pages, Features: features, Companion: companion}
|
||||
return domain.GameClientBridgeManifest{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, OperationTemplates: operationTemplates, Retention: domain.GameClientBridgeRetention{KeepForSeconds: body.CommandRetentionSeconds, MaxRecords: body.MaxCommands}, Pages: pages, Features: features, Companion: companion}
|
||||
}
|
||||
|
||||
func protectedRequestToDomain(value *GameClientBridgeProtectedRequestDeclarationBody) *domain.GameClientBridgeProtectedRequestDeclaration {
|
||||
@@ -1595,9 +1639,13 @@ func gameClientBridgeManifestFromDomain(value domain.GameClientBridgeManifest) G
|
||||
for index, template := range value.QueryTemplates {
|
||||
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, MaxRows: template.MaxRows, TimeoutSeconds: template.TimeoutSeconds}
|
||||
}
|
||||
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, FeatureKeys: page.FeatureKeys}
|
||||
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 {
|
||||
@@ -1607,7 +1655,7 @@ func gameClientBridgeManifestFromDomain(value domain.GameClientBridgeManifest) G
|
||||
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, CommandRetentionSeconds: value.Retention.KeepForSeconds, MaxCommands: value.Retention.MaxRecords, Pages: pages, Features: features, Companion: companion}
|
||||
return GameClientBridgeManifestBody{Commands: commands, Snapshots: snapshots, QueryTemplates: queryTemplates, OperationTemplates: operationTemplates, CommandRetentionSeconds: value.Retention.KeepForSeconds, MaxCommands: value.Retention.MaxRecords, Pages: pages, Features: features, Companion: companion}
|
||||
}
|
||||
|
||||
func protectedRequestFromDomain(value *domain.GameClientBridgeProtectedRequestDeclaration) *GameClientBridgeProtectedRequestDeclarationBody {
|
||||
|
||||
@@ -3,6 +3,7 @@ package dto
|
||||
import (
|
||||
"encoding/json"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
@@ -177,3 +178,40 @@ func TestGameClientBridgeQueryTemplateDeclarationRoundTripIsSafe(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGameClientBridgeOperationTemplateDeclarationRoundTripIsSafe(t *testing.T) {
|
||||
body := GameClientBridgeManifestBody{
|
||||
OperationTemplates: []GameClientBridgeOperationTemplateDeclarationBody{{
|
||||
Key: "player.attribute.855.set", Title: "Set player attribute 855", Permission: "server.game-client.maintenance", ApprovalLevel: "platform-admin", Kind: "sqlite-mutation", TransportKey: "scum-mutation-db", TargetKey: "scum-mutation-db",
|
||||
PayloadSchemaRef: "schemas/bridge/operations/player-attribute-855-set.payload.schema.json", ResultSchemaRef: "schemas/bridge/operations/player-attribute-855-set.result.schema.json", ConfirmationSchemaRef: "schemas/bridge/operations/player-attribute-855-set.confirmation.schema.json", TimeoutSeconds: 120, MaxPayloadBytes: 4096, MaxRowsAffected: 1,
|
||||
Safety: GameClientBridgeOperationSafetyBody{RequiresApproval: true, RequiresOfflinePlayer: true, RequiresBeforeValue: true, RequiresConfirmation: true, BackupRequired: true},
|
||||
}},
|
||||
CommandRetentionSeconds: 86400,
|
||||
MaxCommands: 1000,
|
||||
Pages: []GameClientBridgePageContractBody{{PageKey: "players", OperationKeys: []string{"player.attribute.855.set"}}},
|
||||
}
|
||||
|
||||
domainManifest := body.ToDomain()
|
||||
if len(domainManifest.OperationTemplates) != 1 || domainManifest.OperationTemplates[0].Kind != "sqlite-mutation" || domainManifest.OperationTemplates[0].MaxRowsAffected != 1 || !domainManifest.OperationTemplates[0].Safety.RequiresBeforeValue || domainManifest.Pages[0].OperationKeys[0] != "player.attribute.855.set" {
|
||||
t.Fatalf("operation template conversion lost declaration fields: %#v", domainManifest)
|
||||
}
|
||||
domainManifest.Pages[0].OperationKeys[0] = "mutated"
|
||||
if body.Pages[0].OperationKeys[0] != "player.attribute.855.set" {
|
||||
t.Fatal("operation template page keys alias request DTO data")
|
||||
}
|
||||
domainManifest.Pages[0].OperationKeys[0] = "player.attribute.855.set"
|
||||
|
||||
response := gameClientBridgeManifestFromDomain(domainManifest)
|
||||
response.Pages[0].OperationKeys[0] = "mutated"
|
||||
if domainManifest.Pages[0].OperationKeys[0] != "player.attribute.855.set" {
|
||||
t.Fatal("operation template page keys alias domain data")
|
||||
}
|
||||
|
||||
encoded, err := json.Marshal(response.OperationTemplates[0])
|
||||
if err != nil {
|
||||
t.Fatalf("marshal safe operation template projection: %v", err)
|
||||
}
|
||||
if strings.Contains(strings.ToLower(string(encoded)), "sqltext") || strings.Contains(strings.ToLower(string(encoded)), "dsn") || strings.Contains(strings.ToLower(string(encoded)), "hostpath") || strings.Contains(strings.ToLower(string(encoded)), "socket") || strings.Contains(strings.ToLower(string(encoded)), "credential") {
|
||||
t.Fatalf("operation template projection leaked unsafe material: %s", encoded)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package dto
|
||||
|
||||
import "browser.local/platform/domain"
|
||||
|
||||
type SCUMPlayerLiveStateListResponse struct {
|
||||
Items []domain.SCUMPlayerLiveState `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type SCUMSquadListResponse struct {
|
||||
Items []domain.SCUMSquad `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type SCUMSquadMemberListResponse struct {
|
||||
Items []domain.SCUMSquadMember `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type SCUMVehicleListResponse struct {
|
||||
Items []domain.SCUMVehicle `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type SCUMFlagListResponse struct {
|
||||
Items []domain.SCUMFlag `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type SCUMCurrentPositionListResponse struct {
|
||||
Items []domain.SCUMCurrentPosition `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
func SCUMPlayerLiveStatesFromDomain(values []domain.SCUMPlayerLiveState) SCUMPlayerLiveStateListResponse {
|
||||
out := make([]domain.SCUMPlayerLiveState, len(values))
|
||||
for index, value := range values {
|
||||
out[index] = domain.CopySCUMPlayerLiveState(value)
|
||||
}
|
||||
return SCUMPlayerLiveStateListResponse{Items: out, Count: len(out)}
|
||||
}
|
||||
|
||||
func SCUMSquadsFromDomain(values []domain.SCUMSquad) SCUMSquadListResponse {
|
||||
out := make([]domain.SCUMSquad, len(values))
|
||||
for index, value := range values {
|
||||
out[index] = domain.CopySCUMSquad(value)
|
||||
}
|
||||
return SCUMSquadListResponse{Items: out, Count: len(out)}
|
||||
}
|
||||
|
||||
func SCUMSquadMembersFromDomain(values []domain.SCUMSquadMember) SCUMSquadMemberListResponse {
|
||||
out := make([]domain.SCUMSquadMember, len(values))
|
||||
for index, value := range values {
|
||||
out[index] = domain.CopySCUMSquadMember(value)
|
||||
}
|
||||
return SCUMSquadMemberListResponse{Items: out, Count: len(out)}
|
||||
}
|
||||
|
||||
func SCUMVehiclesFromDomain(values []domain.SCUMVehicle) SCUMVehicleListResponse {
|
||||
out := make([]domain.SCUMVehicle, len(values))
|
||||
for index, value := range values {
|
||||
out[index] = domain.CopySCUMVehicle(value)
|
||||
}
|
||||
return SCUMVehicleListResponse{Items: out, Count: len(out)}
|
||||
}
|
||||
|
||||
func SCUMFlagsFromDomain(values []domain.SCUMFlag) SCUMFlagListResponse {
|
||||
out := make([]domain.SCUMFlag, len(values))
|
||||
for index, value := range values {
|
||||
out[index] = domain.CopySCUMFlag(value)
|
||||
}
|
||||
return SCUMFlagListResponse{Items: out, Count: len(out)}
|
||||
}
|
||||
|
||||
func SCUMCurrentPositionsFromDomain(values []domain.SCUMCurrentPosition) SCUMCurrentPositionListResponse {
|
||||
out := make([]domain.SCUMCurrentPosition, len(values))
|
||||
for index, value := range values {
|
||||
out[index] = domain.CopySCUMCurrentPosition(value)
|
||||
}
|
||||
return SCUMCurrentPositionListResponse{Items: out, Count: len(out)}
|
||||
}
|
||||
@@ -0,0 +1,243 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"browser.local/platform/domain"
|
||||
)
|
||||
|
||||
type SCUMSafeSummaryBody struct {
|
||||
Title string `json:"title,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Details map[string]string `json:"details,omitempty"`
|
||||
}
|
||||
|
||||
type SCUMDataObservationResponse struct {
|
||||
ID string `json:"id"`
|
||||
ServerInstanceID string `json:"serverInstanceId"`
|
||||
PluginID string `json:"pluginId"`
|
||||
Source string `json:"source"`
|
||||
QueryKey string `json:"queryKey,omitempty"`
|
||||
SubjectType string `json:"subjectType,omitempty"`
|
||||
SubjectID string `json:"subjectId,omitempty"`
|
||||
Sequence uint64 `json:"sequence"`
|
||||
Checksum string `json:"checksum,omitempty"`
|
||||
Status string `json:"status"`
|
||||
ErrorCode string `json:"errorCode,omitempty"`
|
||||
SafeSummary SCUMSafeSummaryBody `json:"safeSummary,omitempty"`
|
||||
ObservedAt time.Time `json:"observedAt"`
|
||||
ReceivedAt time.Time `json:"receivedAt"`
|
||||
}
|
||||
|
||||
type SCUMProjectionFreshnessBody struct {
|
||||
Status string `json:"status"`
|
||||
ObservationID string `json:"observationId,omitempty"`
|
||||
Source string `json:"source,omitempty"`
|
||||
QueryKey string `json:"queryKey,omitempty"`
|
||||
Sequence uint64 `json:"sequence,omitempty"`
|
||||
Checksum string `json:"checksum,omitempty"`
|
||||
StaleReason string `json:"staleReason,omitempty"`
|
||||
ObservedAt time.Time `json:"observedAt,omitempty"`
|
||||
ReceivedAt time.Time `json:"receivedAt,omitempty"`
|
||||
}
|
||||
|
||||
type SCUMMutationGuardBody struct {
|
||||
FieldKey string `json:"fieldKey,omitempty"`
|
||||
Before any `json:"before,omitempty"`
|
||||
After any `json:"after,omitempty"`
|
||||
MaxRowsAffected int `json:"maxRowsAffected,omitempty"`
|
||||
SafetyWindow string `json:"safetyWindow,omitempty"`
|
||||
BackupRef string `json:"backupRef,omitempty"`
|
||||
RequiresOfflinePlayer bool `json:"requiresOfflinePlayer,omitempty"`
|
||||
RequiresMaintenance bool `json:"requiresMaintenance,omitempty"`
|
||||
RequiresBackup bool `json:"requiresBackup,omitempty"`
|
||||
}
|
||||
|
||||
type SCUMOperationConfirmationBody struct {
|
||||
Status string `json:"status,omitempty"`
|
||||
ObservationID string `json:"observationId,omitempty"`
|
||||
ConfirmedFields map[string]any `json:"confirmedFields,omitempty"`
|
||||
AffectedRows int `json:"affectedRows,omitempty"`
|
||||
MutationChecksum string `json:"mutationChecksum,omitempty"`
|
||||
Checksum string `json:"checksum,omitempty"`
|
||||
ObservedAt time.Time `json:"observedAt,omitempty"`
|
||||
SafeSummary SCUMSafeSummaryBody `json:"safeSummary,omitempty"`
|
||||
}
|
||||
|
||||
type SCUMOperationRequestBody struct {
|
||||
TemplateKey string `json:"templateKey"`
|
||||
PlayerID string `json:"playerId,omitempty"`
|
||||
Payload map[string]any `json:"payload,omitempty"`
|
||||
Guard SCUMMutationGuardBody `json:"guard,omitempty"`
|
||||
Reason string `json:"reason"`
|
||||
IdempotencyKey string `json:"idempotencyKey"`
|
||||
}
|
||||
|
||||
type SCUMWorkflowCreateRequest struct {
|
||||
TemplateKey string `json:"templateKey"`
|
||||
IdempotencyKey string `json:"idempotencyKey"`
|
||||
Input map[string]any `json:"input,omitempty"`
|
||||
}
|
||||
|
||||
type SCUMOperationResponse struct {
|
||||
ID string `json:"id"`
|
||||
ServerInstanceID string `json:"serverInstanceId"`
|
||||
PluginID string `json:"pluginId"`
|
||||
TemplateKey string `json:"templateKey"`
|
||||
PlayerID string `json:"playerId,omitempty"`
|
||||
RequesterID string `json:"requesterId,omitempty"`
|
||||
ApproverID string `json:"approverId,omitempty"`
|
||||
ApprovalLevel string `json:"approvalLevel"`
|
||||
Payload map[string]any `json:"payload,omitempty"`
|
||||
Guard SCUMMutationGuardBody `json:"guard,omitempty"`
|
||||
Confirmation SCUMOperationConfirmationBody `json:"confirmation,omitempty"`
|
||||
Status string `json:"status"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
RunJobID string `json:"runJobId,omitempty"`
|
||||
SafeSummary SCUMSafeSummaryBody `json:"safeSummary,omitempty"`
|
||||
AuditReferences []string `json:"auditReferences,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
ApprovedAt time.Time `json:"approvedAt,omitempty"`
|
||||
CompletedAt time.Time `json:"completedAt,omitempty"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type SCUMOperationListResponse struct {
|
||||
Items []SCUMOperationResponse `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type SCUMWorkflowResponse struct {
|
||||
ID string `json:"id"`
|
||||
ServerInstanceID string `json:"serverInstanceId"`
|
||||
PluginID string `json:"pluginId"`
|
||||
TemplateKey string `json:"templateKey"`
|
||||
RequestedBy string `json:"requestedBy,omitempty"`
|
||||
IdempotencyKey string `json:"idempotencyKey,omitempty"`
|
||||
Status string `json:"status"`
|
||||
CurrentStepKey string `json:"currentStepKey,omitempty"`
|
||||
Input map[string]any `json:"input,omitempty"`
|
||||
SafeSummary SCUMSafeSummaryBody `json:"safeSummary,omitempty"`
|
||||
BlockerReason string `json:"blockerReason,omitempty"`
|
||||
AuditReferences []string `json:"auditReferences,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
CompletedAt time.Time `json:"completedAt,omitempty"`
|
||||
}
|
||||
|
||||
type SCUMWorkflowListResponse struct {
|
||||
Items []SCUMWorkflowResponse `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type SCUMWorkflowStepResponse struct {
|
||||
ID string `json:"id"`
|
||||
WorkflowID string `json:"workflowId"`
|
||||
ServerInstanceID string `json:"serverInstanceId"`
|
||||
StepKey string `json:"stepKey"`
|
||||
DependsOn []string `json:"dependsOn,omitempty"`
|
||||
Status string `json:"status"`
|
||||
OperationKey string `json:"operationKey,omitempty"`
|
||||
QueryTemplateKey string `json:"queryTemplateKey,omitempty"`
|
||||
Capability string `json:"capability,omitempty"`
|
||||
TargetKey string `json:"targetKey,omitempty"`
|
||||
JobID string `json:"jobId,omitempty"`
|
||||
Attempt int `json:"attempt,omitempty"`
|
||||
MaxAttempts int `json:"maxAttempts,omitempty"`
|
||||
MutatesState bool `json:"mutatesState,omitempty"`
|
||||
Confirmation SCUMOperationConfirmationBody `json:"confirmation,omitempty"`
|
||||
SafeSummary SCUMSafeSummaryBody `json:"safeSummary,omitempty"`
|
||||
BlockerReason string `json:"blockerReason,omitempty"`
|
||||
AuditReferences []string `json:"auditReferences,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
CompletedAt time.Time `json:"completedAt,omitempty"`
|
||||
}
|
||||
|
||||
type SCUMWorkflowStepListResponse struct {
|
||||
Items []SCUMWorkflowStepResponse `json:"items"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
func SCUMSafeSummaryFromDomain(value domain.SCUMSafeSummary) SCUMSafeSummaryBody {
|
||||
value = domain.CopySCUMSafeSummary(value)
|
||||
return SCUMSafeSummaryBody{Title: value.Title, Message: value.Message, Details: value.Details}
|
||||
}
|
||||
|
||||
func scumSafeSummaryToDomain(value SCUMSafeSummaryBody) domain.SCUMSafeSummary {
|
||||
return domain.SCUMSafeSummary{Title: value.Title, Message: value.Message, Details: domain.CopyStringMap(value.Details)}
|
||||
}
|
||||
|
||||
func SCUMDataObservationFromDomain(value domain.SCUMDataObservation) SCUMDataObservationResponse {
|
||||
value = domain.CopySCUMDataObservation(value)
|
||||
return SCUMDataObservationResponse{ID: value.ID, ServerInstanceID: value.ServerInstanceID, PluginID: value.PluginID, Source: value.Source, QueryKey: value.QueryKey, SubjectType: value.SubjectType, SubjectID: value.SubjectID, Sequence: value.Sequence, Checksum: value.Checksum, Status: string(value.Status), ErrorCode: value.ErrorCode, SafeSummary: SCUMSafeSummaryFromDomain(value.SafeSummary), ObservedAt: value.ObservedAt, ReceivedAt: value.ReceivedAt}
|
||||
}
|
||||
|
||||
func SCUMProjectionFreshnessFromDomain(value domain.SCUMProjectionFreshnessState) SCUMProjectionFreshnessBody {
|
||||
value = domain.CopySCUMProjectionFreshnessState(value)
|
||||
return SCUMProjectionFreshnessBody{Status: string(value.Status), ObservationID: value.ObservationID, Source: value.Source, QueryKey: value.QueryKey, Sequence: value.Sequence, Checksum: value.Checksum, StaleReason: value.StaleReason, ObservedAt: value.ObservedAt, ReceivedAt: value.ReceivedAt}
|
||||
}
|
||||
|
||||
func SCUMOperationRequestBodyToDomain(request SCUMOperationRequestBody) domain.SCUMOperationRequest {
|
||||
return domain.SCUMOperationRequest{TemplateKey: request.TemplateKey, PlayerID: request.PlayerID, Payload: domain.CopyGameClientBridgePayload(request.Payload), Guard: scumMutationGuardToDomain(request.Guard), Reason: request.Reason, IdempotencyKey: request.IdempotencyKey}
|
||||
}
|
||||
|
||||
func SCUMWorkflowCreateRequestToDomain(request SCUMWorkflowCreateRequest) domain.SCUMWorkflowInstance {
|
||||
return domain.SCUMWorkflowInstance{TemplateKey: request.TemplateKey, IdempotencyKey: request.IdempotencyKey, Input: domain.CopyGameClientBridgePayload(request.Input)}
|
||||
}
|
||||
|
||||
func SCUMOperationFromDomain(value domain.SCUMOperationRequest) SCUMOperationResponse {
|
||||
value = domain.CopySCUMOperationRequest(value)
|
||||
return SCUMOperationResponse{ID: value.ID, ServerInstanceID: value.ServerInstanceID, PluginID: value.PluginID, TemplateKey: value.TemplateKey, PlayerID: value.PlayerID, RequesterID: value.RequesterID, ApproverID: value.ApproverID, ApprovalLevel: string(value.ApprovalLevel), Payload: value.Payload, Guard: scumMutationGuardFromDomain(value.Guard), Confirmation: scumOperationConfirmationFromDomain(value.Confirmation), Status: string(value.Status), Reason: value.Reason, RunJobID: value.RunJobID, SafeSummary: SCUMSafeSummaryFromDomain(value.SafeSummary), AuditReferences: value.AuditReferences, CreatedAt: value.CreatedAt, ApprovedAt: value.ApprovedAt, CompletedAt: value.CompletedAt, UpdatedAt: value.UpdatedAt}
|
||||
}
|
||||
|
||||
func SCUMOperationsFromDomain(values []domain.SCUMOperationRequest) SCUMOperationListResponse {
|
||||
items := make([]SCUMOperationResponse, len(values))
|
||||
for index, value := range values {
|
||||
items[index] = SCUMOperationFromDomain(value)
|
||||
}
|
||||
return SCUMOperationListResponse{Items: items, Count: len(items)}
|
||||
}
|
||||
|
||||
func SCUMWorkflowFromDomain(value domain.SCUMWorkflowInstance) SCUMWorkflowResponse {
|
||||
value = domain.CopySCUMWorkflowInstance(value)
|
||||
return SCUMWorkflowResponse{ID: value.ID, ServerInstanceID: value.ServerInstanceID, PluginID: value.PluginID, TemplateKey: value.TemplateKey, RequestedBy: value.RequestedBy, IdempotencyKey: value.IdempotencyKey, Status: string(value.Status), CurrentStepKey: value.CurrentStepKey, Input: value.Input, SafeSummary: SCUMSafeSummaryFromDomain(value.SafeSummary), BlockerReason: value.BlockerReason, AuditReferences: value.AuditReferences, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, CompletedAt: value.CompletedAt}
|
||||
}
|
||||
|
||||
func SCUMWorkflowsFromDomain(values []domain.SCUMWorkflowInstance) SCUMWorkflowListResponse {
|
||||
items := make([]SCUMWorkflowResponse, len(values))
|
||||
for index, value := range values {
|
||||
items[index] = SCUMWorkflowFromDomain(value)
|
||||
}
|
||||
return SCUMWorkflowListResponse{Items: items, Count: len(items)}
|
||||
}
|
||||
|
||||
func SCUMWorkflowStepFromDomain(value domain.SCUMWorkflowStep) SCUMWorkflowStepResponse {
|
||||
value = domain.CopySCUMWorkflowStep(value)
|
||||
return SCUMWorkflowStepResponse{ID: value.ID, WorkflowID: value.WorkflowID, ServerInstanceID: value.ServerInstanceID, StepKey: value.StepKey, DependsOn: value.DependsOn, Status: string(value.Status), OperationKey: value.OperationKey, QueryTemplateKey: value.QueryTemplateKey, Capability: value.Capability, TargetKey: value.TargetKey, JobID: value.JobID, Attempt: value.Attempt, MaxAttempts: value.MaxAttempts, MutatesState: value.MutatesState, Confirmation: scumOperationConfirmationFromDomain(value.Confirmation), SafeSummary: SCUMSafeSummaryFromDomain(value.SafeSummary), BlockerReason: value.BlockerReason, AuditReferences: value.AuditReferences, CreatedAt: value.CreatedAt, UpdatedAt: value.UpdatedAt, CompletedAt: value.CompletedAt}
|
||||
}
|
||||
|
||||
func SCUMWorkflowStepsFromDomain(values []domain.SCUMWorkflowStep) SCUMWorkflowStepListResponse {
|
||||
items := make([]SCUMWorkflowStepResponse, len(values))
|
||||
for index, value := range values {
|
||||
items[index] = SCUMWorkflowStepFromDomain(value)
|
||||
}
|
||||
return SCUMWorkflowStepListResponse{Items: items, Count: len(items)}
|
||||
}
|
||||
|
||||
func scumMutationGuardFromDomain(value domain.SCUMMutationGuard) SCUMMutationGuardBody {
|
||||
return SCUMMutationGuardBody{FieldKey: value.FieldKey, Before: value.Before, After: value.After, MaxRowsAffected: value.MaxRowsAffected, SafetyWindow: value.SafetyWindow, BackupRef: value.BackupRef, RequiresOfflinePlayer: value.RequiresOfflinePlayer, RequiresMaintenance: value.RequiresMaintenance, RequiresBackup: value.RequiresBackup}
|
||||
}
|
||||
|
||||
func scumMutationGuardToDomain(value SCUMMutationGuardBody) domain.SCUMMutationGuard {
|
||||
return domain.SCUMMutationGuard{FieldKey: value.FieldKey, Before: value.Before, After: value.After, MaxRowsAffected: value.MaxRowsAffected, SafetyWindow: value.SafetyWindow, BackupRef: value.BackupRef, RequiresOfflinePlayer: value.RequiresOfflinePlayer, RequiresMaintenance: value.RequiresMaintenance, RequiresBackup: value.RequiresBackup}
|
||||
}
|
||||
|
||||
func scumOperationConfirmationFromDomain(value domain.SCUMOperationConfirmation) SCUMOperationConfirmationBody {
|
||||
value = domain.CopySCUMOperationConfirmation(value)
|
||||
return SCUMOperationConfirmationBody{Status: value.Status, ObservationID: value.ObservationID, ConfirmedFields: value.ConfirmedFields, AffectedRows: value.AffectedRows, MutationChecksum: value.MutationChecksum, Checksum: value.Checksum, ObservedAt: value.ObservedAt, SafeSummary: SCUMSafeSummaryFromDomain(value.SafeSummary)}
|
||||
}
|
||||
|
||||
func scumOperationConfirmationToDomain(value SCUMOperationConfirmationBody) domain.SCUMOperationConfirmation {
|
||||
return domain.SCUMOperationConfirmation{Status: value.Status, ObservationID: value.ObservationID, ConfirmedFields: domain.CopyGameClientBridgePayload(value.ConfirmedFields), AffectedRows: value.AffectedRows, MutationChecksum: value.MutationChecksum, Checksum: value.Checksum, ObservedAt: value.ObservedAt, SafeSummary: scumSafeSummaryToDomain(value.SafeSummary)}
|
||||
}
|
||||
Reference in New Issue
Block a user