diff --git a/scripts/backfill_customer_hints.py b/scripts/backfill_customer_hints.py index a5f6f4d40..22a39b0f5 100644 --- a/scripts/backfill_customer_hints.py +++ b/scripts/backfill_customer_hints.py @@ -161,6 +161,8 @@ async def _resolve_batch( async def _run(args: argparse.Namespace) -> dict[str, object]: if args.hint_code and args.all: raise ValueError("--hint-code and --all cannot be combined") + if not args.hint_code and not args.all: + raise ValueError("one of --hint-code or --all is required") # The resolution channel itself must be configured; hierarchy inference # and verification are separately optional -- resolve_customer_hint # falls back to a flat entity when they decline, same as its own @@ -170,7 +172,7 @@ async def _run(args: argparse.Namespace) -> dict[str, object]: resolution_client = _customer_hint_resolution_client() verification_client = _relation_verification_client() hierarchy_client = _corporate_hierarchy_inference_client() - limit = 1 if args.hint_code or not args.all else args.limit + limit = 1 if args.hint_code else args.limit pool = await asyncpg.create_pool(settings.database_url, min_size=1, max_size=1) try: diff --git a/tests/test_backfill_customer_hints.py b/tests/test_backfill_customer_hints.py index b895665fa..1581c332f 100644 --- a/tests/test_backfill_customer_hints.py +++ b/tests/test_backfill_customer_hints.py @@ -27,6 +27,19 @@ def test_run_rejects_hint_code_and_all_combined() -> None: raise AssertionError("expected ValueError") +def test_run_rejects_neither_hint_code_nor_all() -> None: + # A bare invocation must not silently resolve one real hint via a live + # orchestrator call -- an operator running this with no flags almost + # certainly expected a no-op, not a real provider call. + args = argparse.Namespace(hint_code=None, all=False, limit=25, hint_timeout=120.0) + try: + asyncio.run(backfill._run(args)) + except ValueError as exc: + assert "one of --hint-code or --all is required" in str(exc) + else: + raise AssertionError("expected ValueError") + + def test_resolve_batch_counts_resolved_declined_and_failed(monkeypatch) -> None: outcomes = { "CUST-1": {"corporate_entity_id": "e-1", "entity_name": "Acme", "linked_post_count": 3,