Skip to content

refactor: use zod-openapi for ensanalytics-api-v1#1686

Merged
notrab merged 4 commits intomainfrom
zod-openapi-ensanalytics-api-v1
Feb 26, 2026
Merged

refactor: use zod-openapi for ensanalytics-api-v1#1686
notrab merged 4 commits intomainfrom
zod-openapi-ensanalytics-api-v1

Conversation

@notrab
Copy link
Member

@notrab notrab commented Feb 26, 2026

Lite PR

Tip: Review docs on the ENSNode PR process

Summary

  • Migrate ensanalytics-api-v1 (3 routes) from hono-openapi to @hono/zod-openapi route definitions.
  • Created ensanalytics-api-v1.routes.ts with createRoute() definitions, updated handler to use createApp()/app.openapi(), registered in stub-routes.ts.

Why

Consistent with the pattern established across other migrated routes (ensnode-api, amirealtime-api, resolution-api), enabling OpenAPI spec generation from route definitions without runtime dependencies.


Testing

  • All 12 existing tests pass with identical assertions. No response shapes, error messages, status codes, or types were changed.
  • Verified via git diff that every c.json() call, responseCode, error, errorMessage, satisfies type assertion, and serialization function is byte-for-byte identical to main (only indentation changed from removing chained .get() nesting).
  • Typecheck and lint pass.

Notes for Reviewer (Optional)

Test file updated to replace testClient(app) with app.request(). OpenAPIHono's app.openapi() doesn't produce the chained route types that testClient needs for inference. The app.request() pattern is already used by amirealtime-api.test.ts and by several tests in this same file.


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)

@notrab notrab requested a review from a team as a code owner February 26, 2026 07:19
Copilot AI review requested due to automatic review settings February 26, 2026 07:19
@vercel
Copy link
Contributor

vercel bot commented Feb 26, 2026

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

3 Skipped Deployments
Project Deployment Actions Updated (UTC)
admin.ensnode.io Skipped Skipped Feb 26, 2026 8:25am
ensnode.io Skipped Skipped Feb 26, 2026 8:25am
ensrainbow.io Skipped Skipped Feb 26, 2026 8:25am

@changeset-bot
Copy link

changeset-bot bot commented Feb 26, 2026

⚠️ No Changeset found

Latest commit: a53c30a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 26, 2026

Warning

Rate limit exceeded

@notrab has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 0 seconds before requesting another review.

⌛ 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 9185e15 and a53c30a.

📒 Files selected for processing (1)
  • apps/ensapi/src/stub-routes.ts
📝 Walkthrough

Walkthrough

Adds a new ENS analytics v1 routes module with Zod/OpenAPI route descriptors, migrates the handler to register those routes via app.openapi on a new createApp() instance, updates tests to use app.request, and registers the new route group in stub-routes.ts.

Changes

Cohort / File(s) Summary
Route definitions
apps/ensapi/src/handlers/ensanalytics-api-v1.routes.ts
New route module: base path constant, Zod validation schemas, OpenAPI metadata and three exported Route objects (getReferralLeaderboardRoute, getReferrerDetailRoute, getEditionsRoute) and routes array.
Handler migration
apps/ensapi/src/handlers/ensanalytics-api-v1.ts
Replaced per-route .get registrations with app.openapi(route, handler) using the new route descriptors; switched to top-level createApp() and centralized cache/config validation, error mapping (200/400/404/503/500) and response shaping.
Tests
apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts
Switched test interactions from testClient to app.request(...), updated response parsing via httpResponse.json() and adjusted test variable names.
Route registration
apps/ensapi/src/stub-routes.ts
Added import of the new ENS analytics v1 route group and included it in the routeGroups array for OpenAPI registration.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant App as ENSAPI App
    participant Config as EditionConfigStore
    participant Cache as EditionLeaderboardCache
    participant Handler as Route Handler

    Client->>App: HTTP GET /ensanalytics/v1/referral-leaderboard?edition=slug&page=1
    App->>Handler: invoke getReferralLeaderboardRoute handler
    Handler->>Config: check edition config availability
    alt config load failed
        Config-->>Handler: error (-> 503)
    else config ok
        Handler->>Cache: read leaderboard for edition
        alt cache read failed / not found
            Cache-->>Handler: error or empty (-> 503 or 404)
        else cache hit
            Cache-->>Handler: leaderboard data
            Handler-->>Client: 200 + paginated leaderboard
        end
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐇 I hopped through routes and schemas bright,
I trimmed the paths and stitched the light,
Leaderboards hum, editions align,
OpenAPI sings—this rabbit's fine,
Binky-bop, the routes take flight! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main refactoring effort—migrating ensanalytics-api-v1 from hono-openapi to @hono/zod-openapi.
Description check ✅ Passed The description follows the template with all required sections (Summary, Why, Testing, Notes for Reviewer, Pre-Review Checklist) and provides clear, substantive details about the changes and testing approach.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch zod-openapi-ensanalytics-api-v1

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.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 26, 2026

