project_artifact_overview_click_through_bug.md 2.71 KB

name: project-artifact-overview-click-through-bug description: Investigation findings for the "Planner 产出总览" list-item click-through bug (frontend/app.js), needed by whoever writes the SDD/benchmark content for this task metadata:

type: project

Investigated 2026-08-04 for the "Planner 产出总览面板列表项点击无反应" bug-fix task (graph_manifest planned same session). Root cause is real and narrower than it first looks — three separate gaps, not one:

  1. renderArtifactSummaryList() (frontend/app.js:1344) renders bare <li> with no data-artifact-id and no click handler — confirmed, matches the task's stated root cause.
  2. The router (frontend/app.js:77-132, routes object + render()) does exact-string lookup on window.location.hash (routes[hash]), with only two regex-based dynamic routes today: TASK_DETAIL_RE (#/tasks/:id) and SKILL_AUDIT_RE (#/skills/:id/audit). There is no query-string parsing anywhere in the router — a hash like #/artifacts?artifact_id=xxx would fail routes[hash] and both regexes and fall through to "Not found". Fixing this bug requires extending routing (either a new #/artifacts/:id-style dynamic route matched the same way as TASK_DETAIL_RE, or adding query-string stripping/parsing to render() before route lookup) — it is not just a matter of adding an href.
  3. mountArtifactBrowser() (frontend/app.js:1582) already has the exact mechanism needed to display a specific artifact once you have its id — showPreview(artifactId) sets selectedArtifactId and fetches /api/artifacts/:id — but it is only ever invoked from a click on li[data-artifact-id] inside refreshList(), never from a URL param. The comment at app.js:1353-1356 ("v_artifact_browser and v_task_board don't parse URL query params today ... out of scope") was written about the "查看全部" link specifically (intentionally unfiltered) — it is not evidence that per-item deep-linking is already supported or was rejected; don't misread it as covering this case.

How to apply: when writing the SDD for this task, the technical design must cover (a) adding data-artifact-id + click → hash navigation in renderArtifactSummaryList, (b) a route-level change (new dynamic route or hash query-parsing) so #/artifacts can carry an artifact id, and (c) mountArtifactBrowser reading that id on mount and calling the existing showPreview()/refreshList() flow to preselect it — reusing c_artifact_get / GET /api/artifacts/:artifact_id as-is, no new content-preview logic. The "查看全部" links (app.js:1387-1390) must keep pointing at plain #/artifacts / #/tasks — do not add the id param to those.