167 lines
6.4 KiB
Go
167 lines
6.4 KiB
Go
// Package intentstream defines the frozen Redis Stream contract used for
|
|
// Notification Service intent intake.
|
|
package intentstream
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"galaxy/notification/internal/service/malformedintent"
|
|
"galaxy/notificationintent"
|
|
)
|
|
|
|
const (
|
|
fieldNotificationType = "notification_type"
|
|
fieldProducer = "producer"
|
|
fieldAudienceKind = "audience_kind"
|
|
fieldRecipientUserIDs = "recipient_user_ids_json"
|
|
fieldIdempotencyKey = "idempotency_key"
|
|
fieldOccurredAtMS = "occurred_at_ms"
|
|
fieldRequestID = "request_id"
|
|
fieldTraceID = "trace_id"
|
|
fieldPayloadJSON = "payload_json"
|
|
defaultResolvedLocale = "en"
|
|
)
|
|
|
|
// NotificationType identifies one supported normalized notification type.
|
|
type NotificationType = notificationintent.NotificationType
|
|
|
|
const (
|
|
// NotificationTypeGeoReviewRecommended identifies the
|
|
// `geo.review_recommended` notification.
|
|
NotificationTypeGeoReviewRecommended = notificationintent.NotificationTypeGeoReviewRecommended
|
|
|
|
// NotificationTypeGameTurnReady identifies the `game.turn.ready`
|
|
// notification.
|
|
NotificationTypeGameTurnReady = notificationintent.NotificationTypeGameTurnReady
|
|
|
|
// NotificationTypeGameFinished identifies the `game.finished`
|
|
// notification.
|
|
NotificationTypeGameFinished = notificationintent.NotificationTypeGameFinished
|
|
|
|
// NotificationTypeGameGenerationFailed identifies the
|
|
// `game.generation_failed` notification.
|
|
NotificationTypeGameGenerationFailed = notificationintent.NotificationTypeGameGenerationFailed
|
|
|
|
// NotificationTypeLobbyRuntimePausedAfterStart identifies the
|
|
// `lobby.runtime_paused_after_start` notification.
|
|
NotificationTypeLobbyRuntimePausedAfterStart = notificationintent.NotificationTypeLobbyRuntimePausedAfterStart
|
|
|
|
// NotificationTypeLobbyApplicationSubmitted identifies the
|
|
// `lobby.application.submitted` notification.
|
|
NotificationTypeLobbyApplicationSubmitted = notificationintent.NotificationTypeLobbyApplicationSubmitted
|
|
|
|
// NotificationTypeLobbyMembershipApproved identifies the
|
|
// `lobby.membership.approved` notification.
|
|
NotificationTypeLobbyMembershipApproved = notificationintent.NotificationTypeLobbyMembershipApproved
|
|
|
|
// NotificationTypeLobbyMembershipRejected identifies the
|
|
// `lobby.membership.rejected` notification.
|
|
NotificationTypeLobbyMembershipRejected = notificationintent.NotificationTypeLobbyMembershipRejected
|
|
|
|
// NotificationTypeLobbyMembershipBlocked identifies the
|
|
// `lobby.membership.blocked` notification.
|
|
NotificationTypeLobbyMembershipBlocked = notificationintent.NotificationTypeLobbyMembershipBlocked
|
|
|
|
// NotificationTypeLobbyInviteCreated identifies the
|
|
// `lobby.invite.created` notification.
|
|
NotificationTypeLobbyInviteCreated = notificationintent.NotificationTypeLobbyInviteCreated
|
|
|
|
// NotificationTypeLobbyInviteRedeemed identifies the
|
|
// `lobby.invite.redeemed` notification.
|
|
NotificationTypeLobbyInviteRedeemed = notificationintent.NotificationTypeLobbyInviteRedeemed
|
|
|
|
// NotificationTypeLobbyInviteExpired identifies the
|
|
// `lobby.invite.expired` notification.
|
|
NotificationTypeLobbyInviteExpired = notificationintent.NotificationTypeLobbyInviteExpired
|
|
|
|
// NotificationTypeLobbyRaceNameRegistrationEligible identifies the
|
|
// `lobby.race_name.registration_eligible` notification.
|
|
NotificationTypeLobbyRaceNameRegistrationEligible = notificationintent.NotificationTypeLobbyRaceNameRegistrationEligible
|
|
|
|
// NotificationTypeLobbyRaceNameRegistered identifies the
|
|
// `lobby.race_name.registered` notification.
|
|
NotificationTypeLobbyRaceNameRegistered = notificationintent.NotificationTypeLobbyRaceNameRegistered
|
|
|
|
// NotificationTypeLobbyRaceNameRegistrationDenied identifies the
|
|
// `lobby.race_name.registration_denied` notification.
|
|
NotificationTypeLobbyRaceNameRegistrationDenied = notificationintent.NotificationTypeLobbyRaceNameRegistrationDenied
|
|
)
|
|
|
|
// Producer identifies one supported upstream producer.
|
|
type Producer = notificationintent.Producer
|
|
|
|
const (
|
|
// ProducerGeoProfile identifies Geo Profile Service.
|
|
ProducerGeoProfile = notificationintent.ProducerGeoProfile
|
|
|
|
// ProducerGameMaster identifies Game Master.
|
|
ProducerGameMaster = notificationintent.ProducerGameMaster
|
|
|
|
// ProducerGameLobby identifies Game Lobby.
|
|
ProducerGameLobby = notificationintent.ProducerGameLobby
|
|
)
|
|
|
|
// AudienceKind identifies one supported target-audience kind.
|
|
type AudienceKind = notificationintent.AudienceKind
|
|
|
|
const (
|
|
// AudienceKindUser identifies user-targeted notifications.
|
|
AudienceKindUser = notificationintent.AudienceKindUser
|
|
|
|
// AudienceKindAdminEmail identifies administrator-email notifications.
|
|
AudienceKindAdminEmail = notificationintent.AudienceKindAdminEmail
|
|
)
|
|
|
|
// Channel identifies one durable notification-delivery channel slot.
|
|
type Channel = notificationintent.Channel
|
|
|
|
const (
|
|
// ChannelPush identifies the push-delivery channel.
|
|
ChannelPush = notificationintent.ChannelPush
|
|
|
|
// ChannelEmail identifies the email-delivery channel.
|
|
ChannelEmail = notificationintent.ChannelEmail
|
|
)
|
|
|
|
// Intent stores one normalized notification intent accepted from the Redis
|
|
// Stream ingress contract.
|
|
type Intent = notificationintent.Intent
|
|
|
|
// DecodeIntent validates one raw Redis Stream entry and returns the normalized
|
|
// notification intent frozen by the shared producer contract.
|
|
func DecodeIntent(fields map[string]any) (Intent, error) {
|
|
return notificationintent.DecodeIntent(fields)
|
|
}
|
|
|
|
// ClassifyDecodeError maps one intake decoding or validation error to the
|
|
// stable malformed-intent failure surface.
|
|
func ClassifyDecodeError(err error) malformedintent.FailureCode {
|
|
if err == nil {
|
|
return malformedintent.FailureCodeInvalidIntent
|
|
}
|
|
|
|
message := err.Error()
|
|
switch {
|
|
case strings.Contains(message, "payload_json"),
|
|
strings.Contains(message, "turn_number"),
|
|
strings.Contains(message, "final_turn_number"),
|
|
strings.Contains(message, "failure_reason"),
|
|
strings.Contains(message, "applicant_name"),
|
|
strings.Contains(message, "inviter_name"),
|
|
strings.Contains(message, "invitee_name"),
|
|
strings.Contains(message, "review_reason"),
|
|
strings.Contains(message, "race_name"),
|
|
strings.Contains(message, "eligible_until_ms"),
|
|
strings.Contains(message, "reason"):
|
|
return malformedintent.FailureCodeInvalidPayload
|
|
default:
|
|
return malformedintent.FailureCodeInvalidIntent
|
|
}
|
|
}
|
|
|
|
// DefaultResolvedLocale returns the frozen fallback locale assigned when the
|
|
// current rollout has no supported exact user locale other than English.
|
|
func DefaultResolvedLocale() string {
|
|
return defaultResolvedLocale
|
|
}
|