Skip to content

Conversation

@Goader
Copy link
Contributor

@Goader Goader commented Jan 21, 2026

ENSAnalytics API Versioning: Add Explicit v1 Routes

closes: #1520


Reviewer Focus (Read This First)

What reviewers should focus on
  • New ensanalytics-api-v1.ts handler - exact duplicate (apart from a few strings in errors and similar) of 'ensanalytics-api.ts`
  • Route mounting in index.ts - both v0 and v1 now available
  • Zero changes to existing v0 implementation
Diff between `ensanalytics-api.ts` and `ensanalytics-api-v1.ts`

diff apps/ensapi/src/handlers/ensanalytics-api.ts apps/ensapi/src/handlers/ensanalytics-api-v1.ts
23c23
< const logger = makeLogger("ensanalytics-api");
---
> const logger = makeLogger("ensanalytics-api-v1");
55c55
<       summary: "Get Referrer Leaderboard",
---
>       summary: "Get Referrer Leaderboard (v1)",
70c70
<         throw new Error(`Invariant(ensanalytics-api): referrerLeaderboardMiddleware required`);
---
>         throw new Error(`Invariant(ensanalytics-api-v1): referrerLeaderboardMiddleware required`);
98c98
<         logger.error({ error }, "Error in /ensanalytics/referrers endpoint");
---
>         logger.error({ error }, "Error in /ensanalytics/v1/referrers endpoint");
125c125
<     summary: "Get Referrer Detail",
---
>     summary: "Get Referrer Detail (v1)",
143c143
<       throw new Error(`Invariant(ensanalytics-api): referrerLeaderboardMiddleware required`);
---
>       throw new Error(`Invariant(ensanalytics-api-v1): referrerLeaderboardMiddleware required`);
169c169
<       logger.error({ error }, "Error in /ensanalytics/referrers/:referrer endpoint");
---
>       logger.error({ error }, "Error in /ensanalytics/v1/referrers/:referrer endpoint");
Diff between `ensanalytics-api.test.ts` and `ensanalytics-api-v1.test.ts`

