Skip to content

Fix invalid delete on rollback - #555

Merged
JonoPrest merged 8 commits into
mainfrom
jp/fix-invalid-delete-on-rollback
May 27, 2025
Merged

Fix invalid delete on rollback#555
JonoPrest merged 8 commits into
mainfrom
jp/fix-invalid-delete-on-rollback

Conversation

@JonoPrest

@JonoPrest JonoPrest commented May 27, 2025

Copy link
Copy Markdown
Collaborator

The issue was in multiple copies of an different entities into entity history within a batch and these copies were not filtered out of the diffing queries.

I've created a sequence diagram to explain the case and I've added tests to validate that it now works.

sequenceDiagram
  participant Indexer
  participant MyEntity
  participant MyEntity_history

  Note over Indexer: Batch processing begins (contains single event from blockNumber 100)

  Indexer->>MyEntity: Update MyEntity(id="a")
  Note right of MyEntity: No recent history for "a"
  MyEntity->>MyEntity_history: Insert copy of current "a" (eg. serial = 10)
  MyEntity->>MyEntity_history: Insert updated "a" (serial = 11)

  Indexer->>MyEntity: Update MyEntity(id="b")
  Note right of MyEntity: No recent history for "b"
  MyEntity->>MyEntity_history: Insert copy of current "b" (serial = 12)
  MyEntity->>MyEntity_history: Insert updated "b" (serial = 13)

  Note over Indexer: Batch finished

  Note over Indexer: Reorg detected at block 100

  Indexer->>MyEntity_history: Find first entity change ≥ block 100
  Note over MyEntity_history: Serial 11 found (update for "a") ✅

  Indexer->>MyEntity_history: Find all changes ≥ serial 11
  Note over MyEntity_history: Finds "b" at serial 12 ❌ (copied row)

  Indexer->>MyEntity_history: Lookup previous values
  MyEntity_history-->>Indexer: Found previous for "a" (upsert) ✅
  MyEntity_history-->>Indexer: No previous for "b" (delete) ❌

  Note over Indexer: Misinterpreted copied row as first change for "b"
Loading

Summary by CodeRabbit

  • Bug Fixes
    • Improved reliability of entity history rollback and pruning by excluding placeholder entries with zero chain ID and timestamp.
  • Documentation
    • Expanded comments to clarify the behavior of rollback modes and event handling.
  • Tests
    • Added comprehensive tests for entity history rollback and pruning, including scenarios with copied entities and reorg thresholds.
    • Introduced new mock data to support advanced test cases.

@JonoPrest
JonoPrest requested a review from DZakh May 27, 2025 16:44
@coderabbitai

coderabbitai Bot commented May 27, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This update introduces additional filtering to SQL queries in entity history rollback and pruning functions, ensuring that rows with both entity_history_chain_id and entity_history_block_timestamp set to zero are excluded. Formatting improvements such as trailing commas and enhanced comments are also included. The test suite is expanded to cover rollback and pruning scenarios involving copied entities.

Changes

File(s) Change Summary
codegenerator/cli/templates/static/codegen/src/db/DbFunctionsImplementation.js Added filtering to exclude rows with chain ID and timestamp zero in SQL queries; improved formatting and comments.
scenarios/test_codegen/test/lib_tests/EntityHistory_test.res Added new tests and mocks for entity history rollback and pruning, including scenarios with copied entities.

Sequence Diagram(s)

sequenceDiagram
    participant TestSuite as Test Suite
    participant DB as Database
    participant EntityHistory as Entity History Logic

    TestSuite->>DB: Reset and migrate database
    TestSuite->>EntityHistory: Insert mock entities and history rows
    EntityHistory->>DB: Insert entities/history (with possible chain_id=0)
    TestSuite->>EntityHistory: Trigger rollback/prune operations
    EntityHistory->>DB: Execute SQL with filtering (exclude chain_id=0 & timestamp=0)
    DB-->>EntityHistory: Return filtered results
    EntityHistory-->>TestSuite: Provide rollback/prune outcome
Loading

Possibly related PRs

Suggested reviewers

  • DZakh

Poem