Greptile Summary

Successfully migrated ensanalytics-api-v1 from hono-openapi to @hono/zod-openapi, following the established pattern from previous API migrations. Route definitions moved to dedicated routes file, handlers updated to use app.openapi() pattern, and tests adapted for OpenAPIHono compatibility.

Key Changes:

  • Created ensanalytics-api-v1.routes.ts with createRoute() definitions for 3 endpoints
  • Refactored handler to use createApp() and app.openapi() instead of chained .get() calls
  • Updated tests from testClient() to app.request() pattern (required for OpenAPIHono)
  • Registered routes in stub-routes.ts for OpenAPI spec generation

Verification:

  • All response shapes, error messages, status codes, and satisfies type assertions preserved
  • Handler logic unchanged (only structural refactoring)
  • Route paths and middleware unchanged
  • Consistent with patterns in amirealtime-api, ensnode-api, and resolution-api migrations

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • This is a clean refactoring that follows an established migration pattern. All handler logic, error responses, and type assertions are preserved. The changes are purely structural, moving to a more maintainable pattern that enables OpenAPI spec generation. All tests pass and the PR author verified byte-for-byte equivalence of response handling.
  • No files require special attention

Important Files Changed

Filename Overview
apps/ensapi/src/handlers/ensanalytics-api-v1.routes.ts New file containing route definitions with Zod schemas migrated from handler file. Follows established pattern from other migrated routes.
apps/ensapi/src/handlers/ensanalytics-api-v1.ts Handler refactored to use app.openapi() pattern with route definitions imported from routes file. Logic unchanged, only structure updated.
apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts Tests updated to use app.request() instead of testClient() for compatibility with OpenAPIHono. Test assertions unchanged.
apps/ensapi/src/stub-routes.ts Added ensanalytics-api-v1 routes to stub registration for OpenAPI spec generation.

Last reviewed commit: 287852f

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

4 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

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 ensanalytics-api-v1 to follow the repository’s @hono/zod-openapi route-definition pattern (like amirealtime-api, resolution-api, ensnode-api) so OpenAPI definitions live in createRoute() modules and handlers register them via app.openapi().

Changes:

  • Added ensanalytics-api-v1.routes.ts with createRoute() definitions (+ basePath/routes exports) for the 3 v1 endpoints.
  • Updated ensanalytics-api-v1.ts to use createApp() and app.openapi(route, handler) instead of hono-openapi + describeRoute() + validate().
  • Updated v1 tests to use app.request() instead of testClient(), and registered the new route group in stub-routes.ts for spec generation.

Reviewed changes

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

