Skip to content

Complete per-viewport image-scan outcome: crawler wiring, query/viewer/MCP exposure - #375

Open
YusukeHirao wants to merge 4 commits into
devfrom
feat/image-scan-crawler-wiring
Open

Complete per-viewport image-scan outcome: crawler wiring, query/viewer/MCP exposure#375
YusukeHirao wants to merge 4 commits into
devfrom
feat/image-scan-crawler-wiring

Conversation

@YusukeHirao

Copy link
Copy Markdown
Member

Summary

Follow-up to #374 (which added the page_meta.image_scan_desktop/image_scan_mobile columns and --retry-failed support ahead of the @d-zero/beholder version bump). This PR completes the feature now that @d-zero/beholder@5.0.0 (reporting PageData.imageScan) is published:

  • crawler: bumps @d-zero/beholder to 5.0.0 and wires the scraped imageScan value through insertPagecomputeMainContentsDenormalizedpage_meta. The three synthetic PageData builders (fetch-destination.ts, link-to-page-data.ts, resource-to-page-data.ts) set imageScan: { desktop: null, mobile: null } since none of them run an actual scan.
  • query: PageDetail/PageListItem gain imageScanDesktop/imageScanMobile (mapped to the ImageScanOutcome name), PageMainContents gains a nested imageScan object alongside scrollHeight, and both listPages (live) and listViewerPages (read-model fast path) gain an imageScan filter — OR across the desktop/mobile columns since a page's two viewports can differ. VIEWER_READ_MODEL_SCHEMA_VERSION bumps 33 → 34 (viewer_pages gains the two columns, nullable — not defaulted to 0 like the sibling count columns, since 0 ("ok") is a real outcome here, not a placeholder).
  • viewer: adds the imageScan checklist filter to the Pages view, two new list columns, and an ImageScanBadge component (three severity tiers) shown in the page-detail main-content summary alongside scroll height.
  • mcp-server: exposes the same imageScan filter on list_pages and documents the new fields on get_page_detail.

Test plan

  • yarn lint / yarn build / yarn test all pass at the repo root
  • New database.spec.ts case exercises the real write path end-to-end (PageData.imageScaninsertPagepage_metabuild-page-query.ts's SELECT)
  • New list-pages.spec.ts / apply-viewer-pages-filters.spec.ts cases cover the imageScan filter (single value, array OR, omitted) on both the live and fast paths
  • New register-pages-route.spec.ts cases cover the /api/pages?imageScan= query param end-to-end, including dropping an invalid value from a repeated param
  • New mcp-server.spec.ts case covers list_pages's imageScan filter and get_page_detail's new fields
  • New get-image-scan-label.spec.ts / image-scan-outcome.spec.ts cases cover every outcome and the code↔outcome mapping (including the imageScanOutcomeToCode reverse mapping)
  • Storybook: ImageScanBadge (all 6 outcomes + not-attempted) and MainContentSummary (degraded/frame-lost variants) stories added

🤖 Generated with Claude Code

YusukeHirao and others added 4 commits September 10, 2026 20:17
Bumps @d-zero/beholder from 4.2.3 to 5.0.0 (breaking: PageData.imageScan
is a new required field) and wires the scraped per-viewport image-scan
outcome through insertPage's computeMainContentsDenormalized call. The
three synthetic PageData builders (fetch-destination.ts,
link-to-page-data.ts, resource-to-page-data.ts) set imageScan to
{ desktop: null, mobile: null } since none of them run an actual scan.

The database.spec.ts round-trip test now exercises the real write path
end-to-end (PageData.imageScan -> insertPage -> page_meta -> build-page-
query.ts's SELECT) instead of writing page_meta directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds page_meta.image_scan_desktop/mobile to the read side: PageDetail and
PageListItem gain imageScanDesktop/imageScanMobile (mapped to the
ImageScanOutcome name), PageMainContents gains a nested imageScan object
alongside scrollHeight, and both listPages (live) and listViewerPages
(read-model fast path) gain an imageScan filter — an OR across the
desktop/mobile columns since a page's two viewports can differ.

VIEWER_READ_MODEL_SCHEMA_VERSION bumps 33 -> 34: viewer_pages gains
image_scan_desktop/mobile as nullable columns (copied from page_meta
verbatim, not defaulted to 0 like the sibling count columns -- 0 ("ok")
is a real, distinct outcome here, not a placeholder for "unmeasured").
sanitizeRedirectSourceRow nulls both columns like every other audit
signal on a redirect-source row.

hasFilterValue is now a type predicate so a caller narrows away
`undefined` without an extra cast when building the desktop/mobile OR.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds the imageScan checklist filter to the Pages view (server-side
toImageScanOutcome parses the query param; both the fast-path
listViewerPages and live listPages routes wire it through), two new page
list columns (imageScanDesktop/Mobile), and an ImageScanBadge component
(three severity tiers: ok/scroll-height-exceeded neutral, degraded/
nav-unsettled warn, frame-lost/unknown danger) shown alongside scroll
height in the page-detail main-content summary.

get-image-scan-label.ts mirrors get-error-kind-label.ts's localised-label-
with-raw-fallback pattern; en/ja labels live under views.imageScan.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds an imageScan enum parameter to list_pages' input schema (OR across
the desktop/mobile columns, same semantics as the query-layer filter) and
documents the new imageScanDesktop/Mobile fields on get_page_detail's
description.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant