package engine import ( "context" "fmt" "log/slog" "git.cloudinit.dev/coreci/orca/internal/model" "git.cloudinit.dev/coreci/orca/internal/store" ) type NodeRegistry struct { repo *store.NodeRepo audit *Audit log *slog.Logger } func NewNodeRegistry(repo *store.NodeRepo, audit *Audit, log *slog.Logger) *NodeRegistry { if log == nil { log = slog.Default() } return &NodeRegistry{repo: repo, audit: audit, log: log} } func (r *NodeRegistry) Join(ctx context.Context, n *model.Node) error { if err := r.repo.Insert(ctx, n); err != nil { r.audit.Record(ctx, "cli", "node.join", n.ID, "failure", err, map[string]any{ "name": n.Name, "address": n.Address, }) return fmt.Errorf("join node: %w", err) } r.audit.Record(ctx, "cli", "node.join", n.ID, "success", nil, map[string]any{ "name": n.Name, "address": n.Address, }) r.log.Info("node joined", slog.String("node_id", n.ID), slog.String("name", n.Name), slog.String("address", n.Address)) return nil } func (r *NodeRegistry) Leave(ctx context.Context, id string) error { if err := r.repo.UpdateState(ctx, id, model.NodeStateLeft); err != nil { r.audit.Record(ctx, "cli", "node.leave", id, "failure", err, nil) return fmt.Errorf("leave node: %w", err) } r.audit.Record(ctx, "cli", "node.leave", id, "success", nil, nil) r.log.Info("node left", slog.String("node_id", id)) return nil } func (r *NodeRegistry) Forget(ctx context.Context, id string) error { if err := r.repo.Delete(ctx, id); err != nil { r.audit.Record(ctx, "cli", "node.forget", id, "failure", err, nil) return fmt.Errorf("forget node: %w", err) } r.audit.Record(ctx, "cli", "node.forget", id, "success", nil, nil) r.log.Info("node removed from registry", slog.String("node_id", id)) return nil } func (r *NodeRegistry) List(ctx context.Context) ([]*model.Node, error) { return r.repo.List(ctx) } func (r *NodeRegistry) Get(ctx context.Context, id string) (*model.Node, error) { return r.repo.Get(ctx, id) }