Skip to content

Update ENSDb schema definitions#1752

Open
tk-o wants to merge 13 commits intomainfrom
refactor/ensdb-schema
Open

Update ENSDb schema definitions#1752
tk-o wants to merge 13 commits intomainfrom
refactor/ensdb-schema

Conversation

@tk-o
Copy link
Contributor

@tk-o tk-o commented Mar 12, 2026

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

Database schemas

  • @ensnode/ensnode-schema package was refactored to support three distinct database schemas:
    • Ponder Schema
    • ENSIndexer Schema
    • ENSNode Schema
  • All schemas are available independently with the following import paths:
    • @ensnode/ensnode-schema/ponder
    • @ensnode/ensnode-schema/ensindexer
    • @ensnode/ensnode-schema/ensnode

ENSApi

  • ENSApi now uses read-only connections to prevent accidential writes into ENSDb.

ENSIndexer

  • ENSDb Client implementation uses the updated database schemas now.
    • Writes to ENSNode Metadata table require passing ensIndexerRef.
    • ensIndexerRef and key columns are now part of composite primary key for ENSNode Metadata table .

Why

  • We have to create for ENSNode database schema in isolation to Ponder Schema and ENSIndexer Schema.
  • We need ENSApi to be only able to read from ENSDb.

Testing

  • I ran local instances of ENSIndexer and ENSApi working together.
  • I manually created ensnode schema in local ENSDb.

Notes for Reviewer (Optional)


Pre-Review Checklist (Blocking)

  • This PR does not introduce significant changes and is low-risk to review quickly.
  • Relevant changesets are included (or are not required)

tk-o added 4 commits March 12, 2026 10:50
1) Ponder Schema - describing Ponder runtime state. 2) ENSIndexer Schema - describing ENSIndexer runtime state. 3) ENSNode Schema - describing runtime state across ENSNode services.
Replaces `makeDrizzle` DB connection helper with `makeReadOnlyDrizzle` one that is guaranteed to connect in read-only mode.
…itions.

Handle multi-tenancy in ENSNode Metadata table.
Copilot AI review requested due to automatic review settings March 12, 2026 10:06
@vercel
Copy link
Contributor

vercel bot commented Mar 12, 2026

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

Project Deployment Actions Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Mar 12, 2026 2:20pm
ensnode.io Ready Ready Preview, Comment Mar 12, 2026 2:20pm
ensrainbow.io Ready Ready Preview, Comment Mar 12, 2026 2:20pm

@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: 03fecc1

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

This PR includes changesets to release 19 packages
Name Type
@ensnode/ensnode-schema Major
ensapi Major
ensadmin Major
ensindexer Major
ensrainbow Major
fallback-ensapi 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
@docs/mintlify Major
@namehash/ens-referrals Major
@namehash/namehash-ui Major
@ensnode/integration-test-env 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
Contributor

coderabbitai bot commented Mar 12, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR adds a multi-tenant ENSNode metadata table and wiring, updates EnsDbClient to accept and scope by ensIndexerRef, converts ENSApi DB usage to a read-only Drizzle connection, and restructures the ensnode-schema package exports, build entries, and related tests/mocks.

Changes

