feat: backend service

This commit is contained in:
Ilia Denisov
2026-05-06 10:14:55 +03:00
committed by GitHub
parent 3e2622757e
commit f446c6a2ac
1486 changed files with 49720 additions and 266401 deletions
+127
View File
@@ -0,0 +1,127 @@
package notification
// Kind constants name every supported notification kind. The implementation // trims the README §10 catalog to the set with active producers in
// the codebase; further kinds (`game.*`, `mail.dead_lettered`) require
// an additive change here together with a producer.
const (
KindLobbyInviteReceived = "lobby.invite.received"
KindLobbyInviteRevoked = "lobby.invite.revoked"
KindLobbyApplicationSubmitted = "lobby.application.submitted"
KindLobbyApplicationApproved = "lobby.application.approved"
KindLobbyApplicationRejected = "lobby.application.rejected"
KindLobbyMembershipRemoved = "lobby.membership.removed"
KindLobbyMembershipBlocked = "lobby.membership.blocked"
KindLobbyRaceNameRegistered = "lobby.race_name.registered"
KindLobbyRaceNamePending = "lobby.race_name.pending"
KindLobbyRaceNameExpired = "lobby.race_name.expired"
KindRuntimeImagePullFailed = "runtime.image_pull_failed"
KindRuntimeContainerStartFailed = "runtime.container_start_failed"
KindRuntimeStartConfigInvalid = "runtime.start_config_invalid"
)
// CatalogEntry describes the per-kind delivery policy: which channels
// fan out and whether the kind targets the platform admin recipient
// instead of per-user accounts.
type CatalogEntry struct {
// Channels lists the channels this kind fans out to, in the order
// rows are materialised in `notification_routes`. The closed set is
// {`push`, `email`}.
Channels []string
// Admin reports whether the email channel targets the configured
// admin recipient (`BACKEND_NOTIFICATION_ADMIN_EMAIL`) rather than
// per-user accounts. Admin-targeted kinds carry an empty Recipients
// slice on the producer side.
Admin bool
// MailTemplateID is the template_id passed to `mail.EnqueueTemplate`
// for email routes. The catalog uses the kind itself by convention,
// matching `mail.TemplateLoginCode`'s use of `auth.login_code`.
MailTemplateID string
}
// catalog maps each supported kind to its delivery policy. The map is
// queried by Submit and by the dispatcher worker; producers do not
// inspect it directly.
var catalog = map[string]CatalogEntry{
KindLobbyInviteReceived: {
Channels: []string{ChannelPush, ChannelEmail},
MailTemplateID: KindLobbyInviteReceived,
},
KindLobbyInviteRevoked: {
Channels: []string{ChannelPush},
},
KindLobbyApplicationSubmitted: {
Channels: []string{ChannelPush},
},
KindLobbyApplicationApproved: {
Channels: []string{ChannelPush, ChannelEmail},
MailTemplateID: KindLobbyApplicationApproved,
},
KindLobbyApplicationRejected: {
Channels: []string{ChannelPush, ChannelEmail},
MailTemplateID: KindLobbyApplicationRejected,
},
KindLobbyMembershipRemoved: {
Channels: []string{ChannelPush, ChannelEmail},
MailTemplateID: KindLobbyMembershipRemoved,
},
KindLobbyMembershipBlocked: {
Channels: []string{ChannelPush, ChannelEmail},
MailTemplateID: KindLobbyMembershipBlocked,
},
KindLobbyRaceNameRegistered: {
Channels: []string{ChannelPush},
},
KindLobbyRaceNamePending: {
Channels: []string{ChannelPush, ChannelEmail},
MailTemplateID: KindLobbyRaceNamePending,
},
KindLobbyRaceNameExpired: {
Channels: []string{ChannelPush},
},
KindRuntimeImagePullFailed: {
Channels: []string{ChannelEmail},
Admin: true,
MailTemplateID: KindRuntimeImagePullFailed,
},
KindRuntimeContainerStartFailed: {
Channels: []string{ChannelEmail},
Admin: true,
MailTemplateID: KindRuntimeContainerStartFailed,
},
KindRuntimeStartConfigInvalid: {
Channels: []string{ChannelEmail},
Admin: true,
MailTemplateID: KindRuntimeStartConfigInvalid,
},
}
// LookupCatalog returns the per-kind policy and a boolean reporting
// whether the kind exists. Callers (Submit, Worker) branch on the
// boolean rather than receiving a sentinel error.
func LookupCatalog(kind string) (CatalogEntry, bool) {
entry, ok := catalog[kind]
return entry, ok
}
// SupportedKinds returns the closed kind set in deterministic order.
// The function exists to back tests and the migration CHECK constraint
// audit; it is not on the hot path.
func SupportedKinds() []string {
return []string{
KindLobbyInviteReceived,
KindLobbyInviteRevoked,
KindLobbyApplicationSubmitted,
KindLobbyApplicationApproved,
KindLobbyApplicationRejected,
KindLobbyMembershipRemoved,
KindLobbyMembershipBlocked,
KindLobbyRaceNameRegistered,
KindLobbyRaceNamePending,
KindLobbyRaceNameExpired,
KindRuntimeImagePullFailed,
KindRuntimeContainerStartFailed,
KindRuntimeStartConfigInvalid,
}
}