Skip to content

feat: view list metadata by height#1141

Merged
MicBun merged 7 commits into
mainfrom
feat/view-metadata-by-height
Sep 5, 2025
Merged

feat: view list metadata by height#1141
MicBun merged 7 commits into
mainfrom
feat/view-metadata-by-height

Conversation

@williamrusdyputra
Copy link
Copy Markdown
Contributor

@williamrusdyputra williamrusdyputra commented Sep 4, 2025

Related Problem

resolves: https://github.com/trufnetwork/trufscan/issues/32

How Has This Been Tested?

migrated

Summary by CodeRabbit

  • New Features

    • Added a public action to list metadata by block height with key/ref filters, height-range bounds, pagination, and input validation.
  • Tests

    • Added by-height metadata tests (standard, no-key, pagination, invalid range/pagination) and renamed an existing metadata test.
    • Added test helper call and input type for the new listing action.
    • Enhanced test table assertion to allow excluding specific columns when comparing results.
  • Style

    • Minor formatting: added trailing newline in a migration file.

@williamrusdyputra williamrusdyputra self-assigned this Sep 4, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Sep 4, 2025

Walkthrough

Adds a new SQL action to list metadata by block height with pagination and optional ref filtering, integrates test utilities and tests for that action, updates table assertion logic to support excluded columns, and appends a trailing newline to an existing migration file.

Changes

Cohort / File(s) Summary
Migration formatting
internal/migrations/001-common-actions.sql
Appends a trailing newline; no functional change.
Metadata by-height action
internal/migrations/021-metadata-actions.sql
Adds public action list_metadata_by_height($key, $ref, $from_height, $to_height, $limit, $offset) that computes effective bounds using @height, validates from ≤ to, clamps pagination defaults, filters non-disabled metadata by key/ref and created_at, orders by created_at ASC, and returns typed columns.
Test executor & types
tests/streams/utils/procedure/execute.go, tests/streams/utils/procedure/types.go
Adds ListMetadataByHeightInput and ListMetadataByHeight executor which builds TxContext (height, signer, caller), calls the engine action with six params, streams rows into results, and wraps errors.
Table assertion changes
tests/streams/utils/table/assert.go
Adds ExcludedColumns []int to assertion input; applies per-column transformers to expected rows, drops excluded columns from actual rows, and updates sorting to use header maps that account for excluded columns.
Metadata tests
tests/streams/query/metadata_test.go
Renames main test to TestQUERY04Metadata and adds tests: listing by height, no-key case, pagination, invalid range, and invalid pagination; uses markdown table assertions and the new executor.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant T as Tests (Go)
  participant U as Test Utils
  participant E as Engine
  participant A as Action:list_metadata_by_height
  participant DB as DB (metadata)

  T->>U: ListMetadataByHeight(input)
  U->>U: Build TxContext (height, signer, caller)
  U->>E: Call action list_metadata_by_height(params)
  E->>A: Execute action with params
  A->>A: Compute effective_from/to, validate range, clamp pagination
  A->>DB: SELECT metadata WHERE key, optional ref, disabled_at IS NULL, created_at BETWEEN bounds ORDER BY created_at
  DB-->>A: Stream rows
  A-->>E: Stream rows to engine
  E-->>U: Row callbacks
  U-->>T: Result rows or error
  note right of A: On invalid range -> error returned
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Assessment against linked issues

Objective Addressed Explanation
Investigate/fix read access status mismatch between Explorer and DB (#32)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Add action list_metadata_by_height (internal/migrations/021-metadata-actions.sql) New metadata query by height; unrelated to read_visibility or Explorer access-control fixes.
Add ListMetadataByHeight executor & input (tests/streams/utils/procedure/execute.go, types.go) Test utility to call the new action; does not modify access-control or visibility behavior.
Add by-height metadata tests (tests/streams/query/metadata_test.go) Tests exercise the new action and pagination; not related to read visibility bug.
Add ExcludedColumns and related assertion logic (tests/streams/utils/table/assert.go) Test assertion enhancement; unrelated to read_visibility or Explorer integration.

Suggested labels

type: feat

Suggested reviewers

  • outerlook
  • MicBun

Poem

I hop through blocks and nibble at keys,
Counting rows like carrots beneath the trees,
Paginate my burrow—one hop, then two,
Tests hum softly as I sort every view.
A newline tip-tap — tidy, and adieu.


📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 71e8c20 and d69f9d5.

📒 Files selected for processing (1)
  • tests/streams/utils/table/assert.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/streams/utils/table/assert.go
⏰ 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). (1)
  • GitHub Check: acceptance-test
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/view-metadata-by-height

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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit 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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

Comment thread internal/migrations/001-common-actions.sql Outdated
@holdex
Copy link
Copy Markdown

