feat: notification service

This commit is contained in:
Ilia Denisov
2026-04-22 08:49:45 +02:00
committed by GitHub
parent 5b7593e6f6
commit 32dc29359a
135 changed files with 21828 additions and 130 deletions
+390
View File
@@ -0,0 +1,390 @@
package transcoder
import (
"errors"
"fmt"
notificationfbs "galaxy/schema/fbs/notification"
flatbuffers "github.com/google/flatbuffers/go"
)
// GameTurnReadyEvent is the independent Go representation of
// `notification.GameTurnReadyEvent`.
type GameTurnReadyEvent struct {
GameID string
TurnNumber int64
}
// GameFinishedEvent is the independent Go representation of
// `notification.GameFinishedEvent`.
type GameFinishedEvent struct {
GameID string
FinalTurnNumber int64
}
// LobbyApplicationSubmittedEvent is the independent Go representation of
// `notification.LobbyApplicationSubmittedEvent`.
type LobbyApplicationSubmittedEvent struct {
GameID string
ApplicantUserID string
}
// LobbyMembershipApprovedEvent is the independent Go representation of
// `notification.LobbyMembershipApprovedEvent`.
type LobbyMembershipApprovedEvent struct {
GameID string
}
// LobbyMembershipRejectedEvent is the independent Go representation of
// `notification.LobbyMembershipRejectedEvent`.
type LobbyMembershipRejectedEvent struct {
GameID string
}
// LobbyInviteCreatedEvent is the independent Go representation of
// `notification.LobbyInviteCreatedEvent`.
type LobbyInviteCreatedEvent struct {
GameID string
InviterUserID string
}
// LobbyInviteRedeemedEvent is the independent Go representation of
// `notification.LobbyInviteRedeemedEvent`.
type LobbyInviteRedeemedEvent struct {
GameID string
InviteeUserID string
}
// GameTurnReadyEventToPayload converts GameTurnReadyEvent to FlatBuffers bytes
// suitable for the authenticated gateway push transport.
func GameTurnReadyEventToPayload(event *GameTurnReadyEvent) ([]byte, error) {
if event == nil {
return nil, errors.New("encode game turn ready payload: event is nil")
}
if event.GameID == "" {
return nil, errors.New("encode game turn ready payload: game_id is empty")
}
builder := flatbuffers.NewBuilder(64)
gameID := builder.CreateString(event.GameID)
notificationfbs.GameTurnReadyEventStart(builder)
notificationfbs.GameTurnReadyEventAddGameId(builder, gameID)
notificationfbs.GameTurnReadyEventAddTurnNumber(builder, event.TurnNumber)
offset := notificationfbs.GameTurnReadyEventEnd(builder)
notificationfbs.FinishGameTurnReadyEventBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToGameTurnReadyEvent converts FlatBuffers payload bytes into
// GameTurnReadyEvent.
func PayloadToGameTurnReadyEvent(data []byte) (result *GameTurnReadyEvent, err error) {
if len(data) == 0 {
return nil, errors.New("decode game turn ready payload: data is empty")
}
defer recoverNotificationDecodePanic("decode game turn ready payload", &result, &err)
event := notificationfbs.GetRootAsGameTurnReadyEvent(data, 0)
gameID, err := requiredNotificationString(event.GameId(), "game_id")
if err != nil {
return nil, fmt.Errorf("decode game turn ready payload: %w", err)
}
return &GameTurnReadyEvent{
GameID: gameID,
TurnNumber: event.TurnNumber(),
}, nil
}
// GameFinishedEventToPayload converts GameFinishedEvent to FlatBuffers bytes
// suitable for the authenticated gateway push transport.
func GameFinishedEventToPayload(event *GameFinishedEvent) ([]byte, error) {
if event == nil {
return nil, errors.New("encode game finished payload: event is nil")
}
if event.GameID == "" {
return nil, errors.New("encode game finished payload: game_id is empty")
}
builder := flatbuffers.NewBuilder(64)
gameID := builder.CreateString(event.GameID)
notificationfbs.GameFinishedEventStart(builder)
notificationfbs.GameFinishedEventAddGameId(builder, gameID)
notificationfbs.GameFinishedEventAddFinalTurnNumber(builder, event.FinalTurnNumber)
offset := notificationfbs.GameFinishedEventEnd(builder)
notificationfbs.FinishGameFinishedEventBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToGameFinishedEvent converts FlatBuffers payload bytes into
// GameFinishedEvent.
func PayloadToGameFinishedEvent(data []byte) (result *GameFinishedEvent, err error) {
if len(data) == 0 {
return nil, errors.New("decode game finished payload: data is empty")
}
defer recoverNotificationDecodePanic("decode game finished payload", &result, &err)
event := notificationfbs.GetRootAsGameFinishedEvent(data, 0)
gameID, err := requiredNotificationString(event.GameId(), "game_id")
if err != nil {
return nil, fmt.Errorf("decode game finished payload: %w", err)
}
return &GameFinishedEvent{
GameID: gameID,
FinalTurnNumber: event.FinalTurnNumber(),
}, nil
}
// LobbyApplicationSubmittedEventToPayload converts
// LobbyApplicationSubmittedEvent to FlatBuffers bytes suitable for the
// authenticated gateway push transport.
func LobbyApplicationSubmittedEventToPayload(event *LobbyApplicationSubmittedEvent) ([]byte, error) {
if event == nil {
return nil, errors.New("encode lobby application submitted payload: event is nil")
}
if event.GameID == "" {
return nil, errors.New("encode lobby application submitted payload: game_id is empty")
}
if event.ApplicantUserID == "" {
return nil, errors.New("encode lobby application submitted payload: applicant_user_id is empty")
}
builder := flatbuffers.NewBuilder(96)
gameID := builder.CreateString(event.GameID)
applicantUserID := builder.CreateString(event.ApplicantUserID)
notificationfbs.LobbyApplicationSubmittedEventStart(builder)
notificationfbs.LobbyApplicationSubmittedEventAddGameId(builder, gameID)
notificationfbs.LobbyApplicationSubmittedEventAddApplicantUserId(builder, applicantUserID)
offset := notificationfbs.LobbyApplicationSubmittedEventEnd(builder)
notificationfbs.FinishLobbyApplicationSubmittedEventBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToLobbyApplicationSubmittedEvent converts FlatBuffers payload bytes
// into LobbyApplicationSubmittedEvent.
func PayloadToLobbyApplicationSubmittedEvent(data []byte) (result *LobbyApplicationSubmittedEvent, err error) {
if len(data) == 0 {
return nil, errors.New("decode lobby application submitted payload: data is empty")
}
defer recoverNotificationDecodePanic("decode lobby application submitted payload", &result, &err)
event := notificationfbs.GetRootAsLobbyApplicationSubmittedEvent(data, 0)
gameID, err := requiredNotificationString(event.GameId(), "game_id")
if err != nil {
return nil, fmt.Errorf("decode lobby application submitted payload: %w", err)
}
applicantUserID, err := requiredNotificationString(event.ApplicantUserId(), "applicant_user_id")
if err != nil {
return nil, fmt.Errorf("decode lobby application submitted payload: %w", err)
}
return &LobbyApplicationSubmittedEvent{
GameID: gameID,
ApplicantUserID: applicantUserID,
}, nil
}
// LobbyMembershipApprovedEventToPayload converts LobbyMembershipApprovedEvent
// to FlatBuffers bytes suitable for the authenticated gateway push transport.
func LobbyMembershipApprovedEventToPayload(event *LobbyMembershipApprovedEvent) ([]byte, error) {
if event == nil {
return nil, errors.New("encode lobby membership approved payload: event is nil")
}
if event.GameID == "" {
return nil, errors.New("encode lobby membership approved payload: game_id is empty")
}
builder := flatbuffers.NewBuilder(48)
gameID := builder.CreateString(event.GameID)
notificationfbs.LobbyMembershipApprovedEventStart(builder)
notificationfbs.LobbyMembershipApprovedEventAddGameId(builder, gameID)
offset := notificationfbs.LobbyMembershipApprovedEventEnd(builder)
notificationfbs.FinishLobbyMembershipApprovedEventBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToLobbyMembershipApprovedEvent converts FlatBuffers payload bytes
// into LobbyMembershipApprovedEvent.
func PayloadToLobbyMembershipApprovedEvent(data []byte) (result *LobbyMembershipApprovedEvent, err error) {
if len(data) == 0 {
return nil, errors.New("decode lobby membership approved payload: data is empty")
}
defer recoverNotificationDecodePanic("decode lobby membership approved payload", &result, &err)
event := notificationfbs.GetRootAsLobbyMembershipApprovedEvent(data, 0)
gameID, err := requiredNotificationString(event.GameId(), "game_id")
if err != nil {
return nil, fmt.Errorf("decode lobby membership approved payload: %w", err)
}
return &LobbyMembershipApprovedEvent{GameID: gameID}, nil
}
// LobbyMembershipRejectedEventToPayload converts LobbyMembershipRejectedEvent
// to FlatBuffers bytes suitable for the authenticated gateway push transport.
func LobbyMembershipRejectedEventToPayload(event *LobbyMembershipRejectedEvent) ([]byte, error) {
if event == nil {
return nil, errors.New("encode lobby membership rejected payload: event is nil")
}
if event.GameID == "" {
return nil, errors.New("encode lobby membership rejected payload: game_id is empty")
}
builder := flatbuffers.NewBuilder(48)
gameID := builder.CreateString(event.GameID)
notificationfbs.LobbyMembershipRejectedEventStart(builder)
notificationfbs.LobbyMembershipRejectedEventAddGameId(builder, gameID)
offset := notificationfbs.LobbyMembershipRejectedEventEnd(builder)
notificationfbs.FinishLobbyMembershipRejectedEventBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToLobbyMembershipRejectedEvent converts FlatBuffers payload bytes
// into LobbyMembershipRejectedEvent.
func PayloadToLobbyMembershipRejectedEvent(data []byte) (result *LobbyMembershipRejectedEvent, err error) {
if len(data) == 0 {
return nil, errors.New("decode lobby membership rejected payload: data is empty")
}
defer recoverNotificationDecodePanic("decode lobby membership rejected payload", &result, &err)
event := notificationfbs.GetRootAsLobbyMembershipRejectedEvent(data, 0)
gameID, err := requiredNotificationString(event.GameId(), "game_id")
if err != nil {
return nil, fmt.Errorf("decode lobby membership rejected payload: %w", err)
}
return &LobbyMembershipRejectedEvent{GameID: gameID}, nil
}
// LobbyInviteCreatedEventToPayload converts LobbyInviteCreatedEvent to
// FlatBuffers bytes suitable for the authenticated gateway push transport.
func LobbyInviteCreatedEventToPayload(event *LobbyInviteCreatedEvent) ([]byte, error) {
if event == nil {
return nil, errors.New("encode lobby invite created payload: event is nil")
}
if event.GameID == "" {
return nil, errors.New("encode lobby invite created payload: game_id is empty")
}
if event.InviterUserID == "" {
return nil, errors.New("encode lobby invite created payload: inviter_user_id is empty")
}
builder := flatbuffers.NewBuilder(96)
gameID := builder.CreateString(event.GameID)
inviterUserID := builder.CreateString(event.InviterUserID)
notificationfbs.LobbyInviteCreatedEventStart(builder)
notificationfbs.LobbyInviteCreatedEventAddGameId(builder, gameID)
notificationfbs.LobbyInviteCreatedEventAddInviterUserId(builder, inviterUserID)
offset := notificationfbs.LobbyInviteCreatedEventEnd(builder)
notificationfbs.FinishLobbyInviteCreatedEventBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToLobbyInviteCreatedEvent converts FlatBuffers payload bytes into
// LobbyInviteCreatedEvent.
func PayloadToLobbyInviteCreatedEvent(data []byte) (result *LobbyInviteCreatedEvent, err error) {
if len(data) == 0 {
return nil, errors.New("decode lobby invite created payload: data is empty")
}
defer recoverNotificationDecodePanic("decode lobby invite created payload", &result, &err)
event := notificationfbs.GetRootAsLobbyInviteCreatedEvent(data, 0)
gameID, err := requiredNotificationString(event.GameId(), "game_id")
if err != nil {
return nil, fmt.Errorf("decode lobby invite created payload: %w", err)
}
inviterUserID, err := requiredNotificationString(event.InviterUserId(), "inviter_user_id")
if err != nil {
return nil, fmt.Errorf("decode lobby invite created payload: %w", err)
}
return &LobbyInviteCreatedEvent{
GameID: gameID,
InviterUserID: inviterUserID,
}, nil
}
// LobbyInviteRedeemedEventToPayload converts LobbyInviteRedeemedEvent to
// FlatBuffers bytes suitable for the authenticated gateway push transport.
func LobbyInviteRedeemedEventToPayload(event *LobbyInviteRedeemedEvent) ([]byte, error) {
if event == nil {
return nil, errors.New("encode lobby invite redeemed payload: event is nil")
}
if event.GameID == "" {
return nil, errors.New("encode lobby invite redeemed payload: game_id is empty")
}
if event.InviteeUserID == "" {
return nil, errors.New("encode lobby invite redeemed payload: invitee_user_id is empty")
}
builder := flatbuffers.NewBuilder(96)
gameID := builder.CreateString(event.GameID)
inviteeUserID := builder.CreateString(event.InviteeUserID)
notificationfbs.LobbyInviteRedeemedEventStart(builder)
notificationfbs.LobbyInviteRedeemedEventAddGameId(builder, gameID)
notificationfbs.LobbyInviteRedeemedEventAddInviteeUserId(builder, inviteeUserID)
offset := notificationfbs.LobbyInviteRedeemedEventEnd(builder)
notificationfbs.FinishLobbyInviteRedeemedEventBuffer(builder, offset)
return builder.FinishedBytes(), nil
}
// PayloadToLobbyInviteRedeemedEvent converts FlatBuffers payload bytes into
// LobbyInviteRedeemedEvent.
func PayloadToLobbyInviteRedeemedEvent(data []byte) (result *LobbyInviteRedeemedEvent, err error) {
if len(data) == 0 {
return nil, errors.New("decode lobby invite redeemed payload: data is empty")
}
defer recoverNotificationDecodePanic("decode lobby invite redeemed payload", &result, &err)
event := notificationfbs.GetRootAsLobbyInviteRedeemedEvent(data, 0)
gameID, err := requiredNotificationString(event.GameId(), "game_id")
if err != nil {
return nil, fmt.Errorf("decode lobby invite redeemed payload: %w", err)
}
inviteeUserID, err := requiredNotificationString(event.InviteeUserId(), "invitee_user_id")
if err != nil {
return nil, fmt.Errorf("decode lobby invite redeemed payload: %w", err)
}
return &LobbyInviteRedeemedEvent{
GameID: gameID,
InviteeUserID: inviteeUserID,
}, nil
}
func requiredNotificationString(value []byte, field string) (string, error) {
if len(value) == 0 {
return "", fmt.Errorf("%s is missing", field)
}
return string(value), nil
}
func recoverNotificationDecodePanic[T any](message string, result **T, err *error) {
if recovered := recover(); recovered != nil {
*result = nil
*err = fmt.Errorf("%s: panic recovered: %v", message, recovered)
}
}