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:
co-authored by
Claude Fable 5
parent
7b6ea90934
commit
90e75daf98
@@ -260,6 +260,62 @@ def test_removals_filter_rebuilds_photo_scoped():
|
||||
]
|
||||
|
||||
|
||||
def test_hand_added_titles_survive_rebuilds_and_merge_with_sightings(tmp_path):
|
||||
from bggpipe.extract import record_title_addition
|
||||
|
||||
cfg = Config(data_dir=tmp_path / "data", photos_dir=tmp_path / "photos")
|
||||
raw = cfg.extract_raw_dir
|
||||
raw.mkdir(parents=True)
|
||||
(raw / "a.jpg.json").write_text(
|
||||
json.dumps({"titles": [_entry("Catan", "a.jpg")], "unidentified": []})
|
||||
)
|
||||
record_title_addition(
|
||||
cfg.title_additions_path,
|
||||
{
|
||||
"title_raw": "Wingspan: European Expansion",
|
||||
"confidence": "high",
|
||||
"publisher_hint": "Stonemaier Games",
|
||||
"edition_hint": "",
|
||||
"year_hint": None,
|
||||
"language_hint": "",
|
||||
"art_notes": "",
|
||||
"source_photos": [],
|
||||
},
|
||||
)
|
||||
replay_titles(cfg)
|
||||
titles = {e["title_raw"] for e in json.loads(cfg.titles_path.read_text())}
|
||||
assert titles == {"Catan", "Wingspan: European Expansion"}
|
||||
# a later photo SEES the expansion: the sighting merges, no duplicate
|
||||
(raw / "b.jpg.json").write_text(
|
||||
json.dumps(
|
||||
{
|
||||
"titles": [
|
||||
_entry(
|
||||
"Wingspan: European Expansion",
|
||||
"b.jpg",
|
||||
publisher_hint="Stonemaier Games",
|
||||
)
|
||||
],
|
||||
"unidentified": [],
|
||||
}
|
||||
)
|
||||
)
|
||||
replay_titles(cfg)
|
||||
expansion = [
|
||||
e
|
||||
for e in json.loads(cfg.titles_path.read_text())
|
||||
if e["title_raw"] == "Wingspan: European Expansion"
|
||||
]
|
||||
assert len(expansion) == 1
|
||||
assert expansion[0]["source_photos"] == ["b.jpg"] # photo provenance won
|
||||
# re-recording the same title is a no-op
|
||||
record_title_addition(
|
||||
cfg.title_additions_path,
|
||||
{"title_raw": "WINGSPAN EUROPEAN EXPANSION", "source_photos": []},
|
||||
)
|
||||
assert len(json.loads(cfg.title_additions_path.read_text())) == 1
|
||||
|
||||
|
||||
def test_stores_roundtrip_and_replay_from_raw(tmp_path):
|
||||
cfg = Config(data_dir=tmp_path / "data", photos_dir=tmp_path / "photos")
|
||||
raw = cfg.extract_raw_dir
|
||||
|
||||
Reference in New Issue
Block a user