Skip to content

feat: implement directory tree read model and API#155

Merged
YusukeHirao merged 3 commits into
feature/impl-new-dbfrom
feature/107-directory-tree-read-model
Jul 3, 2026
Merged

feat: implement directory tree read model and API#155
YusukeHirao merged 3 commits into
feature/impl-new-dbfrom
feature/107-directory-tree-read-model

Conversation

@YusukeHirao

Copy link
Copy Markdown
Member

Summary

  • Add viewer_directory_nodes / viewer_directory_pages read-model tables and buildDirectoryTreeRows (pure builder, reuses buildViewerReadModel's existing sourceRows, no second pages SELECT).
  • Add getDirectoryTree / listDirectoryChildren / listDirectoryPages query functions and wire them into the viewer as GET /api/directory-tree, /api/directory-tree/children, /api/directory-tree/pages.
  • root_key is host-based, excluding hosts with zero internal pages (avoids pointless single-page trees for external link targets).
  • Directory/page boundary resolved via trailing slash (/blog/2024/post-1 and /blog/2024/ land on the same node).
  • has_children reflects only child directories, not direct pages, matching the tree UI's actual expand affordance.
  • isViewerReadModelCurrent (not just hasViewerReadModel) guards all three query functions, since this feature has no legacy fallback path.
  • vdn_path_depth index leads with path_sort_key so getDirectoryTree's depth <= 3 filter stays a residual check instead of forcing a TEMP B-TREE sort — verified via EXPLAIN QUERY PLAN.
  • Bumps VIEWER_READ_MODEL_SCHEMA_VERSION 3 → 4.

Closes #107. Frontend UI is intentionally out of scope (no companion issue existed yet; to be filed separately).

Test plan

  • yarn test — 2351 passed, 5 skipped
  • yarn lint — 0 errors (eslint/stylelint/markuplint/prettier/textlint/cspell all clean)
  • Type-checked query/viewer/cli/mcp-server directly via tsc (sandbox's yarn build silently no-ops on tsc — verified separately)
  • EXPLAIN QUERY PLAN confirms vdn_path_depth avoids a temp b-tree sort for getDirectoryTree's query
  • Route-level integration tests cover: initial tree (depth ≤ 3), dynamic children expansion beyond depth 3, cursor pagination to exhaustion, missing-nodeId 400s, and empty response when the read model isn't built

🤖 Generated with Claude Code

Add design notes for viewer_directory_nodes/viewer_directory_pages —
host-based root_key exclusion rule, trailing-slash directory/page
boundary, has_children semantics, and the index-column-order fix
(vdn_path_depth) found via EXPLAIN QUERY PLAN.
Add viewer_directory_nodes/viewer_directory_pages tables plus
getDirectoryTree/listDirectoryChildren/listDirectoryPages so the
viewer can browse the crawled URL space as a directory tree without
splitting/counting URL strings at request time (issue #107).

- buildDirectoryTreeRows: pure builder reusing buildViewerReadModel's
  existing sourceRows, no second pages SELECT. Groups nodes by host,
  excludes hosts with zero internal pages, and resolves the
  directory/page boundary via trailing slash.
- has_children reflects only child directories (not direct pages),
  since the tree UI only ever expands into subdirectories.
- getDirectoryTree/listDirectoryChildren/listDirectoryPages guard on
  isViewerReadModelCurrent (not just hasViewerReadModel) because this
  feature has no legacy fallback path.
- vdn_path_depth leads with path_sort_key so the depth<=3 filter stays
  a residual check instead of forcing a temp b-tree sort, verified via
  EXPLAIN QUERY PLAN.
- Bumps VIEWER_READ_MODEL_SCHEMA_VERSION 3 -> 4 to force a rebuild.
Register GET /api/directory-tree, /api/directory-tree/children, and
/api/directory-tree/pages, wiring @nitpicker/query's new directory
tree functions into the viewer's Hono app (issue #107).
@YusukeHirao YusukeHirao merged commit 2769876 into feature/impl-new-db Jul 3, 2026
8 of 10 checks passed
@YusukeHirao YusukeHirao deleted the feature/107-directory-tree-read-model branch July 3, 2026 06:37
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