diff --git a/cmd/twhelp/cmd_consumer.go b/cmd/twhelp/cmd_consumer.go index d28785d..7e63fd8 100644 --- a/cmd/twhelp/cmd_consumer.go +++ b/cmd/twhelp/cmd_consumer.go @@ -60,6 +60,7 @@ var cmdConsumer = &cli.Command{ logger, marshaler, c.String(rmqFlagTopicSyncServersCmd.Name), + c.String(rmqFlagTopicServerSyncedEvent.Name), ) consumer.Register(router) diff --git a/internal/adapter/http_tw.go b/internal/adapter/http_tw.go index d874545..c0db887 100644 --- a/internal/adapter/http_tw.go +++ b/internal/adapter/http_tw.go @@ -39,3 +39,115 @@ func (t *TWHTTP) convertServersToDomain(servers []tw.Server) (domain.BaseServers return res, nil } + +func (t *TWHTTP) GetServerConfig(ctx context.Context, baseURL string) (domain.ServerConfig, error) { + cfg, err := t.client.GetServerConfig(ctx, baseURL) + if err != nil { + return domain.ServerConfig{}, err + } + + res, err := domain.NewServerConfig( + cfg.Speed, + cfg.UnitSpeed, + cfg.Moral, + domain.ServerConfigBuild(cfg.Build), + domain.ServerConfigMisc(cfg.Misc), + domain.ServerConfigCommands(cfg.Commands), + domain.ServerConfigNewbie(cfg.Newbie), + domain.ServerConfigGame{ + BuildtimeFormula: cfg.Game.BuildtimeFormula, + Knight: cfg.Game.Knight, + KnightNewItems: cfg.Game.KnightNewItems.Int(), + Archer: cfg.Game.Archer, + Tech: cfg.Game.Tech, + FarmLimit: cfg.Game.FarmLimit, + Church: cfg.Game.Church, + Watchtower: cfg.Game.Watchtower, + Stronghold: cfg.Game.Stronghold, + FakeLimit: cfg.Game.FakeLimit, + BarbarianRise: cfg.Game.BarbarianRise, + BarbarianShrink: cfg.Game.BarbarianShrink, + BarbarianMaxPoints: cfg.Game.BarbarianMaxPoints, + Scavenging: cfg.Game.Scavenging, + Hauls: cfg.Game.Hauls, + HaulsBase: cfg.Game.HaulsBase, + HaulsMax: cfg.Game.HaulsMax, + BaseProduction: cfg.Game.BaseProduction, + Event: cfg.Game.Event, + SuppressEvents: cfg.Game.SuppressEvents, + }, + domain.ServerConfigBuildings(cfg.Buildings), + domain.ServerConfigSnob(cfg.Snob), + domain.ServerConfigAlly(cfg.Ally), + domain.ServerConfigCoord(cfg.Coord), + domain.ServerConfigSitter(cfg.Sitter), + domain.ServerConfigSleep(cfg.Sleep), + domain.ServerConfigNight(cfg.Night), + domain.ServerConfigWin(cfg.Win), + ) + if err != nil { + return domain.ServerConfig{}, fmt.Errorf("couldn't construct domain.ServerConfig: %w", err) + } + + return res, nil +} + +func (t *TWHTTP) GetUnitInfo(ctx context.Context, baseURL string) (domain.UnitInfo, error) { + info, err := t.client.GetUnitInfo(ctx, baseURL) + if err != nil { + return domain.UnitInfo{}, err + } + + res, err := domain.NewUnitInfo( + domain.Unit(info.Spear), + domain.Unit(info.Sword), + domain.Unit(info.Axe), + domain.Unit(info.Archer), + domain.Unit(info.Spy), + domain.Unit(info.Light), + domain.Unit(info.Marcher), + domain.Unit(info.Heavy), + domain.Unit(info.Ram), + domain.Unit(info.Catapult), + domain.Unit(info.Knight), + domain.Unit(info.Snob), + domain.Unit(info.Militia), + ) + if err != nil { + return domain.UnitInfo{}, fmt.Errorf("couldn't construct domain.UnitInfo: %w", err) + } + + return res, nil +} + +func (t *TWHTTP) GetBuildingInfo(ctx context.Context, baseURL string) (domain.BuildingInfo, error) { + info, err := t.client.GetBuildingInfo(ctx, baseURL) + if err != nil { + return domain.BuildingInfo{}, err + } + + res, err := domain.NewBuildingInfo( + domain.Building(info.Main), + domain.Building(info.Barracks), + domain.Building(info.Stable), + domain.Building(info.Garage), + domain.Building(info.Watchtower), + domain.Building(info.Snob), + domain.Building(info.Smith), + domain.Building(info.Place), + domain.Building(info.Statue), + domain.Building(info.Market), + domain.Building(info.Wood), + domain.Building(info.Stone), + domain.Building(info.Iron), + domain.Building(info.Farm), + domain.Building(info.Storage), + domain.Building(info.Hide), + domain.Building(info.Wall), + ) + if err != nil { + return domain.BuildingInfo{}, fmt.Errorf("couldn't construct domain.BuildingInfo: %w", err) + } + + return res, nil +} diff --git a/internal/adapter/repository_bun_server.go b/internal/adapter/repository_bun_server.go index 388355b..87fd990 100644 --- a/internal/adapter/repository_bun_server.go +++ b/internal/adapter/repository_bun_server.go @@ -77,6 +77,49 @@ func (repo *ServerBunRepository) baseListQuery(params domain.ListServersParams) return repo.db.NewSelect().Apply(listServersParamsApplier{params: params}.apply) } +func (repo *ServerBunRepository) Update(ctx context.Context, key string, params domain.UpdateServerParams) error { + if params.IsZero() { + return errors.New("nothing to update") + } + + res, err := repo.db.NewUpdate(). + Model(&bunmodel.Server{}). + Where("key = ?", key). + Apply(updateServerParamsApplier{params: params}.apply). + Returning(""). + Exec(ctx) + if err != nil { + return fmt.Errorf("couldn't update server with key %s: %w", key, err) + } + if affected, _ := res.RowsAffected(); affected == 0 { + return domain.ServerNotFoundError{ + Key: key, + } + } + + return nil +} + +type updateServerParamsApplier struct { + params domain.UpdateServerParams +} + +func (a updateServerParamsApplier) apply(q *bun.UpdateQuery) *bun.UpdateQuery { + if config := a.params.Config(); config.Valid { + q = q.Set("config = ?", bunmodel.NewServerConfig(config.Value)) + } + + if unitInfo := a.params.UnitInfo(); unitInfo.Valid { + q = q.Set("unit_info = ?", bunmodel.NewUnitInfo(unitInfo.Value)) + } + + if buildingInfo := a.params.BuildingInfo(); buildingInfo.Valid { + q = q.Set("building_info = ?", bunmodel.NewBuildingInfo(buildingInfo.Value)) + } + + return q +} + type listServersParamsApplier struct { params domain.ListServersParams } diff --git a/internal/adapter/repository_server_test.go b/internal/adapter/repository_server_test.go index 989c4cb..2fd3c90 100644 --- a/internal/adapter/repository_server_test.go +++ b/internal/adapter/repository_server_test.go @@ -18,14 +18,14 @@ import ( func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories) { t.Helper() + ctx := context.Background() + t.Run("CreateOrUpdate", func(t *testing.T) { t.Parallel() t.Run("OK", func(t *testing.T) { t.Parallel() - ctx := context.Background() - repos := newRepos(t) versions, err := repos.version.List(ctx, domain.NewListVersionsParams()) @@ -103,7 +103,7 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories repos := newRepos(t) - servers, listServersErr := repos.server.List(context.Background(), domain.NewListServersParams()) + servers, listServersErr := repos.server.List(ctx, domain.NewListServersParams()) require.NoError(t, listServersErr) require.NotEmpty(t, servers) randServer := servers[0] @@ -370,7 +370,6 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories t.Run(tt.name, func(t *testing.T) { t.Parallel() - ctx := context.Background() params := tt.params(t) res, err := repos.server.List(ctx, params) @@ -379,6 +378,74 @@ func testServerRepository(t *testing.T, newRepos func(t *testing.T) repositories }) } }) + + t.Run("Update", func(t *testing.T) { + t.Parallel() + + repos := newRepos(t) + + t.Run("OK", func(t *testing.T) { + t.Parallel() + + listServersBeforeUpdateParams := domain.NewListServersParams() + require.NoError(t, listServersBeforeUpdateParams.SetLimit(1)) + + serversBeforeUpdate, err := repos.server.List(ctx, listServersBeforeUpdateParams) + require.NoError(t, err) + require.NotEmpty(t, serversBeforeUpdate) + + var updateParams domain.UpdateServerParams + require.NoError(t, updateParams.SetConfig(domain.NullServerConfig{ + Value: domaintest.NewServerConfig(t), + Valid: true, + })) + require.NoError(t, updateParams.SetUnitInfo(domain.NullUnitInfo{ + Value: domaintest.NewUnitInfo(t), + Valid: true, + })) + require.NoError(t, updateParams.SetBuildingInfo(domain.NullBuildingInfo{ + Value: domaintest.NewBuildingInfo(t), + Valid: true, + })) + + require.NoError(t, repos.server.Update(ctx, serversBeforeUpdate[0].Key(), updateParams)) + + listServersAfterUpdateParams := domain.NewListServersParams() + require.NoError(t, listServersAfterUpdateParams.SetLimit(1)) + require.NoError(t, listServersAfterUpdateParams.SetKeys([]string{serversBeforeUpdate[0].Key()})) + + serversAfterUpdate, err := repos.server.List(ctx, listServersAfterUpdateParams) + require.NoError(t, err) + require.NotEmpty(t, serversAfterUpdate) + assert.Equal(t, updateParams.Config().Value, serversAfterUpdate[0].Config()) + assert.Equal(t, updateParams.UnitInfo().Value, serversAfterUpdate[0].UnitInfo()) + assert.Equal(t, updateParams.BuildingInfo().Value, serversAfterUpdate[0].BuildingInfo()) + }) + + t.Run("ERR: not found", func(t *testing.T) { + t.Parallel() + + var updateParams domain.UpdateServerParams + require.NoError(t, updateParams.SetConfig(domain.NullServerConfig{ + Value: domaintest.NewServerConfig(t), + Valid: true, + })) + + key := domaintest.RandServerKey() + + require.ErrorIs(t, repos.server.Update(ctx, key, updateParams), domain.ServerNotFoundError{ + Key: key, + }) + }) + + t.Run("ERR: nothing to update", func(t *testing.T) { + t.Parallel() + + key := domaintest.RandServerKey() + + require.Error(t, repos.server.Update(ctx, key, domain.UpdateServerParams{})) + }) + }) } func randURL(tb testing.TB) *url.URL { diff --git a/internal/adapter/repository_test.go b/internal/adapter/repository_test.go index 4874558..64d0771 100644 --- a/internal/adapter/repository_test.go +++ b/internal/adapter/repository_test.go @@ -22,6 +22,7 @@ type versionRepository interface { type serverRepository interface { CreateOrUpdate(ctx context.Context, params ...domain.CreateServerParams) error List(ctx context.Context, params domain.ListServersParams) (domain.Servers, error) + Update(ctx context.Context, key string, params domain.UpdateServerParams) error } type repositories struct { diff --git a/internal/app/service_server.go b/internal/app/service_server.go index f3c826b..a1fa504 100644 --- a/internal/app/service_server.go +++ b/internal/app/service_server.go @@ -10,6 +10,7 @@ import ( type ServerRepository interface { CreateOrUpdate(ctx context.Context, params ...domain.CreateServerParams) error List(ctx context.Context, params domain.ListServersParams) (domain.Servers, error) + Update(ctx context.Context, key string, params domain.UpdateServerParams) error } type ServerService struct { @@ -135,3 +136,47 @@ func (svc *ServerService) ListAll(ctx context.Context, params domain.ListServers } } } + +func (svc *ServerService) SyncConfigAndInfo(ctx context.Context, payload domain.ServerSyncedEventPayload) error { + url := payload.URL().String() + + cfg, err := svc.twSvc.GetServerConfig(ctx, url) + if err != nil { + return fmt.Errorf("couldn't get server config for server %s: %w", payload.Key(), err) + } + + buildingInfo, err := svc.twSvc.GetBuildingInfo(ctx, url) + if err != nil { + return fmt.Errorf("couldn't get building info for server %s: %w", payload.Key(), err) + } + + unitInfo, err := svc.twSvc.GetUnitInfo(ctx, url) + if err != nil { + return fmt.Errorf("couldn't get unit info for server %s: %w", payload.Key(), err) + } + + var updateParams domain.UpdateServerParams + + if err = updateParams.SetConfig(domain.NullServerConfig{ + Value: cfg, + Valid: true, + }); err != nil { + return err + } + + if err = updateParams.SetBuildingInfo(domain.NullBuildingInfo{ + Value: buildingInfo, + Valid: true, + }); err != nil { + return err + } + + if err = updateParams.SetUnitInfo(domain.NullUnitInfo{ + Value: unitInfo, + Valid: true, + }); err != nil { + return err + } + + return svc.repo.Update(ctx, payload.Key(), updateParams) +} diff --git a/internal/app/service_tw.go b/internal/app/service_tw.go index cdf90d7..2a8b248 100644 --- a/internal/app/service_tw.go +++ b/internal/app/service_tw.go @@ -8,4 +8,7 @@ import ( type TWService interface { GetOpenServers(ctx context.Context, baseURL string) (domain.BaseServers, error) + GetServerConfig(ctx context.Context, baseURL string) (domain.ServerConfig, error) + GetUnitInfo(ctx context.Context, baseURL string) (domain.UnitInfo, error) + GetBuildingInfo(ctx context.Context, baseURL string) (domain.BuildingInfo, error) } diff --git a/internal/domain/building_info.go b/internal/domain/building_info.go index 6cb58e9..a889414 100644 --- a/internal/domain/building_info.go +++ b/internal/domain/building_info.go @@ -35,6 +35,8 @@ type BuildingInfo struct { wall Building } +type NullBuildingInfo = NullValue[BuildingInfo] + func NewBuildingInfo( main Building, barracks Building, diff --git a/internal/domain/domaintest/building_info.go b/internal/domain/domaintest/building_info.go new file mode 100644 index 0000000..ad47f4a --- /dev/null +++ b/internal/domain/domaintest/building_info.go @@ -0,0 +1,31 @@ +package domaintest + +import ( + "gitea.dwysokinski.me/twhelp/corev3/internal/domain" + "github.com/brianvoe/gofakeit/v6" + "github.com/stretchr/testify/require" +) + +func NewBuildingInfo(tb TestingTB) domain.BuildingInfo { + buildingInfo, err := domain.NewBuildingInfo( + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + domain.Building{MaxLevel: gofakeit.IntRange(1, 30)}, + ) + require.NoError(tb, err) + return buildingInfo +} diff --git a/internal/domain/domaintest/server.go b/internal/domain/domaintest/server.go index c97e0b2..f4d0442 100644 --- a/internal/domain/domaintest/server.go +++ b/internal/domain/domaintest/server.go @@ -54,9 +54,9 @@ func NewServer(tb TestingTB, opts ...func(cfg *ServerConfig)) domain.Server { 0, 0, 0, - domain.ServerConfig{}, - domain.BuildingInfo{}, - domain.UnitInfo{}, + NewServerConfig(tb), + NewBuildingInfo(tb), + NewUnitInfo(tb), time.Now(), time.Time{}, time.Time{}, diff --git a/internal/domain/domaintest/server_config.go b/internal/domain/domaintest/server_config.go new file mode 100644 index 0000000..b1277dd --- /dev/null +++ b/internal/domain/domaintest/server_config.go @@ -0,0 +1,30 @@ +package domaintest + +import ( + "gitea.dwysokinski.me/twhelp/corev3/internal/domain" + "github.com/brianvoe/gofakeit/v6" + "github.com/stretchr/testify/require" +) + +func NewServerConfig(tb TestingTB) domain.ServerConfig { + cfg, err := domain.NewServerConfig( + gofakeit.Float64Range(1, 1000), + gofakeit.Float64Range(1, 1000), + gofakeit.IntRange(1, 20), + domain.ServerConfigBuild{}, + domain.ServerConfigMisc{}, + domain.ServerConfigCommands{}, + domain.ServerConfigNewbie{}, + domain.ServerConfigGame{}, + domain.ServerConfigBuildings{}, + domain.ServerConfigSnob{}, + domain.ServerConfigAlly{Limit: gofakeit.IntRange(1, 20)}, + domain.ServerConfigCoord{}, + domain.ServerConfigSitter{}, + domain.ServerConfigSleep{}, + domain.ServerConfigNight{}, + domain.ServerConfigWin{Check: gofakeit.IntRange(1, 20)}, + ) + require.NoError(tb, err) + return cfg +} diff --git a/internal/domain/domaintest/unit_info.go b/internal/domain/domaintest/unit_info.go new file mode 100644 index 0000000..721adf3 --- /dev/null +++ b/internal/domain/domaintest/unit_info.go @@ -0,0 +1,27 @@ +package domaintest + +import ( + "gitea.dwysokinski.me/twhelp/corev3/internal/domain" + "github.com/brianvoe/gofakeit/v6" + "github.com/stretchr/testify/require" +) + +func NewUnitInfo(tb TestingTB) domain.UnitInfo { + unitInfo, err := domain.NewUnitInfo( + domain.Unit{Speed: gofakeit.Float64Range(1, 25)}, + domain.Unit{Pop: gofakeit.IntRange(1, 3000)}, + domain.Unit{BuildTime: gofakeit.Float64Range(1, 25)}, + domain.Unit{Attack: gofakeit.IntRange(1, 3000)}, + domain.Unit{Defense: gofakeit.IntRange(1, 3000)}, + domain.Unit{Carry: gofakeit.IntRange(1, 3000)}, + domain.Unit{DefenseCavalry: gofakeit.IntRange(1, 3000)}, + domain.Unit{DefenseArcher: gofakeit.IntRange(1, 3000)}, + domain.Unit{Speed: gofakeit.Float64Range(1, 25)}, + domain.Unit{Attack: gofakeit.IntRange(1, 3000)}, + domain.Unit{DefenseArcher: gofakeit.IntRange(1, 3000)}, + domain.Unit{Carry: gofakeit.IntRange(1, 3000)}, + domain.Unit{Pop: gofakeit.IntRange(1, 3000)}, + ) + require.NoError(tb, err) + return unitInfo +} diff --git a/internal/domain/server.go b/internal/domain/server.go index 43c1ea2..500ae1e 100644 --- a/internal/domain/server.go +++ b/internal/domain/server.go @@ -243,6 +243,45 @@ func (params CreateServerParams) VersionCode() string { return params.versionCode } +type UpdateServerParams struct { + config NullServerConfig + buildingInfo NullBuildingInfo + unitInfo NullUnitInfo +} + +func (params *UpdateServerParams) Config() NullServerConfig { + return params.config +} + +func (params *UpdateServerParams) SetConfig(config NullServerConfig) error { + params.config = config + return nil +} + +func (params *UpdateServerParams) BuildingInfo() NullBuildingInfo { + return params.buildingInfo +} + +func (params *UpdateServerParams) SetBuildingInfo(buildingInfo NullBuildingInfo) error { + params.buildingInfo = buildingInfo + return nil +} + +func (params *UpdateServerParams) UnitInfo() NullUnitInfo { + return params.unitInfo +} + +func (params *UpdateServerParams) SetUnitInfo(unitInfo NullUnitInfo) error { + params.unitInfo = unitInfo + return nil +} + +func (params *UpdateServerParams) IsZero() bool { + return !params.config.Valid && + !params.buildingInfo.Valid && + !params.unitInfo.Valid +} + type ServerSort uint8 const ( @@ -392,3 +431,27 @@ func (params *ListServersParams) SetOffset(offset int) error { return nil } + +type ServerNotFoundError struct { + Key string +} + +var _ ErrorWithParams = ServerNotFoundError{} + +func (e ServerNotFoundError) Error() string { + return fmt.Sprintf("server with key %s not found", e.Key) +} + +func (e ServerNotFoundError) Code() ErrorCode { + return ErrorCodeEntityNotFound +} + +func (e ServerNotFoundError) Slug() string { + return "server-not-found" +} + +func (e ServerNotFoundError) Params() map[string]any { + return map[string]any{ + "Key": e.Key, + } +} diff --git a/internal/domain/server_config.go b/internal/domain/server_config.go index 3df9592..8b160d2 100644 --- a/internal/domain/server_config.go +++ b/internal/domain/server_config.go @@ -153,6 +153,8 @@ type ServerConfig struct { win ServerConfigWin } +type NullServerConfig = NullValue[ServerConfig] + func NewServerConfig( speed float64, unitSpeed float64, diff --git a/internal/domain/unit_info.go b/internal/domain/unit_info.go index 4cba101..2acc3a9 100644 --- a/internal/domain/unit_info.go +++ b/internal/domain/unit_info.go @@ -27,6 +27,8 @@ type UnitInfo struct { militia Unit } +type NullUnitInfo = NullValue[UnitInfo] + func NewUnitInfo( spear Unit, sword Unit, diff --git a/internal/port/consumer_watermill_server.go b/internal/port/consumer_watermill_server.go index d301fec..972872f 100644 --- a/internal/port/consumer_watermill_server.go +++ b/internal/port/consumer_watermill_server.go @@ -9,11 +9,12 @@ import ( ) type ServerWatermillConsumer struct { - svc *app.ServerService - subscriber message.Subscriber - logger watermill.LoggerAdapter - marshaler watermillmsg.Marshaler - cmdSyncTopic string + svc *app.ServerService + subscriber message.Subscriber + logger watermill.LoggerAdapter + marshaler watermillmsg.Marshaler + cmdSyncTopic string + eventServerSyncedTopic string } func NewServerWatermillConsumer( @@ -22,18 +23,26 @@ func NewServerWatermillConsumer( logger watermill.LoggerAdapter, marshaler watermillmsg.Marshaler, cmdSyncTopic string, + eventServerSyncedTopic string, ) *ServerWatermillConsumer { return &ServerWatermillConsumer{ - svc: svc, - subscriber: subscriber, - logger: logger, - marshaler: marshaler, - cmdSyncTopic: cmdSyncTopic, + svc: svc, + subscriber: subscriber, + logger: logger, + marshaler: marshaler, + cmdSyncTopic: cmdSyncTopic, + eventServerSyncedTopic: eventServerSyncedTopic, } } func (c *ServerWatermillConsumer) Register(router *message.Router) { router.AddNoPublisherHandler("ServerConsumer.sync", c.cmdSyncTopic, c.subscriber, c.sync) + router.AddNoPublisherHandler( + "ServerConsumer.syncConfigAndInfo", + c.eventServerSyncedTopic, + c.subscriber, + c.syncConfigAndInfo, + ) } func (c *ServerWatermillConsumer) sync(msg *message.Message) error { @@ -56,3 +65,24 @@ func (c *ServerWatermillConsumer) sync(msg *message.Message) error { return c.svc.Sync(msg.Context(), payload) } + +func (c *ServerWatermillConsumer) syncConfigAndInfo(msg *message.Message) error { + var rawPayload watermillmsg.ServerSyncedEventPayload + + if err := c.marshaler.Unmarshal(msg, &rawPayload); err != nil { + c.logger.Error("couldn't unmarshal payload", err, watermill.LogFields{ + "handler": message.HandlerNameFromCtx(msg.Context()), + }) + return nil + } + + payload, err := domain.NewServerSyncedEventPayload(rawPayload.Key, rawPayload.URL, rawPayload.VersionCode) + if err != nil { + c.logger.Error("couldn't construct domain.ServerSyncedEventPayload", err, watermill.LogFields{ + "handler": message.HandlerNameFromCtx(msg.Context()), + }) + return nil + } + + return c.svc.SyncConfigAndInfo(msg.Context(), payload) +}