Skip to content

Librarify persistence layer#558

Merged
DZakh merged 14 commits into
mainfrom
dz/persistence-layer
Jun 3, 2025
Merged

Librarify persistence layer#558
DZakh merged 14 commits into
mainfrom
dz/persistence-layer

Conversation

@DZakh

@DZakh DZakh commented May 28, 2025

Copy link
Copy Markdown
Member

And add DI support

Summary by CodeRabbit

  • New Features

    • Introduced a configurable persistence layer with support for asynchronous initialization, dependency injection, and testability.
    • Added PostgreSQL schema management with automated creation of tables, indexes, enums, and initialization transactions.
  • Refactor

    • Centralized entity, enum, and storage configuration into a unified persistence abstraction.
    • Replaced manual migration logic with a single persistence initialization call.
    • Updated enum handling to use configuration objects instead of concrete enum modules.
    • Separated logger creation and assignment for improved clarity.
  • Bug Fixes

    • Standardized enum schema and configuration references across modules.
  • Tests

    • Added comprehensive tests for persistence initialization and PostgreSQL SQL generation.
    • Updated existing tests to use the new persistence and storage initialization patterns.
  • Chores

    • Updated Cursor rules for ReScript code style and documentation references.
  • Revert

    • Removed obsolete enum abstraction file and related manual SQL migration helpers.

@coderabbitai

coderabbitai Bot commented May 28, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

This update introduces a new persistence abstraction for managing database and in-memory state, refactors enum and entity configuration handling, and centralizes initialization logic for storage and migrations. It adds PostgreSQL schema generation utilities, restructures configuration and migration flows, and updates related tests. Several obsolete or redundant functions and files are removed.

Changes

File(s) / Group Change Summary
.cursor/rules/rescript.mdc Added Cursor rules for ReScript files specifying documentation version, syntax preferences, and assignment conventions.
codegenerator/cli/npm/envio/src/Internal.res Added abstract enum type, enumConfig record, and helper functions for enum configuration.
codegenerator/cli/npm/envio/src/Logging.res Split logger creation and assignment into makeLogger and setLogger; updated signatures.
codegenerator/cli/npm/envio/src/Persistence.res New module implementing persistence abstraction with storage interface, status tracking, and initialization logic.
codegenerator/cli/npm/envio/src/PgStorage.res New module for PostgreSQL schema SQL generation and initialization, implementing Persistence.storage.
codegenerator/cli/npm/envio/src/Enum.res Deleted file; removed enum abstraction and related types/functions.
codegenerator/cli/npm/envio/src/db/EntityHistory.res Updated to use schema directly for enums; adjusted field construction and references.
codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs Removed explicit ~entities parameter from Config.make call.
codegenerator/cli/templates/dynamic/codegen/src/db/Entities.res.hbs Replaced module-type-based entity casts with direct internal config usage; added cast function in entity modules; restructured entity arrays.
codegenerator/cli/templates/dynamic/codegen/src/db/Enums.res.hbs Changed enum creation to use Internal.makeEnumConfig; renamed enum to config; updated allEnums to use config objects.
codegenerator/cli/templates/static/codegen/src/Config.res Replaced entities field with persistence in config type; introduced codegenPersistence; updated make implementation.
codegenerator/cli/templates/static/codegen/src/Env.res Updated logger setup to use makeLogger and pass logger instance to setLogger.
codegenerator/cli/templates/static/codegen/src/Index.res Replaced migration check with direct call to Persistence.init for initialization.
codegenerator/cli/templates/static/codegen/src/db/Migrations.res Removed manual migration logic and helpers; simplified to a call to Persistence.init.
codegenerator/cli/templates/static/codegen/src/db/TablesStatic.res Updated enum schema references from .enum to .config in table definitions.
codegenerator/cli/src/config_parsing/postgres_types.rs Changed enum property reference from .enum.name to .config.name in string formatting.
codegenerator/cli/src/rescript_types.rs Changed enum schema reference from .enum.schema to .config.schema in schema formatting.
scenarios/erc20_multichain_factory/test/TestDeleteEntity.res Removed explicit ~entities override from Config.make call.
scenarios/erc20_multichain_factory/test/TestWhereQuery.res Removed explicit ~entities override from Config.make call.
scenarios/test_codegen/test/SerDe_Test.res Changed SQL generation function call to use PgStorage.makeCreateTableSqlUnsafe.
scenarios/test_codegen/test/lib_tests/EntityHistory_test.res Replaced direct migration calls with unified storage initialization via PgStorage; updated SQL generation references.
scenarios/test_codegen/test/lib_tests/Persistence_test.res Added new test suite for Persistence initialization logic, covering state transitions and initialization scenarios.
scenarios/test_codegen/test/lib_tests/PgStorage_test.res Added new test suite for PgStorage SQL generation functions, verifying output for various schema scenarios.
scenarios/test_codegen/test/rollback/Rollback_test.res Removed explicit ~entities override from Config.make call.

Sequence Diagram(s)

sequenceDiagram
    participant Main
    participant Persistence
    participant Storage
    participant Callback

    Main->>Persistence: init(~skipIsInitializedCheck, ~reset)
    alt Already Initializing
        Persistence-->>Main: Await existing promise
    else Ready and not reset
        Persistence-->>Main: Return (no-op)
    else Needs Initialization
        Persistence->>Storage: isInitialized()
        alt Already initialized
            Persistence-->>Main: Set status to Ready(cleanRun=false)
        else Not initialized or reset
            Persistence->>Storage: initialize(~entities, ~staticTables, ~enums, ~cleanRun)
            alt onStorageInitialize exists
                Persistence->>Callback: onStorageInitialize()
            end
            Persistence-->>Main: Set status to Ready(cleanRun=true)
        end
    end
