Files
gogobee/internal/plugin/cleanup_l5.go
prosolis c0f03a41b5 Adv 2.0 L5 close-out: loader rewire + adventure_characters purge gate
Rewires loadAdvCharacter / createAdvCharacter to source from player_meta,
drops every legacy-table fallback in the loadXxxState helpers, and adds a
GOGOBEE_LEGACY_PURGE=1 gate to drop the now-cold adventure_characters
table. Schema CREATE removed and column migrations tolerate the missing
table so the purge stays sticky across reboots.

§7.4 of the migration plan is reconciled to document that
player_meta.combat_level stays — combat_stats.go consumes it via the
overlay and is shared infrastructure, not legacy.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:25:23 -07:00

41 lines
1.3 KiB
Go

package plugin
import (
"log/slog"
"os"
"gogobee/internal/db"
)
// purgeLegacyAdvCharacterTable drops the `adventure_characters` table when
// the operator opts in via GOGOBEE_LEGACY_PURGE=1. Phase L5 close-out: the
// table has been frozen since L5h (saveAdvCharacter fans out into player_meta
// only), and the loader rewire moved every read off it. This is the final
// step.
//
// The pre-D&D rollback snapshot table (`adventure_characters_pre_dnd`) is
// preserved — it's a separate insurance copy and a future
// `GOGOBEE_PRE_DND_PURGE=1` pass can drop it once the soak window expires.
//
// Idempotent: skips silently if the table is already gone (or never existed
// on a fresh install).
func purgeLegacyAdvCharacterTable() {
if os.Getenv("GOGOBEE_LEGACY_PURGE") != "1" {
return
}
d := db.Get()
var name string
err := d.QueryRow(
`SELECT name FROM sqlite_master WHERE type='table' AND name='adventure_characters'`,
).Scan(&name)
if err != nil {
// sql.ErrNoRows or any scan error → nothing to drop.
return
}
if _, err := d.Exec(`DROP TABLE adventure_characters`); err != nil {
slog.Error("L5 purge: drop adventure_characters failed", "err", err)
return
}
slog.Warn("L5 purge: adventure_characters table dropped (GOGOBEE_LEGACY_PURGE=1)")
}