diff --git a/src/zotero_kb/api.py b/src/zotero_kb/api.py index 30e346c..c95bdc2 100644 --- a/src/zotero_kb/api.py +++ b/src/zotero_kb/api.py @@ -135,22 +135,28 @@ def create_app( else: item_keys = [str(value) for value in payload.item_keys] - project_payload = _read_json(project_file) - llm_payload = project_payload.get("llm", {}) - try: - resolved_client = llm_client or create_card_generation_client( - str(llm_payload.get("provider", "deterministic")), - str(llm_payload.get("model", "deterministic")), - ) - except ValueError as exc: - raise HTTPException(status_code=400, detail=str(exc)) from exc - - builder = CardBuilder(config.workspace_dir, resolved_client) items = reader.read_items(item_keys) - imported_keys = [] + + # Write item metadata to items.json without generating cards + items_index_path = config.workspace_dir / "library" / "index" / "items.json" + items_index = project_service._read_json(items_index_path) + for item in items: - builder.build_or_update(item) - imported_keys.append(item.item_key) + items_index[item.item_key] = { + "item_key": item.item_key, + "title": item.title, + "creators": item.creators, + "year": item.year, + "item_type": item.item_type, + "abstract": item.abstract, + "tags": item.tags, + "collection_paths": item.collection_paths, + "attachment_status": "ok" if item.attachment_texts else "missing", + } + + project_service._write_json(items_index_path, items_index) + + imported_keys = [item.item_key for item in items] project_view = project_service.add_items(project_id, imported_keys) return {"project_id": project_id, "imported_item_keys": imported_keys, "project_view": project_view} diff --git a/tests/test_api.py b/tests/test_api.py index bd0c644..7acede6 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -196,7 +196,8 @@ def test_import_state_endpoint_shows_pending_when_no_card(tmp_path: Path) -> Non assert payload["done_count"] == 0 -def test_import_state_endpoint_shows_done_when_card_exists(tmp_path: Path) -> None: +def test_import_state_endpoint_shows_pending_after_import(tmp_path: Path) -> None: + """After import_item_keys, card_status should be pending (cards generated separately).""" app = create_app(make_test_config(tmp_path), llm_client=FakeLlmClient()) create_project = _route(app, "/api/projects", "POST") import_keys = _route(app, "/api/projects/{project_id}/imports/item-keys", "POST") @@ -217,6 +218,46 @@ def test_import_state_endpoint_shows_done_when_card_exists(tmp_path: Path) -> No assert payload["project_id"] == "thesis-ch2" assert len(payload["items"]) == 1 assert payload["items"][0]["item_key"] == "PAPER0001" - assert payload["items"][0]["card_status"] == "done" - assert payload["pending_count"] == 0 - assert payload["done_count"] == 1 + assert payload["items"][0]["card_status"] == "pending" + assert payload["pending_count"] == 1 + assert payload["done_count"] == 0 + + +def test_import_item_keys_does_not_generate_cards(tmp_path: Path) -> None: + """import_item_keys should only register items, not generate cards.""" + config = make_test_config(tmp_path) + config.bridge_file.unlink() + app = create_app(config, llm_client=FakeLlmClient()) + create_project = _route(app, "/api/projects", "POST") + import_keys = _route(app, "/api/projects/{project_id}/imports/item-keys", "POST") + + create_project( + CreateProjectRequest( + project_id="thesis-ch2", + name="Thesis Chapter 2", + llm_provider="openai", + llm_model="gpt-5-mini", + ) + ) + + import_keys("thesis-ch2", {"item_keys": ["PAPER0001"]}) + + # Verify item was added to selected-items.json + selected_items_path = tmp_path / "workspace" / "projects" / "thesis-ch2" / "selected-items.json" + selected_items = json.loads(selected_items_path.read_text(encoding="utf-8")) + assert "PAPER0001" in selected_items + + # Verify item metadata was written to items.json + items_index_path = tmp_path / "workspace" / "library" / "index" / "items.json" + items_index = json.loads(items_index_path.read_text(encoding="utf-8")) + assert "PAPER0001" in items_index + assert items_index["PAPER0001"]["title"] == "Card Pipelines for Research Writing" + + # Verify NO card was generated (cards.json should not have PAPER0001) + cards_index_path = tmp_path / "workspace" / "library" / "index" / "cards.json" + if cards_index_path.exists(): + cards_index = json.loads(cards_index_path.read_text(encoding="utf-8")) + assert "PAPER0001" not in cards_index + else: + # File not existing means no cards were generated, which is expected + pass