Loading

Suggested reviewers

  • JonoPrest

Poem

In fields of code where schemas grow,
The rabbits hop and enums flow.
Persistence now is smart and neat,
With PostgreSQL beneath our feet.
Migrations gone, the tests all cheer—
The garden’s clean, the sky is clear!
🐇✨

✨ Finishing Touches
  • 📝 Generate Docstrings

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

@DZakh DZakh marked this pull request as draft May 28, 2025 15:51

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

🧹 Nitpick comments (10)
codegenerator/cli/templates/static/codegen/src/Config.res (1)

81-88: Excellent architectural improvement with persistence abstraction.

The new codegenPersistence construction centralizes all persistence concerns:

  • User entities and dynamic contract registry entities
  • All enums with proper internal configuration casting
  • PostgreSQL storage backend integration
  • Clean separation between configuration and storage concerns

This represents a significant improvement in code organization and maintainability.

Note: The Utils.magic cast for enums on line 86 may be necessary due to type system limitations, but consider adding a comment explaining this type conversion.

codegenerator/cli/npm/envio/src/Persistence.res (1)

54-56: Avoid %raw("null") for safer, typed initialisation

Using a raw null can lead to runtime undefined is not a function errors if the promise is resolved before resolveRef is mutated. Prefer () => () as a typed no-op placeholder (as shown in the diff above).

codegenerator/cli/templates/static/codegen/src/db/DbFunctionsEntities.res (2)

75-86: WeakMap keying by record may miss cache hits

Internal.entityConfig is a record; every call site that constructs an identical record literal produces a fresh JS object.
Because WeakMap keys are compared by reference, two logically identical configs will not hit the cache unless the same instance is reused.

If the codebase recreates configs (e.g. via Entities.entityModToInternal), the cache degenerates and the batch‐set query is rebuilt for every call.

Possible remedies:

  1. Store the generated function inside the entityConfig itself, or
  2. Use a stable primitive key (e.g. table name) for the WeakMap.

109-146: Sanitise fieldName before passing to external SQL helpers

fieldName is interpolated into log params and forwarded to JS externs.
Although callers are expected to use compile-time constants, adding a simple whitelist check (against entityConfig.table.columnNames) will guard against accidental injection when new code paths are added.

codegenerator/cli/templates/static/codegen/src/db/DbFunctions.res (2)

408-423: Unbounded parallel DB calls – consider throttling

allEntities->Belt.Array.map(async ...) |> Promise.all fires one concurrent query per entity.
With many entities this can:

  • Exhaust the Postgres connection pool
  • Cause large memory spikes on the JS side
  • Reduce overall throughput due to contention

If the entity count can grow, introduce a small concurrency limiter:

let parallelMap = Concurrency.mapWithLimit(~limit=8)

await allEntities
->parallelMap(async entityConfig => { /* body unchanged */ })
->Promise.all

(or reuse an existing rate-limiter util).


549-567: Minor: await on plain arrays is unnecessary

Entities.allEntities is already an array; the leading await is a no-op and may mislead future readers into thinking it is a promise. Removing it improves readability with zero functional impact.

codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (2)

296-299: logger parameter is shadowed and never used

~logger as _=? discards the supplied logger. Either remove the argument or forward it to child calls so users can debug failed entity loads.

-  (ids, ~entityConfig, ~logger as _=?) => {
+  (ids, ~entityConfig, ~logger=?) => {
     let operations = mockDb->getEntityOperations(~entityConfig)
-    ids->Array.keepMap(id => operations.get(id))->Promise.resolve
+    ids
+    ->Array.keepMap(id => operations.get(id))
+    ->Promise.resolve
+    ->Promise.tap(_ =>
+      switch logger {
+      | Some(l) => l->Pino.debug("Loaded " ++ string_of_int(Array.length(ids)) ++ " entities")
+      | None => ()
+      }
+    )
   }

312-318: Unusual partial-application pattern harms readability

mockDbTable->InMemoryTable.Entity.hasIndex(~fieldName, ~operator))(fieldValueHash) nests a second pair of parentheses, implying that hasIndex returns a function. This isn’t obvious to a reader skimming the code.

A flatter style improves clarity:

