adventure: drain the actions a player asked for from the web

Pete now records two verbs an owner can ask for: pull out of a run, and
take today's bout against the Siege. This is the game-side loop that
answers them, modelled on the equip poller down to the applied-order
ledger, because neither action is idempotent: replaying an extraction
would end a run they had resumed, and replaying a bout would spend a day
they never got back.

The web verbs run the game's own paths, not lookalikes. !extract and
!adventure worldboss fight are now thin command framing over
performExtraction and takeSiegeBout, which both take the per-user lock,
so a click and a command race each other exactly as two commands do. A
web extraction still DMs the whole party, still writes the log line, and
still resumes for seven days.

Claude-Session: https://claude.ai/code/session_012bxpQQJDjC1mTtLN3VVtBQ
This commit is contained in:
prosolis
2026-07-24 18:55:52 -07:00
parent d6136d39d9
commit fff2aa79d0
7 changed files with 581 additions and 30 deletions
+14
View File
@@ -1845,6 +1845,20 @@ CREATE TABLE IF NOT EXISTS equip_applied_orders (
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- The web ACTION queue's idempotency ledger — the same job as the table above,
-- for the verbs that play the game rather than dress the character (extract, a
-- Siege bout). Its own table because the two queues have their own guid spaces
-- and their own poll loops, and a shared ledger would make a bug in one able to
-- silence the other. The stakes are higher here than for equip: a replayed
-- extraction ends a run the player resumed, and a replayed bout spends a day the
-- player has not been given back.
CREATE TABLE IF NOT EXISTS adv_applied_orders (
guid TEXT PRIMARY KEY,
status TEXT NOT NULL, -- the terminal verdict we filed, replayed on re-offer
detail TEXT NOT NULL DEFAULT '',
applied_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
);
-- Babysitting Service
CREATE TABLE IF NOT EXISTS adventure_babysit_log (
id INTEGER PRIMARY KEY AUTOINCREMENT,