Cohort / File(s) Summary
ENSApi read-only
apps/ensapi/src/lib/db.ts, apps/ensapi/src/lib/handlers/drizzle.ts
Switched DB init to makeReadOnlyDrizzle; parse connection string, inject read-only option, and make databaseSchema optional.
ENSIndexer client & tests
apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts, .../ensdb-client.test.ts, .../ensdb-client.mock.ts, .../singleton.ts, .../drizzle.ts
Changed EnsDbClient ctor to take ensIndexerRef; queries/upserts now include ensIndexerRef and use composite conflict target [ensIndexerRef, key]; updated tests, mocks, singleton, and drizzle factory signature.
ENSNode schema addition
packages/ensnode-schema/src/ensnode-schema/schema.ts, packages/ensnode-schema/src/ensnode-schema/index.ts
Added ENSNODE_SCHEMA_NAME, ENSNODE_SCHEMA, and new ensNodeMetadata table with columns (ensIndexerRef, key, value) and composite primary key (ensIndexerRef, key).
Package exports & indexes
packages/ensnode-schema/package.json, packages/ensnode-schema/src/index.ts, packages/ensnode-schema/src/ensindexer-schema/index.ts, packages/ensnode-schema/src/ponder-schema/index.ts
Expanded package exports into subpaths (., ./ponder, ./ensindexer, ./ensnode) and added re-export index files for subschemas.
Build & config
packages/ensnode-schema/tsconfig.json, packages/ensnode-schema/tsup.config.ts
Switched tsconfig base, set rootDir, expanded tsup entry points, and enabled dts: true.
Removed legacy aggregation
packages/ensnode-schema/src/ponder.schema.ts, packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts
Removed old aggregated re-exports and deleted legacy ensnode-metadata.schema.ts (schema migrated to new module).
Docs & changesets
packages/ensnode-schema/src/README.md, .changeset/*.md
Added README describing three schemas and added changesets noting read-only ENSApi and schema refactor.

Sequence Diagram(s)

sequenceDiagram
    participant Indexer as EnsDbClient
    participant Handler as ReadOnly Drizzle Factory
    participant DB as PostgreSQL

    Indexer->>Handler: init client (databaseUrl, ensIndexerRef, schema)
    Note right of Handler: parse DB URL + add "-c default_transaction_read_only=on"
    Indexer->>Handler: query/upsert (ensIndexerRef, key, value)
    Handler->>DB: execute SQL (WHERE ensIndexerRef = ... / ON CONFLICT (ensIndexerRef, key))
    DB-->>Handler: rows / ack
    Handler-->>Indexer: result
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped through schemas, stitched a multi-tenant key,
Each indexer finds its nest — metadata neat as can be.
API reads in whisper-mode, writes scoped to their ref,
Exports split and indexed — tidy maps for every chef.
A rabbit cheers with carrots bright, deployment’s feeling deft! 🎉

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'Update ENSDb schema definitions' directly and clearly summarizes the main change: refactoring the ENSDb schema package to support three distinct schemas.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description follows the required template with all major sections completed: Summary (3 bullets covering schema refactoring and read-only connections), Why (clear rationale for changes), Testing (local testing mentioned), Notes for Reviewer, and Pre-Review Checklist (both items checked).

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/ensdb-schema
📝 Coding Plan for PR comments
  • Generate coding plan

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
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 @ensnode/ensnode-schema to expose three independently importable schema modules (Ponder, ENSIndexer, ENSNode), updates ENSIndexer’s ENSDb client to use the new ENSNode metadata schema (with multi-tenant ensIndexerRef), and makes ENSApi’s Drizzle connection read-only to avoid accidental writes.

Changes:

  • Split @ensnode/ensnode-schema into ./ponder, ./ensindexer, and ./ensnode entrypoints (plus root re-export for compatibility).
  • Update ENSIndexer ENSDb client to read/write ENSNode metadata in the ensnode schema and scope records by (ensIndexerRef, key).
  • Update ENSApi DB initialization to use a read-only Postgres session configuration.

Reviewed changes

Copilot reviewed 15 out of 21 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pnpm-lock.yaml Adjusts ensnode-schema dependency classification (peer vs dev) and adds drizzle-orm dev dep.
packages/ensnode-schema/tsup.config.ts Builds multiple entrypoints (root, ponder-schema, ensindexer-schema, ensnode-schema) and emits DTS.
packages/ensnode-schema/tsconfig.json Switches to shared lib tsconfig and sets rootDir to resolve ambiguity.
packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts Removes old ENSNode metadata definition from the previous combined ponder schema.
packages/ensnode-schema/src/ponder.schema.ts Removes old “single combined schema” barrel export file.
packages/ensnode-schema/src/ponder-schema/schema.ts Introduces Drizzle pgSchema wrapper/constants for the Ponder sync schema.
packages/ensnode-schema/src/ponder-schema/index.ts Adds the Ponder sync-store (RPC cache) table definitions under the Ponder schema.
packages/ensnode-schema/src/index.ts Re-exports ensindexer schema from the package root for backward compatibility.
packages/ensnode-schema/src/ensnode-schema/schema.ts Introduces Drizzle pgSchema wrapper/constants for the ensnode schema.
packages/ensnode-schema/src/ensnode-schema/index.ts Adds ENSNode metadata table with composite PK (ensIndexerRef, key).
packages/ensnode-schema/src/ensindexer-schema/tokenscope.subschema.ts Adds TokenScope subschema tables.
packages/ensnode-schema/src/ensindexer-schema/subgraph.subschema.ts Adds legacy-subgraph-compatible tables/relations used by the subgraph-compatible API.
packages/ensnode-schema/src/ensindexer-schema/registrars.subschema.ts Adds registrar tracking subschema (registrar actions, lifecycle, etc).
packages/ensnode-schema/src/ensindexer-schema/protocol-acceleration.subschema.ts Adds protocol-acceleration subschema (resolver records, reverse records, resolver relations).
packages/ensnode-schema/src/ensindexer-schema/index.ts New barrel export for the ENSIndexer schema module.
packages/ensnode-schema/src/ensindexer-schema/ensv2.subschema.ts Adds ENSv2 subschema tables/relations.
packages/ensnode-schema/package.json Updates exports to new subpath modules and changes deps to peerDependencies.
apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts Updates ENSDb client to use @ensnode/ensnode-schema/ensnode, fixed schema name, and adds ensIndexerRef scoping.
apps/ensindexer/src/lib/ensdb-client/ensdb-client.test.ts Updates mocks/assertions for new schema import and new composite conflict target/values.
apps/ensapi/src/lib/handlers/drizzle.ts Renames to makeReadOnlyDrizzle and configures default read-only transactions for Postgres connections.
apps/ensapi/src/lib/db.ts Switches ENSApi DB init to makeReadOnlyDrizzle for read-only ENSDb access.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

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

You can also share your feedback on Copilot code review. Take the survey.

Copy link
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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensapi/src/lib/handlers/drizzle.ts`:
- Around line 26-30: The connection options set when calling drizzle currently
overwrite any options returned by parseIntoClientConfig(databaseUrl); update the
call that builds the connection object (the drizzle invocation) to preserve
existing options: read the existing options from
parseIntoClientConfig(databaseUrl) (via the returned object's options property)
and combine them with "-c default_transaction_read_only=on" (e.g., append with a
space if options exists, otherwise set to the read-only option alone) so that
parseIntoClientConfig, drizzle, and the connection.options value all keep
URL-provided options.

In `@apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts`:
- Around line 54-63: The constructor of EnsDbClient is repurposing the second
parameter as ensIndexerRef and hard-coding ensNodeSchema.ENSNODE_SCHEMA_NAME
into makeDrizzle, which ignores the configured database schema and breaks
multi-tenancy; update the constructor signature to accept the schema name and
the tenant ref separately (e.g., databaseUrl, databaseSchemaName, ensIndexerRef)
or ensure callers pass both values, then call makeDrizzle with databaseSchema:
databaseSchemaName (not ENSNODE_SCHEMA_NAME) and set this.ensIndexerRef from the
explicit ensIndexerRef argument; also update callers (e.g., where new
EnsDbClient(...) is invoked in singleton code) and the config model so
databaseSchemaName and ensIndexerRef are provided distinctly.

In `@packages/ensnode-schema/package.json`:
- Around line 19-23: The package.json top-level "exports" currently points to
source files ("./src/index.ts", "./src/ponder-schema/index.ts",
"./src/ensindexer-schema/index.ts", "./src/ensnode-schema/index.ts") while
"files" only includes "dist", so consumers will get broken entry points after
publish; update the top-level "exports" entries (e.g., "./": "./dist/index.js",
"./ponder": "./dist/ponder-schema/index.js", "./ensindexer":
"./dist/ensindexer-schema/index.js", "./ensnode":
"./dist/ensnode-schema/index.js") to reference built outputs, or alternatively
add "src" to the "files" array so the current "./src/*" export paths are
included in the package artifacts before publishing.
🪄 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: 87674b99-ce73-416c-bc7b-f0b7cd95ff6d

📥 Commits

Reviewing files that changed from the base of the PR and between 6dbee3e and 92afddf.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • apps/ensapi/src/lib/db.ts
  • apps/ensapi/src/lib/handlers/drizzle.ts
  • apps/ensindexer/src/lib/ensdb-client/ensdb-client.test.ts
  • apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts
  • packages/ensnode-schema/package.json
  • packages/ensnode-schema/src/ensindexer-schema/ensv2.subschema.ts
  • packages/ensnode-schema/src/ensindexer-schema/index.ts
  • packages/ensnode-schema/src/ensindexer-schema/protocol-acceleration.subschema.ts
  • packages/ensnode-schema/src/ensindexer-schema/registrars.subschema.ts
  • packages/ensnode-schema/src/ensindexer-schema/subgraph.subschema.ts
  • packages/ensnode-schema/src/ensindexer-schema/tokenscope.subschema.ts
  • packages/ensnode-schema/src/ensnode-schema/index.ts
  • packages/ensnode-schema/src/ensnode-schema/schema.ts
  • packages/ensnode-schema/src/index.ts
  • packages/ensnode-schema/src/ponder-schema/index.ts
  • packages/ensnode-schema/src/ponder-schema/schema.ts
  • packages/ensnode-schema/src/ponder.schema.ts
  • packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts
  • packages/ensnode-schema/tsconfig.json
  • packages/ensnode-schema/tsup.config.ts
💤 Files with no reviewable changes (2)
  • packages/ensnode-schema/src/ponder.schema.ts
  • packages/ensnode-schema/src/schemas/ensnode-metadata.schema.ts

Copy link
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: 6

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/ensnode-schema/src/README.md`:
- Line 20: Replace the wording "May be large in size, depending on selected ENS
Namespace and active plugins." in the README with the more concise "May be
large, depending on selected ENS Namespace and active plugins." to match the
simpler phrasing used elsewhere and improve consistency.
- Line 13: The sentence "For example, pulling production backup into local
environment in order to test production workflows in isolation." uses the
verbose phrase "in order to test"; update that sentence to use the concise
wording "to test" (i.e., change "in order to test" -> "to test") so it reads
"For example, pulling production backup into local environment to test
production workflows in isolation." Ensure only that phrase is changed and
preserve the rest of the sentence.
- Line 27: Replace the phrase "Tiny in size." in the README with the more
concise "Tiny" to match wording consistency across sections; locate the text
"Tiny in size." and update it to "Tiny" so phrasing aligns with other short
descriptors.
- Line 17: Replace the vague phrase "influenced by Ponder implementation
details" with a concise list of the specific aspects Ponder affects (for
example: "schema structure, table naming conventions, indexing metadata,
relation mappings, and migration behavior") and update the sentence mentioning
ENSIndexer so it reads something like: "Owned by an ENSIndexer instance and
influenced by Ponder implementation details (schema structure, table naming
conventions, indexing metadata, relation mappings, migration behavior)." Refer
to the term ENSIndexer and Ponder in the README to ensure clarity.
- Around line 20-22: The README's "ENSIndexer Schema" section currently
describes size and rebuild cost but omits backup guidance; update the ENSIndexer
Schema section to mirror the Ponder Schema backup recommendation by adding a
short backup/restore recommendation (e.g., take periodic snapshots or export
indexes before changing indexing logic or plugins) and explicitly advise
creating backups prior to rebuild-triggering changes such as event handler or
plugin modifications so users can restore instead of rebuilding from scratch.
- Line 10: Replace the phrase "Usually large in size, depending on selected ENS
Namespace." with a more concise wording such as "Usually large, depending on
selected ENS Namespace." — update the README sentence to remove the redundant
"in size" for improved readability.
🪄 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: a68ac681-c3ea-47d2-8dfc-ac1fcf74695a

📥 Commits

Reviewing files that changed from the base of the PR and between 92afddf and 3f7f0e8.

📒 Files selected for processing (2)
  • packages/ensnode-schema/src/README.md
  • packages/ensnode-schema/src/ponder-schema/index.ts

- Owned by Ponder app.
- Shared across ENSIndexer instances.
- Includes responses to RPC requests made by cached public clients.
- Usually large in size, depending on selected ENS Namespace.
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider more concise wording.

The phrase "large in size" could be simplified to "large" for better readability.

✍️ Proposed style improvement
-- Usually large in size, depending on selected ENS Namespace.
+- Usually large, depending on selected ENS Namespace.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Usually large in size, depending on selected ENS Namespace.
- Usually large, depending on selected ENS Namespace.
🧰 Tools
🪛 LanguageTool

[style] ~10-~10: This wording could be more concise.
Context: ...ade by cached public clients. - Usually large in size, depending on selected ENS Namespace. -...

(ADJECTIVE_IN_ATTRIBUTE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-schema/src/README.md` at line 10, Replace the phrase
"Usually large in size, depending on selected ENS Namespace." with a more
concise wording such as "Usually large, depending on selected ENS Namespace." —
update the README sentence to remove the redundant "in size" for improved
readability.

- Usually large in size, depending on selected ENS Namespace.
- Takes a long time to build.
- Backups highly recommended for sharing RPC cache across different ENSNode environments.
- For example, pulling production backup into local environment in order to test production workflows in isolation.
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider more concise wording.

The phrase "in order to test" could be simplified to "to test" for better readability.

✍️ Proposed style improvement
-  - For example, pulling production backup into local environment in order to test production workflows in isolation.
+  - For example, pulling production backup into local environment to test production workflows in isolation.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- For example, pulling production backup into local environment in order to test production workflows in isolation.
- For example, pulling production backup into local environment to test production workflows in isolation.
🧰 Tools
🪛 LanguageTool

[style] ~13-~13: Consider a more concise word here.
Context: ...roduction backup into local environment in order to test production workflows in isolation....

(IN_ORDER_TO_PREMIUM)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-schema/src/README.md` at line 13, The sentence "For example,
pulling production backup into local environment in order to test production
workflows in isolation." uses the verbose phrase "in order to test"; update that
sentence to use the concise wording "to test" (i.e., change "in order to test"
-> "to test") so it reads "For example, pulling production backup into local
environment to test production workflows in isolation." Ensure only that phrase
is changed and preserve the rest of the sentence.


## ENSIndexer Schema

- Owned by an ENSIndexer instance and also influenced by Ponder implementation details, as ENSIndexer is a Ponder app.
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Clarify what "influenced by Ponder implementation details" means.

The phrase "influenced by Ponder implementation details" is vague. Consider being more specific about what aspects are influenced (e.g., schema structure, table naming conventions, indexing metadata).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-schema/src/README.md` at line 17, Replace the vague phrase
"influenced by Ponder implementation details" with a concise list of the
specific aspects Ponder affects (for example: "schema structure, table naming
conventions, indexing metadata, relation mappings, and migration behavior") and
update the sentence mentioning ENSIndexer so it reads something like: "Owned by
an ENSIndexer instance and influenced by Ponder implementation details (schema
structure, table naming conventions, indexing metadata, relation mappings,
migration behavior)." Refer to the term ENSIndexer and Ponder in the README to
ensure clarity.

- Owned by an ENSIndexer instance and also influenced by Ponder implementation details, as ENSIndexer is a Ponder app.
- Isolated for specific ENSIndexer instance.
- Includes indexed data based on event handlers logic from active ENSIndexer plugins.
- May be large in size, depending on selected ENS Namespace and active plugins.
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider more concise wording.

The phrase "large in size" could be simplified to "large" for consistency with the suggested improvements in other sections.

✍️ Proposed style improvement
-- May be large in size, depending on selected ENS Namespace and active plugins.
+- May be large, depending on selected ENS Namespace and active plugins.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- May be large in size, depending on selected ENS Namespace and active plugins.
- May be large, depending on selected ENS Namespace and active plugins.
🧰 Tools
🪛 LanguageTool

[style] ~20-~20: To form a complete sentence, be sure to include a subject.
Context: ...logic from active ENSIndexer plugins. - May be large in size, depending on selected...

(MISSING_IT_THERE)


[style] ~20-~20: This wording could be more concise.
Context: ...rom active ENSIndexer plugins. - May be large in size, depending on selected ENS Namespace an...

(ADJECTIVE_IN_ATTRIBUTE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-schema/src/README.md` at line 20, Replace the wording "May
be large in size, depending on selected ENS Namespace and active plugins." in
the README with the more concise "May be large, depending on selected ENS
Namespace and active plugins." to match the simpler phrasing used elsewhere and
improve consistency.

Comment on lines +20 to +22
- May be large in size, depending on selected ENS Namespace and active plugins.
- May take a long time to build. Must be re-built from scratch in case of indexing logic changes (i.e. event handler code change, active plugins change).

Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding backup recommendation for consistency.

The Ponder Schema section recommends backups (line 12), but ENSIndexer Schema doesn't mention backups despite also being large and time-consuming to build. Consider adding backup guidance, especially since line 21 notes it "must be re-built from scratch" on logic changes—backups before such changes could be valuable.

🧰 Tools
🪛 LanguageTool

[style] ~20-~20: To form a complete sentence, be sure to include a subject.
Context: ...logic from active ENSIndexer plugins. - May be large in size, depending on selected...

(MISSING_IT_THERE)


[style] ~20-~20: This wording could be more concise.
Context: ...rom active ENSIndexer plugins. - May be large in size, depending on selected ENS Namespace an...

(ADJECTIVE_IN_ATTRIBUTE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-schema/src/README.md` around lines 20 - 22, The README's
"ENSIndexer Schema" section currently describes size and rebuild cost but omits
backup guidance; update the ENSIndexer Schema section to mirror the Ponder
Schema backup recommendation by adding a short backup/restore recommendation
(e.g., take periodic snapshots or export indexes before changing indexing logic
or plugins) and explicitly advise creating backups prior to rebuild-triggering
changes such as event handler or plugin modifications so users can restore
instead of rebuilding from scratch.


- Owned by ENSNode services.
- Includes metadata describing configuration and state of various ENSNode services.
- Tiny in size.
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider more concise wording.

The phrase "Tiny in size" could be simplified to "Tiny" for consistency with the suggested improvements in other sections.

✍️ Proposed style improvement
-- Tiny in size.
+- Tiny.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Tiny in size.
- Tiny.
🧰 Tools
🪛 LanguageTool

[style] ~27-~27: This wording could be more concise.
Context: ...nd state of various ENSNode services. - Tiny in size. - Takes virtually no time to be built....

(ADJECTIVE_IN_ATTRIBUTE)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/ensnode-schema/src/README.md` at line 27, Replace the phrase "Tiny
in size." in the README with the more concise "Tiny" to match wording
consistency across sections; locate the text "Tiny in size." and update it to
"Tiny" so phrasing aligns with other short descriptors.

Copilot AI review requested due to automatic review settings March 12, 2026 11:05
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 12, 2026 11:05 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 12, 2026 11:05 Inactive
@tk-o tk-o force-pushed the refactor/ensdb-schema branch from db6da86 to 9c05883 Compare March 12, 2026 11:47
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 12, 2026 11:47 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 12, 2026 11:47 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 12, 2026 11:47 Inactive
Copy link
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 20 out of 26 changed files in this pull request and generated 1 comment.

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

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

You can also share your feedback on Copilot code review. Take the survey.

@tk-o
Copy link
Contributor Author

tk-o commented Mar 12, 2026

@greptile review

tk-o added 2 commits March 12, 2026 13:08
We do not write into ENSIndexer Schema anymore, so no need for extra queries to make writes to work.
@vercel vercel bot temporarily deployed to Preview – ensnode.io March 12, 2026 12:08 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io March 12, 2026 12:08 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io March 12, 2026 12:08 Inactive
@tk-o
Copy link
Contributor Author

tk-o commented Mar 12, 2026

@greptile review

@tk-o tk-o mentioned this pull request Mar 12, 2026
2 tasks
Copy link
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

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/ensdb-client/ensdb-client.ts (1)

142-149: 🛠️ Refactor suggestion | 🟠 Major

Drop the redundant @returns tag.

Get ENSNode metadata record already says what this method returns, so the @returns line is just repetition. Since this JSDoc block is already being edited, please remove it to match the repo's TS doc rules. As per coding guidelines, "Do not add JSDoc @returns tags that merely restate the method summary; remove such redundancy during PR review".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts` around lines 142 - 149,
Remove the redundant JSDoc `@returns` tag from the ENSNode metadata method's
docblock (the block starting "Get ENSNode metadata record"); leave the summary
and the `@throws` text referencing the composite PK on 'ensIndexerRef' and 'key'
but delete the line that restates the return value so the docs follow the repo's
rule against redundant `@returns` tags.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts`:
- Around line 56-60: The code in the constructor uses makeDrizzle with
ensNodeSchema and the runtime depends on the composite primary key (ON CONFLICT
(ensIndexerRef, key)), so ensure the database migration that creates the ensnode
table and adds the composite PK is shipped together with this client; add or
reference the migration that creates the ensnode schema and the composite
primary key (ensIndexerRef,key) before enabling/rolling out this code, or add an
explicit startup check in the constructor (or in the init path used by
constructor) that verifies the ensnode table and composite index exist and fails
fast with a clear error if not, preventing deployment against unmigrated ENSDb
(also apply the same fix to the other usages referenced around the code block at
symbols handling reads/writes in lines ~182-190).

---

Outside diff comments:
In `@apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts`:
- Around line 142-149: Remove the redundant JSDoc `@returns` tag from the ENSNode
metadata method's docblock (the block starting "Get ENSNode metadata record");
leave the summary and the `@throws` text referencing the composite PK on
'ensIndexerRef' and 'key' but delete the line that restates the return value so
the docs follow the repo's rule against redundant `@returns` tags.
🪄 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: 38bb9ba0-977e-4318-8294-032793dc2246

📥 Commits

Reviewing files that changed from the base of the PR and between 0252adc and 1791217.

📒 Files selected for processing (4)
  • apps/ensapi/src/lib/db.ts
  • apps/ensapi/src/lib/handlers/drizzle.ts
  • apps/ensindexer/src/lib/ensdb-client/drizzle.ts
  • apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts
💤 Files with no reviewable changes (1)
  • apps/ensindexer/src/lib/ensdb-client/drizzle.ts

Comment on lines +56 to 60
constructor(databaseUrl: string, ensIndexerRef: string) {
this.db = makeDrizzle({
databaseSchema: databaseSchemaName,
databaseUrl,
schema,
schema: ensNodeSchema,
});
Copy link
Contributor

@coderabbitai coderabbitai bot Mar 12, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Ship the ensnode schema/PK migration before rolling this out.

This client now hard-depends on the ensnode schema and on ON CONFLICT (ensIndexerRef, key), but the PR notes say migration management for that schema is deferred to a follow-up PR and local testing required manual schema creation. On any existing ENSDb that has not been migrated yet, the first read/write here will fail at runtime. Please land the schema + composite-PK migration in the same release, or explicitly block deployment of this client until the database is migrated.

Also applies to: 182-190

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/ensindexer/src/lib/ensdb-client/ensdb-client.ts` around lines 56 - 60,
The code in the constructor uses makeDrizzle with ensNodeSchema and the runtime
depends on the composite primary key (ON CONFLICT (ensIndexerRef, key)), so
ensure the database migration that creates the ensnode table and adds the
composite PK is shipped together with this client; add or reference the
migration that creates the ensnode schema and the composite primary key
(ensIndexerRef,key) before enabling/rolling out this code, or add an explicit
startup check in the constructor (or in the init path used by constructor) that
verifies the ensnode table and composite index exist and fails fast with a clear
error if not, preventing deployment against unmigrated ENSDb (also apply the
same fix to the other usages referenced around the code block at symbols
handling reads/writes in lines ~182-190).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's the plan, PRs #1753 and #1754 will address missing pieces.

Copy link
Contributor

Choose a reason for hiding this comment

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

@tk-o, understood — thanks for the context! Tracking the follow-up in #1753 and #1754 sounds like a solid plan. I'll keep an eye on those PRs to confirm the ensnode schema creation and the composite PK migration land before this client is deployed against production ENSDb instances.


🧠 Learnings used
Learnt from: CR
Repo: namehash/ensnode PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-02T05:28:59.644Z
Learning: Applies to apps/ensindexer/**/*.ts : Use Ponder as the indexer framework for blockchain indexing

