Remove AI config approval flow
This commit is contained in:
@@ -31,7 +31,6 @@ type StoreSnapshot struct {
|
||||
MetricSamples []domain.MetricSample `json:"metricSamples"`
|
||||
Backups []domain.BackupRecord `json:"backups"`
|
||||
PluginLifecycles []domain.PluginLifecycleInstallation `json:"pluginLifecycles"`
|
||||
AIConfigDiffs []domain.AIConfigDiffPreview `json:"aiConfigDiffs"`
|
||||
GameClientBridgeCommands []domain.GameClientBridgeCommand `json:"gameClientBridgeCommands"`
|
||||
GameClientBridgeSnapshots []domain.GameClientBridgeSnapshot `json:"gameClientBridgeSnapshots"`
|
||||
GameClientBridgeStreams []domain.GameClientBridgeSnapshotStream `json:"gameClientBridgeStreams"`
|
||||
@@ -152,10 +151,6 @@ func (store *FileStore) PluginLifecycles() PluginLifecycleRepository {
|
||||
return &persistentRepository[domain.PluginLifecycleInstallation, domain.PluginLifecycleFilter]{repository: store.MemoryStore.pluginLifecycle, persist: store.persist}
|
||||
}
|
||||
|
||||
func (store *FileStore) AIConfigDiffs() AIConfigDiffRepository {
|
||||
return &persistentRepository[domain.AIConfigDiffPreview, domain.AIConfigDiffFilter]{repository: store.MemoryStore.aiConfigDiffs, persist: store.persist}
|
||||
}
|
||||
|
||||
func (store *FileStore) GameClientBridgeCommands() GameClientBridgeCommandRepository {
|
||||
return &persistentGameClientBridgeCommandRepository{
|
||||
persistentRepository: &persistentRepository[domain.GameClientBridgeCommand, domain.GameClientBridgeCommandFilter]{repository: store.MemoryStore.bridgeCommands, persist: store.persist},
|
||||
@@ -327,7 +322,6 @@ func (store *FileStore) snapshot() StoreSnapshot {
|
||||
MetricSamples: snapshotRepository(store.MemoryStore.metricSamples),
|
||||
Backups: snapshotRepository(store.MemoryStore.backups),
|
||||
PluginLifecycles: snapshotRepository(store.MemoryStore.pluginLifecycle),
|
||||
AIConfigDiffs: snapshotRepository(store.MemoryStore.aiConfigDiffs),
|
||||
GameClientBridgeCommands: snapshotRepository(store.MemoryStore.bridgeCommands.memoryRepository),
|
||||
GameClientBridgeSnapshots: snapshotRepository(store.MemoryStore.bridgeSnapshots.memoryRepository),
|
||||
GameClientBridgeStreams: snapshotRepository(store.MemoryStore.bridgeStreams),
|
||||
@@ -368,7 +362,6 @@ func (store *FileStore) loadSnapshot(snapshot StoreSnapshot) {
|
||||
loadRepository(store.MemoryStore.metricSamples, snapshot.MetricSamples)
|
||||
loadRepository(store.MemoryStore.backups, snapshot.Backups)
|
||||
loadRepository(store.MemoryStore.pluginLifecycle, snapshot.PluginLifecycles)
|
||||
loadRepository(store.MemoryStore.aiConfigDiffs, snapshot.AIConfigDiffs)
|
||||
loadRepository(store.MemoryStore.bridgeCommands.memoryRepository, snapshot.GameClientBridgeCommands)
|
||||
loadRepository(store.MemoryStore.bridgeSnapshots.memoryRepository, snapshot.GameClientBridgeSnapshots)
|
||||
loadRepository(store.MemoryStore.bridgeStreams, snapshot.GameClientBridgeStreams)
|
||||
|
||||
@@ -15,7 +15,6 @@ func normalizeStoreSnapshot(snapshot StoreSnapshot) StoreSnapshot {
|
||||
snapshot.ServerInstances = rewriteSnapshotServerInstances(snapshot.ServerInstances, replacements)
|
||||
snapshot.RuntimeBindings = rewriteSnapshotRuntimeBindings(snapshot.RuntimeBindings, replacements)
|
||||
snapshot.PluginLifecycles = rewriteSnapshotPluginLifecycles(snapshot.PluginLifecycles, replacements)
|
||||
snapshot.AIConfigDiffs = rewriteSnapshotAIConfigDiffs(snapshot.AIConfigDiffs, replacements)
|
||||
snapshot.PluginDataRecords = retainedSnapshotPluginData(snapshot.PluginDataRecords, replacements)
|
||||
return snapshot
|
||||
}
|
||||
@@ -81,17 +80,6 @@ func rewriteSnapshotPluginLifecycles(values []domain.PluginLifecycleInstallation
|
||||
return out
|
||||
}
|
||||
|
||||
func rewriteSnapshotAIConfigDiffs(values []domain.AIConfigDiffPreview, replacements map[string]domain.GamePlugin) []domain.AIConfigDiffPreview {
|
||||
out := make([]domain.AIConfigDiffPreview, len(values))
|
||||
for index, value := range values {
|
||||
if kept, ok := replacements[value.PluginID]; ok {
|
||||
value.PluginID = kept.ID
|
||||
}
|
||||
out[index] = domain.CopyAIConfigDiffPreview(value)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func retainedSnapshotPluginData(values []domain.PluginDataRecord, replacements map[string]domain.GamePlugin) []domain.PluginDataRecord {
|
||||
byID := map[string]domain.PluginDataRecord{}
|
||||
for _, value := range values {
|
||||
|
||||
@@ -132,10 +132,6 @@ func (store *MySQLStore) PluginLifecycles() PluginLifecycleRepository {
|
||||
return &persistentRepository[domain.PluginLifecycleInstallation, domain.PluginLifecycleFilter]{repository: store.MemoryStore.pluginLifecycle, persist: store.persist}
|
||||
}
|
||||
|
||||
func (store *MySQLStore) AIConfigDiffs() AIConfigDiffRepository {
|
||||
return &persistentRepository[domain.AIConfigDiffPreview, domain.AIConfigDiffFilter]{repository: store.MemoryStore.aiConfigDiffs, persist: store.persist}
|
||||
}
|
||||
|
||||
func (store *MySQLStore) GameClientBridgeCommands() GameClientBridgeCommandRepository {
|
||||
return &persistentGameClientBridgeCommandRepository{
|
||||
persistentRepository: &persistentRepository[domain.GameClientBridgeCommand, domain.GameClientBridgeCommandFilter]{repository: store.MemoryStore.bridgeCommands, persist: store.persist},
|
||||
@@ -328,7 +324,6 @@ func (store *MySQLStore) snapshot() StoreSnapshot {
|
||||
MetricSamples: snapshotRepository(store.MemoryStore.metricSamples),
|
||||
Backups: snapshotRepository(store.MemoryStore.backups),
|
||||
PluginLifecycles: snapshotRepository(store.MemoryStore.pluginLifecycle),
|
||||
AIConfigDiffs: snapshotRepository(store.MemoryStore.aiConfigDiffs),
|
||||
GameClientBridgeCommands: snapshotRepository(store.MemoryStore.bridgeCommands.memoryRepository),
|
||||
GameClientBridgeSnapshots: snapshotRepository(store.MemoryStore.bridgeSnapshots.memoryRepository),
|
||||
GameClientBridgeStreams: snapshotRepository(store.MemoryStore.bridgeStreams),
|
||||
@@ -370,7 +365,6 @@ func (store *MySQLStore) loadSnapshot(snapshot StoreSnapshot) {
|
||||
loadRepository(store.MemoryStore.metricSamples, snapshot.MetricSamples)
|
||||
loadRepository(store.MemoryStore.backups, snapshot.Backups)
|
||||
loadRepository(store.MemoryStore.pluginLifecycle, snapshot.PluginLifecycles)
|
||||
loadRepository(store.MemoryStore.aiConfigDiffs, snapshot.AIConfigDiffs)
|
||||
loadRepository(store.MemoryStore.bridgeCommands.memoryRepository, snapshot.GameClientBridgeCommands)
|
||||
loadRepository(store.MemoryStore.bridgeSnapshots.memoryRepository, snapshot.GameClientBridgeSnapshots)
|
||||
loadRepository(store.MemoryStore.bridgeStreams, snapshot.GameClientBridgeStreams)
|
||||
|
||||
@@ -147,13 +147,6 @@ type PluginLifecycleRepository interface {
|
||||
Update(domain.PluginLifecycleInstallation) error
|
||||
}
|
||||
|
||||
type AIConfigDiffRepository interface {
|
||||
Create(domain.AIConfigDiffPreview) error
|
||||
Get(id string) (domain.AIConfigDiffPreview, error)
|
||||
List(domain.AIConfigDiffFilter) ([]domain.AIConfigDiffPreview, error)
|
||||
Update(domain.AIConfigDiffPreview) error
|
||||
}
|
||||
|
||||
type GameClientBridgeCommandRepository interface {
|
||||
Create(domain.GameClientBridgeCommand) error
|
||||
Get(id string) (domain.GameClientBridgeCommand, error)
|
||||
@@ -247,7 +240,6 @@ type Store interface {
|
||||
MetricSamples() MetricSampleRepository
|
||||
Backups() BackupRepository
|
||||
PluginLifecycles() PluginLifecycleRepository
|
||||
AIConfigDiffs() AIConfigDiffRepository
|
||||
GameClientBridgeCommands() GameClientBridgeCommandRepository
|
||||
GameClientBridgeSnapshots() GameClientBridgeSnapshotRepository
|
||||
GameClientBridgeSnapshotStreams() GameClientBridgeSnapshotStreamRepository
|
||||
@@ -278,7 +270,6 @@ type MemoryStore struct {
|
||||
metricSamples *memoryRepository[domain.MetricSample, domain.MetricSampleFilter]
|
||||
backups *memoryRepository[domain.BackupRecord, domain.BackupFilter]
|
||||
pluginLifecycle *memoryRepository[domain.PluginLifecycleInstallation, domain.PluginLifecycleFilter]
|
||||
aiConfigDiffs *memoryRepository[domain.AIConfigDiffPreview, domain.AIConfigDiffFilter]
|
||||
bridgeCommands *memoryGameClientBridgeCommandRepository
|
||||
bridgeSnapshots *memoryGameClientBridgeSnapshotRepository
|
||||
bridgeStreams *memoryRepository[domain.GameClientBridgeSnapshotStream, domain.GameClientBridgeSnapshotStreamFilter]
|
||||
@@ -378,11 +369,6 @@ func NewMemoryStore() *MemoryStore {
|
||||
domain.CopyPluginLifecycleInstallation,
|
||||
matchPluginLifecycle,
|
||||
),
|
||||
aiConfigDiffs: newMemoryRepository(
|
||||
func(preview domain.AIConfigDiffPreview) string { return preview.ID },
|
||||
domain.CopyAIConfigDiffPreview,
|
||||
matchAIConfigDiff,
|
||||
),
|
||||
bridgeCommands: newMemoryGameClientBridgeCommandRepository(),
|
||||
bridgeSnapshots: newMemoryGameClientBridgeSnapshotRepository(),
|
||||
bridgeStreams: newMemoryRepository(
|
||||
@@ -421,7 +407,6 @@ func (store *MemoryStore) Backups() BackupRepository { retu
|
||||
func (store *MemoryStore) PluginLifecycles() PluginLifecycleRepository {
|
||||
return store.pluginLifecycle
|
||||
}
|
||||
func (store *MemoryStore) AIConfigDiffs() AIConfigDiffRepository { return store.aiConfigDiffs }
|
||||
func (store *MemoryStore) GameClientBridgeCommands() GameClientBridgeCommandRepository {
|
||||
return store.bridgeCommands
|
||||
}
|
||||
@@ -722,12 +707,6 @@ func matchPluginLifecycle(installation domain.PluginLifecycleInstallation, filte
|
||||
(filter.CurrentState == "" || installation.CurrentState == filter.CurrentState)
|
||||
}
|
||||
|
||||
func matchAIConfigDiff(preview domain.AIConfigDiffPreview, filter domain.AIConfigDiffFilter) bool {
|
||||
return (filter.ServerInstanceID == "" || preview.ServerInstanceID == filter.ServerInstanceID) &&
|
||||
(filter.PluginID == "" || preview.PluginID == filter.PluginID) &&
|
||||
(filter.State == "" || preview.State == filter.State)
|
||||
}
|
||||
|
||||
func matchGameClientBridgeCommand(command domain.GameClientBridgeCommand, filter domain.GameClientBridgeCommandFilter) bool {
|
||||
return (filter.ServerInstanceID == "" || command.ServerInstanceID == filter.ServerInstanceID) &&
|
||||
(filter.PluginID == "" || command.PluginID == filter.PluginID) &&
|
||||
|
||||
@@ -435,19 +435,9 @@ func TestFileStorePersistsPluginOperationsStateAcrossRestart(t *testing.T) {
|
||||
DependencyState: domain.DependencyStatePresent, JobID: "job-upgrade",
|
||||
IdempotencyKey: "upgrade-once", CreatedAt: stamp.Add(-time.Hour), UpdatedAt: stamp,
|
||||
}
|
||||
diff := domain.AIConfigDiffPreview{
|
||||
ID: "ai-config-diff-1", RequestID: "ai-request-1", CreatedBy: "operator-1",
|
||||
ServerInstanceID: "server-1", PluginID: "game.scum", ProviderID: "ai.openai", Model: "gpt-4.1",
|
||||
Key: "server.properties", ConfigVersion: 4, CurrentConfigChecksum: "sha256:" + strings.Repeat("a", 64),
|
||||
ProposedConfig: "MaxPlayers=80\n", DiffSummary: "review required before config write dispatch",
|
||||
State: domain.AIConfigDiffStatePending, ExpiresAt: stamp.Add(30 * time.Minute), CreatedAt: stamp, UpdatedAt: stamp,
|
||||
}
|
||||
if err := store.PluginLifecycles().Create(installation); err != nil {
|
||||
t.Fatalf("create plugin lifecycle: %v", err)
|
||||
}
|
||||
if err := store.AIConfigDiffs().Create(diff); err != nil {
|
||||
t.Fatalf("create AI config diff: %v", err)
|
||||
}
|
||||
|
||||
restarted, err := NewFileStore(path)
|
||||
if err != nil {
|
||||
@@ -457,10 +447,6 @@ func TestFileStorePersistsPluginOperationsStateAcrossRestart(t *testing.T) {
|
||||
if lifecycleErr != nil || gotInstallation.CurrentState != installation.CurrentState || gotInstallation.TargetVersion != installation.TargetVersion || gotInstallation.JobID != installation.JobID {
|
||||
t.Fatalf("unexpected durable plugin lifecycle: installation=%+v err=%v", gotInstallation, lifecycleErr)
|
||||
}
|
||||
gotDiff, diffErr := restarted.AIConfigDiffs().Get(diff.ID)
|
||||
if diffErr != nil || gotDiff.State != diff.State || gotDiff.CurrentConfigChecksum != diff.CurrentConfigChecksum || gotDiff.ProposedConfig != diff.ProposedConfig {
|
||||
t.Fatalf("unexpected durable AI config diff: diff=%+v err=%v", gotDiff, diffErr)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMySQLStoreRequiresDSN(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user