export const scumFeatureKeys = ["configuration", "players", "rewards", "state-patches", "trajectories"] as const; export type SCUMFeatureKey = (typeof scumFeatureKeys)[number]; export type SCUMFeatureAvailability = { feature: SCUMFeatureKey; available: boolean; reason?: string }; export type SCUMMigrationProvenance = "plugin" | "transitional-read-only"; export type SCUMMigrationRecord> = { provenance: SCUMMigrationProvenance; readOnly: boolean; payload: T; recordedAt: string; sourceRecordId?: string }; export type SCUMFeatureMigrationAuthority = { serverInstanceId: string; feature: SCUMFeatureKey; authority: "plugin" | "transitional-read-only"; reason?: string }; export type SCUMFeatureMigrationStatus = { authority: "plugin" | "transitional-read-only"; readOnlyHistory: true; pluginWritesEnabled: boolean; reason?: string }; export type SCUMCommandResult = { status: "delivered" | "failed" | "unknown" | "unsupported" | "validation-failed" | "queued"; summary: string }; export type SCUMVehicleSpawn = { vehicleCode: string }; export type SCUMVehicleSpawnOption = { code: string; label: string }; export type SCUMLogicalDirectory = { key: string; label: string; scope: "config" | "logs" }; export type SCUMLogicalFile = { key: string; directoryKey: string; label: string; kind: "config" | "log"; streamKey?: string; editable?: boolean }; export type SCUMConfigField = { key: string; label: string; description: string; control: "text" | "number" | "port" | "boolean"; fileKey: string; configKey: string; defaultValue: string; restartImpact: "restart-required" | "none"; minimum?: number; maximum?: number; }; export type SCUMConfigRead = { fields: Record; observedAt: string }; export type SCUMConfigPatch = { changes: Array<{ key: string; value: string }>; reason: string; idempotencyKey: string }; export type SCUMPlayer = { id: string; gamePlayerId: string; displayName: string; lastSeenAt?: string; status: "online" | "offline" | "unknown" }; export type SCUMPlayerSession = { id: string; playerId: string; kind: "login" | "logout"; occurredAt: string; networkCorrelation?: string }; export type SCUMPlayerRisk = { kind: string; level: "low" | "medium" | "high"; observedAt: string; summary: string }; export type SCUMPlayerProfile = { player: SCUMPlayer; sessions: SCUMPlayerSession[]; risks: SCUMPlayerRisk[] }; export type SCUMGiftItem = { key: string; label: string; quantity: number }; export type SCUMGiftRevision = { id: string; catalogId: string; revision: number; items: SCUMGiftItem[]; publishedAt: string }; export type SCUMGiftGrant = { id: string; revisionId: string; playerId: string; notice: string; status: "pending-approval" | "queued" | "delivered" | "notification_failed" | "failed" | "unknown"; createdAt: string; completedAt?: string }; export type SCUMStateField = { key: string; label: string; value: number; minimum: number; maximum: number; editable: boolean; reason?: string }; export type SCUMStateSnapshot = { playerId: string; stateVersion: string; safetyWindow?: string; fields: SCUMStateField[]; observedAt: string }; export type SCUMStatePatch = { id: string; playerId: string; expectedStateVersion: string; safetyWindow: string; reason: string; changes: Array<{ fieldKey: string; before: number; after: number }>; status: "pending-approval" | "queued" | "succeeded" | "failed" | "unsupported" | "unknown"; createdAt: string }; export type SCUMTrajectoryPoint = { occurredAt: string; subjectId: string; subjectType: "player" | "vehicle"; x: number; y: number; z?: number; source: string }; export type SCUMTrajectory = { subjectId: string; subjectType: "player" | "vehicle"; points: SCUMTrajectoryPoint[]; provenance: SCUMMigrationProvenance }; export type SCUMTrajectoryCollection = { available: boolean; reason?: string; trajectories: SCUMTrajectory[] }; export type MapViewState = { zoom: number; x: number; y: number }; export type MapPlaybackState = { playing: boolean; value: number; speed: number; startedAt: number; startValue: number }; export type MapTimeWindow = { from: number; to: number; label: string }; export type MapTrackPoint = { key: string; row: Record; x: number; y: number; time: number; riding: boolean; rideCode: string }; export type MapTrackSegment = { key: string; mode: "walk" | "ride"; points: MapTrackPoint[] }; export type MapTrack = { key: string; kind: "player" | "vehicle"; label: string; color: string; points: MapTrackPoint[]; walk: number; ride: number; from: number; to: number; vehicles: string[] }; export type MapPlaybackFrame = { tracks: MapTrack[]; span: { from: number; to: number } }; export type MapSceneData = MapPlaybackFrame & { points: Record[]; settings?: Record; bounds: Record; window: MapTimeWindow; catalog: Map; users: Array<{ key: string; label: string; count: number }>; playerLabels: Map; segments: Map; }; export type SCUMFeatureWorkspace = { defaultDirectoryKey?: string; directories?: SCUMLogicalDirectory[]; files?: SCUMLogicalFile[]; configFields?: SCUMConfigField[]; map?: { mapId: string; mapVersion: string; precision: number; sampleDistance: number; sampleIntervalSeconds: number; retentionSeconds: number } };