In the warren of code, a filter appears,
Excluding the zeros, allaying our fears.
Rollbacks and pruning, now tested with care,
Copied histories handled, no bugs to ensnare.
With commas aligned and queries refined,
The database garden is perfectly designed!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

♻️ Duplicate comments (2)
codegenerator/cli/templates/static/codegen/src/db/DbFunctionsImplementation.js (2)

477-482: Rollback-diff query repeats the filter

The filter is re-introduced here. Switching to the shared constant and row comparison keeps all three queries consistent and index-friendly.


409-414: 🛠️ Refactor suggestion

Same predicate duplicated – DRY & index​ability

Same remarks as above apply inside the pruneStaleEntityHistory CTE. Re-use the shared constant to avoid drifting implementations.

🧹 Nitpick comments (2)
scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (2)

219-225: Extremely brittle string-equality assertion

A one-to-one equality against the full CREATE TABLE DDL will fail on harmless changes (e.g. re-ordering fields, formatting, or adding an index).
Consider asserting only the essential parts:

let createQuery =Assert.ok(createQuery->Js.String.includes("\"TestEntity_history\""))
Assert.ok(createQuery->Js.String.includes("\"serial\" SERIAL"))

This preserves intent while avoiding noisy test failures.


718-735: Test suite is performing full DB migrations in every iteration

Running down/up migrations for each test is ~seconds per call and dominates CI time. Group the “setup schema” phase into a beforeAll and use transactions/ROLLBACK in beforeEach to restore a clean slate instantaneously:

Async.beforeAll(async () => { /* run migrations once */ })
Async.beforeEach(async () => await Db.sql->Postgres.beginSql(sql => [sql`BEGIN`]))
Async.afterEach(async () => await Db.sql->Postgres.unsafe("ROLLBACK"))

This keeps isolation while slashing execution time.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4e7d8df and 22b9c91.

⛔ Files ignored due to path filters (1)
  • scenarios/test_codegen/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (2)
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctionsImplementation.js (20 hunks)
  • scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build_and_test

Comment on lines +369 to 374
-- Filter out rows with a chain_id of 0 since they are the copied history rows
-- check timestamp as well in case a future chain is added with id of 0
AND NOT (
entity_history_chain_id = 0 AND
entity_history_block_timestamp = 0
);

@coderabbitai coderabbitai Bot May 27, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consolidate the “copied history” filter for maintainability and speed

The duplicated 4-line predicate appears in three separate queries. Besides the maintenance overhead, row-wise AND/NOT comparisons prevent Postgres from using multi-column indexes efficiently.

-    AND NOT (
-      entity_history_chain_id = 0 AND
-      entity_history_block_timestamp = 0
-    );
+    -- `(row) <> (0,0)` lets the planner leverage a composite index
+    AND (entity_history_chain_id, entity_history_block_timestamp) <> (0, 0);

Consider extracting this into:

const copiedHistoryRowFilter = sql`
  (entity_history_chain_id, entity_history_block_timestamp) <> (0, 0)
`;

and re-using it in all queries.
This both DRYs the code and makes adding a composite index on (entity_history_chain_id, entity_history_block_timestamp) straight-forward.

🤖 Prompt for AI Agents
In
codegenerator/cli/templates/static/codegen/src/db/DbFunctionsImplementation.js
around lines 369 to 374, the filter excluding copied history rows is duplicated
across multiple queries using separate AND/NOT conditions, which hinders
maintainability and index usage. Refactor by defining a single reusable
constant, copiedHistoryRowFilter, that uses a tuple comparison to exclude rows
where (entity_history_chain_id, entity_history_block_timestamp) equals (0, 0).
Replace all occurrences of the original filter with this constant to DRY the
code and enable efficient multi-column indexing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Actually not a bad optimisation suggestion, but I think the query engine planner should be able to leverage a composite in both cases. Either way need to add a composite for this. Not sure it's necessary for a low amount of rows in a reorg threshold where this operates. So probably just a 👎🏼 from me

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@JonoPrest Fair point! You're absolutely right that with the low row counts in reorg thresholds, the performance difference would be negligible. The query planner should indeed handle both cases similarly, especially once you add that composite index. Thanks for the consideration and the clear reasoning - makes sense to keep it as is! 👍

