You've already forked agentic-coding-workflow
feat(jobs): emit job.enqueue + worktree.pruned audit rows
Deferred audit retrofits from Plan #5 self-review: - WebhookNotifier now records a job.enqueue audit row after each successful repo.Enqueue (best-effort: failures are warn-logged, not propagated). Added optional audit.Recorder + *slog.Logger params to NewWebhookNotifier. - WorktreePrune.executionPhase now records a worktree.pruned audit row after each successful FinishPruneSuccess. Added optional audit.Recorder param to NewWorktreePrune. - app.go wires the existing auditRec into both constructors. - integration_test.go: drop the _ = auditRec suppression and pass auditRec into the webhook notifier so the closed-loop test exercises the audit emit path.
This commit is contained in:
@@ -3,8 +3,10 @@ package jobs
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"time"
|
||||
|
||||
"github.com/yan1h/agent-coding-workflow/internal/audit"
|
||||
"github.com/yan1h/agent-coding-workflow/internal/infra/clock"
|
||||
"github.com/yan1h/agent-coding-workflow/internal/infra/notify"
|
||||
)
|
||||
@@ -27,14 +29,20 @@ type WebhookNotifier struct {
|
||||
repo Repository
|
||||
cfg WebhookNotifierConfig
|
||||
clk clock.Clock
|
||||
rec audit.Recorder
|
||||
log *slog.Logger
|
||||
}
|
||||
|
||||
// NewWebhookNotifier constructs the notifier.
|
||||
func NewWebhookNotifier(repo Repository, cfg WebhookNotifierConfig, clk clock.Clock) *WebhookNotifier {
|
||||
// NewWebhookNotifier constructs the notifier. rec is optional; when non-nil the
|
||||
// notifier emits a job.enqueue audit row after each successful Enqueue.
|
||||
func NewWebhookNotifier(repo Repository, cfg WebhookNotifierConfig, clk clock.Clock, rec audit.Recorder, log *slog.Logger) *WebhookNotifier {
|
||||
if clk == nil {
|
||||
clk = clock.Real()
|
||||
}
|
||||
return &WebhookNotifier{repo: repo, cfg: cfg, clk: clk}
|
||||
if log == nil {
|
||||
log = slog.Default()
|
||||
}
|
||||
return &WebhookNotifier{repo: repo, cfg: cfg, clk: clk, rec: rec, log: log}
|
||||
}
|
||||
|
||||
// Name reports the notify.Channel for this notifier.
|
||||
@@ -66,8 +74,24 @@ func (n *WebhookNotifier) Send(ctx context.Context, msg notify.Message) error {
|
||||
if maxAttempts < 1 {
|
||||
maxAttempts = 1
|
||||
}
|
||||
_, err = n.repo.Enqueue(ctx, TypeWebhookDeliver, payload, n.clk.Now(), maxAttempts)
|
||||
return err
|
||||
enqueued, err := n.repo.Enqueue(ctx, TypeWebhookDeliver, payload, n.clk.Now(), maxAttempts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if n.rec != nil {
|
||||
if rerr := n.rec.Record(ctx, audit.Entry{
|
||||
Action: "job.enqueue",
|
||||
TargetType: "job",
|
||||
TargetID: enqueued.ID.String(),
|
||||
Metadata: map[string]any{
|
||||
"topic": msg.Topic,
|
||||
"job_type": string(TypeWebhookDeliver),
|
||||
},
|
||||
}); rerr != nil {
|
||||
n.log.Warn("webhook_notifier.audit_failed", "job_id", enqueued.ID, "err", rerr.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func topicAllowed(allow []string, t string) bool {
|
||||
|
||||
Reference in New Issue
Block a user