60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
package recovery
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
|
|
"git.k6n.net/mats/go-cart-actor/pkg/cart"
|
|
)
|
|
|
|
// LoggingNotifier is the v0 default: it writes one INFO line per candidate
|
|
// and returns nil. It deliberately does NOT pretend to send anything.
|
|
//
|
|
// Future implementations (MailerSend, FCM, APNs) implement the same Notifier
|
|
// interface; the scanner doesn't change. LoggingNotifier also serves as the
|
|
// "dry-run" mode in production by leaving the seam unconfigured.
|
|
type LoggingNotifier struct{}
|
|
|
|
// NewLoggingNotifier returns a Notifier that logs every candidate. The struct
|
|
// is empty today; the constructor is kept for parity with future notifiers
|
|
// that need credentials / config.
|
|
func NewLoggingNotifier() *LoggingNotifier { return &LoggingNotifier{} }
|
|
|
|
// NotifyAbandoned logs the cart id, contact present, and a tiny summary.
|
|
// Push tokens are summarized by platform only — never log the raw token, so
|
|
// a misconfigured log aggregator can't leak device handles.
|
|
func (LoggingNotifier) NotifyAbandoned(_ context.Context, c RecoveryCandidate) error {
|
|
hasEmail := c.Email != ""
|
|
hasPush := len(c.PushTokens) > 0
|
|
channel := "none"
|
|
switch {
|
|
case hasEmail && hasPush:
|
|
channel = "email+push"
|
|
case hasEmail:
|
|
channel = "email"
|
|
case hasPush:
|
|
channel = "push"
|
|
}
|
|
log.Printf(
|
|
"recovery [dry-run]: cart=%d user=%q channel=%s items=%d total=%d currency=%s email=%q pushPlatforms=%v lastChangeUnix=%d",
|
|
c.CartID,
|
|
c.UserID,
|
|
channel,
|
|
c.ItemCount,
|
|
c.TotalIncVat,
|
|
c.Currency,
|
|
c.Email,
|
|
platformsOf(c.PushTokens),
|
|
c.LastChangeUnix,
|
|
)
|
|
return nil
|
|
}
|
|
|
|
func platformsOf(tokens []cart.PushToken) []string {
|
|
out := make([]string, 0, len(tokens))
|
|
for _, t := range tokens {
|
|
out = append(out, t.Platform)
|
|
}
|
|
return out
|
|
}
|