From ce4d49caef50b073d3699e75d465b1815691cfdf Mon Sep 17 00:00:00 2001 From: Trey t Date: Fri, 1 May 2026 08:59:51 -0700 Subject: [PATCH] tools: add send-test-push for one-shot Asynq push verification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tiny CLI that enqueues a notification:send_push task into Redis. The worker picks it up and routes through internal/push/Client.SendToAll — which is exactly the path used by HandleSmartReminder, HandleDailyDigest, and any other in-process push, so a successful round-trip here proves the production push pipeline end-to-end without waiting for the next cron tick. Requires Redis to be reachable. Easiest path: kubectl -n honeydue port-forward svc/redis 6379:6379 go run ./cmd/send-test-push --user-id 6 --title "..." --message "..." The worker logs `Sending push notification...` followed by the APNs batch result; failure modes (BadDeviceToken, circuit breaker, etc.) surface as the same error_message rows the existing notif-diag tool already reports on. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitignore | 1 + cmd/send-test-push/main.go | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 cmd/send-test-push/main.go diff --git a/.gitignore b/.gitignore index 620f8c7..a79fead 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ bin/ /admin /admin-reset /notif-diag +/send-test-push !admin/ *.exe *.exe~ diff --git a/cmd/send-test-push/main.go b/cmd/send-test-push/main.go new file mode 100644 index 0000000..0b938b8 --- /dev/null +++ b/cmd/send-test-push/main.go @@ -0,0 +1,59 @@ +// send-test-push enqueues a one-shot Asynq push notification task. The worker +// picks it up and routes it through internal/push/Client.SendToAll, which now +// hits APNs production. Verifies end-to-end that push delivery is working +// without waiting for the next cron tick. +// +// Usage: +// +// # Port-forward Redis from the cluster first: +// kubectl --kubeconfig=~/.kube/honeydue-k3s.yaml -n honeydue port-forward svc/redis 6379:6379 +// +// # Then in another shell: +// go run ./cmd/send-test-push --user-id 6 --title "Test" --message "Hello from notif-diag" +package main + +import ( + "flag" + "fmt" + "os" + "strconv" + + "github.com/hibiken/asynq" + + "github.com/treytartt/honeydue-api/internal/worker/jobs" +) + +func main() { + userID := flag.Uint("user-id", 0, "Target auth_user.id (required)") + title := flag.String("title", "Test push", "Notification title") + message := flag.String("message", "Hello from send-test-push", "Notification body") + redisAddr := flag.String("redis", "localhost:6379", "Redis host:port (use kubectl port-forward to reach the in-cluster redis)") + flag.Parse() + + if *userID == 0 { + fmt.Fprintln(os.Stderr, "--user-id is required") + os.Exit(2) + } + + task, err := jobs.NewSendPushTask(*userID, *title, *message, map[string]string{ + "type": "test", + "user_id": strconv.FormatUint(uint64(*userID), 10), + }) + if err != nil { + fmt.Fprintf(os.Stderr, "build task: %v\n", err) + os.Exit(1) + } + + client := asynq.NewClient(asynq.RedisClientOpt{Addr: *redisAddr}) + defer func() { _ = client.Close() }() + + info, err := client.Enqueue(task, asynq.Queue("default"), asynq.MaxRetry(3)) + if err != nil { + fmt.Fprintf(os.Stderr, "enqueue: %v\n", err) + os.Exit(1) + } + + fmt.Printf("Enqueued task: id=%s queue=%s type=%s\n", info.ID, info.Queue, info.Type) + fmt.Printf("Tail worker logs to see the result:\n") + fmt.Printf(" kubectl --kubeconfig=~/.kube/honeydue-k3s.yaml -n honeydue logs deploy/worker --tail=20 -f\n") +}