Add a game by hand: the fourth curation store

BGG wants base game and expansion as separate collection entries, but
a box that stores its expansion's bits shows one spine to the camera —
the hidden half was unreachable. "add a game" on the Titles page
records an entry in data/title_additions.json (committed, like every
curation store), joined into every rebuild BEFORE edits and dedupe: so
corrections apply to it, a later photo sighting of the same game
merges instead of duplicating (photo provenance wins), and re-adding
an existing title is a no-op. Photo-less lines show an "added by hand"
chip where their photo links would be; from resolve onward they are
ordinary titles.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
This commit is contained in:
Eric Wagoner
2026-08-05 19:13:49 -04:00
co-authored by Claude Fable 5
parent 7b6ea90934
commit 90e75daf98
9 changed files with 216 additions and 16 deletions
+21
View File
@@ -1139,3 +1139,24 @@ def test_local_decision_via_web(tmp_path):
saved = {r["title_raw"]: r for r in read_matches(cfg.matches_path)}
assert saved["Mystery"]["match_status"] == "local"
assert state["summary"]["local"] == 1
def test_add_title_by_hand(tmp_path):
web, cfg = make_client(tmp_path)
res = web.post(
"/api/add-title",
json={"title": "Wingspan: European Expansion", "publisher": "Stonemaier Games"},
)
assert res.status_code == 200
line = next(
c
for c in res.json()["catalog"]
if c["title_raw"] == "Wingspan: European Expansion"
)
assert line["status"] == "awaiting_resolve"
assert line["photos"] == [] # no photo — shown as added by hand
assert web.post("/api/add-title", json={"title": " "}).status_code == 400
assert (
web.post("/api/add-title", json={"title": "X", "year": "199Y"}).status_code
== 400
)