Skip to content

Conversation

@anxolin
Copy link
Contributor

@anxolin anxolin commented Jul 23, 2025

This PR adds a repository to access dune queries, or execute them and get results.

It also exposes hook!

Motivation

We don't have a way to easily read in CoW Swap from Dune.

Soon we will need to implement the affiliate program, so I did this experimental PR to see if I can get the hooks (since we worked recently in creating some query to return the hooks for the bridge and swap feature 😃

Scope

This is experimental, I don't plan to use it yet in CoW Swap, but leave this easy to add any data we want in CoW Swap now, I think it will be very handy.

Repository

It can:

  • getQueryResults: Return the cached last execution for a given query. Allows pagination
  • executeQuery: Execute a query. The query returns an execution_id
  • getExecutionResults: Return the result for a given execution_id if ready
  • waitForExecution: Waits for a execution_id to be ready, and then return the result

Hooks Service

  • getHooks: Returns hooks given some parameters (blockchain and period).
  • getLatestHooks: Returns all the cached hooks for the last 30 days. This is kind of experimental query. In this PR I'm only interested on implementing a generic way to access dune and extract data so it can be exported nicely in our endpoints.

New Endpoints

/hooks

Screenshot at Jul 23 21-43-41

/hooks/latest

image

Caveats

The parametrization of getHooks is not working for me. I pass the parameters to executeQuery as I understood from the API, but somehow they are ignored. It's likely something silly, and since this is easily fixable by having a query with the parameters we want, and we don't plan to use this right now I didn't loose more time on this.

Test

add API key for dune

DUNE_API_KEY=

Start service:

yarn start

Go to:
http://localhost:3001

Get all hooks:

http://localhost:3001/hooks/latest?limit=1000&offset=0

Screenshot at Jul 23 22-07-54

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 23, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This change refactors and expands the Dune Analytics hooks querying infrastructure. It introduces parameter-object patterns for repository and service interfaces, adds new endpoints and pagination, implements and exports new repository and service classes, and provides comprehensive tests and type guards for data validation. Previous implementations and type signatures are replaced or removed.

Changes

File(s) Change Summary
apps/api/src/app/inversify.config.ts Updated import and binding for HooksService to use HooksServiceImpl instead of HooksServiceMain.
apps/api/src/app/routes/hooks.ts Modified /hooks endpoint to use new parameter schema; added /hooks/latest endpoint with pagination and updated handler logic.
libs/repositories/src/index.ts
libs/services/src/index.ts
Added exports for new implementation modules (DuneRepositoryImpl, HooksServiceImpl).
libs/repositories/src/repos/DuneRepository/DuneRepository.ts Refactored DuneRepository interface to use parameter objects; removed implementation and symbol; added new method signatures.
libs/repositories/src/repos/DuneRepository/DuneRepositoryImpl.ts New: Implements DuneRepositoryImpl class with all repository methods, polling, validation, and error handling.
libs/repositories/src/repos/DuneRepository/DuneRepository.spec.ts Rewritten and expanded tests for DuneRepositoryImpl, covering execution, results, polling, validation, and errors.
libs/services/src/HooksService/HooksService.ts Refactored HooksService interface and types to use parameter objects; removed previous implementation and type guards; added constants and type aliases.
libs/services/src/HooksService/HooksServiceImpl.ts New: Implements HooksServiceImpl class with methods for hooks retrieval and validation, using new repository interface.
libs/services/src/HooksService/HooksServiceImpl.spec.ts New: Unit tests for HooksServiceImpl, including parameter passing, error handling, and data validation.
libs/services/src/HooksService/utils/isHookData.ts New: Utility function for type guarding HookData objects.

Sequence Diagram(s)

sequenceDiagram
    participant API as API Route
    participant HooksService as HooksServiceImpl
    participant Repo as DuneRepositoryImpl
    participant Dune as Dune API

    API->>HooksService: getHooks({blockchain, period, maxWaitTimeMs})
    HooksService->>Repo: executeQuery({queryId, parameters})
    Repo->>Dune: POST /execute_query
    Dune-->>Repo: executionId
    HooksService->>Repo: waitForExecution({executionId, maxWaitTimeMs, typeAssertion})
    Repo->>Dune: GET /execution_results (polling)
    Dune-->>Repo: result rows
    Repo-->>HooksService: validated rows
    HooksService-->>API: HookData[]
Loading
sequenceDiagram
    participant API as API Route
    participant HooksService as HooksServiceImpl
    participant Repo as DuneRepositoryImpl
    participant Dune as Dune API

    API->>HooksService: getLatestHooks({limit, offset})
    HooksService->>Repo: getQueryResults({queryId, limit, offset, typeAssertion})
    Repo->>Dune: GET /query_results
    Dune-->>Repo: result rows
    Repo-->>HooksService: validated rows
    HooksService-->>API: HookData[]
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Poem

🐇

A hop, a skip, a code refactored neat,
With hooks and queries now complete.
Type guards strong, endpoints new,
Pagination hopping through!
Dune data fetched with careful care—
This rabbit’s proud of changes there.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dune-and-hooks

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@anxolin anxolin marked this pull request as draft July 23, 2025 20:05
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: 7

🧹 Nitpick comments (4)
libs/services/src/HooksService/HooksServiceImpl.ts (1)

20-41: Consider adding service-level error handling.

While the implementation is correct, wrapping errors would provide better context for debugging.

   async getHooks(params: GetHooksParams): Promise<HookData[]> {
     const { blockchain, period, maxWaitTimeMs } = params;
 
-    // Execute the query with parameters
-    const execution = await this.duneRepository.executeQuery({
-      queryId: DEFAULT_QUERY_ID,
-      parameters: {
-        blockchain,
-        period,
-      },
-    });
-
-    // Wait for execution to complete with type assertion
-    const result = await this.duneRepository.waitForExecution<HookData>({
-      executionId: execution.execution_id,
-      typeAssertion: isHookData,
-      maxWaitTimeMs,
-    });
-
-    // The data is already typed as HookData from the generic repository
-    return result.result.rows;
+    try {
+      // Execute the query with parameters
+      const execution = await this.duneRepository.executeQuery({
+        queryId: DEFAULT_QUERY_ID,
+        parameters: {
+          blockchain,
+          period,
+        },
+      });
+
+      // Wait for execution to complete with type assertion
+      const result = await this.duneRepository.waitForExecution<HookData>({
+        executionId: execution.execution_id,
+        typeAssertion: isHookData,
+        maxWaitTimeMs,
+      });
+
+      // The data is already typed as HookData from the generic repository
+      return result.result.rows;
+    } catch (error) {
+      throw new Error(`Failed to fetch hooks data: ${error.message}`);
+    }
   }
apps/api/src/app/routes/hooks.ts (2)

30-47: Avoid duplicating the HookData interface.

The response interface duplicates the HookData type definition. Consider importing and reusing it.

+import { HookData } from '@cowprotocol/services';

 interface HooksResponse {
-  hooks: Array<{
-    environment: string;
-    block_time: string;
-    is_bridging: boolean;
-    success: boolean;
-    app_code: string;
-    destination_chain_id: number | null;
-    destination_token_address: string | null;
-    hook_type: string;
-    app_id: string | null;
-    target: string;
-    gas_limit: number;
-    app_hash: string;
-    tx_hash: string;
-  }>;
+  hooks: HookData[];
   count: number;
 }

164-197: Extract duplicate response schema.

The response schema is identical to the /hooks endpoint. Consider extracting it to reduce duplication.

+const hooksResponseSchema = {
+  type: 'object',
+  properties: {
+    hooks: {
+      type: 'array',
+      items: {
+        type: 'object',
+        properties: {
+          environment: { type: 'string' },
+          block_time: { type: 'string' },
+          is_bridging: { type: 'boolean' },
+          success: { type: 'boolean' },
+          app_code: { type: 'string' },
+          destination_chain_id: { type: ['number', 'null'] },
+          destination_token_address: { type: ['string', 'null'] },
+          hook_type: { type: 'string' },
+          app_id: { type: ['string', 'null'] },
+          target: { type: 'string' },
+          gas_limit: { type: 'number' },
+          app_hash: { type: 'string' },
+          tx_hash: { type: 'string' },
+        },
+      },
+    },
+    count: { type: 'number' },
+  },
+};

 // Then use it in both endpoints:
 response: {
-  200: { /* current schema */ }
+  200: hooksResponseSchema
 }
libs/services/src/HooksService/HooksService.ts (1)

61-62: Track the temporary PoC method removal.

The TODO indicates getLatestHooks is temporary due to parameter issues with getHooks. This aligns with the PR objectives mentioning parameterization problems.

Would you like me to create an issue to track the removal of this method once the parameterization issue is resolved?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f45a753 and 15b252c.

📒 Files selected for processing (11)
  • apps/api/src/app/inversify.config.ts (2 hunks)
  • apps/api/src/app/routes/hooks.ts (5 hunks)
  • libs/repositories/src/index.ts (1 hunks)
  • libs/repositories/src/repos/DuneRepository/DuneRepository.spec.ts (1 hunks)
  • libs/repositories/src/repos/DuneRepository/DuneRepository.ts (1 hunks)
  • libs/repositories/src/repos/DuneRepository/DuneRepositoryImpl.ts (1 hunks)
  • libs/services/src/HooksService/HooksService.ts (2 hunks)
  • libs/services/src/HooksService/HooksServiceImpl.spec.ts (1 hunks)
  • libs/services/src/HooksService/HooksServiceImpl.ts (1 hunks)
  • libs/services/src/HooksService/utils/isHookData.ts (1 hunks)
  • libs/services/src/index.ts (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
libs/repositories/src/repos/DuneRepository/DuneRepository.spec.ts (1)

Learnt from: anxolin
PR: #127
File: libs/repositories/src/datasources/orm/postgresOrm.ts:7-12
Timestamp: 2025-04-23T09:18:47.273Z
Learning: The ensureEnvs utility from @cowprotocol/shared causes issues when used with TypeORM migrations in the repositories module, so direct assert statements are used instead for environment variable validation in the ORM datasource configuration.

🧬 Code Graph Analysis (3)
apps/api/src/app/inversify.config.ts (1)
libs/services/src/HooksService/HooksServiceImpl.ts (1)
  • HooksServiceImpl (13-55)
libs/services/src/HooksService/utils/isHookData.ts (1)
libs/services/src/HooksService/HooksService.ts (1)
  • HookData (31-45)
libs/services/src/HooksService/HooksServiceImpl.ts (3)
libs/services/src/HooksService/HooksService.ts (4)
  • HooksService (58-63)
  • GetHooksParams (47-51)
  • HookData (31-45)
  • GetLatestHooksParams (53-56)
libs/repositories/src/repos/DuneRepository/DuneRepository.ts (1)
  • DuneRepository (58-72)
libs/services/src/HooksService/utils/isHookData.ts (1)
  • isHookData (4-58)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: docker (apps/telegram)
  • GitHub Check: docker (apps/api)
  • GitHub Check: docker (apps/notification-producer)
  • GitHub Check: docker (apps/twap)
🔇 Additional comments (19)
apps/api/src/app/inversify.config.ts (1)

33-33: LGTM! Service implementation updated correctly.

The import and binding changes properly integrate the new HooksServiceImpl with its duneRepository dependency.

Also applies to: 102-102

libs/repositories/src/index.ts (1)

60-60: Export addition follows established pattern.

The new export for DuneRepositoryImpl is correctly placed and consistent with other repository exports.

libs/services/src/index.ts (1)

11-11: Service export added correctly.

The export for HooksServiceImpl follows the established pattern for service exports.

libs/services/src/HooksService/utils/isHookData.ts (1)

4-58: Well-implemented type guard with comprehensive validation.

The type guard correctly validates all required and nullable fields of the HookData interface with proper type checking.

libs/repositories/src/repos/DuneRepository/DuneRepository.spec.ts (1)

1-518: Comprehensive test coverage with realistic scenarios.

The test suite thoroughly covers all methods with success cases, error handling, and edge cases. Good use of realistic mock data and proper test isolation.

libs/services/src/HooksService/HooksServiceImpl.spec.ts (3)

10-151: Well-structured mock implementation!

The MockDuneRepository class provides a comprehensive mock with proper type validation simulation and helpful error messages for debugging test failures.


153-204: Comprehensive test coverage for successful hook retrieval!

The test properly validates all fields of the HookData interface, including nullable fields.


326-416: Excellent test coverage for edge cases and enum combinations!

The tests properly handle empty results and validate all supported blockchain/period combinations, ensuring comprehensive coverage.

libs/repositories/src/repos/DuneRepository/DuneRepositoryImpl.ts (4)

1-26: Well-structured repository implementation!

The class setup with configurable base URL and reasonable default constants provides good flexibility.


27-57: Correct implementation of query execution!

The method properly handles parameter serialization and includes helpful logging.


125-138: Clean implementation of paginated query results!

The method correctly handles pagination parameters.


140-181: Robust API request handling!

The method includes proper authentication, comprehensive logging, and clear error messages.

libs/services/src/HooksService/HooksServiceImpl.ts (1)

46-51: Ignore removal of typeAssertion and renaming of the constant

The getQueryResults method accepts a typeAssertion parameter because its params type (GetQueryResultsParams<T>) extends WithTypeAssertion<T>. The constant name DEFAULT_QUERY_LATESTS matches its declaration and should not be renamed.

Evidence:

  • In libs/repositories/src/repos/DuneRepository/DuneRepository.ts:
    export interface GetQueryResultsParams<T> extends WithTypeAssertion<T> {
      queryId: number;
      limit?: number;
      offset?: number;
    }
  • The repository interface declares:
    getQueryResults<T>(
      params: GetQueryResultsParams<T>
    ): Promise<DuneResultResponse<T>>;

Please disregard the original suggestion.

Likely an incorrect or invalid review comment.

apps/api/src/app/routes/hooks.ts (1)

50-140: Well-implemented hooks endpoint!

The endpoint properly validates parameters using enums, handles errors gracefully, and includes appropriate caching.

libs/services/src/HooksService/HooksService.ts (1)

5-29: Excellent type definition pattern!

The single source of truth approach for enum values with both compile-time types and runtime arrays is a best practice.

libs/repositories/src/repos/DuneRepository/DuneRepository.ts (4)

31-37: Well-structured parameter object pattern

The PerformanceTier type and ExecuteQueryParams interface are well-designed. The use of a union type for performance tiers provides type safety while maintaining flexibility.


39-46: Good use of interface composition

The interfaces properly utilize TypeScript's extension mechanism to compose functionality. The optional maxWaitTimeMs parameter provides sensible timeout configuration.


48-56: Excellent type assertion pattern for runtime safety

The WithTypeAssertion<T> interface provides a clean way to validate data at runtime using TypeScript's type predicate pattern. The pagination support in GetQueryResultsParams is well-structured.


58-72: executeQuery correctly forwards parameters and performance

The executeQuery implementation appends both parameters (as query_parameters) and performance to the request URL, and the existing Jest tests confirm all combinations pass through as intended. No changes are needed.

Comment on lines +152 to +155
limit: {
type: 'number',
default: 1000,
description: 'Number of hooks to return',
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix inconsistent default limit values.

The schema specifies default: 1000 but the handler uses limit: request.query.limit || 100. These should be consistent.

             limit: {
               type: 'number',
-              default: 1000,
+              default: 100,
               description: 'Number of hooks to return',
             },

Also applies to: 210-211

🤖 Prompt for AI Agents
In apps/api/src/app/routes/hooks.ts at lines 152-155 and also lines 210-211, the
default limit value in the schema is set to 1000 but the handler uses 100 as the
fallback limit. To fix this inconsistency, update the handler code to use 1000
as the default limit value to match the schema's default, ensuring both places
use the same default number for the limit parameter.

Comment on lines 369 to 372
return (
typeof data === 'object' && data !== null && 'environment' in data
);
fail('Expected error to be thrown');
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : String(error);

// Check that error message contains expected information
expect(errorMessage).toContain(
'Data validation failed for execution test-execution-id'
);
expect(errorMessage).toContain('Invalid rows found: 1/2');
expect(errorMessage).toContain('Example invalid row (index 1):');
expect(errorMessage).toContain('"id": 2');
expect(errorMessage).toContain('"name": "Test 2"');
expect(errorMessage).toContain(
'Expected columns from Dune: id, name, active'
);
}
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Strengthen the type assertion function in the test.

The type assertion function only checks for the presence of the 'environment' property, which doesn't properly validate all required fields of the HookData type. This could lead to false test passes.

-      const isHookData = (
-        data: unknown
-      ): data is {
-        environment: string;
-        block_time: string;
-        is_bridging: boolean;
-        success: boolean;
-        app_code: string;
-        destination_chain_id: number | null;
-        destination_token_address: string | null;
-        hook_type: string;
-        app_id: string | null;
-        target: string;
-        gas_limit: number;
-        app_hash: string;
-        tx_hash: string;
-      } => {
-        return (
-          typeof data === 'object' && data !== null && 'environment' in data
-        );
-      };
+      // Import the actual isHookData function from the utils
+      import { isHookData } from '@cowprotocol/services';

Alternatively, if you want to keep it inline for testing purposes, implement proper validation:

       const isHookData = (
         data: unknown
       ): data is {
         environment: string;
         block_time: string;
         is_bridging: boolean;
         success: boolean;
         app_code: string;
         destination_chain_id: number | null;
         destination_token_address: string | null;
         hook_type: string;
         app_id: string | null;
         target: string;
         gas_limit: number;
         app_hash: string;
         tx_hash: string;
       } => {
-        return (
-          typeof data === 'object' && data !== null && 'environment' in data
-        );
+        if (typeof data !== 'object' || data === null) return false;
+        const d = data as Record<string, unknown>;
+        return (
+          typeof d.environment === 'string' &&
+          typeof d.block_time === 'string' &&
+          typeof d.is_bridging === 'boolean' &&
+          typeof d.success === 'boolean' &&
+          typeof d.app_code === 'string' &&
+          (d.destination_chain_id === null || typeof d.destination_chain_id === 'number') &&
+          (d.destination_token_address === null || typeof d.destination_token_address === 'string') &&
+          typeof d.hook_type === 'string' &&
+          (d.app_id === null || typeof d.app_id === 'string') &&
+          typeof d.target === 'string' &&
+          typeof d.gas_limit === 'number' &&
+          typeof d.app_hash === 'string' &&
+          typeof d.tx_hash === 'string'
+        );
       };

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In libs/repositories/src/repos/DuneRepository/DuneRepository.spec.ts around
lines 369 to 372, the type assertion function only checks if the 'environment'
property exists on the data object, which is insufficient to validate the full
HookData type. To fix this, enhance the function to verify all required
properties of HookData are present and have the correct types, ensuring the test
accurately validates the data structure and prevents false positives.

Comment on lines 84 to 91
const invalidRows: Array<{ index: number; data: unknown }> = [];
const isValid = result.result.rows.every((row, index) => {
if (!typeAssertion(row)) {
invalidRows.push({ index, data: row });
return false;
}
return true;
});
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix validation logic to check all rows.

The current implementation stops validation at the first invalid row due to the early return on line 88, but the error message suggests all invalid rows are collected. This inconsistency should be fixed.

-          const isValid = result.result.rows.every((row, index) => {
-            if (!typeAssertion(row)) {
-              invalidRows.push({ index, data: row });
-              return false;
-            }
-            return true;
-          });
+          result.result.rows.forEach((row, index) => {
+            if (!typeAssertion(row)) {
+              invalidRows.push({ index, data: row });
+            }
+          });
+          const isValid = invalidRows.length === 0;
📝 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
const invalidRows: Array<{ index: number; data: unknown }> = [];
const isValid = result.result.rows.every((row, index) => {
if (!typeAssertion(row)) {
invalidRows.push({ index, data: row });
return false;
}
return true;
});
const invalidRows: Array<{ index: number; data: unknown }> = [];
result.result.rows.forEach((row, index) => {
if (!typeAssertion(row)) {
invalidRows.push({ index, data: row });
}
});
const isValid = invalidRows.length === 0;
🤖 Prompt for AI Agents
In libs/repositories/src/repos/DuneRepository/DuneRepositoryImpl.ts around lines
84 to 91, the validation logic uses Array.every which stops at the first invalid
row, preventing collection of all invalid rows. Replace Array.every with
Array.forEach or a similar iteration method to check every row, push all invalid
rows to invalidRows, and then determine validity after the loop to ensure all
invalid rows are collected as intended.

@@ -1,7 +1,33 @@
import { DuneRepository } from '@cowprotocol/repositories';
import { PerformanceTier } from '@cowprotocol/repositories';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unused import.

PerformanceTier is imported but not used in this file.

-import { PerformanceTier } from '@cowprotocol/repositories';
📝 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
import { PerformanceTier } from '@cowprotocol/repositories';
// (The import of `PerformanceTier` has been removed; no other changes are needed.)
🤖 Prompt for AI Agents
In libs/services/src/HooksService/HooksService.ts at line 1, the import of
PerformanceTier from '@cowprotocol/repositories' is unused. Remove this import
statement to clean up the code and avoid unnecessary dependencies.

const executeQuerySpy = jest.spyOn(mockRepository, 'executeQuery');
const waitForExecutionSpy = jest.spyOn(
mockRepository,
'waitForExecution'
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Verify default limit value consistency.

The test expects limit: request.query.limit || 100 but the actual route implementation uses limit: request.query.limit || 100 while the schema specifies default: 1000. This inconsistency should be addressed.


🏁 Script executed:

#!/bin/bash
# Description: Check for inconsistent default limit values across the codebase

# Search for default limit values in the codebase
rg -A 2 -B 2 "limit.*default|default.*limit" --type ts

Length of output: 56


I couldn’t find any matches for generic “limit.*default” patterns. Let’s narrow down to the actual implementation and schema defaults:


🏁 Script executed:

#!/bin/bash
# Find where the route reads request.query.limit
rg -n "request.query.limit" --type ts

# Find any schema declaring a default of 1000
rg -n "default.*1000" --type ts

# Find Zod number() definitions with default()
rg -n "z\\.number.*default" --type ts

Length of output: 258


Align default limit value between schema and implementation

The route’s schema (apps/api/src/app/routes/hooks.ts:154) specifies a default limit of 1000, but the implementation falls back to 100 (apps/api/src/app/routes/hooks.ts:210) and the test assumes 100. These must be consistent.

• Schema default at line 154:

default: 1000,

• Implementation fallback at line 210:

limit: request.query.limit || 100,

Action required:

  • Decide on the intended default (100 or 1000).
  • Update either the schema’s default or the implementation’s fallback (and tests) so they match.
🤖 Prompt for AI Agents
In libs/services/src/HooksService/HooksServiceImpl.spec.ts at line 210, the
default limit value used in the implementation (100) does not match the schema
default (1000) defined in apps/api/src/app/routes/hooks.ts at line 154. Decide
whether the default limit should be 100 or 1000, then update the implementation
fallback value at line 210 and the related tests in HooksServiceImpl.spec.ts to
use the chosen default, ensuring consistency with the schema default.

Comment on lines +10 to +11
const DEFAULT_QUERY_ID = 5302473; // Example on executing a query
const DEFAULT_QUERY_LATESTS = 5527161; // Example on getting of a query
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider making query IDs configurable and fix typo.

  1. The hardcoded query IDs should ideally be configurable through environment variables or constructor parameters
  2. Typo in comment: "getting of a query" → "getting results of a query"
-const DEFAULT_QUERY_ID = 5302473; // Example on executing a query
-const DEFAULT_QUERY_LATESTS = 5527161; // Example on getting of a query
+const DEFAULT_QUERY_ID = process.env.DUNE_HOOKS_QUERY_ID ? parseInt(process.env.DUNE_HOOKS_QUERY_ID) : 5302473; // Query for executing hooks with parameters
+const DEFAULT_QUERY_LATEST_ID = process.env.DUNE_HOOKS_LATEST_QUERY_ID ? parseInt(process.env.DUNE_HOOKS_LATEST_QUERY_ID) : 5527161; // Query for getting latest hooks results
📝 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
const DEFAULT_QUERY_ID = 5302473; // Example on executing a query
const DEFAULT_QUERY_LATESTS = 5527161; // Example on getting of a query
const DEFAULT_QUERY_ID = process.env.DUNE_HOOKS_QUERY_ID
? parseInt(process.env.DUNE_HOOKS_QUERY_ID, 10)
: 5302473; // Query for executing hooks with parameters
const DEFAULT_QUERY_LATEST_ID = process.env.DUNE_HOOKS_LATEST_QUERY_ID
? parseInt(process.env.DUNE_HOOKS_LATEST_QUERY_ID, 10)
: 5527161; // Query for getting latest hooks results
🤖 Prompt for AI Agents
In libs/services/src/HooksService/HooksServiceImpl.ts around lines 10 to 11, the
query IDs are hardcoded and the comment contains a typo. Refactor the code to
accept these query IDs as configurable parameters, such as environment variables
or constructor arguments, instead of hardcoding them. Also, correct the comment
typo by changing "getting of a query" to "getting results of a query" for
clarity.

@@ -0,0 +1,58 @@
import { DuneRepository, PerformanceTier } from '@cowprotocol/repositories';
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Remove unused imports.

The imports DuneRepository and PerformanceTier are not used in this file.

-import { DuneRepository, PerformanceTier } from '@cowprotocol/repositories';
📝 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
import { DuneRepository, PerformanceTier } from '@cowprotocol/repositories';
🤖 Prompt for AI Agents
In libs/services/src/HooksService/utils/isHookData.ts at line 1, remove the
unused imports DuneRepository and PerformanceTier from
'@cowprotocol/repositories' since they are not used anywhere in the file.

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