Skip to content

feat(ensapi): refactor domain name queries onto materialized canonical fields#2125

Merged
lightwalker-eth merged 16 commits into
mainfrom
feat/domain-name-queries
May 18, 2026
Merged

feat(ensapi): refactor domain name queries onto materialized canonical fields#2125
lightwalker-eth merged 16 commits into
mainfrom
feat/domain-name-queries

Conversation

@shrugs
Copy link
Copy Markdown
Member

@shrugs shrugs commented May 15, 2026

Reviewer Focus (Read This First)

  • the new filterByNameIn / filterByNameStartsWith layers — these replace the upward recursive CTE in filterByName with single-column lookups on the materialized canonicalName
  • the DomainsNameFilter @oneOf shape on Query.domains / Account.domains / Registry.domains / Domain.subdomains
  • DomainCanonical.path now reads from the materialized canonicalPath column instead of the dataloader-backed reverse CTE — canonicalPath loader and getCanonicalPath are deleted.

Problem & Motivation

  • where: { name: String } did partial-prefix matching via an upward recursive CTE that walked the canonical-edge agreement (registry.canonicalDomainIddomain.subregistryId) once per query — expensive, and the only path to exact-match was prefix sugar that didn't actually constrain to exact.
  • DomainCanonical.path walked the same reverse traversal per-Domain via a dataloader.
  • post feat: materialize Domain.canonical{Name,LabelHashPath,Node} #2101 materialized Domain.canonicalName / canonicalLabelHashPath / canonicalNode; this PR adds the remaining canonicalPath (head-first DomainId array) and canonicalDepth, and replaces the runtime CTEs with column reads.

What Changed (Concrete)

  1. DomainsWhereInput.name (and the equivalents on Account/Registry/Subdomains) goes from StringDomainsNameFilter (@oneOf of starts_with | eq | in).
  2. filterByName becomes a thin dispatcher. New filterByNameStartsWith (ILIKE on canonicalName) and filterByNameIn (inArray(canonicalName, names), with empty-array short-circuit to WHERE false).
  3. DomainsOrderBy gains DEPTH (orders by canonicalDepth). name: { starts_with } surfaces defaultOrderBy: "DEPTH" so typeahead naturally surfaces shorter names first.
  4. DomainCanonical.depth: Int! added. DomainCanonical.path now reads from materialized canonicalPath; getCanonicalPath + canonicalPath dataloader deleted. Path direction is now root→leaf inclusive (matches canonicalLabelHashPath); previous comment said leaf→root.
  5. domainsBase drops the label join — sortableLabel is replaced by canonicalName / canonicalDepth passed through from the materialized Domain columns.
  6. canonicality-db-helpers.ts: materializes canonicalPath and canonicalDepth on the canonical write path and in the cascade CTE alongside the existing canonicalLabelHashPath / canonicalName.
  7. ENSDb docs (database-schemas, sdk, sql, integration-options): document the full canonical-* column set with index choices and switch examples from WHERE type = ... to WHERE canonical_name = ... to model the intended query shape.
  8. @pothos/plugin-zod added for DomainsNameFilter.in maxLength: 100 validation.

Design & Planning

  • the materialized columns landed in feat: materialize Domain.canonical{Name,LabelHashPath,Node} #2101; this PR is the consumer-side cleanup. no separate design doc.

  • alternatives considered: backwards compatibility, but ignored for this breaking change

  • Planning artifacts: none beyond the changesets in this PR

  • Reviewed / approved by: none pre-merge

Self-Review

-n/a