holdex Bot commented Sep 4, 2025

Time Submission Status

Member Status Time Action Last Update
MicBun ✅ Submitted 20min Update time Sep 5, 2025, 3:09 AM
williamrusdyputra ✅ Submitted 5h Update time Sep 5, 2025, 3:09 AM

@williamrusdyputra williamrusdyputra marked this pull request as ready for review September 4, 2025 16:02
Copy link
Copy Markdown

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

🧹 Nitpick comments (6)
internal/migrations/021-metadata-actions.sql (4)

35-48: Enforce an upper bound on limit for safety/perf parity with list_streams.

list_streams caps/errs at 5000. Consider mirroring that here to prevent accidental full scans.

Apply:

     if $limit IS NULL {
         $limit := 1000;
     }
+    if $limit > 5000 {
+        ERROR('Limit exceeds maximum allowed value of 5000');
+    }
     if $offset IS NULL {
         $offset := 0;
     }

62-80: Add deterministic tiebreaker to ORDER BY.

Multiple rows can share the same created_at height. Add row_id as a stable secondary sort to avoid pagination flakiness.

-            ORDER BY created_at ASC
+            ORDER BY created_at ASC, row_id ASC
             LIMIT $limit OFFSET $offset;

17-24: Clarify/validate required parameters and visibility semantics.

  • Should $key be mandatory? Today WHERE metadata_key = $key returns no rows if $key is NULL. If this is unintended, return a clear error when $key is NULL/empty.
  • Should this listing respect stream read_visibility (public/private) like Explorer endpoints do? If not, confirm that exposing metadata across all streams is acceptable.

71-79: Indexing check for query path.

To keep this fast at scale, ensure an index like (metadata_key, created_at) (and optionally value_ref) exists, given the filter + order used here.

tests/streams/utils/procedure/types.go (1)

162-172: Name alignment and parameter clarity.

  • Nit: fix spacing on Key to match surrounding style.
  • Consider renaming ValueRef to reflect $ref in the SQL and avoid confusion with typed value columns (value_i, etc.). This is optional but improves readability.
 type ListMetadataByHeightInput struct {
 	Platform   *kwilTesting.Platform
-	Key 			 string
+	Key        string
-	Value      *string
+	// Ref corresponds to SQL parameter $ref (matches metadata.value_ref)
+	// Ref *string  // optional future rename; would require callsite updates
+	Value      *string
 	FromHeight *int64
 	ToHeight   *int64
 	Limit      *int
 	Offset     *int
 	Height     int64
 }
tests/streams/query/metadata_test.go (1)

265-326: Optional: factor out duplicated seeding across tests.

The three by-height tests repeat the same insert loop. Extract a small helper to seed metadataItems to reduce noise.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 82f1d36 and 304efdf.

📒 Files selected for processing (5)
  • internal/migrations/001-common-actions.sql (1 hunks)
  • internal/migrations/021-metadata-actions.sql (1 hunks)
  • tests/streams/query/metadata_test.go (4 hunks)
  • tests/streams/utils/procedure/execute.go (1 hunks)
  • tests/streams/utils/procedure/types.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
tests/streams/utils/procedure/execute.go (1)
tests/streams/utils/procedure/types.go (2)
  • ListMetadataByHeightInput (163-172)
  • ResultRow (32-32)
tests/streams/query/metadata_test.go (6)
tests/streams/utils/utils.go (1)
  • RunSchemaTest (372-407)
tests/streams/utils/setup/common.go (1)
  • StreamInfo (20-23)
tests/streams/utils/procedure/metadata.go (2)
  • InsertMetadata (293-328)
  • InsertMetadataInput (283-290)
tests/streams/utils/procedure/execute.go (1)
  • ListMetadataByHeight (848-888)
tests/streams/utils/procedure/types.go (1)
  • ListMetadataByHeightInput (163-172)
tests/streams/utils/table/assert.go (2)
  • AssertResultRowsEqualMarkdownTable (18-81)
  • AssertResultRowsEqualMarkdownTableInput (11-16)
⏰ 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). (2)
  • GitHub Check: acceptance-test
  • GitHub Check: lint
🔇 Additional comments (3)
internal/migrations/001-common-actions.sql (1)

1322-1322: No functional change — OK to merge.

Only a trailing newline added; nothing else modified.

tests/streams/utils/procedure/execute.go (1)

847-888: LGTM — engine call wiring and context setup look consistent with existing helpers.

tests/streams/query/metadata_test.go (1)

36-47: Nice test coverage expansion.

Good additions covering happy path, missing key, pagination, invalid ranges, and negative pagination.

Comment thread tests/streams/query/metadata_test.go
Comment thread tests/streams/query/metadata_test.go
Copy link
Copy Markdown

@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

