Branching zones G9b: stop persisting current_room / room_seq_json

The two legacy columns are no longer needed at runtime. CurrentRoom is
derived from len(VisitedNodes)-1 on read (lockstep with what the
dual-write era stored), and RoomSeq is a transient in-memory field
populated only when a fresh run is started.

- INSERT, SELECT, and UPDATE statements drop the two columns. The
  schema still carries them — they retire in G9c.
- scanZoneRun derives CurrentRoom and falls back to a linear-derived
  CurrentNode only if a row predates the G4 dual-write deploy.
- markRoomCleared rewritten to walk the registered graph (first
  outgoing edge / dead-end completion). Tests that use it as an
  end-to-end run driver continue to pass.
- advanceZoneRunNode drops its current_room dual-write.
- adventure_activity_unified reads visited_nodes for the daily
  "X/N rooms" progress fragment.
- Camp boss-room test pivots to setting current_node directly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
prosolis
2026-05-09 17:21:33 -07:00
parent 103cf30987
commit a5c0a83e2a
4 changed files with 69 additions and 51 deletions

View File

@@ -1,6 +1,7 @@
package plugin
import (
"encoding/json"
"fmt"
"time"
@@ -78,9 +79,10 @@ func loadAdvDailyActivity(date string) (map[id.UserID][]AdvDailyActivity, error)
}
rows.Close()
// 2. dnd_zone_run — rows touched today.
// 2. dnd_zone_run — rows touched today. Progress count is derived
// from len(visited_nodes) — current_room retired in G9.
rows, err = d.Query(`
SELECT user_id, zone_id, current_room, total_rooms, abandoned,
SELECT user_id, zone_id, visited_nodes, total_rooms, abandoned,
boss_defeated, completed_at, last_action_at
FROM dnd_zone_run
WHERE last_action_at >= ? AND last_action_at < DATE(?, '+1 day')
@@ -91,16 +93,23 @@ func loadAdvDailyActivity(date string) (map[id.UserID][]AdvDailyActivity, error)
for rows.Next() {
var (
uid, zoneID string
currentRoom, totalRooms int
visitedJSON string
totalRooms int
abandoned, bossDefeated int
completedAt *time.Time
lastAction time.Time
)
if err := rows.Scan(&uid, &zoneID, &currentRoom, &totalRooms,
if err := rows.Scan(&uid, &zoneID, &visitedJSON, &totalRooms,
&abandoned, &bossDefeated, &completedAt, &lastAction); err != nil {
rows.Close()
return nil, fmt.Errorf("zone run scan: %w", err)
}
var visited []string
_ = json.Unmarshal([]byte(visitedJSON), &visited)
currentRoom := len(visited) - 1
if currentRoom < 0 {
currentRoom = 0
}
userID := id.UserID(uid)
zoneDef := zoneOrFallback(ZoneID(zoneID))