fix(patrol): add idempotency check for digest command
Checks if a 'Patrol Report YYYY-MM-DD' bead already exists before attempting to create a new one. This prevents confusing output when the patrol digest runs multiple times per day. Fixes: gt-budqv9 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -103,6 +103,19 @@ func runPatrolDigest(cmd *cobra.Command, args []string) error {
|
||||
|
||||
dateStr := targetDate.Format("2006-01-02")
|
||||
|
||||
// Idempotency check: see if digest already exists for this date
|
||||
existingID, err := findExistingPatrolDigest(dateStr)
|
||||
if err != nil {
|
||||
// Non-fatal: continue with creation attempt
|
||||
if patrolDigestVerbose {
|
||||
fmt.Fprintf(os.Stderr, "[patrol] warning: failed to check existing digest: %v\n", err)
|
||||
}
|
||||
} else if existingID != "" {
|
||||
fmt.Printf("%s Patrol digest already exists for %s (bead: %s)\n",
|
||||
style.Dim.Render("○"), dateStr, existingID)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Query ephemeral patrol digest beads for target date
|
||||
cycles, err := queryPatrolDigests(targetDate)
|
||||
if err != nil {
|
||||
@@ -305,6 +318,40 @@ func createPatrolDigestBead(digest PatrolDigest) (string, error) {
|
||||
return digestID, nil
|
||||
}
|
||||
|
||||
// findExistingPatrolDigest checks if a patrol digest already exists for the given date.
|
||||
// Returns the bead ID if found, empty string if not found.
|
||||
func findExistingPatrolDigest(dateStr string) (string, error) {
|
||||
expectedTitle := fmt.Sprintf("Patrol Report %s", dateStr)
|
||||
|
||||
// Query event beads with patrol.digest category
|
||||
listCmd := exec.Command("bd", "list",
|
||||
"--type=event",
|
||||
"--json",
|
||||
"--limit=50", // Recent events only
|
||||
)
|
||||
listOutput, err := listCmd.Output()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var events []struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(listOutput, &events); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for _, evt := range events {
|
||||
if evt.Title == expectedTitle {
|
||||
return evt.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// deletePatrolDigests deletes ephemeral patrol digest beads for a target date.
|
||||
func deletePatrolDigests(targetDate time.Time) (int, error) {
|
||||
// Query patrol digests for the target date
|
||||
|
||||
Reference in New Issue
Block a user