Reject empty environment/project, disable FAV consumers at register time, and keep historical classification/repair/replay as audited application use cases with no raw SQL entrypoint. Co-authored-by: Cursor <cursoragent@cursor.com>
83 lines
2.3 KiB
Go
83 lines
2.3 KiB
Go
package events
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"chat-agent-system/internal/app/uow"
|
|
)
|
|
|
|
func PersistInventory(ctx context.Context, row InventoryRow, operator, approval string) error {
|
|
scope, ok := uow.ScopeFrom(ctx)
|
|
if !ok {
|
|
return fmt.Errorf("events: inventory requires a unit of work")
|
|
}
|
|
tx, err := uow.AsPG(scope)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec(ctx, `
|
|
INSERT INTO event_inventory_decisions (
|
|
event_id, consumer, classification, reason, payload_digest, operator, approval_ref
|
|
) VALUES ($1,$2,$3,$4,$5,$6,$7)
|
|
ON CONFLICT (event_id, consumer) DO UPDATE SET
|
|
classification = EXCLUDED.classification,
|
|
reason = EXCLUDED.reason,
|
|
payload_digest = EXCLUDED.payload_digest,
|
|
operator = EXCLUDED.operator,
|
|
approval_ref = EXCLUDED.approval_ref,
|
|
decided_at = now()
|
|
`, row.EventID, row.Consumer, row.Classification, row.Reason, row.PayloadDigest, operator, approval)
|
|
return err
|
|
}
|
|
|
|
func PersistReplayPlan(ctx context.Context, p ReplayPlan, dryRun bool) error {
|
|
if err := AuthorizeReplayPlan(p); err != nil {
|
|
return err
|
|
}
|
|
scope, ok := uow.ScopeFrom(ctx)
|
|
if !ok {
|
|
return fmt.Errorf("events: replay plan requires a unit of work")
|
|
}
|
|
tx, err := uow.AsPG(scope)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
ids := ""
|
|
for i, id := range p.EventIDs {
|
|
if i > 0 {
|
|
ids += ","
|
|
}
|
|
ids += id
|
|
}
|
|
_, err = tx.Exec(ctx, `
|
|
INSERT INTO event_replay_plans (
|
|
plan_id, operator, approver, environment, project_id, consumer,
|
|
event_ids_digest, plan_digest, reason, approval_ref, dry_run
|
|
) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)
|
|
ON CONFLICT (plan_id) DO NOTHING
|
|
`, p.PlanID, p.Operator, p.Approver, p.Environment, p.ProjectID, p.Consumer,
|
|
DigestText(ids), p.Digest(), p.Reason, p.ApprovalRef, dryRun)
|
|
return err
|
|
}
|
|
|
|
func PersistRepair(ctx context.Context, r RepairRecord) error {
|
|
if err := ValidateRepair(r); err != nil {
|
|
return err
|
|
}
|
|
scope, ok := uow.ScopeFrom(ctx)
|
|
if !ok {
|
|
return fmt.Errorf("events: repair requires a unit of work")
|
|
}
|
|
tx, err := uow.AsPG(scope)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = tx.Exec(ctx, `
|
|
INSERT INTO event_repair_audit (
|
|
event_id, field_name, old_digest, new_digest, operator, reason, approval_ref
|
|
) VALUES ($1,$2,$3,$4,$5,$6,$7)
|
|
`, r.EventID, r.FieldName, r.OldDigest, r.NewDigest, r.Operator, r.Reason, r.ApprovalRef)
|
|
return err
|
|
}
|