File Description
apps/ensapi/src/stub-routes.ts Registers the new ensanalytics-api-v1 route group for OpenAPI stub/spec generation.
apps/ensapi/src/handlers/ensanalytics-api-v1.ts Migrates v1 handler implementation to @hono/zod-openapi route registration via app.openapi().
apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts Switches tests from testClient(app) to app.request() calls.
apps/ensapi/src/handlers/ensanalytics-api-v1.routes.ts New: defines v1 OpenAPI routes and request schemas using createRoute().

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

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/handlers/ensanalytics-api-v1.routes.ts`:
- Around line 62-75: Add a 400 validation response to the /referral-leaderboard
route's OpenAPI responses: update the responses object used when registering the
`/referral-leaderboard` route in ensanalytics-api-v1.routes.ts to include a 400
entry (e.g., description: "Bad request — validation failed") and, if present in
your project schema conventions, reference the validation error schema or
example payload used elsewhere for request validation errors so consumers see
the expected error shape.

In `@apps/ensapi/src/handlers/ensanalytics-api-v1.ts`:
- Around line 107-116: The catch blocks that build the 500 response (the ones
calling serializeReferrerLeaderboardPageResponse with
ReferrerLeaderboardPageResponseCodes.Error and returning error/errorMessage) are
exposing raw exception messages; instead, remove usage of error.message in the
JSON response, log the full error internally (e.g., via processLogger or the
existing logger), and return a generic server-facing message such as { error:
"Internal server error", errorMessage: "An unexpected error occurred while
processing your request" } (or similar) while keeping the existing response
shape defined by ReferrerLeaderboardPageResponse; apply the same change to the
other two catch blocks that use the same serializer to ensure consistent mapping
per the guidelines.
- Line 222: The error log incorrectly names the endpoint as
"/v1/ensanalytics/referral-leaderboard/:referrer"; update the logger.error call
in the referrer-detail handler to reference the correct route (e.g.
"/v1/ensanalytics/referrer-detail/:referrer") so the log reflects the actual
handler; locate and edit the logger.error invocation (the logger.error({ error
}, "...") statement) in the referrer-detail handler to replace the endpoint
string accordingly.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c6e7d5c and 287852f.

📒 Files selected for processing (4)
  • apps/ensapi/src/handlers/ensanalytics-api-v1.routes.ts
  • apps/ensapi/src/handlers/ensanalytics-api-v1.test.ts
  • apps/ensapi/src/handlers/ensanalytics-api-v1.ts
  • apps/ensapi/src/stub-routes.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 26, 2026 07:31
@vercel vercel bot temporarily deployed to Preview – ensnode.io February 26, 2026 07:31 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io February 26, 2026 07:31 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io February 26, 2026 07:31 Inactive
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.

@notrab Looks good, thank you 👍

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.

♻️ Duplicate comments (1)
apps/ensapi/src/handlers/ensanalytics-api-v1.ts (1)

107-116: ⚠️ Potential issue | 🟠 Major

Do not expose raw exception messages in 500 responses.

Line [107], Line [223], and Line [279] return error.message to clients. This can leak internal details; keep full error detail in logs and return a fixed generic message in 500 responses.

🔒 Suggested hardening
-    const errorMessage =
-      error instanceof Error
-        ? error.message
-        : "An unexpected error occurred while processing your request";
+    const errorMessage = "An unexpected error occurred while processing your request";

As per coding guidelines "Map errors to response codes: validation errors (ZodError/Standard Schema) → 400 with { message, details }; known client errors → 4xx with { message }; server errors → 500 with { message }."

Also applies to: 223-232, 279-288

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

In `@apps/ensapi/src/handlers/ensanalytics-api-v1.ts` around lines 107 - 116, The
handler currently exposes raw exception text by using error.message in responses
built by serializeReferrerLeaderboardPageResponse with responseCode
ReferrerLeaderboardPageResponseCodes.Error; replace that by returning a fixed
generic message (e.g., "Internal server error") in the response payload and move
the full error details to server logs (call your logger.error or console.error
with the original error) so clients never receive internal exception text;
update the same pattern wherever serializeReferrerLeaderboardPageResponse (and
similar 500 branches) are used to ensure consistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@apps/ensapi/src/handlers/ensanalytics-api-v1.ts`:
- Around line 107-116: The handler currently exposes raw exception text by using
error.message in responses built by serializeReferrerLeaderboardPageResponse
with responseCode ReferrerLeaderboardPageResponseCodes.Error; replace that by
returning a fixed generic message (e.g., "Internal server error") in the
response payload and move the full error details to server logs (call your
logger.error or console.error with the original error) so clients never receive
internal exception text; update the same pattern wherever
serializeReferrerLeaderboardPageResponse (and similar 500 branches) are used to
ensure consistency.

ℹ️ Review info

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 287852f and 9185e15.

📒 Files selected for processing (1)
  • apps/ensapi/src/handlers/ensanalytics-api-v1.ts

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 4 out of 4 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.

@vercel vercel bot temporarily deployed to Preview – ensnode.io February 26, 2026 08:25 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io February 26, 2026 08:25 Inactive
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io February 26, 2026 08:25 Inactive
Copilot AI review requested due to automatic review settings February 26, 2026 08:25
@vercel vercel bot temporarily deployed to Preview – admin.ensnode.io February 26, 2026 08:25 Inactive
@vercel vercel bot temporarily deployed to Preview – ensnode.io February 26, 2026 08:25 Inactive
@vercel vercel bot temporarily deployed to Preview – ensrainbow.io February 26, 2026 08:25 Inactive
@notrab notrab merged commit 4af9dc6 into main Feb 26, 2026
17 of 18 checks passed
@notrab notrab deleted the zod-openapi-ensanalytics-api-v1 branch February 26, 2026 08:28
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 4 out of 4 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.

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