Comment on lines +631 to +659
Async.it("Rollback ignores copied entities as an item in reorg threshold", async () => {
let rollbackDiff = await Db.sql->DbFunctions.EntityHistory.getRollbackDiff(
OrderedMultichain({
reorgChainId: Mocks.GnosisBug.chain_id,
safeBlockNumber: 9,
safeBlockTimestamp: 9 * 5,
}),
~entityMod=module(TestEntity),
)

let expectedDiff: array<EntityHistory.historyRow<TestEntity.t>> = [
{
current: {chain_id: 0, block_timestamp: 0, block_number: 0, log_index: 0},
previous: %raw(`undefined`),
entityData: Set(Mocks.Entity.mockEntity1),
},
{
current: {chain_id: 0, block_timestamp: 0, block_number: 0, log_index: 0},
previous: %raw(`undefined`),
entityData: Set(Mocks.Entity.mockEntity5),
},
]

Assert.deepStrictEqual(
rollbackDiff,
expectedDiff,
~message="Should rollback to the copied entity",
)
})

@coderabbitai coderabbitai Bot May 27, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Order-sensitive deep comparison may flicker

DbFunctions.EntityHistory.getRollbackDiff does not guarantee deterministic ordering of diff rows. deepStrictEqual on the raw array will intermittently fail if Postgres returns rows in a different order.

Instead, sort by entityData.id or current.serial before comparing:

let cmp = (a,b) => Js.String.compare(a.EntityHistory.entityData.getId, b.EntityHistory.entityData.getId)
Assert.deepStrictEqual(rollbackDiff->Js.Array2.sortInPlaceWith(cmp), expectedDiff->Js.Array2.sortInPlaceWith(cmp))
🤖 Prompt for AI Agents
In scenarios/test_codegen/test/lib_tests/EntityHistory_test.res around lines 631
to 659, the test uses deepStrictEqual to compare rollbackDiff and expectedDiff
arrays directly, but the order of rows returned by getRollbackDiff is not
guaranteed, causing intermittent test failures. To fix this, sort both
rollbackDiff and expectedDiff arrays by a stable key such as entityData.id or
current.serial before comparing them with deepStrictEqual, ensuring
order-insensitive comparison.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Should not be the case for this isolated test

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@JonoPrest You're absolutely right. In this isolated test scenario with controlled mock data and a clean database setup, the ordering should be deterministic. The test creates a specific controlled environment where the getRollbackDiff results should be predictable based on the exact mock entities and history rows being inserted.

Since this test runs in isolation with the beforeEach setup resetting the state and inserting specific controlled data, there shouldn't be any non-deterministic ordering issues. My suggestion was overly cautious for this particular test context.

  /|   /|   
 ( :v:  :v: )
  |(_)(_)|
  |       |
  \       /
   \_   _/
     ^^^

✏️ Learnings added
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:631-659
Timestamp: 2025-05-27T17:07:12.870Z
Learning: In isolated tests for EntityHistory rollbacks with controlled mock data setup, the ordering of getRollbackDiff results is deterministic and doesn't require sorting before comparison with deepStrictEqual.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

