mirror of
https://github.com/prosolis/gogobee.git
synced 2026-07-15 16:42:41 +00:00
Drop the coop_dungeon system per migration plan §5. 11 coop_*.go files removed; cleanup_l3.go added with an idempotent per-run status-guarded UPDATE that cancels any open/active runs and refunds member contributions plus unsettled bets via EuroPlugin.Credit. Tables retained for now; schema purge deferred to a future GOGOBEE_COOP_PURGE pass. adventure.go drops !coop dispatch, coopTicker, the startup combat-lock hook, and the !coop help line. adventure_scheduler.go loses the activeCoopMemberSet skip branch and the post-reset combat-lock call. adventure_render.go drops the teaser plus the in-coop status block; replaced with a one-week morning-DM closure announcement (TODO: remove after 2026-05-16). TestPickCoopTeaserCandidate_SkipsLeader removed. go vet ./... and go test ./... clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
112 lines
3.1 KiB
Go
112 lines
3.1 KiB
Go
package plugin
|
|
|
|
import (
|
|
"log/slog"
|
|
|
|
"gogobee/internal/db"
|
|
|
|
"maunium.net/go/mautrix/id"
|
|
)
|
|
|
|
// closeAndRefundLegacyCoopRuns is the Phase L3 one-shot. On every startup
|
|
// it scans for any coop_dungeon_runs still in 'open' or 'active' status,
|
|
// refunds member contributions and unsettled bets via the wallet, and
|
|
// flips the run to 'cancelled'.
|
|
//
|
|
// Idempotent: once a run is 'cancelled' it is skipped on subsequent runs.
|
|
// The cancel UPDATE is per-run with a status-guard, so two parallel calls
|
|
// (or a crashed-then-restarted process) will not double-credit a member
|
|
// or bettor — only the writer that flips status from 'open'/'active' to
|
|
// 'cancelled' performs the refund for that run.
|
|
//
|
|
// Tables are NOT dropped here. Historical rows remain for querying; a
|
|
// future GOGOBEE_COOP_PURGE pass will drop the schema.
|
|
func closeAndRefundLegacyCoopRuns(euro *EuroPlugin) {
|
|
d := db.Get()
|
|
|
|
rows, err := d.Query(`SELECT id FROM coop_dungeon_runs WHERE status IN ('open','active')`)
|
|
if err != nil {
|
|
slog.Error("coop L3 cleanup: list runs", "err", err)
|
|
return
|
|
}
|
|
var runIDs []int
|
|
for rows.Next() {
|
|
var id int
|
|
if err := rows.Scan(&id); err != nil {
|
|
slog.Error("coop L3 cleanup: scan run id", "err", err)
|
|
continue
|
|
}
|
|
runIDs = append(runIDs, id)
|
|
}
|
|
rows.Close()
|
|
|
|
if len(runIDs) == 0 {
|
|
return
|
|
}
|
|
|
|
totalRuns, totalMembers, totalBets := 0, 0, 0
|
|
for _, runID := range runIDs {
|
|
res, err := d.Exec(`UPDATE coop_dungeon_runs
|
|
SET status = 'cancelled', completed_at = CURRENT_TIMESTAMP
|
|
WHERE id = ? AND status IN ('open','active')`, runID)
|
|
if err != nil {
|
|
slog.Error("coop L3 cleanup: cancel run", "run_id", runID, "err", err)
|
|
continue
|
|
}
|
|
n, _ := res.RowsAffected()
|
|
if n != 1 {
|
|
continue
|
|
}
|
|
totalRuns++
|
|
|
|
mRows, err := d.Query(`SELECT user_id, total_contributed
|
|
FROM coop_dungeon_members
|
|
WHERE run_id = ? AND total_contributed > 0`, runID)
|
|
if err != nil {
|
|
slog.Error("coop L3 cleanup: load members", "run_id", runID, "err", err)
|
|
} else {
|
|
for mRows.Next() {
|
|
var uid string
|
|
var amt int
|
|
if err := mRows.Scan(&uid, &amt); err != nil {
|
|
slog.Error("coop L3 cleanup: scan member", "run_id", runID, "err", err)
|
|
continue
|
|
}
|
|
if euro != nil && amt > 0 {
|
|
euro.Credit(id.UserID(uid), float64(amt), "coop_l3_cancel_refund")
|
|
totalMembers++
|
|
}
|
|
}
|
|
mRows.Close()
|
|
}
|
|
|
|
bRows, err := d.Query(`SELECT player_id, amount
|
|
FROM coop_dungeon_bets
|
|
WHERE run_id = ? AND payout IS NULL`, runID)
|
|
if err != nil {
|
|
slog.Error("coop L3 cleanup: load bets", "run_id", runID, "err", err)
|
|
} else {
|
|
for bRows.Next() {
|
|
var uid string
|
|
var amt int
|
|
if err := bRows.Scan(&uid, &amt); err != nil {
|
|
slog.Error("coop L3 cleanup: scan bet", "run_id", runID, "err", err)
|
|
continue
|
|
}
|
|
if euro != nil && amt > 0 {
|
|
euro.Credit(id.UserID(uid), float64(amt), "coop_l3_cancel_bet_refund")
|
|
totalBets++
|
|
}
|
|
}
|
|
bRows.Close()
|
|
}
|
|
}
|
|
|
|
if totalRuns > 0 {
|
|
slog.Info("coop L3 cleanup: cancelled in-flight runs",
|
|
"runs_cancelled", totalRuns,
|
|
"member_refunds", totalMembers,
|
|
"bet_refunds", totalBets)
|
|
}
|
|
}
|