The quiet successes learn to speak

Eric pressed "pick edition", the button vanished, and nothing said
where the ballot went; he edited a matched title and its row silently
entered re-resolve limbo until a resolve run nobody knew was owed. Now:
pick edition banners a link to the Review ballot it created; saving an
edit banners the re-queue contract with an inline "run resolve now"
button; and the waiting chip says "awaiting resolve" (its old label,
"awaiting BGG", described the token era). Data-wise this commit also
carries the re-resolved IMG_4504 Wiz-War copy — whose 2012 year cue
correctly matched NO version of game 589, the breadcrumb that it
belongs to the FFG entry (104710).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqdWSz9g
This commit is contained in:
Eric Wagoner
2026-08-05 21:16:16 -04:00
co-authored by Claude Fable 5
parent ab28476741
commit edb72514f4
6 changed files with 36 additions and 10 deletions
+5 -5
View File
File diff suppressed because one or more lines are too long
+8
View File
@@ -87,5 +87,13 @@
"match": "BOTANY EXPANSION PERILOUS PERFUMES POISONOUS, CARNIVOROUS, PARASITIC AND BIZARRE PLANTS",
"title_raw": "BOTANY: PERILOUS PERFUMES",
"confidence": "high"
},
{
"match": "WIZ-WAR",
"photos": [
"IMG_4504.jpeg"
],
"year_hint": 2012,
"confidence": "high"
}
]
+1 -1
View File
@@ -355,7 +355,7 @@
"confidence": "high",
"publisher_hint": "Fantasy Flight Games",
"edition_hint": "",
"year_hint": null,
"year_hint": 2012,
"language_hint": "English",
"art_notes": "Dark spine with wizard/warrior artwork, sepia tones",
"source_photos": [
+1 -1
View File
@@ -152,7 +152,7 @@ function wireDismiss(root, done) {
/* Status chip for a catalog entry — shared by the catalog and photo pages. */
function statusChip(c) {
if (c.status === "awaiting_resolve") return `<span class="chip wait">awaiting BGG</span>`;
if (c.status === "awaiting_resolve") return `<span class="chip wait">awaiting resolve</span>`;
if (c.status === "auto" || c.status === "approved") return `<span class="chip ok">${esc(c.status)}</span>`;
if (c.status === "rejected") return `<span class="chip no">rejected</span>`;
if (c.status === "local") return `<span class="chip open">local — not on BGG</span>`;
+1 -1
View File
@@ -47,7 +47,7 @@
<h2 id="statuses">What the status chips mean</h2>
<div class="card prose">
<p><span class="chip wait">awaiting BGG</span> extracted, not yet matched — usually waiting on the BGG API token.</p>
<p><span class="chip wait">awaiting resolve</span> extracted (or re-queued by an edit) but not yet matched — run <b>resolve</b> from the Pipeline page.</p>
<p><span class="chip ok">auto</span> matched confidently, no review needed. <span class="chip ok">approved</span> you picked the match yourself.</p>
<p><span class="chip open">ambiguous</span> several plausible games — needs your pick on Review. <span class="chip open">unmatched</span> nothing plausible found — enter a BGG id or re-search on Review.</p>
<p><span class="chip merged">merged</span> two reads judged to be the same physical box; the merge is veto-able on Review. <span class="chip merged">copy</span> one copy of a title you split.</p>
+20 -2
View File
@@ -138,7 +138,12 @@ document.getElementById("catbody").addEventListener("click", async e => {
source_photos: pe.dataset.photos,
row_ix: pe.dataset.rowix === "" ? null : Number(pe.dataset.rowix),
});
if (res) { GATE.reset(); refresh().catch(() => {}); }
if (res) {
showBanner(`<div class="banner">edition ballot ready for
<b>${esc(pe.dataset.title)}</b> —
<a href="/review#editions">pick it in Review</a></div>`);
GATE.reset(); refresh().catch(() => {});
}
return;
}
const ok = e.target.closest("button.confirmread");
@@ -205,7 +210,20 @@ document.getElementById("catbody").addEventListener("submit", async e => {
EDITING = null; render(); return;
}
const res = await apiPost("/api/edit-title", body);
if (res) { EDITING = null; GATE.reset(); refresh().catch(() => {}); }
if (res) {
EDITING = null; GATE.reset(); refresh().catch(() => {});
// an edit re-queues any matched row: without a resolve run the line
// sits "awaiting resolve" — say so, and offer the run right here
showBanner(`<div class="banner">saved — a previously matched title
re-matches on the next resolve run.
<button id="resolvenow">run resolve now</button></div>`);
const btn = document.getElementById("resolvenow");
if (btn) btn.addEventListener("click", async () => {
const r = await apiPost("/api/run/resolve");
if (r) showBanner(`<div class="banner">resolve running — progress on
the <a href="/">Pipeline</a> page; this list updates itself</div>`);
});
}
});
const addForm = document.getElementById("addform");