Comment on lines +582 to +629
describe("Entity history rollbacks", () => {
Async.beforeEach(async () => {
try {
let _ = DbHelpers.resetPostgresClient()
let _ = await Migrations.runDownMigrations(~shouldExit=false)
let _ = await Migrations.createEnumIfNotExists(Db.sql, EntityHistory.RowAction.enum)
let _ = await Migrations.creatTableIfNotExists(Db.sql, TestEntity.table)
let _ = await Migrations.creatTableIfNotExists(Db.sql, TestEntity.entityHistory.table)

let _ = await Db.sql->Postgres.unsafe(TestEntity.entityHistory.createInsertFnQuery)

try await Db.sql->DbFunctionsEntities.batchSet(~entityMod=module(TestEntity))([
Mocks.Entity.mockEntity1,
Mocks.Entity.mockEntity5,
]) catch {
| exn =>
Js.log2("batchSet mock entity exn", exn)
Assert.fail("Failed to set mock entity in table")
}

try await Db.sql->Postgres.beginSql(
sql => [
TestEntity.entityHistory->EntityHistory.batchInsertRows(
~sql,
~rows=Mocks.GnosisBug.historyRows,
),
],
) catch {
| exn =>
Js.log2("insert mock rows exn", exn)
Assert.fail("Failed to insert mock rows")
}

let historyItems = {
let items = await Db.sql->getAllMockEntityHistory
items->S.parseJsonOrThrow(TestEntity.entityHistory.schemaRows)
}
Assert.equal(historyItems->Js.Array2.length, 4, ~message="Should have 4 history items")
Assert.ok(
historyItems->Belt.Array.some(item => item.current.chain_id == 0),
~message="Should contain 2 copied items",
)
} catch {
| exn =>
Js.log2(" Entity history setup exn", exn)
Assert.fail("Failed setting up tables")
}
})

@coderabbitai coderabbitai Bot May 27, 2025

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

beforeEach does not await DbHelpers.resetPostgresClient()

resetPostgresClient() is called without await, so subsequent statements can race with the connection teardown, leading to rare “connection already closed” failures on busy CI runners.

-    try {
-      let _ = DbHelpers.resetPostgresClient()
+    try {
+      await DbHelpers.resetPostgresClient()

Ensuring the promise resolves keeps the setup deterministic.

📝 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
describe("Entity history rollbacks", () => {
Async.beforeEach(async () => {
try {
let _ = DbHelpers.resetPostgresClient()
let _ = await Migrations.runDownMigrations(~shouldExit=false)
let _ = await Migrations.createEnumIfNotExists(Db.sql, EntityHistory.RowAction.enum)
let _ = await Migrations.creatTableIfNotExists(Db.sql, TestEntity.table)
let _ = await Migrations.creatTableIfNotExists(Db.sql, TestEntity.entityHistory.table)
let _ = await Db.sql->Postgres.unsafe(TestEntity.entityHistory.createInsertFnQuery)
try await Db.sql->DbFunctionsEntities.batchSet(~entityMod=module(TestEntity))([
Mocks.Entity.mockEntity1,
Mocks.Entity.mockEntity5,
]) catch {
| exn =>
Js.log2("batchSet mock entity exn", exn)
Assert.fail("Failed to set mock entity in table")
}
try await Db.sql->Postgres.beginSql(
sql => [
TestEntity.entityHistory->EntityHistory.batchInsertRows(
~sql,
~rows=Mocks.GnosisBug.historyRows,
),
],
) catch {
| exn =>
Js.log2("insert mock rows exn", exn)
Assert.fail("Failed to insert mock rows")
}
let historyItems = {
let items = await Db.sql->getAllMockEntityHistory
items->S.parseJsonOrThrow(TestEntity.entityHistory.schemaRows)
}
Assert.equal(historyItems->Js.Array2.length, 4, ~message="Should have 4 history items")
Assert.ok(
historyItems->Belt.Array.some(item => item.current.chain_id == 0),
~message="Should contain 2 copied items",
)
} catch {
| exn =>
Js.log2(" Entity history setup exn", exn)
Assert.fail("Failed setting up tables")
}
})
describe("Entity history rollbacks", () => {
Async.beforeEach(async () => {
try {
await DbHelpers.resetPostgresClient()
let _ = await Migrations.runDownMigrations(~shouldExit=false)
let _ = await Migrations.createEnumIfNotExists(Db.sql, EntityHistory.RowAction.enum)
let _ = await Migrations.creatTableIfNotExists(Db.sql, TestEntity.table)
let _ = await Migrations.creatTableIfNotExists(Db.sql, TestEntity.entityHistory.table)
let _ = await Db.sql->Postgres.unsafe(TestEntity.entityHistory.createInsertFnQuery)
try await Db.sql->DbFunctionsEntities.batchSet(~entityMod=module(TestEntity))([
Mocks.Entity.mockEntity1,
Mocks.Entity.mockEntity5,
]) catch {
| exn =>
Js.log2("batchSet mock entity exn", exn)
Assert.fail("Failed to set mock entity in table")
}
try await Db.sql->Postgres.beginSql(
sql => [
TestEntity.entityHistory->EntityHistory.batchInsertRows(
~sql,
~rows=Mocks.GnosisBug.historyRows,
),
],
) catch {
| exn =>
Js.log2("insert mock rows exn", exn)
Assert.fail("Failed to insert mock rows")
}
let historyItems = {
let items = await Db.sql->getAllMockEntityHistory
items->S.parseJsonOrThrow(TestEntity.entityHistory.schemaRows)
}
Assert.equal(historyItems->Js.Array2.length, 4, ~message="Should have 4 history items")
Assert.ok(
historyItems->Belt.Array.some(item => item.current.chain_id == 0),
~message="Should contain 2 copied items",
)
} catch {
| exn =>
Js.log2(" Entity history setup exn", exn)
Assert.fail("Failed setting up tables")
}
})
🤖 Prompt for AI Agents
In scenarios/test_codegen/test/lib_tests/EntityHistory_test.res around lines 582
to 629, the call to DbHelpers.resetPostgresClient() inside the beforeEach hook
is missing an await, causing potential race conditions with connection teardown.
Fix this by adding await before DbHelpers.resetPostgresClient() to ensure the
promise resolves before proceeding with subsequent setup steps.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not valid

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

I need to investigate the DbHelpers.resetPostgresClient() function to understand why my analysis was incorrect.


🏁 Script executed:

#!/bin/bash
# Find and examine the DbHelpers.resetPostgresClient function implementation
ast-grep --pattern 'resetPostgresClient($_) {
  $$$
}'

Length of output: 56


🏁 Script executed:

#!/bin/bash
# Search for resetPostgresClient function definition
rg "resetPostgresClient" -A 10 -B 2

Length of output: 6496


🏁 Script executed:

#!/bin/bash
# Find DbHelpers module files
fd "DbHelpers" --type f

Length of output: 127


@JonoPrest You're absolutely right - my analysis was incorrect.

Looking at the implementation, DbHelpers.resetPostgresClient has the signature unit => unit, making it a synchronous function that doesn't return a promise:

let resetPostgresClient: unit => unit = () => {
  // This is a hack to reset the postgres client between tests. postgres.js seems to cache some types, and if tests clear the DB you need to also reset sql.
  %raw("require('../../generated/src/db/Db.bs.js').sql = require('postgres')(_sqlConfig)")
}

The function performs a synchronous JavaScript operation to reassign the SQL client, so adding await would be incorrect. I apologize for the false positive.


🏁 Script executed:

#!/bin/bash
# Let's examine the function signature more clearly
cat scenarios/test_codegen/test/helpers/DbHelpers.res

Length of output: 541


@JonoPrest You're absolutely right - my analysis was incorrect.

Looking at the implementation, DbHelpers.resetPostgresClient has the signature unit => unit, making it a synchronous function that doesn't return a promise:

let resetPostgresClient: unit => unit = () => {
  // This is a hack to reset the postgres client between tests. postgres.js seems to cache some types, and if tests clear the DB you need to also reset sql.
  %raw("require('../../generated/src/db/Db.bs.js').sql = require('postgres')(_sqlConfig)")
}

The function performs a synchronous JavaScript operation to reassign the SQL client, so adding await would be incorrect. I apologize for the false positive.


✏️ Learnings added
Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.658Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.

Learnt from: JonoPrest
PR: enviodev/hyperindex#555
File: scenarios/test_codegen/test/lib_tests/EntityHistory_test.res:582-629
Timestamp: 2025-05-27T17:07:04.658Z
Learning: In ReScript test files using DbHelpers.resetPostgresClient(), this function is synchronous with signature `unit => unit` and should not be awaited. It performs a raw JavaScript reassignment of the postgres client and does not return a promise.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@DZakh DZakh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nice 🥳 I'm still reviewing, but approve before hand, if I won't internet later

@DZakh DZakh left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@JonoPrest
JonoPrest merged commit d951ba3 into main May 27, 2025
@JonoPrest
JonoPrest deleted the jp/fix-invalid-delete-on-rollback branch May 27, 2025 19:03
@coderabbitai coderabbitai Bot mentioned this pull request Jul 24, 2025
17 tasks
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