RolloverDailyRP now locks the guild row with SELECT FOR UPDATE and
re-checks rp_reset_at inside the transaction, so concurrent callers
cannot double-rollover and zero out freshly donated RP.
Gacha stepup entry-type check is now skipped when the row was already
deleted as stale, avoiding a redundant DELETE on step 0.
Gacha stepup progress now resets when queried after the most recent
noon boundary, using a new created_at column on gacha_stepup.
Guild member rp_today rolls into rp_yesterday lazily when members are
enumerated after noon, using a new rp_reset_at column on guilds.
Both follow the established lazy-reset pattern from the cafe handler.
The handler was a stub that discarded pkt.NumUsers. Now it
looks up the player's guild and atomically accumulates the
count via a new weekly_bonus_users column on the guilds table.
sqlx.Open was called with no pool configuration, risking PostgreSQL
connection exhaustion under load. Set max open/idle conns and lifetimes.
CreatePost INSERT + soft-delete UPDATE were two separate queries with
no transaction, risking inconsistent state on partial failure.
CollectAdventure used SELECT then UPDATE without a lock, allowing
concurrent guild members to double-collect. Now uses SELECT FOR UPDATE
within a transaction.
Eliminate 18 direct s.server.db calls from handlers_items.go,
handlers_distitem.go, and handlers_session.go by moving queries into
dedicated repository types.
New repositories:
- StampRepository (7 methods, stamps table)
- DistributionRepository (4 methods, distribution/distribution_items)
- SessionRepository (4 methods, sign_sessions/servers)
Also adds ClearTreasureHunt and InsertKillLog to GuildRepository,
which already owns those tables for read operations.
Move ~39 inline SQL queries from six handler files into repo_guild.go,
consolidating all guild-related DB access (posts, alliances, adventures,
treasure hunts, meals, kill logs, scouts) behind GuildRepository methods.
Handler files now contain only packet serialization, business logic, and
ACK responses with no direct database calls.
Per anti-patterns.md item #9, guild-related SQL was scattered across
~15 handler files with no repository abstraction. Following the same
pattern established by CharacterRepository, this centralizes all
guilds, guild_characters, and guild_applications table access into a
single GuildRepository (~30 methods).
guild_model.go and handlers_guild_member.go are trimmed to types and
pure business logic only. All handler files (guild_*, festa, mail,
house, mercenary, rengoku) now call s.server.guildRepo methods
instead of direct DB queries or methods on domain objects.