Onboarding step 3 push opt-in and test-push endpoint (Feature 19) (#168)
CI / ci (push) Successful in 7m17s

Co-authored-by: orchestrator-agent <20+orchestrator-agent@code.cubecraftcreations.com>
This commit was merged in pull request #168.
This commit is contained in:
2026-10-09 17:37:53 -04:00
committed by approver_agent
parent 51e0213e92
commit 63ed5a67a8
13 changed files with 573 additions and 141 deletions
+28
View File
@@ -5,6 +5,7 @@ import (
"log/slog"
"net/http"
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/notify"
"code.cubecraftlabs.com/Maniacs_Mansion/Meal-Quest/internal/push"
)
@@ -85,6 +86,33 @@ func deletePushSubscription(logger *slog.Logger, svc *push.Service) http.Handler
}
}
// postTestPush answers POST /settings/notifications/test-push: it queues
// push.TestTitle for every device that turned on push, aimed at /plan, and
// answers 202 with the event key and how many subscriptions it goes to.
// Delivery follows through the notification outbox. With push switched
// off for plan_ready it is 409 push_off, whether or not any device has
// turned on push; otherwise with no subscription it is 409
// no_subscriptions. Neither sends anything. It never posts to Google Chat.
func postTestPush(logger *slog.Logger, svc *push.Service) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
sent, err := svc.SendTest(r.Context())
switch {
case errors.Is(err, push.ErrNoSubscriptions):
writeError(w, r, logger, http.StatusConflict, "no_subscriptions",
"no device has turned on notifications, so there is nothing to send the test to")
case errors.Is(err, notify.ErrPushOff):
writeError(w, r, logger, http.StatusConflict, "push_off",
"push is switched off for New weekly plan ready in Notifications settings, so no test was sent")
case err != nil:
logger.ErrorContext(r.Context(), "send test push", "error", err)
writeError(w, r, logger, http.StatusInternalServerError, "internal", "internal error")
default:
logger.InfoContext(r.Context(), "test push queued", "event_key", sent.EventKey, "subscriptions", sent.Subscriptions)
writeJSON(w, r, logger, http.StatusAccepted, sent)
}
}
}
// writePushError maps a push.Service error to its API error: an invalid
// subscription is 400 invalid_subscription, anything else 500.
func writePushError(w http.ResponseWriter, r *http.Request, logger *slog.Logger, action string, err error) {