feat: CheckSnapshots y UpdateSnapshot en fn_operations library

Añade UpdateTypeSnapshot al store, CheckSnapshots para comparar snapshots
locales vs registry (up_to_date/outdated/missing), y UpdateSnapshot para
re-snapshot con retorno de old/new para diffing.
This commit is contained in:
2026-03-28 13:41:35 +01:00
parent 762fcbeb58
commit 0095de2ce7
2 changed files with 102 additions and 0 deletions
+88
View File
@@ -189,6 +189,94 @@ func GetEntityGraph(db *DB) (*Graph, error) {
}, nil
}
// SnapshotStatus describes the state of a snapshot vs the registry.
type SnapshotStatus string
const (
SnapshotUpToDate SnapshotStatus = "up_to_date"
SnapshotOutdated SnapshotStatus = "outdated"
SnapshotMissing SnapshotStatus = "missing" // exists locally but not in registry
)
// SnapshotCheckResult holds the comparison for one type snapshot.
type SnapshotCheckResult struct {
ID string
LocalVersion string
RegistryVersion string
Status SnapshotStatus
}
// CheckSnapshots compares all local snapshots against the registry.
func CheckSnapshots(opsDB *DB, registryDB *registry.DB) ([]SnapshotCheckResult, error) {
snaps, err := opsDB.ListTypeSnapshots()
if err != nil {
return nil, fmt.Errorf("listing snapshots: %w", err)
}
var results []SnapshotCheckResult
for _, snap := range snaps {
regType, err := registryDB.GetType(snap.ID)
if err != nil {
// Not found in registry
results = append(results, SnapshotCheckResult{
ID: snap.ID,
LocalVersion: snap.Version,
Status: SnapshotMissing,
})
continue
}
status := SnapshotUpToDate
if regType.Version != snap.Version {
status = SnapshotOutdated
}
results = append(results, SnapshotCheckResult{
ID: snap.ID,
LocalVersion: snap.Version,
RegistryVersion: regType.Version,
Status: status,
})
}
return results, nil
}
// UpdateSnapshot re-snapshots a type from the registry, replacing the local copy.
// Returns the old and new definitions for diffing.
func UpdateSnapshot(opsDB *DB, registryDB *registry.DB, typeID string) (old, new_ *TypeSnapshot, err error) {
// Get current local snapshot
oldSnap, err := opsDB.GetTypeSnapshot(typeID)
if err != nil {
return nil, nil, fmt.Errorf("reading local snapshot: %w", err)
}
if oldSnap == nil {
return nil, nil, fmt.Errorf("type %q not found in local snapshots", typeID)
}
// Get current registry type
regType, err := registryDB.GetType(typeID)
if err != nil {
return nil, nil, fmt.Errorf("fetching type %q from registry: %w", typeID, err)
}
// Build new snapshot
newSnap := &TypeSnapshot{
ID: regType.ID,
Version: regType.Version,
Lang: regType.Lang,
Algebraic: string(regType.Algebraic),
Definition: regType.Definition,
Description: regType.Description,
SnappedAt: time.Now().UTC(),
}
if err := opsDB.UpdateTypeSnapshot(newSnap); err != nil {
return nil, nil, fmt.Errorf("updating snapshot: %w", err)
}
return oldSnap, newSnap, nil
}
func buildEntitySet(db *DB) (map[string]bool, error) {
all, err := db.ListEntities("", "")
if err != nil {