diff apps/ensapi/src/handlers/ensanalytics-api.test.ts apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts
41c41
< import app from "./ensanalytics-api";
---
> import app from "./ensanalytics-api-v1";
43c43
< describe("/ensanalytics", () => {
---
> describe("/ensanalytics/v1", () => {

Problem & Motivation

Why this exists

What Changed (Concrete)

What actually changed
  1. apps/ensapi/src/handlers/ensanalytics-api-v1.ts - duplicate of existing handler
  2. apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts - duplicate of existing tests
  3. apps/ensapi/src/index.ts - added v1 route mounting at /ensanalytics/v1

Design & Planning

How this approach was chosen

Both v0 and v1 are identical initially. Future PRs will evolve v1 with breaking changes while v0 remains frozen to support current ENSAwards.

  • Planning artifacts: Strategy outlined in issue, will create additional issue to monitor duplicated types (see ENS Referral API versioning duplicated artifacts #1555), so we can remove them later, when v0 gets deprecated
  • Copy-pasted original handlers
  • Reviewed / approved by: N/A

Self-Review

What you caught yourself
  • Nothing
  • Bugs caught: None
  • Logic simplified: None
  • Naming / terminology improved: None
  • Dead or unnecessary code removed: None

Cross-Codebase Alignment

Related code you checked
  • Verified v0 handler remains completely unchanged
  • Both test suites are identical and passing
  • Search terms used: ensanalytics, referrer, referral
  • Reviewed but unchanged: middleware cache
  • Deferred alignment: None

Downstream & Consumer Impact

Who this affects and how
  • Zero impact on existing consumers (ENSAwards, etc.)
  • Public APIs affected: None (additive only, v0 unchanged)
  • Docs updated: v1 has the same docs as v0
  • Naming decisions: Used /v1/ prefix for explicit versioning

Testing Evidence

How this was validated
  • Standard CI testing
  • Manual validation of new endpoints
  • Testing performed: Automated testing + manual validation
  • Known gaps: None
  • What reviewers have to reason about manually: Nothing specific

Scope Reductions

What you intentionally didn't do

No changes to v1 implementation.

  • Follow-ups: Evolve v1 with breaking changes, migrate ENSAwards, deprecate v0
  • Why they were deferred: This PR only sets up versioning infrastructure

Risk Analysis

How this could go wrong

Very low risk - purely additive change with no modifications to existing behavior.

  • Risk areas: None (v0 completely unchanged)
  • Mitigations or rollback options: Trivial to revert, nothing depends on v1 yet
  • Named owner if this causes problems: @Goader

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)

@Goader Goader added this to the ENS Referrals - Round 2 milestone Jan 21, 2026
@Goader Goader self-assigned this Jan 21, 2026
Copilot AI review requested due to automatic review settings January 21, 2026 15:04
@changeset-bot
Copy link

changeset-bot bot commented Jan 21, 2026

🦋 Changeset detected

Latest commit: fb3a04d

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

This PR includes changesets to release 18 packages
Name Type
ensapi Major
ensindexer Major
ensadmin Major
ensrainbow Major
fallback-ensapi Major
@ensnode/datasources Major
@ensnode/ensrainbow-sdk Major
@ensnode/ponder-metadata Major
@ensnode/ensnode-schema Major
@ensnode/ensnode-react Major
@ensnode/ponder-subgraph Major
@ensnode/ensnode-sdk Major
@ensnode/shared-configs Major
@docs/ensnode Major
@docs/ensrainbow Major
@docs/mintlify Major
@namehash/ens-referrals Major
@namehash/namehash-ui Major

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

@vercel
Copy link
Contributor

vercel bot commented Jan 21, 2026

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

Project Deployment Review Updated (UTC)
admin.ensnode.io Ready Ready Preview, Comment Jan 21, 2026 4:21pm
ensnode.io Ready Ready Preview, Comment Jan 21, 2026 4:21pm
ensrainbow.io Ready Ready Preview, Comment Jan 21, 2026 4:21pm

@coderabbitai
Copy link

coderabbitai bot commented Jan 21, 2026

📝 Walkthrough

Walkthrough

Introduces API versioning for ENSAnalytics referral endpoints by creating new v1 routes at /ensanalytics/v1/* while preserving existing /ensanalytics/* routes as implicit v0. Includes new v1 handler implementation with pagination and referrer detail endpoints, comprehensive test coverage, and index routing updates.

Changes

Cohort / File(s) Summary
API v1 Handler Implementation
apps/ensapi/src/handlers/ensanalytics-api-v1.ts
New handler exporting two GET endpoints: /referrers (paginated leaderboard with validation) and /referrers/:referrer (referrer detail). Includes input validation schemas, middleware-injected leaderboard cache, error handling with standard response serialization, and logging.
API v1 Handler Tests
apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts
Comprehensive test suite covering pagination across multiple pages, leaderboard edge cases (empty/populated), referrer detail retrieval (existing/non-existing), and error handling paths. Uses testClient, vitest, and type-safe response helpers.
Route Registration
apps/ensapi/src/index.ts
Registers new v1 handler at /ensanalytics/v1 route; adds import for ensanalyticsApiV1; clarifies comments distinguishing v0 (implicit) from v1 (explicit) routes.
Documentation & Cleanup
apps/ensapi/src/handlers/ensanalytics-api.test.ts, .changeset/tough-phones-cry.md
Removes stale comment from test file; documents minor version bump and API versioning strategy in changeset.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 A v1 pathway emerges, so neat,
While v0 stays stable, the retreat,
New routes now tested with thorough care,
Pagination and details, a feature pair! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed Title clearly and concisely summarizes the main change: introducing API versioning for ENS Referrals with explicit v1 routes.
Linked Issues check ✅ Passed PR successfully implements all objectives from issue #1520: creates v1 routes by duplicating v0 implementations, maintains v0 unchanged, and achieves purely additive versioning infrastructure.
Out of Scope Changes check ✅ Passed All changes are in-scope and directly related to API versioning: new v1 handler and tests, route mounting. No unrelated modifications to v0 or other systems.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description is comprehensive, well-structured, and covers all required sections from the template with extensive detail and context.

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

✨ Finishing touches
  • 📝 Docstrings were successfully generated.
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/ens-referrals-api-versioning

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

Copy link

@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: 5

🤖 Fix all issues with AI agents
In `@apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts`:
- Around line 140-175: Add a new test verifying the /referrers error path by
mocking middleware.referrerLeaderboardMiddleware to set
c.set("referrerLeaderboard", new Error("...")) and then calling
client.referrers.$get(...) and deserializing with
deserializeReferrerLeaderboardPageResponse; assert the response.responseCode
equals ReferrerLeaderboardPageResponseCodes.Error and that response.error and
response.errorMessage match the expected "Internal Server Error" and "Failed to
load referrer leaderboard data." values respectively so the handler's lines
handling Error referrerLeaderboard are covered.
- Around line 158-172: The test's expectedResponse.pageContext is missing
startIndex and endIndex; update the expected object in
apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts so the pageContext includes
startIndex: 0 and endIndex: 0 (alongside hasNext, hasPrev, recordsPerPage, page,
totalPages, totalRecords) so it satisfies ReferrerLeaderboardPageResponseOk and
validates that the handler returns those fields even for
emptyReferralLeaderboard when using ReferrerLeaderboardPageResponseCodes.Ok.

In `@apps/ensapi/src/handlers/ensanalytics-api-v1.ts`:
- Around line 69-71: The current invariant check throws an Error when
c.var.referrerLeaderboard is undefined (referrerLeaderboardMiddleware missing),
which bypasses the endpoint's serialized error response; instead, replace the
throw with the same serialized 500 response used elsewhere (call the existing
errorResponse helper or the handler's JSON error payload) so the endpoint
adheres to the OpenAPI contract; apply the same change to the other invariant at
lines referencing c.var.referrerLeaderboard (the similar check around 142-144)
so both checks return a structured 500 response rather than throwing.
- Around line 74-83: The /referrers handler returns HTTP 500 when
c.var.referrerLeaderboard is an Error but the /referrers/:referrer handler
returns 503 for the same condition; update the first handler to return 503 for
consistency and to reflect a temporary service-unavailable condition by changing
the status argument on the c.json call that sends
serializeReferrerLeaderboardPageResponse({ responseCode:
ReferrerLeaderboardPageResponseCodes.Error, ... }) from 500 to 503 so both
endpoints behave the same.
- Around line 74-83: The referrer leaderboard error message in the
c.var.referrerLeaderboard handling (inside the
serializeReferrerLeaderboardPageResponse call using
ReferrerLeaderboardPageResponseCodes.Error) is inconsistent with the referrer
detail endpoint; change the error string "Failed to load referrer leaderboard
data." to the same canonical message used by the referrer detail endpoint
("Referrer leaderboard data has not been successfully cached yet.") or, better,
extract a shared constant (e.g., REFERRER_LEADERBOARD_NOT_CACHED_MESSAGE) and
use it in both serializeReferrerLeaderboardPageResponse and the referrer detail
response path so both endpoints return identical wording.

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

This PR introduces explicit API versioning for ENS Referrals endpoints by duplicating the existing handler and tests under a new /ensanalytics/v1 route. The existing /ensanalytics routes are preserved as implicit v0, ensuring zero breaking changes while preparing infrastructure for future v1 evolution.

Changes:

  • Added new v1 handler (ensanalytics-api-v1.ts) that duplicates existing v0 implementation
  • Added corresponding v1 test suite (ensanalytics-api-v1.test.ts)
  • Mounted v1 routes at /ensanalytics/v1 in the main application index
  • Minor cleanup: removed incorrect comment from v0 test file

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
apps/ensapi/src/index.ts Added v1 route mounting at /ensanalytics/v1 while preserving existing v0 routes
apps/ensapi/src/handlers/ensanalytics-api-v1.ts Complete duplicate of v0 handler with only string changes in logger name, error messages, and API summaries
apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts Complete duplicate of v0 tests adapted for v1 endpoints
apps/ensapi/src/handlers/ensanalytics-api.test.ts Removed incorrect comment header
.changeset/tough-phones-cry.md Documented the API versioning change as a minor version bump

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

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 21, 2026

Greptile Summary

Introduces API versioning for ENSAnalytics referral endpoints by creating duplicate v1 routes while preserving existing v0 routes.

Key Changes:

  • Created ensanalytics-api-v1.ts - exact duplicate of v0 handler with only logger names and error messages updated
  • Created ensanalytics-api-v1.test.ts - duplicate test suite with correct imports
  • Mounted v1 routes at /ensanalytics/v1 in index.ts:69-70
  • v0 routes remain at /ensanalytics with zero functional changes
  • Both versions share the same middleware and cache implementation

Architecture:
This establishes the foundation for future breaking changes to v1 while keeping v0 stable for existing consumers like ENSAwards. The duplication is intentional and tracked in issue #1555 for eventual cleanup after v0 deprecation.

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Score reflects the purely additive nature of this change - v0 implementation is completely untouched (only a comment removed from tests), v1 is an exact duplicate with appropriate string updates, and both versions share battle-tested middleware. The implementation follows the strategy outlined in issue Introduce API versioning for ENS Referrals APIs #1520 precisely.
  • No files require special attention

Important Files Changed

Filename Overview
apps/ensapi/src/handlers/ensanalytics-api-v1.ts Exact duplicate of v0 handler with only logger names and error messages updated to reflect v1
apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts Test suite duplicated from v0 with correct imports and describe blocks updated for v1
apps/ensapi/src/index.ts Added v1 route mounting at /ensanalytics/v1, preserving existing v0 route at /ensanalytics

Sequence Diagram

sequenceDiagram
    participant Client
    participant ENSApi as ENSApi Server
    participant Router as Router (index.ts)
    participant V0Handler as ensanalytics-api (v0)
    participant V1Handler as ensanalytics-api-v1 (v1)
    participant Middleware as referrerLeaderboardMiddleware
    participant Cache as referrerLeaderboardCache

    Note over Client,Cache: API Versioning - Both v0 and v1 Routes Available

    Client->>ENSApi: GET /ensanalytics/referrers
    ENSApi->>Router: Route request
    Router->>V0Handler: Forward to v0 handler
    V0Handler->>Middleware: Apply middleware
    Middleware->>Cache: Get leaderboard data
    Cache-->>Middleware: Return cached data
    Middleware-->>V0Handler: Set context variable
    V0Handler->>V0Handler: Process request & paginate
    V0Handler-->>Client: Return leaderboard page

    Client->>ENSApi: GET /ensanalytics/v1/referrers
    ENSApi->>Router: Route request
    Router->>V1Handler: Forward to v1 handler
    V1Handler->>Middleware: Apply middleware
    Middleware->>Cache: Get leaderboard data
    Cache-->>Middleware: Return cached data
    Middleware-->>V1Handler: Set context variable
    V1Handler->>V1Handler: Process request & paginate
    V1Handler-->>Client: Return leaderboard page

    Note over V0Handler,V1Handler: Currently identical implementations<br/>Future PRs will evolve v1 with breaking changes
Loading

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 5 out of 5 changed files in this pull request and generated no new comments.


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

@coderabbitai
Copy link

coderabbitai bot commented Jan 21, 2026

Caution

Docstrings generation - FAILED

No docstrings were generated.

Copy link
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.

@Goader Looks good! Thank you! 👍

@lightwalker-eth lightwalker-eth merged commit 365c996 into main Jan 21, 2026
22 of 24 checks passed
@lightwalker-eth lightwalker-eth deleted the feat/ens-referrals-api-versioning branch January 21, 2026 18:10
@github-actions github-actions bot mentioned this pull request Jan 21, 2026
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.

Introduce API versioning for ENS Referrals APIs

3 participants