Learnt from: tk-o
Repo: namehash/ensnode PR: 1715
File: apps/ensindexer/ponder/src/api/handlers/ensnode-api.ts:21-25
Timestamp: 2026-03-04T11:40:35.846Z
Learning: In `apps/ensindexer/ponder/src/api/handlers/ensnode-api.ts`, the guard `if (typeof publicConfig === "undefined") { throw new Error("Unreachable: ...") }` in the `/config` handler is intentionally unreachable. The `EnsDbWriterWorker` populates the ENSIndexer public config into ENSDb at startup (fail-fast), so the HTTP layer is guaranteed to only serve requests after the config is available. The `throw` is a defensive invariant, not a real error path.

Learnt from: tk-o
Repo: namehash/ensnode PR: 1639
File: packages/ensnode-sdk/src/ensapi/api/indexing-status/zod-schemas.ts:21-76
Timestamp: 2026-02-16T17:53:46.139Z
Learning: In the ENSNode SDK (`packages/ensnode-sdk`), schema builder functions exported from `zod-schemas.ts` files (e.g., `makeEnsApiIndexingStatusResponseSchema`) are considered internal API, not public API. These can have breaking changes without requiring deprecated aliases, even when exported via the `internal` entry point.

Learnt from: Goader
Repo: namehash/ensnode PR: 1663
File: packages/ens-referrals/src/v1/award-models/rev-share-limit/metrics.ts:74-96
Timestamp: 2026-02-24T15:53:06.633Z
Learning: In TypeScript code reviews, prefer placing invariants on type aliases only when the invariant is context-independent or reused across multiple fields. If an invariant depends on surrounding rules or object semantics (e.g., field-specific metrics), keep the invariant as a field JSDoc instead. This guideline applies to TS files broadly (e.g., the repo's v1/award-models and similar modules).

Learnt from: CR
Repo: namehash/ensnode PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-03-02T05:28:59.644Z
Learning: Applies to **/*.ts : Use Drizzle as the ORM for database interactions

@tk-o tk-o mentioned this pull request Mar 12, 2026
2 tasks
Copy link
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 20 out of 26 changed files in this pull request and generated 1 comment.

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

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

You can also share your feedback on Copilot code review. Take the survey.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file is modified in a later commit to only include reference to Ponder code repository. Feel free to skip reviewing it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This file is removed in a later commit. Feel free to skip reviewing it.

index("rpc_request_results_chain_id_block_number_index").on(table.chainId, table.blockNumber),
],
);
export const PONDER_SCHEMA_NAME = "ponder_sync";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Keeping this one to signal the name of Ponder Schema in database.

* @returns selected record in ENSDb.
* @throws when more than one matching metadata record is found
* (should be impossible given the PK constraint on 'key')
* (should be impossible given the composite PK constraint on
Copy link
Contributor

Choose a reason for hiding this comment

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

JSDoc @returns tag on getEnsNodeMetadata method merely restates information already conveyed by the method summary

Fix on Vercel

@@ -1,7 +1,7 @@
import type { NodePgDatabase } from "drizzle-orm/node-postgres";
import { eq, sql } from "drizzle-orm/sql";
import { and, eq, sql } from "drizzle-orm/sql";
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
import { and, eq, sql } from "drizzle-orm/sql";
import { and, eq } from "drizzle-orm/sql";

The sql import from drizzle-orm/sql is unused in ensdb-client.ts and should be removed

Fix on Vercel

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.

2 participants