-    if (mockDbTable->InMemoryTable.Entity.hasIndex(~fieldName, ~operator))(fieldValueHash) {
+    let hasIdx =
+      mockDbTable->InMemoryTable.Entity.hasIndex(~fieldName, ~operator, fieldValueHash)
+    if hasIdx {

Consider refactoring hasIndex so the full arity is explicit; this yields the same perf but better comprehension.

codegenerator/cli/templates/static/codegen/src/InMemoryStore.res (1)

21-35: Return type relies on unsafe cast; can we eliminate Utils.magic?

EntityTables.get down-casts InMemoryTable.Entity.t<Entities.internalEntity> to InMemoryTable.Entity.t<entity> via Utils.magic. If callers pass an entityConfig that does not correspond to 'entity, we’ll corrupt memory safety and get runtime exceptions later.

A safer design is to return the untyped table and let callers perform the cast in one place, or add a phantom type field to entityConfig so the compiler can verify the mapping.

If keeping the cast, at least document the invariant above the function to alert future maintainers.

codegenerator/cli/templates/static/codegen/src/LoadLayer.resi (1)

8-14: Interface doc blocks still reference entityMod

While the types were migrated to entityConfig, the surrounding docs/examples (and possibly downstream tutorials) still mention entityMod. This can confuse integrators reading the .resi.

Please update the docstrings to reflect the new API surface.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c291898 and 9b1eed5.

⛔ Files ignored due to path filters (1)
  • scenarios/test_codegen/pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (28)
  • .cursor/rules/rescript.mdc (1 hunks)
  • codegenerator/cli/npm/envio/src/Internal.res (1 hunks)
  • codegenerator/cli/npm/envio/src/Logging.res (2 hunks)
  • codegenerator/cli/npm/envio/src/Persistence.res (1 hunks)
  • codegenerator/cli/npm/envio/src/PgStorage.res (1 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs (0 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/TestHelpers_MockDb.res.hbs (4 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/db/Entities.res.hbs (2 hunks)
  • codegenerator/cli/templates/static/codegen/src/Config.res (3 hunks)
  • codegenerator/cli/templates/static/codegen/src/Env.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/IO.res (8 hunks)
  • codegenerator/cli/templates/static/codegen/src/InMemoryStore.res (5 hunks)
  • codegenerator/cli/templates/static/codegen/src/Index.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/LoadLayer.res (6 hunks)
  • codegenerator/cli/templates/static/codegen/src/LoadLayer.resi (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/UserContext.res (9 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/Db.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctions.res (8 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/DbFunctionsEntities.res (4 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/Migrations.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res (1 hunks)
  • scenarios/test_codegen/test/LoadLayer_test.res (18 hunks)
  • scenarios/test_codegen/test/Mock_test.res (3 hunks)
  • scenarios/test_codegen/test/SerDe_Test.res (6 hunks)
  • scenarios/test_codegen/test/helpers/Mock.res (2 hunks)
  • scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (13 hunks)
  • scenarios/test_codegen/test/schema_types/BigDecimal_test.res (1 hunks)
  • scenarios/test_codegen/test/schema_types/Timestamp_test.res (1 hunks)
💤 Files with no reviewable changes (1)
  • codegenerator/cli/templates/dynamic/codegen/src/RegisterHandlers.res.hbs
🧰 Additional context used
🧠 Learnings (1)
scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (1)
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.
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build_and_test
🔇 Additional comments (52)
codegenerator/cli/templates/static/codegen/src/Env.res (1)

102-104: LGTM! Clean separation of logger creation and setting.

The refactoring properly separates logger creation (makeLogger) from logger assignment (setLogger), improving the separation of concerns and making the code more modular.

.cursor/rules/rescript.mdc (1)

1-10: Excellent addition of development tooling configuration.

This Cursor rules file will help maintain consistency across the codebase by:

  • Ensuring developers reference current ReScript 11 documentation
  • Preventing confusion by avoiding ReasonML syntax suggestions
  • Enforcing modern array syntax ([ item ] vs [| item |])
  • Clarifying field assignment conventions (= vs := for refs)

This type of tooling configuration is valuable for team development and code quality.

codegenerator/cli/templates/static/codegen/src/globalState/GlobalState.res (1)

802-808: LGTM! Consistent with the entity handling refactoring.

The change from entityMod to entityConfig with direct access to entityConfig.name is consistent with the broader architectural refactor moving from module-based entity handling to explicit configuration records. This approach:

  • Eliminates the need for module destructuring (module Entity = entityMod)
  • Provides direct access to entity metadata via entityConfig.name
  • Maintains the same functionality while using a cleaner data structure

The change aligns well with the introduction of Internal.entityConfig records throughout the codebase.

scenarios/test_codegen/test/LoadLayer_test.res (2)

10-10: LGTM: Consistent API migration from entityMod to entityConfig.

The systematic replacement of ~entityMod=module(Entities.User) with ~entityConfig=module(Entities.User)->Entities.entityModToInternal across all LoadLayer function calls is well-executed and maintains consistency throughout the test suite.

Also applies to: 40-40, 77-77, 108-108, 156-156, 197-197, 238-238, 290-290, 334-334, 345-345, 405-405, 417-417, 501-501


206-206: LGTM: Proper entity casting in assertions.

The updates to cast entities using Entities.User.castToInternal in assertions correctly align with the new internal entity representation pattern. This ensures test assertions work properly with the refactored persistence layer.

Also applies to: 257-257, 427-432, 455-456, 532-532

scenarios/test_codegen/test/schema_types/Timestamp_test.res (1)

22-24: LGTM: Correct migration to entityConfig-based persistence.

The update to DbFunctionsEntities.batchSet properly adopts the new API pattern:

  • Uses ~entityConfig with Entities.entityModToInternal transformation
  • Casts entity to internal representation via castToInternal before persistence

This aligns perfectly with the DI refactor objectives.

scenarios/test_codegen/test/schema_types/BigDecimal_test.res (1)

27-35: LGTM: Consistent entityConfig migration for multiple entities.

The migration correctly handles multiple entities:

  • Proper use of ~entityConfig parameter with Entities.entityModToInternal
  • Both entities correctly cast to internal representation using castToInternal
  • Array syntax properly maintained

This demonstrates the refactor works well for batch operations.

codegenerator/cli/templates/static/codegen/src/db/Db.res (3)

19-21: LGTM: Simplified entity table access pattern.

The direct access to entityConfig.table removes unnecessary module aliasing and aligns with the new entityConfig-based architecture. This simplifies the code while maintaining the same functionality.


26-27: LGTM: Consistent entityHistory handling.

The changes properly adapt entity history processing to use entityConfig.entityHistory directly, maintaining consistency with the table access pattern above.


19-30:

Details

❓ Verification inconclusive

Verify integration with Entities.allEntities structure.

Ensure that Entities.allEntities returns the appropriate entityConfig records that contain the expected table and entityHistory fields. The refactor appears sound, but the integration point should be verified.


🏁 Script executed:

#!/bin/bash
# Description: Verify that Entities.allEntities provides entityConfig records with required fields
# Expected: Find definitions showing entityConfig type and allEntities structure

# Search for entityConfig type definition
ast-grep --pattern 'type entityConfig = $_'

# Search for allEntities definition
ast-grep --pattern 'let allEntities = $_'

# Search for entityModToInternal function
ast-grep --pattern 'let entityModToInternal = $_'

Length of output: 141


🏁 Script executed:

#!/bin/bash
# Broaden the search to locate entityConfig, allEntities, and entityHistory definitions

# Search for entityConfig occurrences with context
rg --color=always -n -C2 'entityConfig' .

# Search for the definition of allEntities
rg --color=always -n -C2 'let allEntities' .

# Search for any EntityConfig type declaration (case‐insensitive)
rg --color=always -i -n -C2 'type.*entityconfig' .

# Search for entityHistory occurrences with context
rg --color=always -n -C2 'entityHistory' .

Length of output: 79220


Verify Entities.allEntities Record Shape

Ensure that your generated Entities module defines allEntities as an array of entityConfig records whose shape matches every consumer in the CLI templates:

  • In codegenerator/cli/templates/static/codegen/src/db/Db.res (lines 19–30), each entityConfig must have:
    • .table: Table.table
    • .entityHistory: EntityHistory.t<…> with a .table field
  • In DbFunctionsEntities.res, the entityConfig is deconstructed for .table, .schema, and .rowsSchema
  • In LoadLayer & UserContext templates, entityConfig is passed to functions expecting:
    • .name (for cache keys)
    • .entityHistory.schemaRows (for parsing history diffs)

Please review the definition in
codegenerator/cli/templates/dynamic/codegen/src/db/Entities.res.hbs
(or the generated Entities.res) to confirm that the entityConfig type includes all required fields and that allEntities is correctly built from it.

scenarios/test_codegen/test/SerDe_Test.res (6)

57-59: LGTM! Consistent with entity configuration refactoring.

The change from ~entityMod=module(...) to ~entityConfig=module(...)->Entities.entityModToInternal follows the expected pattern for the persistence layer DI refactoring.


61-63: LGTM! Consistent entity configuration pattern.

The batchRead function correctly follows the same refactoring pattern as batchSet.


75-75: LGTM! Proper internal casting for database operations.

Converting entities to their internal representation using castToInternal before database insertion is the correct approach for the new persistence layer.


85-85: LGTM! Assertion correctly compares internal representations.

Since database operations now use internal entity representations, comparing the read entity against the internally cast version is the correct approach.


155-157: LGTM! Consistent entity configuration pattern in second test.

The second test case correctly follows the same refactoring pattern for entity configuration.


159-161: LGTM! Consistent application of refactoring patterns.

All remaining changes in the second test case correctly follow the same entity configuration and internal casting patterns established in the first test case.

Also applies to: 176-176, 186-187

codegenerator/cli/npm/envio/src/Internal.res (2)

163-169: LGTM! Well-designed entity configuration record.

The entityConfig record provides a clean abstraction that encapsulates all necessary entity metadata including schema, table reference, and history tracking. This is a good foundation for the DI refactoring.


170-171: LGTM! Proper enum type abstraction.

The abstract enum type provides type safety, and the enumConfig alias creates a consistent interface for enum configuration that aligns with the entity configuration approach.

codegenerator/cli/npm/envio/src/Logging.res (2)

29-73: LGTM! Improved separation of concerns in logger creation.

Renaming setLogger to makeLogger and making it return a logger instance instead of setting it directly improves the functional design by separating logger creation from assignment. The logger creation logic remains intact and correct.


75-77: LGTM! Clean logger assignment interface.

The new setLogger function provides a clean interface for logger assignment, completing the separation between logger creation and assignment responsibilities.

scenarios/test_codegen/test/Mock_test.res (3)

48-56: LGTM! Consistent entity configuration refactoring pattern.

The changes follow the established pattern of using entityConfig with entityModToInternal transformation and applying castToInternal to entity data before database operations.


76-78: LGTM! In-memory store operations updated consistently.

The in-memory store operations correctly use the new entity configuration approach, maintaining consistency with database operations.


91-91: LGTM! Test assertions correctly use internal entity representations.

The test assertions properly compare against internally cast entities, ensuring consistency with how entities are stored and retrieved in the new system.

Also applies to: 99-99, 107-107

codegenerator/cli/templates/static/codegen/src/db/Migrations.res (1)

130-144: LGTM! Improved schema management logic.

The refactored schema management provides better control over database initialization:

  • Conditional schema dropping based on reset parameter
  • Explicit separation of DROP CASCADE and CREATE operations
  • Clear user permission grants for both postgres and public

This approach is more explicit and safer for different migration scenarios.

scenarios/test_codegen/test/helpers/Mock.res (2)

4-6: LGTM! Consistent entity configuration refactor.

The systematic replacement of entityMod with entityConfig and use of Entities.entityModToInternal aligns perfectly with the persistence layer refactor objectives.


57-84: Excellent consistency in parameter updates.

The LoadLayer module updates correctly transition from module-based to configuration-based entity handling:

  • Parameter renaming from ~entityMod to ~entityConfig
  • Direct property access with entityConfig.name
  • Maintains same functionality with improved type clarity
scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (3)

58-58: Good addition of type-safe entity casting.

The castToInternal external function provides a clean way to convert from TestEntity.t to Internal.entity using identity casting, maintaining type safety in the test suite.


595-600: Excellent test adaptation to new entity configuration.

The test updates correctly use the new entity configuration approach:

  • entityConfig derived from module(TestEntity)->Entities.entityModToInternal
  • Entities cast to internal representation using TestEntity.castToInternal
  • Maintains test logic while improving type consistency

642-643: Consistent entity configuration usage throughout tests.

All test functions properly updated to use entityConfig parameter, ensuring the test suite fully exercises the new persistence layer interface.

codegenerator/cli/templates/static/codegen/src/Config.res (2)

97-97: Clean transition from entity array to persistence abstraction.

Replacing the entities field with persistence: Persistence.t provides a much cleaner interface that encapsulates entity management, enum configurations, and storage details in a single abstraction.


106-106: Good default parameter approach for backward compatibility.

Using ~persistence=codegenPersistence as the default parameter maintains backward compatibility while enabling the new persistence abstraction. This allows for gradual migration and testing of the new architecture.

codegenerator/cli/templates/static/codegen/src/UserContext.res (4)

63-99: LGTM! Clean refactoring from entityMod to entityConfig.

The function signature and implementation have been correctly updated to use Internal.entityConfig instead of the module-based approach. The entity access patterns are consistent throughout the function.


114-118: LGTM! Consistent entity lookup refactoring.

The switch from entityMod to entityConfig in the entity lookup logic is correctly implemented, maintaining the same error handling pattern.


133-143: LGTM! Proper type annotation update.

The loaderEntityContextParams type has been correctly updated to use Internal.entityConfig, and the error message formatting consistently uses entityConfig.name.


216-224: LGTM! Consistent entity context creation.

The loader context creation has been properly updated to pass entityConfig instead of the module-based approach, maintaining the same functionality.

codegenerator/cli/templates/static/codegen/src/IO.res (4)

51-58: LGTM! Correct function signature update.

The executeSetEntityWithHistory function signature has been properly updated to use Internal.entityConfig, and the entity table access is consistent with the new approach.


110-117: LGTM! Consistent database function calls.

The database function calls have been correctly updated to pass entityConfig instead of the module-based approach, maintaining the same functionality for both batch operations.


179-181: LGTM! Clean entity iteration refactoring.

The entity iteration has been properly updated to use Entities.allEntities with entityConfig, simplifying the code while maintaining the same functionality.


238-257: LGTM! Rollback logic correctly updated.

The rollback logic has been consistently updated to use entityConfig for entity operations, database queries, and dictionary access. The entity name access pattern using entityConfig.name is correct throughout.

codegenerator/cli/templates/dynamic/codegen/src/db/Entities.res.hbs (4)

14-16: LGTM! Well-designed external function declarations.

The external functions provide clean conversion between module types and internal entity configurations. The use of %identity is appropriate since these are compile-time type conversions.


110-111: LGTM! Consistent castToInternal function addition.

Adding castToInternal to each entity module provides a clean way to convert entities to their internal representation, maintaining type safety.


114-124: LGTM! Logical entity array restructuring.

The separation of user entities from static entities (like DynamicContractRegistry) is a good architectural decision. The concatenation approach maintains all entities while allowing for different handling of user vs. system entities.


125-130: LGTM! Correct dictionary mapping update.

The dictionary mapping has been properly updated to use entityConfig.name instead of module destructuring, which is consistent with the new entity configuration approach.

codegenerator/cli/templates/static/codegen/src/InMemoryStore.res (1)

13-18: EntityTables.make should guard against duplicate entityConfig.name entries

When iterating entities, duplicate names will silently overwrite the first table, leading to subtle data-loss at runtime. A quick check avoids this trap:

-    entities->Belt.Array.forEach(entityConfig => {
-      init->Js.Dict.set((entityConfig.name :> string), InMemoryTable.Entity.make())
-    })
+    entities->Belt.Array.forEach(entityConfig => {
+      let key = (entityConfig.name :> string)
+      if Js.Dict.has(init, key) {
+        UndefinedEntity({entityName: key})
+        ->ErrorHandling.mkLogAndRaise(~msg="Duplicate entity name detected during store init")
+      }
+      init->Js.Dict.set(key, InMemoryTable.Entity.make())
+    })
codegenerator/cli/templates/static/codegen/src/LoadLayer.res (8)

9-11: LGTM! Function type definitions properly refactored.

The function type definitions have been consistently updated to use ~entityConfig: Internal.entityConfig instead of the previous module-based approach, and return types correctly changed to promise<array<Internal.entity>>. This maintains type safety while moving to the new dependency injection pattern.

Also applies to: 14-19


34-37: Function implementation correctly updated for new signature.

The makeWithDbConnection function properly passes the entityConfig parameter to the underlying database functions, maintaining consistency with the refactored function signatures.


42-49: loadById function signature and implementation correctly refactored.

The function signature properly accepts ~entityConfig: Internal.entityConfig and the implementation correctly uses entityConfig.name for key generation and passes the config to InMemoryStore.getInMemTable. This maintains the same functionality with the new architecture.


56-56: Consistent parameter passing in loadEntitiesByIds call.

The ~entityConfig parameter is correctly passed to the loadEntitiesByIds function call, maintaining consistency with the refactored function signature.


82-82: Direct function call approach is consistent with new architecture.

The change from a curried/module-based approach to direct function calls (inMemTable->InMemoryTable.Entity.getUnsafe) aligns with the broader refactoring to use explicit configuration records instead of modules. This maintains the same functionality while simplifying the interface.


123-135: loadByField function signature and key generation properly updated.

The function signature correctly uses ~entityConfig: Internal.entityConfig and the key generation properly references entityConfig.name. The InMemoryStore.getInMemTable call is also updated consistently.


154-154: Consistent entityConfig parameter usage in loadEntitiesByField.

The ~entityConfig parameter is correctly passed to the loadEntitiesByField function call, maintaining consistency throughout the refactoring.


183-183: Direct function call maintains functionality with new architecture.

Similar to line 82, this change from module-based currying to direct function calls (InMemoryTable.Entity.getUnsafeOnIndex) is consistent with the overall refactoring approach and maintains the same functionality.

Comment thread codegenerator/cli/templates/static/codegen/src/Index.res Outdated
Comment thread codegenerator/cli/npm/envio/src/PgStorage.res
Comment thread codegenerator/cli/npm/envio/src/PgStorage.res Outdated
Comment thread codegenerator/cli/npm/envio/src/PgStorage.res Outdated
Comment thread codegenerator/cli/npm/envio/src/PgStorage.res Outdated
Comment thread codegenerator/cli/npm/envio/src/Persistence.res Outdated
Comment on lines +75 to 77
let setLogger = l => {
logger := Some(l)
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Make it easier to mock in the future.

Enabler for testing logs.

@DZakh DZakh marked this pull request as ready for review June 3, 2025 12:45
@DZakh DZakh requested a review from JonoPrest June 3, 2025 12:48

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

♻️ Duplicate comments (1)
codegenerator/cli/npm/envio/src/Persistence.res (1)

68-111: ⚠️ Potential issue

Critical: Promise resolution issue still partially exists.

The promise stored in Initializing state is not resolved in all code paths:

  1. Line 92: When storage is already initialized, resolveRef.contents() is not called
  2. Lines 108-110: In the error handler, resolveRef.contents() is not called before re-raising

This will cause any concurrent calls awaiting the promise to hang indefinitely.

Apply this fix to ensure the promise is always resolved:

 let init = async (
   persistence,
   ~skipIsInitializedCheck=false,
   ~reset=false,
 ) => {
   try {
     let shouldRun = switch persistence.storageStatus {
     | Unknown => true
     | Initializing(promise) => {
         await promise
         reset
       }
     | Ready(_) => reset
     }
     if shouldRun {
       let resolveRef = ref(%raw(`null`))
       let promise = Promise.make((resolve, _) => {
         resolveRef := resolve
       })
       persistence.storageStatus = Initializing(promise)
-      if !(reset || skipIsInitializedCheck) && (await persistence.storage.isInitialized()) {
-        persistence.storageStatus = Ready({cleanRun: false})
-      } else {
-        let _ = await persistence.storage.initialize(
-          ~entities=persistence.allEntities,
-          ~staticTables=persistence.staticTables,
-          ~enums=persistence.allEnums,
-          ~cleanRun=reset || !skipIsInitializedCheck,
-        )
-        persistence.storageStatus = Ready({cleanRun: true})
-        switch persistence.onStorageInitialize {
-        | Some(onStorageInitialize) => await onStorageInitialize()
-        | None => ()
+      try {
+        if !(reset || skipIsInitializedCheck) && (await persistence.storage.isInitialized()) {
+          persistence.storageStatus = Ready({cleanRun: false})
+        } else {
+          let _ = await persistence.storage.initialize(
+            ~entities=persistence.allEntities,
+            ~staticTables=persistence.staticTables,
+            ~enums=persistence.allEnums,
+            ~cleanRun=reset || !skipIsInitializedCheck,
+          )
+          persistence.storageStatus = Ready({cleanRun: true})
+          switch persistence.onStorageInitialize {
+          | Some(onStorageInitialize) => await onStorageInitialize()
+          | None => ()
+          }
         }
+        resolveRef.contents()
+      } catch {
+      | exn => 
+        resolveRef.contents()
+        raise(exn)
       }
-      resolveRef.contents()
     }
   } catch {
   | exn => exn->ErrorHandling.mkLogAndRaise(~msg=`EE800: Failed to initialize the indexer storage.`)
   }
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9b1eed5 and 70b33b8.

📒 Files selected for processing (19)
  • codegenerator/cli/npm/envio/src/Enum.res (0 hunks)
  • codegenerator/cli/npm/envio/src/Internal.res (1 hunks)
  • codegenerator/cli/npm/envio/src/Persistence.res (1 hunks)
  • codegenerator/cli/npm/envio/src/PgStorage.res (1 hunks)
  • codegenerator/cli/npm/envio/src/db/EntityHistory.res (3 hunks)
  • codegenerator/cli/src/config_parsing/postgres_types.rs (1 hunks)
  • codegenerator/cli/src/rescript_types.rs (1 hunks)
  • codegenerator/cli/templates/dynamic/codegen/src/db/Enums.res.hbs (3 hunks)
  • codegenerator/cli/templates/static/codegen/src/Config.res (3 hunks)
  • codegenerator/cli/templates/static/codegen/src/Index.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/Migrations.res (1 hunks)
  • codegenerator/cli/templates/static/codegen/src/db/TablesStatic.res (3 hunks)
  • scenarios/erc20_multichain_factory/test/TestDeleteEntity.res (0 hunks)
  • scenarios/erc20_multichain_factory/test/TestWhereQuery.res (0 hunks)
  • scenarios/test_codegen/test/SerDe_Test.res (1 hunks)
  • scenarios/test_codegen/test/lib_tests/EntityHistory_test.res (5 hunks)
  • scenarios/test_codegen/test/lib_tests/Persistence_test.res (1 hunks)
  • scenarios/test_codegen/test/lib_tests/PgStorage_test.res (1 hunks)
  • scenarios/test_codegen/test/rollback/Rollback_test.res (0 hunks)
💤 Files with no reviewable changes (4)
  • scenarios/erc20_multichain_factory/test/TestWhereQuery.res
  • scenarios/erc20_multichain_factory/test/TestDeleteEntity.res
  • scenarios/test_codegen/test/rollback/Rollback_test.res
  • codegenerator/cli/npm/envio/src/Enum.res
✅ Files skipped from review due to trivial changes (3)
  • codegenerator/cli/src/rescript_types.rs
  • scenarios/test_codegen/test/SerDe_Test.res
  • codegenerator/cli/src/config_parsing/postgres_types.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • codegenerator/cli/templates/static/codegen/src/Index.res
  • scenarios/test_codegen/test/lib_tests/EntityHistory_test.res
  • codegenerator/cli/npm/envio/src/Internal.res
  • codegenerator/cli/templates/static/codegen/src/Config.res
  • codegenerator/cli/npm/envio/src/PgStorage.res
🔇 Additional comments (17)
codegenerator/cli/templates/static/codegen/src/db/TablesStatic.res (3)

34-39: LGTM: Formatting improvement for readability.

The multi-line formatting of the mkField call enhances readability without changing functionality.


247-248: Approve enum configuration update.

The change from Enums.ContractType.enum to Enums.ContractType.config is consistent with the enum refactoring pattern throughout the codebase.


227-227:

Details

✅ Verification successful

Verify enum schema migration across codebase.

The change from Enums.ContractType.enum.schema to Enums.ContractType.config.schema aligns with the enum refactoring. Ensure all references to enum schemas have been consistently updated.


🏁 Script executed:

#!/bin/bash
# Description: Verify all enum schema references have been updated consistently
# Expected: No remaining references to .enum.schema pattern

echo "Searching for any remaining .enum.schema references..."
rg '\.enum\.schema' --type=res --type=hbs

echo "Verifying .config.schema pattern is used consistently..."
rg '\.config\.schema' --type=res --type=hbs -A 2

Length of output: 392


🏁 Script executed:

#!/bin/bash
# Re-run without unsupported --type filter, scoping to .res and .hbs files

echo "Searching for any remaining '.enum.schema' references across .res and .hbs files..."
rg '\.enum\.schema' -g '*.res' -g '*.hbs'

echo ""
echo "Verifying '.config.schema' usage across .res and .hbs files (with context)..."
rg '\.config\.schema' -g '*.res' -g '*.hbs' -A2

Length of output: 1003


All enum schema references have been updated consistently

Ran a global search across .res and .hbs files and confirmed:

  • No remaining occurrences of Enums.*.enum.schema
  • All schema references now use Enums.*.config.schema (e.g., TablesStatic.res)

No further changes are needed.

codegenerator/cli/npm/envio/src/db/EntityHistory.res (1)

91-91: Approve direct property access pattern.

The changes from RowAction.enum.schema to RowAction.schema and RowAction.enum.name to RowAction.name are consistent with the enum refactoring where properties are now accessed directly from the module.

Also applies to: 231-231

codegenerator/cli/templates/dynamic/codegen/src/db/Enums.res.hbs (2)

14-14: Approve enum configuration refactoring.

The replacement of Enum.make(~name, ~variants) with Internal.makeEnumConfig(~name, ~variants) and the binding change from enum to config represents a systematic refactoring of the enum system. The new pattern appears more flexible and centralized.

Also applies to: 32-32, 49-49


53-59:

Details

✅ Verification successful

Verify allEnums transformation logic.

The allEnums array now uses Internal.fromGenericEnumConfig to transform enum configurations. Ensure this transformation maintains the expected array structure and that consuming code has been updated accordingly.


🏁 Script executed:

#!/bin/bash
# Description: Verify allEnums usage and Internal.fromGenericEnumConfig function
# Expected: Code consuming allEnums should work with the new structure

echo "Searching for allEnums usage..."
rg "allEnums" -A 3 -B 1

echo "Checking Internal.fromGenericEnumConfig definition..."
rg "fromGenericEnumConfig" -A 5

Length of output: 12002


Transformation logic verified for allEnums

Internal.fromGenericEnumConfig is defined as an identity function, so the array structure remains unchanged. All consuming code and tests (Persistence, PgStorage, EntityHistory) have been updated to use it and pass the expected enumConfig shape. No further changes needed.

codegenerator/cli/templates/static/codegen/src/db/Migrations.res (1)

29-39:

Details

❓ Verification inconclusive

Significant simplification of migration logic - verify completeness.

The migration logic has been drastically simplified to delegate to Persistence.init. While this centralization improves maintainability, ensure that:

  1. All previous migration functionality is preserved in the persistence layer
  2. Error handling provides sufficient diagnostic information
  3. The skipIsInitializedCheck=true flag is intentional and documented

Consider adding more specific error logging to help diagnose migration failures:

  let exitCode = try {
    await Config.codegenPersistence->Persistence.init(~skipIsInitializedCheck=true, ~reset)
    Success
  } catch {
- | _ => Failure
+ | exn => 
+   exn->ErrorHandling.make(~msg="Migration failed during persistence initialization")->ErrorHandling.log
+   Failure
  }

🏁 Script executed:

#!/bin/bash
# Description: Verify that Persistence.init covers all migration functionality
# Expected: Persistence module should handle schema creation, table setup, etc.

echo "Checking Persistence.init implementation..."
rg "let init" -A 20 --type=res | grep -E "(init|schema|table|migration)"

echo "Verifying Config.codegenPersistence definition..."
rg "codegenPersistence" -A 5 -B 2

Length of output: 2411


🏁 Script executed:

#!/bin/bash
# Locate Persistence module file(s)
echo "Locating Persistence.res files..."
fd -e res -t f | grep -i Persistence.res || echo "No Persistence.res found via fd"

echo
# Find module definitions named Persistence
echo "Searching for 'module Persistence' in .res files..."
rg -n "module Persistence" -g "*.res" || echo "No module Persistence definitions found"

echo
# Inspect the init function within Persistence files
echo "Inspecting 'let init' implementation in Persistence files..."
rg -n "let init" -A 10 -g "*Persistence.res" || echo "No init functions found in Persistence.res"

Length of output: 1520


#!/bin/bash
# Extract the full `init` implementation in Persistence.res for review
echo "Retrieving Persistence.init from envio module..."
rg -n "let init = async" -A 200 -g "codegenerator/cli/npm/envio/src/Persistence.res" || \
rg -n "let init =" -A 200 -g "codegenerator/cli/npm/envio/src/Persistence.res"

Verify Persistence.init covers all migration steps and enhances error diagnostics.

Before merging, please ensure that the new centralized Persistence.init call in Migrations.res truly implements every prior migration step (schema creation, table setup, upserts, version tracking) and that the skipIsInitializedCheck=true flag is intentional and documented. Also consider improving failure diagnostics by logging the caught exception:

• In codegenerator/cli/templates/static/codegen/src/db/Migrations.res

  • Confirm Persistence.init in codegenerator/cli/npm/envio/src/Persistence.res replicates the old manual SQL behavior (upserts, migrations, schema/version checks).
  • Document the rationale for ~skipIsInitializedCheck=true.
  • Enhance error handling:
  let exitCode = try {
    await Config.codegenPersistence->Persistence.init(~skipIsInitializedCheck=true, ~reset)
    Success
  } catch {
-   | _ => Failure
+   | exn =>
+     exn
+     ->ErrorHandling.make(~msg="Migration failed during persistence init")
+     ->ErrorHandling.log;
+     Failure
  }

• Verify that any upstream code relying on detailed migration errors isn’t affected and update docs/tests if needed.

scenarios/test_codegen/test/lib_tests/PgStorage_test.res (4)

4-38: Well-structured tests for index creation SQL.

The test suite properly covers both single-field and composite index creation scenarios with appropriate assertions.


40-66: Good edge case coverage for table indices.

The tests appropriately handle both entities with indices and those without, ensuring correct SQL generation in both cases.


89-101: Duplicate test case needs clarification.

This test case titled "Should handle default values" generates identical SQL to the first test case for entity A. If this is meant to test default value handling, it should use an entity that actually has fields with default values other than the standard db_write_timestamp.


104-285: Comprehensive test coverage for schema initialization.

Excellent test suite that covers all major initialization scenarios including clean runs, conditional initialization, minimal configurations, and single entity setups. The expected SQL outputs are well-formatted and accurate.

scenarios/test_codegen/test/lib_tests/Persistence_test.res (4)

3-52: Excellent mock implementation for async storage interface.

The mock design allows precise control over async behavior and comprehensive tracking of method calls, making it ideal for testing the persistence layer's initialization logic.


54-174: Thorough test of persistence initialization lifecycle.

This test comprehensively covers the initialization flow, including default entity inclusion, status transitions, idempotency, and reset behavior. The manual promise resolution approach effectively tests the async state machine.


176-210: Good coverage of the already-initialized scenario.

The test properly verifies that initialization is skipped when storage reports it's already initialized, and handles concurrent init calls correctly.


212-244: Important backward compatibility test.

This test ensures that the skipIsInitializedCheck flag maintains backward compatibility for the "envio local db-up" command by bypassing the initialization check.

codegenerator/cli/npm/envio/src/Persistence.res (2)

8-36: Well-designed persistence abstraction types.

The storage interface is minimal and focused, the status type properly models async states, and the main type encapsulates all necessary configuration. Good use of mutable field for status tracking.


38-66: Well-implemented factory function.

The make function properly combines user-provided entities and enums with internal ones, and correctly initializes all fields including the optional callback.

let variants = [SET, DELETE]
let name = "ENTITY_HISTORY_ROW_ACTION"
let enum = Enum.make(~name, ~variants)
let schema = S.enum(variants)

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.

💡 Verification agent

🧩 Analysis chain

Verify RowAction module consistency with new enum pattern.

The direct S.enum(variants) usage suggests the RowAction module now defines its schema directly rather than through an enum object. Ensure this aligns with how RowAction is defined elsewhere in the codebase.


🏁 Script executed:

#!/bin/bash
# Description: Verify RowAction module definition and usage consistency
# Expected: RowAction should be defined using Internal.makeEnumConfig pattern

echo "Searching for RowAction module definition..."
rg "module RowAction" -A 10

echo "Checking if RowAction uses the new enum config pattern..."
rg "RowAction.*Internal\.makeEnumConfig" -A 3

Length of output: 1129


Ensure RowAction uses the new enum‐config pattern

The RowAction module still calls

let schema = S.enum(variants)

but should be defined via Internal.makeEnumConfig in line with other enums.

Locations to update:

  • File: codegenerator/cli/npm/envio/src/db/EntityHistory.res
    • In the module RowAction = { … } block, replace
      let schema = S.enum(variants)
      with something like:
      let config = Internal.makeEnumConfig({ name, variants })
      let schema = S.config(config)
      (or the pattern your codebase uses for enum configuration)
🤖 Prompt for AI Agents
In codegenerator/cli/npm/envio/src/db/EntityHistory.res at line 7 within the
module RowAction, replace the current enum schema definition using
S.enum(variants) with the new pattern that uses Internal.makeEnumConfig.
Specifically, create a config using Internal.makeEnumConfig with the name and
variants, then define the schema as S.config(config) to align with the updated
enum configuration approach used elsewhere in the codebase.

~entities=persistence.allEntities,
~staticTables=persistence.staticTables,
~enums=persistence.allEnums,
~cleanRun=reset || !skipIsInitializedCheck,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

This is a little bit of a mess, but I hope we'll get rid of the upserting behaviour at some point, and it'll get simpler.

@JonoPrest JonoPrest left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Awesome, very happy about the decoupling 🙏🏼

@DZakh DZakh enabled auto-merge (squash) June 3, 2025 15:06
@DZakh DZakh merged commit 5a1cbe0 into main Jun 3, 2025
2 checks passed
@DZakh DZakh deleted the dz/persistence-layer branch June 3, 2025 15:15
@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