♻️ Duplicate comments (2)
tests/streams/query/metadata_test.go (2)

207-212: Fix Markdown table delimiter row (malformed).

The separator has the wrong number of columns. Make it match the 7 headers.

-        |---------------|-----------|---------------------|-----------------|--------|------------|----------------|------------|------------|------------|
+        |------------|---------|---------|---------|---------|-----------|------------|

257-260: Bug: wrapping a nil error returns nil — test won’t fail.

Use a new error to fail the test when results are unexpectedly non-empty.

-        if (len(result) > 0) { // should return no rows
-            return errors.Wrapf(err, "expected empty results")
-        }
+        if len(result) > 0 { // should return no rows
+            return errors.New("expected empty results")
+        }
🧹 Nitpick comments (5)
tests/streams/utils/table/assert.go (2)

25-39: Make row filtering robust (avoid hard-coded column index).

Skipping rows via row[1] != "" is brittle for 1-column tables. Check for any non-empty cell instead.

-    for _, row := range expectedTable.Rows {
-        if row[1] != "" {
-            transformedRow := make([]string, len(row))
-            for colIdx, value := range row {
-                colName := expectedTable.Headers[colIdx]
-                if transformer, exists := input.ColumnTransformers[colName]; exists && transformer != nil {
-                    transformedRow[colIdx] = transformer(value)
-                } else {
-                    transformedRow[colIdx] = value
-                }
-            }
-            expected = append(expected, transformedRow)
-        }
-    }
+    for _, row := range expectedTable.Rows {
+        hasValue := false
+        for _, v := range row {
+            if v != "" { hasValue = true; break }
+        }
+        if !hasValue { continue }
+        transformedRow := make([]string, len(row))
+        for colIdx, value := range row {
+            colName := expectedTable.Headers[colIdx]
+            if transformer, exists := input.ColumnTransformers[colName]; exists && transformer != nil {
+                transformedRow[colIdx] = transformer(value)
+            } else {
+                transformedRow[colIdx] = value
+            }
+        }
+        expected = append(expected, transformedRow)
+    }

16-17: Clarify index space of ExcludedColumns.

Document that indices are relative to ACTUAL rows (pre-exclusion), not expected headers.

-    ExcludedColumns    []int // drop only from actual
+    ExcludedColumns    []int // indices relative to ACTUAL rows; drop only from actual
tests/streams/query/metadata_test.go (3)

213-217: Stabilize order: sort by value and created_at in the assertion.

Avoid relying on DB default ordering.

         table.AssertResultRowsEqualMarkdownTable(t, table.AssertResultRowsEqualMarkdownTableInput{
             Actual:   result,
             Expected: expected,
             ExcludedColumns: []int{1},
+            SortColumns: []string{"value_i", "created_at"},
         })

292-307: Strengthen pagination test by asserting content/order, not just counts.

Counts alone won’t catch ordering bugs. Consider asserting expected rows or using the table assertion with SortColumns.


406-431: Clarify expectations for negative pagination values.

  • For negative limit you check for empty results — good.
  • For negative offset you only assert no error; also assert that it’s coerced to 0 (e.g., result length equals total matching rows).

Would you like a follow-up patch to assert the expected length based on the inserted rows?

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 304efdf and 71e8c20.

📒 Files selected for processing (2)
  • tests/streams/query/metadata_test.go (4 hunks)
  • tests/streams/utils/table/assert.go (3 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
tests/streams/query/metadata_test.go (6)
tests/streams/utils/utils.go (1)
  • RunSchemaTest (372-407)
tests/streams/utils/setup/common.go (1)
  • StreamInfo (20-23)
tests/streams/utils/procedure/metadata.go (2)
  • InsertMetadata (293-328)
  • InsertMetadataInput (283-290)
tests/streams/utils/procedure/execute.go (1)
  • ListMetadataByHeight (848-888)
tests/streams/utils/procedure/types.go (1)
  • ListMetadataByHeightInput (163-172)
tests/streams/utils/table/assert.go (2)
  • AssertResultRowsEqualMarkdownTable (19-99)
  • AssertResultRowsEqualMarkdownTableInput (11-17)
⏰ 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). (2)
  • GitHub Check: acceptance-test
  • GitHub Check: lint
🔇 Additional comments (1)
tests/streams/query/metadata_test.go (1)

356-374: LGTM: invalid range negative test is precise.

Error presence and message assertion look good.

Comment thread tests/streams/utils/table/assert.go Outdated
Copy link
Copy Markdown
Contributor

@MicBun MicBun left a comment

Choose a reason for hiding this comment

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

lgtm

@MicBun MicBun merged commit 7ac741c into main Sep 5, 2025
8 checks passed
@MicBun MicBun deleted the feat/view-metadata-by-height branch September 5, 2025 03:09
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