Cross-Codebase Alignment

  • search terms: sortableLabel, canonicalPath, getCanonicalPath, domainsByLabelHashPath, parsePartialInterpretedName, FILTER_BY_NAME_MAX_DEPTH, where: { name
  • deferred: ENSAdmin / other in-repo consumers of where: { name: String } — not encountered in this branch; expected to be picked up via the breaking changeset.

Downstream & Consumer Impact

  • public API: breaking — where: { name: "x" }where: { name: { starts_with: "x" } } on Query.domains, Account.domains, Registry.domains, Domain.subdomains. exact-match consumers now use eq / in. enssdk generated schema + introspection regenerated. The example app (examples/enskit-react-example) is updated in-tree.
  • docs: ENSDb schema docs now describe all five canonical-* columns and their indexes; SDK and SQL usage examples switch to canonical-name lookups.
  • naming: DEPTH ordering value is new; Domain.canonical.depth is new and required (non-null). Both throw the standard Invariant(...) if the column is null on a canonical Domain.

Testing Evidence

  • new integration tests for name: { eq }, name: { in }, empty in, eq + version, and @oneOf rejection in query.integration.test.ts.

  • domain.integration.test.ts updated to assert canonical.depth matches name.split('.').length across DEVNET fixtures.

  • pagination test (test-domain-pagination.ts) updated for the new filter shape.

  • Testing performed: pnpm typecheck, pnpm lint, pnpm test --project ensapi, integration tests pass against the devnet fixture.

  • Known gaps: no perf benchmark in this PR — the simplification removes a recursive CTE per query, but the EPS impact is qualitative.

  • Reviewers reason about manually: ILIKE pattern construction (the existing TODO about LIKE-escaping is preserved verbatim).

Scope Reductions

  • no perf measurement run; baseline is the post-canonicality snapshot, and the new path is strictly less work per query.

  • Follow-ups: migrate in-repo GraphQL consumers off name: String; optionally measure the EPS / p99 delta on Query.domains typeahead.

Risk Analysis

  • relies on canonicalName / canonicalDepth / canonicalPath being correctly materialized on every canonical write path. cascade tests in feat: materialize Domain.canonical{Name,LabelHashPath,Node} #2101 cover the cascade case; the new columns ride the same code path.

  • breaking GraphQL change — any out-of-tree consumer using where: { name: "x" } will fail at parse time with a clear schema error

  • rollback: revert PR; materialized columns remain populated and harmless.

  • Risk areas: any consumer of the old where: { name } shape, including downstream ENSAdmin / ensapp / SDK users.

  • Mitigations: changeset flagged minor+breaking; new DomainCanonical.depth is non-null and will throw Invariant(...) rather than silently returning null.

  • Named owner if this causes problems: @shrugs

Pre-Review Checklist (Blocking)

  • I reviewed every line of this diff and understand it end-to-end
  • I'm prepared to defend this PR line-by-line in review
  • I'm comfortable being the on-call owner for this change
  • Relevant changesets are included (or explicitly not required)

shrugs and others added 5 commits May 11, 2026 14:26
Replace `where: { name: String }` on Query.domains, Account.domains,
Registry.domains, and Domain.subdomains with a DomainsNameFilter @OneOf
input supporting `starts_with` (prefix autocomplete, unchanged behavior),
`eq` (exact match), and `in` (exact match against a set, max 100).

Exact-match implementation (filterByNameIn) currently uses an upward
recursive CTE that walks the canonical-edge agreement and verifies the
topmost matched ancestor lives in a configured root registry. To be
replaced with a single-column lookup on Domain.canonicalName once that
is materialized.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shrugs shrugs requested a review from a team as a code owner May 15, 2026 19:25
Copilot AI review requested due to automatic review settings May 15, 2026 19:25
@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
enskit-react-example.ensnode.io Ready Ready Preview, Comment May 18, 2026 8:45am
ensnode.io Ready Ready Preview, Comment May 18, 2026 8:45am
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped May 18, 2026 8:45am
ensrainbow.io Skipped Skipped May 18, 2026 8:45am

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 15, 2026

🦋 Changeset detected

Latest commit: 6fc3989

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 25 packages
Name Type
ensapi Major
ensindexer Major
@ensnode/ensdb-sdk Major
@ensnode/integration-test-env Major
ensadmin Major
ensrainbow Major
fallback-ensapi Major
enssdk Major
enscli Major
enskit Major
ensskills Major
@ensnode/datasources Major
@ensnode/ensrainbow-sdk Major
@ensnode/ensnode-react Major
@ensnode/ensnode-sdk Major
@ensnode/ponder-sdk Major
@ensnode/ponder-subgraph Major
@ensnode/shared-configs Major
@docs/ensnode Major
@docs/ensrainbow Major
@namehash/ens-referrals Major
@namehash/namehash-ui Major
@ensnode/ensindexer-perf-testing Major
@ensnode/enskit-react-example Patch
@ensnode/enssdk-example Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

Review Change Stack

Warning

Rate limit exceeded

@lightwalker-eth has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 57 minutes and 45 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 943db49d-c84b-41fc-b15f-073c6bedc5e3

📥 Commits

Reviewing files that changed from the base of the PR and between e96a99c and 6fc3989.

📒 Files selected for processing (4)
  • apps/ensapi/src/omnigraph-api/lib/find-domains/domain-cursor.ts
  • docs/ensnode.io/src/content/docs/docs/integrate/integration-options/ensdb.mdx
  • docs/ensnode.io/src/content/docs/docs/services/ensdb/usage/sdk.mdx
  • docs/ensnode.io/src/content/docs/docs/services/ensdb/usage/sql.mdx
📝 Walkthrough

Walkthrough

This pull request refactors ENS domain name filtering to a GraphQL DomainsNameFilter @oneOf (starts_with/eq/in), materializes canonicalPath/canonicalDepth on Domain records, adds DEPTH ordering, removes the canonical-path dataloader, updates base query layers to use canonicalName/canonicalDepth, and wires default ordering through resolvers, tests, docs, and examples.

Changes

Domain Filtering & Canonical Field Materialization

Layer / File(s) Summary
Database Schema: Canonical Fields Materialization
packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts, apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts
Adds canonicalPath and canonicalDepth columns and byCanonicalDepth index; cascade/ensure logic updated to compute and persist canonical path/depth during reconciliation.
GraphQL Input Type: DomainsNameFilter @oneOf
apps/ensapi/src/omnigraph-api/schema/domain-inputs.ts, packages/ensnode-sdk/src/omnigraph-api/example-queries.ts
Introduces DomainsNameFilter with starts_with, eq, and in modes, DOMAINS_NAME_FILTER_IN_MAX = 100, and adds DEPTH to DomainsOrderBy; updates where inputs and example queries to use the new shape.
Base Domain Query Layer: Canonical Fields
apps/ensapi/src/omnigraph-api/lib/find-domains/layers/base-domain-set.ts, apps/ensapi/src/omnigraph-api/lib/find-domains/layers/with-ordering-metadata.ts, apps/ensapi/src/omnigraph-api/lib/find-domains/types.ts
domainsBase() and selectBase() now expose canonicalName/canonicalDepth (removed sortableLabel); ordering metadata updated to use canonical fields; DomainOrderValue now includes number for DEPTH.
Name Filter Functions: Dispatcher & Specialized Filters
apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts, .../filter-by-name-starts-with.ts, .../filter-by-name-in.ts, .../layers/index.ts
Refactors name filtering into a dispatcher accepting DomainsNameFilterValue and routes to filterByNameStartsWith (ILIKE prefix + default DEPTH order) or filterByNameIn (exact single/multi matches), both matching canonicalName.
Find-Domains Resolution: Ordering Logic
apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver.ts, apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver-helpers.ts
resolveFindDomains accepts defaultOrder and resolves effective ordering as order?.by/dir ?? defaultOrder?.by/dir ?? DOMAINS_DEFAULT_ORDER_*; getOrderValueFromResult and cursor decoding use canonicalName/canonicalDepth and explicit DEPTH casting.
Resolver Wiring: Query, Account, Domain, Registry
apps/ensapi/src/omnigraph-api/schema/query.ts, apps/ensapi/src/omnigraph-api/schema/account.ts, apps/ensapi/src/omnigraph-api/schema/domain.ts, apps/ensapi/src/omnigraph-api/schema/registry.ts
All domain-list resolvers now destructure { named, defaultOrder } = filterByName(...), wrap named with ordering metadata, and forward defaultOrder into resolveFindDomains.
DomainCanonical Field: Depth & Path
apps/ensapi/src/omnigraph-api/schema/domain-canonical.ts
Adds depth field resolved from domain.canonicalDepth (with invariant checks) and changes path resolver to directly return domain.canonicalPath (no async dataloader).
Builder & Context: Plugin Setup & Dataloader Removal
apps/ensapi/package.json, apps/ensapi/src/omnigraph-api/builder.ts, apps/ensapi/src/omnigraph-api/context.ts
Adds @pothos/plugin-zod and registers ZodPlugin; removes canonicalPath dataloader from context and deletes the standalone get-canonical-path usage.
Integration Tests: Name Filter & Canonical Fields
apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts, apps/ensapi/src/omnigraph-api/schema/domain.integration.test.ts, apps/ensapi/src/test/integration/find-domains/*
Tests updated to use DomainsNameFilter (starts_with/eq/in), assert canonical.depth, update pagination fixtures and ordering assertions to include DEPTH permutations.
Documentation & Examples: Canonical Fields & Prefix Filtering
docs/ensnode.io/src/content/docs/..., examples/enskit-react-example/src/SearchView.tsx, packages/ensnode-sdk/src/omnigraph-api/example-queries.ts
Docs updated to show canonical-name queries and schema changes; React example and SDK examples updated to use name: { starts_with } and DomainsNameFilter in example variables.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly Related PRs

🐰 A rabbit hops through canonical paths,
Depth counts labels, no more SQL wraths,
Starts_with, eq, or an in-list parade—
Filters neat, and defaults now laid.
Hop on, query fast, the index bids "cheer!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 73.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly and clearly summarizes the main change: refactoring domain name queries to use materialized canonical fields instead of runtime CTEs, which is the core objective of this PR.
Description check ✅ Passed The description comprehensively covers all required sections: Summary (3 key points), Problem & Motivation, What Changed (8 concrete changes), Design & Planning, Self-Review, Cross-Codebase Alignment, Testing Evidence, and Risk Analysis. It follows the template structure and provides detailed context.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/domain-name-queries

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors ENSAPI domain-name queries onto materialized canonical columns. The previous upward recursive CTE for where: { name } and the dataloader-backed reverse traversal for DomainCanonical.path are replaced with single-column reads against canonicalName / canonicalDepth / canonicalPath. Adds a DomainsNameFilter @oneOf GraphQL input (starts_with / eq / in), a DEPTH ordering enum value, materializes the new canonicalPath and canonicalDepth columns on the canonical write path, and updates docs and example queries accordingly.

Changes:

  • Introduces DomainsNameFilter (@oneOf) replacing where: { name: String } on Query.domains, Account.domains, Registry.domains, Domain.subdomains; adds DEPTH ordering and routes starts_with to default-DEPTH ordering.
  • Adds canonicalPath and canonicalDepth materialization (initial write + cascade CTE) on Domain; replaces getCanonicalPath + canonical-path dataloader with direct column reads in DomainCanonical.path and adds DomainCanonical.depth.
  • Drops the label join in domainsBase, swaps sortableLabel for canonicalName / canonicalDepth, and updates docs, examples, integration tests, and pagination tests.

Reviewed changes

Copilot reviewed 33 out of 36 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adds @pothos/plugin-zod and incidental vitest mocker entry.
apps/ensapi/package.json Adds @pothos/plugin-zod dep.
apps/ensapi/src/omnigraph-api/builder.ts Registers ZodPlugin for input validation.
apps/ensapi/src/omnigraph-api/context.ts Removes canonicalPath dataloader and helper.
apps/ensapi/src/omnigraph-api/lib/get-canonical-path.ts Deletes the recursive-CTE path traversal.
apps/ensapi/src/omnigraph-api/schema/domain-canonical.ts Adds depth, reads path from materialized column.
apps/ensapi/src/omnigraph-api/schema/domain-inputs.ts Adds DomainsNameFilter, DEPTH enum value, switches name field to oneOf input.
apps/ensapi/src/omnigraph-api/schema/{query,domain,registry,account}.ts Threads defaultOrderBy from filterByName.
apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts Becomes thin dispatcher onto starts_with/in/eq.
apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name-starts-with.ts New ILIKE prefix on canonicalName.
apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name-in.ts New inArray(canonicalName) with empty-array short-circuit.
apps/ensapi/src/omnigraph-api/lib/find-domains/layers/{base-domain-set,with-ordering-metadata,index}.ts Drops label join; exposes canonicalName/canonicalDepth.
apps/ensapi/src/omnigraph-api/lib/find-domains/{find-domains-resolver,find-domains-resolver-helpers,types}.ts Adds DEPTH ordering / cursor cast / default-order-by plumbing.
apps/ensapi/src/omnigraph-api/schema/{query,domain}.integration.test.ts New tests for eq/in/empty/@oneOf/depth.
apps/ensapi/src/test/integration/find-domains/{domain-pagination-queries,test-domain-pagination}.ts Updates fragment + DEPTH permutations.
apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts Materializes canonicalPath and canonicalDepth (insert + cascade CTE).
packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts Adds canonicalPath, canonicalDepth columns + index.
packages/enssdk/src/omnigraph/generated/{schema.graphql,introspection.ts} Regenerated for new filter and depth/order-by.
packages/ensnode-sdk/src/omnigraph-api/example-queries.ts Updates example to new filter shape.
examples/enskit-react-example/src/SearchView.tsx Migrates to name: { starts_with }.
docs/ensnode.io/.../{database-schemas,sdk,sql,ensdb}.mdx Documents canonical-* columns and switches examples to canonical_name.
.changeset/domains-name-filter-oneof.md, .changeset/domains-orderby-depth.md Changesets for breaking filter change and DEPTH addition.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts (1)

533-536: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Refresh predicate misses stale canonical_path when parent identity changes without label-path change.

On Line 535, updates are gated by canonical_label_hash_path drift only. If a registry is reparented to a canonical parent with the same label-hash path/name but different Domain IDs, canonical_path remains stale because this row won’t update.

Proposed fix
       WHERE d.id = dt.domain_id
         AND (
           d.canonical IS DISTINCT FROM ${nextCanonical}
-          OR (${nextCanonical} AND d.canonical_label_hash_path IS DISTINCT FROM dt.new_path)
+          OR (
+            ${nextCanonical}
+            AND (
+              d.canonical_label_hash_path IS DISTINCT FROM dt.new_path
+              OR d.canonical_path IS DISTINCT FROM dt.new_path_ids
+            )
+          )
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts` around lines 533 -
536, The refresh predicate only checks d.canonical and
d.canonical_label_hash_path against nextCanonical/dt.new_path, but misses when
the computed canonical_path changes due to a parent identity change even if the
label-hash (dt.new_path) stays the same; update the WHERE clause to also trigger
when the stored canonical_path differs from the newly computed canonical path
(e.g., add a condition comparing d.canonical_path IS DISTINCT FROM
dt.new_canonical_path or the expression that builds the new canonical_path) so
rows with identical label-hash but different parent identity get refreshed
(referencing d.canonical_path, d.canonical_label_hash_path, dt.new_path,
dt.new_canonical_path, and nextCanonical).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts`:
- Around line 533-536: The refresh predicate only checks d.canonical and
d.canonical_label_hash_path against nextCanonical/dt.new_path, but misses when
the computed canonical_path changes due to a parent identity change even if the
label-hash (dt.new_path) stays the same; update the WHERE clause to also trigger
when the stored canonical_path differs from the newly computed canonical path
(e.g., add a condition comparing d.canonical_path IS DISTINCT FROM
dt.new_canonical_path or the expression that builds the new canonical_path) so
rows with identical label-hash but different parent identity get refreshed
(referencing d.canonical_path, d.canonical_label_hash_path, dt.new_path,
dt.new_canonical_path, and nextCanonical).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 64601978-789b-437f-8122-7f6a9f6e4146

📥 Commits

Reviewing files that changed from the base of the PR and between 50e22a8 and 6cc5008.

⛔ Files ignored due to path filters (3)
  • packages/enssdk/src/omnigraph/generated/introspection.ts is excluded by !**/generated/**
  • packages/enssdk/src/omnigraph/generated/schema.graphql is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (33)
  • .changeset/domains-name-filter-oneof.md
  • .changeset/domains-orderby-depth.md
  • apps/ensapi/package.json
  • apps/ensapi/src/omnigraph-api/builder.ts
  • apps/ensapi/src/omnigraph-api/context.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver-helpers.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/base-domain-set.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name-in.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name-starts-with.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/index.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/with-ordering-metadata.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/types.ts
  • apps/ensapi/src/omnigraph-api/lib/get-canonical-path.ts
  • apps/ensapi/src/omnigraph-api/schema/account.ts
  • apps/ensapi/src/omnigraph-api/schema/domain-canonical.ts
  • apps/ensapi/src/omnigraph-api/schema/domain-inputs.ts
  • apps/ensapi/src/omnigraph-api/schema/domain.integration.test.ts
  • apps/ensapi/src/omnigraph-api/schema/domain.ts
  • apps/ensapi/src/omnigraph-api/schema/query.integration.test.ts
  • apps/ensapi/src/omnigraph-api/schema/query.ts
  • apps/ensapi/src/omnigraph-api/schema/registry.ts
  • apps/ensapi/src/test/integration/find-domains/domain-pagination-queries.ts
  • apps/ensapi/src/test/integration/find-domains/test-domain-pagination.ts
  • apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts
  • docs/ensnode.io/src/content/docs/docs/integrate/integration-options/ensdb.mdx
  • docs/ensnode.io/src/content/docs/docs/services/ensdb/concepts/database-schemas.mdx
  • docs/ensnode.io/src/content/docs/docs/services/ensdb/usage/sdk.mdx
  • docs/ensnode.io/src/content/docs/docs/services/ensdb/usage/sql.mdx
  • examples/enskit-react-example/src/SearchView.tsx
  • packages/ensdb-sdk/src/ensindexer-abstract/ensv2.schema.ts
  • packages/ensnode-sdk/src/omnigraph-api/example-queries.ts
💤 Files with no reviewable changes (1)
  • apps/ensapi/src/omnigraph-api/lib/get-canonical-path.ts

Filter-supplied default ordering now carries both `by` and `dir` so a filter
can fully drive ordering when the caller doesn't pass `order`. `name:
{ starts_with }` surfaces `{ by: DEPTH, dir: ASC }` for typeahead.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 15, 2026 19:37
@vercel vercel Bot temporarily deployed to Preview – ensnode.io May 15, 2026 19:38 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 15, 2026 19:38 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 15, 2026 19:38 Inactive
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 33 out of 36 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

…erInput

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 15, 2026 19:41 Inactive
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts`:
- Around line 138-140: When deriving a child's canonicalPath and canonicalDepth,
ensure the parent invariant holds: if parentDomain is non-null then
parentDomain.canonicalPath must be non-nullish; otherwise throw or return an
explicit error instead of defaulting to [] and producing a truncated path.
Update the code around the canonicalPath and canonicalDepth construction (the
const canonicalPath: DomainId[] = [...(parentDomain?.canonicalPath ?? []),
domainId]; and the similar logic at lines handling canonicalDepth) to assert or
throw when parentDomain && parentDomain.canonicalPath == null, so callers never
silently get a malformed child path/depth.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1c255b2c-fb69-4cf8-93e3-2da74948412b

📥 Commits

Reviewing files that changed from the base of the PR and between 6cc5008 and e96a99c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (12)
  • .changeset/materialize-canonical-path.md
  • apps/ensapi/src/omnigraph-api/lib/find-domains/find-domains-resolver.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name-starts-with.ts
  • apps/ensapi/src/omnigraph-api/lib/find-domains/layers/filter-by-name.ts
  • apps/ensapi/src/omnigraph-api/schema/account.ts
  • apps/ensapi/src/omnigraph-api/schema/domain.ts
  • apps/ensapi/src/omnigraph-api/schema/query.ts
  • apps/ensapi/src/omnigraph-api/schema/registry.ts
  • apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts
  • docs/ensnode.io/src/content/docs/docs/services/ensdb/concepts/database-schemas.mdx
  • packages/enssdk/src/lib/interpreted-names-and-labels.test.ts
  • packages/enssdk/src/lib/interpreted-names-and-labels.ts
💤 Files with no reviewable changes (2)
  • packages/enssdk/src/lib/interpreted-names-and-labels.ts
  • packages/enssdk/src/lib/interpreted-names-and-labels.test.ts

Comment thread apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 15, 2026 20:34
@shrugs
Copy link
Copy Markdown
Member Author

shrugs commented May 15, 2026

@greptile review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 37 out of 40 changed files in this pull request and generated no new comments.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Copy link
Copy Markdown
Contributor

@vercel vercel Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Suggestion:

Missing invariant check for parentDomain.canonicalPath creates asymmetric validation between canonicalName and canonicalPath fields

Fix on Vercel

Comment thread apps/ensindexer/src/lib/ensv2/canonicality-db-helpers.ts
Copy link
Copy Markdown
Member

@lightwalker-eth lightwalker-eth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@shrugs Super! 🚀 Another big milestone in our roadmap!

Comment thread docs/ensnode.io/src/content/docs/docs/services/ensdb/usage/sdk.mdx Outdated
Comment thread docs/ensnode.io/src/content/docs/docs/services/ensdb/usage/sql.mdx Outdated
Comment thread docs/ensnode.io/src/content/docs/docs/integrate/integration-options/ensdb.mdx Outdated
Copilot AI review requested due to automatic review settings May 18, 2026 08:43
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 18, 2026 08:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 18, 2026 08:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 18, 2026 08:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 18, 2026 08:43 Inactive
@vercel vercel Bot temporarily deployed to Preview – admin.ensnode.io May 18, 2026 08:44 Inactive
@vercel vercel Bot temporarily deployed to Preview – ensrainbow.io May 18, 2026 08:44 Inactive
@lightwalker-eth lightwalker-eth merged commit f6ef397 into main May 18, 2026
15 of 17 checks passed
@lightwalker-eth lightwalker-eth deleted the feat/domain-name-queries branch May 18, 2026 08:44
@github-actions github-actions Bot mentioned this pull request May 18, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 37 out of 40 changed files in this pull request and generated 1 comment.

Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment on lines +2 to +5
"ensapi": minor
---

**Omnigraph (breaking)**: `where: { name }` on `Query.domains`, `Account.domains`, `Registry.domains`, and `Domain.subdomains` now takes a `DomainsNameFilter` `@oneOf` input with three modes: `starts_with` (prefix autocomplete, the previous behavior), `eq` (exact InterpretedName match — sugar for `in: [eq]`), and `in` (exact match against a set of up to 100 InterpretedNames). The old shape `where: { name: "examp" }` becomes `where: { name: { starts_with: "examp" } }`; for exact lookups use `where: { name: { eq: "vitalik.eth" } }` or `where: { name: { in: ["alice.eth", "bob.eth"] } }`. Combine with `version` to disambiguate across ENS protocol versions (e.g. `{ name: { eq: "eth" }, version: ENSv1 }` returns a single Domain).
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.

3 participants