refactor: import_item_keys no longer generates cards immediately

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Saberlve 2026-04-15 19:36:00 +08:00
parent 1f7cbc7d10
commit 9ba1668a66
2 changed files with 65 additions and 18 deletions

View File

@ -135,22 +135,28 @@ def create_app(
else: else:
item_keys = [str(value) for value in payload.item_keys] 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) 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: for item in items:
builder.build_or_update(item) items_index[item.item_key] = {
imported_keys.append(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) project_view = project_service.add_items(project_id, imported_keys)
return {"project_id": project_id, "imported_item_keys": imported_keys, "project_view": project_view} return {"project_id": project_id, "imported_item_keys": imported_keys, "project_view": project_view}

View File

@ -196,7 +196,8 @@ def test_import_state_endpoint_shows_pending_when_no_card(tmp_path: Path) -> Non
assert payload["done_count"] == 0 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()) app = create_app(make_test_config(tmp_path), llm_client=FakeLlmClient())
create_project = _route(app, "/api/projects", "POST") create_project = _route(app, "/api/projects", "POST")
import_keys = _route(app, "/api/projects/{project_id}/imports/item-keys", "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 payload["project_id"] == "thesis-ch2"
assert len(payload["items"]) == 1 assert len(payload["items"]) == 1
assert payload["items"][0]["item_key"] == "PAPER0001" assert payload["items"][0]["item_key"] == "PAPER0001"
assert payload["items"][0]["card_status"] == "done" assert payload["items"][0]["card_status"] == "pending"
assert payload["pending_count"] == 0 assert payload["pending_count"] == 1
assert payload["done_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