Skip to content

refactor: migrate user related models to drizzle - #2798

Merged
stalniy merged 1 commit into
mainfrom
refactor/user-tables
Feb 23, 2026
Merged

refactor: migrate user related models to drizzle#2798
stalniy merged 1 commit into
mainfrom
refactor/user-tables

Conversation

@stalniy

@stalniy stalniy commented Feb 20, 2026

Copy link
Copy Markdown
Contributor

Why

  1. To get rid of extra db pool which we almost do not use
  2. To use modern approach with drizzle and repositories

What

Summary by CodeRabbit

  • New Features

    • Save templates with title, description, resource specs (CPU/RAM/storage) and SDL; mark templates public or private.
    • Favorite templates for quick access; view and manage favorites.
    • Dashboard now includes total template count alongside public and private counts.
  • Chores

    • Backend schema and repository layer reorganized for reliability and maintainability (no breaking API changes).

@coderabbitai

coderabbitai Bot commented Feb 20, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds Drizzle-backed template and templateFavorite tables and schemas; removes legacy Sequelize user models/exports; implements a Drizzle-based UserTemplateRepository and BaseRepository.count(); updates DI, router, service, tests, snapshots, and simplifies the Sequelize DB provider.

Changes

Cohort / File(s) Summary
Migrations & Snapshots
apps/api/drizzle/0028_right_red_ghost.sql, apps/api/drizzle/meta/0028_snapshot.json, apps/api/drizzle/meta/_journal.json
Adds SQL migration creating template and templateFavorite tables, indexes, FKs; adds snapshot and journal entry.
Drizzle Schemas
apps/api/src/user/model-schemas/template/template.schema.ts, apps/api/src/user/model-schemas/template-favorite/template-favorite.schema.ts, apps/api/src/user/model-schemas/index.ts, apps/api/src/user/model-schemas/user/user.schema.ts
Introduces Templates and TemplateFavorites pgTable definitions, indexes, relations to Users, and re-exports; updates UsersRelations to include templates.
Repository Layer
apps/api/src/user/repositories/user-template/user-template.repository.ts, apps/api/src/core/repositories/base.repository.ts
Adds singleton UserTemplateRepository (Drizzle/cursor-backed) with methods (findById, findAllByUserId/Username, isFavorite, add/removeFavorite, getFavoriteTemplates, upsert, updateTemplate, deleteById, accessibleBy); adds count() to BaseRepository.
API / Router / Service / Tests
apps/api/src/routers/dashboardRouter.ts, apps/api/src/user/services/user-templates/user-templates.service.ts, apps/api/src/user/services/user-templates/user-templates.service.spec.ts, apps/api/src/user/repositories/user-template/user-template.repository.integration.ts
Switches usage to DI-resolved repository APIs; dashboard adds totalTemplateCount; service/tests updated to use updateTemplate; integration tests refactored to repository-driven flows.
Legacy Sequelize Model Removal
packages/database/dbSchemas/user/template.ts, packages/database/dbSchemas/user/templateFavorite.ts, packages/database/dbSchemas/user/userSetting.ts
Removes Sequelize model files for Template, TemplateFavorite, and UserSetting.
Module Export Cleanup
packages/database/dbSchemas/index.ts, packages/database/dbSchemas/user/index.ts
Removes legacy Sequelize exports (userModels, Template, TemplateFavorite, UserSetting) from schema index modules.
DB Provider Simplification
apps/api/src/chain/providers/sequelize.provider.ts
Removes USER_DB token and user DB sync/auth logic; provider now manages only CHAIN_DB and simplified connect/dispose flow.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client
  participant Router as Router (dashboard / templates)
  participant Repo as UserTemplateRepository
  participant DB as Postgres (Drizzle)

  rect rgba(135,206,235,0.5)
    Client->>Router: HTTP requests (GET /stats, template ops)
  end

  rect rgba(144,238,144,0.5)
    Router->>Repo: call repository methods (count / findById / upsert / addFavorite / ...)
  end

  rect rgba(255,182,193,0.5)
    Repo->>DB: execute Drizzle cursor queries (select/insert/update/join)
    DB-->>Repo: return rows / ids / affected counts
  end

  Repo-->>Router: return shaped TemplateOutput / counts
  Router-->>Client: JSON response (includes totalTemplateCount / templates)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 I hopped through migrations, seeds, and tests tonight,
Two tables bloomed beneath the DB's soft light,
Drizzle trails and repository burrows made,
Dashboards count more, old models gently laid,
A rabbit's cheer—code tidy, clean, and bright!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description covers the 'Why' section with two clear motivations but leaves the 'What' section incomplete, lacking details on specific changes, breaking changes, and migration considerations. Complete the 'What' section with details on: specific changes made (new schemas, removed models), any breaking changes to public APIs, and migration/deployment considerations for production.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title 'refactor: migrate user related models to drizzle' accurately describes the main purpose of the changeset: migrating user-related database models from Sequelize to Drizzle ORM.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/user-tables

Comment @coderabbitai help to get the list of available commands and usage tips.

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/api/src/user/services/user-templates/user-templates.service.spec.ts (1)

134-149: ⚠️ Potential issue | 🟡 Minor

Test description doesn't match the actual assertion.

The test description says "calls repository updateById" but the test actually asserts updateTemplate. Update the description to match the refactored method name.

📝 Suggested fix
   describe("update", () => {
-    it("calls repository updateById with correct parameters", async () => {
+    it("calls repository updateTemplate with correct parameters", async () => {
       const { service, userTemplateRepository } = setup();
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/src/user/services/user-templates/user-templates.service.spec.ts`
around lines 134 - 149, The test description is out of sync with the assertion:
update() spec says "calls repository updateById" but the test actually asserts
userTemplateRepository.updateTemplate; update the test's it() description string
to accurately reflect the refactored method name (e.g., "calls repository
updateTemplate with correct parameters") so it matches the assertion in the
update test for service.update and the mocked
userTemplateRepository.updateTemplate.
🧹 Nitpick comments (1)
apps/api/drizzle/0028_right_red_ghost.sql (1)

16-24: Consider adding an index on templateFavorite.userId for efficient user favorite lookups.

The unique index on (userId, templateId) is useful for preventing duplicate favorites, but queries that fetch all favorites for a specific user (e.g., WHERE userId = ?) may not efficiently use this composite index depending on the query planner. A dedicated index on userId alone would optimize such lookups.

💡 Suggested addition
 CREATE UNIQUE INDEX IF NOT EXISTS "templateFavorite_userId_templateId_unique" ON "templateFavorite" ("userId","templateId");
+--> statement-breakpoint
+CREATE INDEX IF NOT EXISTS "templateFavorite_userId_idx" ON "templateFavorite" ("userId");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/api/drizzle/0028_right_red_ghost.sql` around lines 16 - 24, Add a
dedicated index on templateFavorite.userId to optimize queries that fetch all
favorites for a user; specifically, create an index (e.g.,
"templateFavorite_userId_idx") on the "templateFavorite" table for the "userId"
column in addition to the existing UNIQUE index
"templateFavorite_userId_templateId_unique" so single-column user lookups use
the index efficiently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/src/user/repositories/user-template/user-template.repository.ts`:
- Around line 97-99: The addFavorite method currently calls the global
crypto.randomUUID(); update the file to use a named import for consistency by
importing { randomUUID } from 'crypto' and replace crypto.randomUUID() with
randomUUID() in addFavorite (which inserts into this.favoriteTable via
this.cursor). Ensure any eslint/formatting rules pass after updating the import
and usage.

---

Outside diff comments:
In `@apps/api/src/user/services/user-templates/user-templates.service.spec.ts`:
- Around line 134-149: The test description is out of sync with the assertion:
update() spec says "calls repository updateById" but the test actually asserts
userTemplateRepository.updateTemplate; update the test's it() description string
to accurately reflect the refactored method name (e.g., "calls repository
updateTemplate with correct parameters") so it matches the assertion in the
update test for service.update and the mocked
userTemplateRepository.updateTemplate.

---

Nitpick comments:
In `@apps/api/drizzle/0028_right_red_ghost.sql`:
- Around line 16-24: Add a dedicated index on templateFavorite.userId to
optimize queries that fetch all favorites for a user; specifically, create an
index (e.g., "templateFavorite_userId_idx") on the "templateFavorite" table for
the "userId" column in addition to the existing UNIQUE index
"templateFavorite_userId_templateId_unique" so single-column user lookups use
the index efficiently.

@codecov

codecov Bot commented Feb 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.21053% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.80%. Comparing base (6b95ff3) to head (c8300e1).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...sitories/user-template/user-template.repository.ts 90.69% 4 Missing ⚠️
apps/api/src/core/repositories/base.repository.ts 0.00% 2 Missing and 1 partial ⚠️
apps/api/src/chain/providers/sequelize.provider.ts 50.00% 1 Missing ⚠️
...emas/template-favorite/template-favorite.schema.ts 75.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2798      +/-   ##
==========================================
- Coverage   53.73%   52.80%   -0.94%     
==========================================
  Files        1018      985      -33     
  Lines       23588    22741     -847     
  Branches     5759     5661      -98     
==========================================
- Hits        12676    12009     -667     
+ Misses       9516     9345     -171     
+ Partials     1396     1387       -9     
Flag Coverage Δ *Carryforward flag
api 76.73% <84.21%> (-0.14%) ⬇️
deploy-web 36.13% <ø> (ø) Carriedforward from 6b95ff3
log-collector ?
notifications 85.56% <ø> (ø) Carriedforward from 6b95ff3
provider-console 81.48% <ø> (ø) Carriedforward from 6b95ff3
provider-proxy 82.41% <ø> (ø) Carriedforward from 6b95ff3
tx-signer ?

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...src/user/model-schemas/template/template.schema.ts 100.00% <100.00%> (ø)
...pps/api/src/user/model-schemas/user/user.schema.ts 100.00% <100.00%> (ø)
.../services/user-templates/user-templates.service.ts 100.00% <100.00%> (ø)
apps/api/src/chain/providers/sequelize.provider.ts 74.07% <50.00%> (-7.33%) ⬇️
...emas/template-favorite/template-favorite.schema.ts 75.00% <75.00%> (ø)
apps/api/src/core/repositories/base.repository.ts 71.71% <0.00%> (+0.88%) ⬆️
...sitories/user-template/user-template.repository.ts 91.30% <90.69%> (-8.70%) ⬇️

... and 36 files with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@stalniy
stalniy force-pushed the refactor/user-tables branch from e6e0f49 to 03bee40 Compare February 20, 2026 13:06
@github-actions github-actions Bot added size: L and removed size: XL labels Feb 20, 2026
@stalniy
stalniy force-pushed the refactor/user-tables branch from 03bee40 to 1e84f00 Compare February 20, 2026 13:07

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@apps/api/src/user/repositories/user-template/user-template.repository.integration.ts`:
- Around line 469-472: The setup function currently has no parameters; update
the setup declaration to accept a single inline-typed parameter (e.g., a
destructured options object with its type defined inline) so it matches test
guidelines; modify function setup(...) to take that single inline-typed param
and use its fields as needed while still resolving UserTemplateRepository via
container.resolve(UserTemplateRepository), ensuring callers pass or omit the new
param as appropriate (provide a default if necessary).

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

🔥

@stalniy
stalniy force-pushed the refactor/user-tables branch from 1e84f00 to e1a9fe9 Compare February 23, 2026 08:16
@stalniy
stalniy enabled auto-merge February 23, 2026 08:16

@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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/src/user/repositories/user-template/user-template.repository.ts`:
- Around line 141-145: The code is calling crypto.randomUUID() but only
randomUUID is imported from node:crypto; replace the undefined crypto usage by
calling the imported randomUUID() directly in the insert values (the block using
this.cursor.insert(this.table).values({...})). Update the values object to use
randomUUID() for id (consistent with the pattern already used elsewhere, e.g.
line ~99) so runtime/type-checking no longer reference the missing crypto
symbol.
ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e84f00 and e1a9fe9.

📒 Files selected for processing (19)
  • apps/api/drizzle/0028_right_red_ghost.sql
  • apps/api/drizzle/meta/0028_snapshot.json
  • apps/api/drizzle/meta/_journal.json
  • apps/api/src/chain/providers/sequelize.provider.ts
  • apps/api/src/core/repositories/base.repository.ts
  • apps/api/src/routers/dashboardRouter.ts
  • apps/api/src/user/model-schemas/index.ts
  • apps/api/src/user/model-schemas/template-favorite/template-favorite.schema.ts
  • apps/api/src/user/model-schemas/template/template.schema.ts
  • apps/api/src/user/model-schemas/user/user.schema.ts
  • apps/api/src/user/repositories/user-template/user-template.repository.integration.ts
  • apps/api/src/user/repositories/user-template/user-template.repository.ts
  • apps/api/src/user/services/user-templates/user-templates.service.spec.ts
  • apps/api/src/user/services/user-templates/user-templates.service.ts
  • packages/database/dbSchemas/index.ts
  • packages/database/dbSchemas/user/index.ts
  • packages/database/dbSchemas/user/template.ts
  • packages/database/dbSchemas/user/templateFavorite.ts
  • packages/database/dbSchemas/user/userSetting.ts
💤 Files with no reviewable changes (5)
  • packages/database/dbSchemas/index.ts
  • packages/database/dbSchemas/user/index.ts
  • packages/database/dbSchemas/user/userSetting.ts
  • packages/database/dbSchemas/user/templateFavorite.ts
  • packages/database/dbSchemas/user/template.ts
🚧 Files skipped from review as they are similar to previous changes (7)
  • apps/api/src/core/repositories/base.repository.ts
  • apps/api/drizzle/meta/_journal.json
  • apps/api/src/user/services/user-templates/user-templates.service.ts
  • apps/api/src/user/model-schemas/user/user.schema.ts
  • apps/api/src/user/services/user-templates/user-templates.service.spec.ts
  • apps/api/src/user/model-schemas/template/template.schema.ts
  • apps/api/drizzle/meta/0028_snapshot.json

@stalniy
stalniy disabled auto-merge February 23, 2026 08:22
@stalniy
stalniy force-pushed the refactor/user-tables branch from e1a9fe9 to 7abecff Compare February 23, 2026 08:22
@stalniy
stalniy force-pushed the refactor/user-tables branch from 7abecff to c8300e1 Compare February 23, 2026 08:24

@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)
apps/api/src/user/repositories/user-template/user-template.repository.integration.ts (1)

469-471: ⚠️ Potential issue | 🟡 Minor

Adjust setup() to accept a single inline-typed parameter.

This still violates the test setup guideline and was flagged previously.

🔧 Suggested fix
-function setup() {
+function setup({}: {} = {}) {
   const userTemplateRepository = container.resolve(UserTemplateRepository);
   return { userTemplateRepository };
 }
Based on learnings, “Use `setup` function instead of `beforeEach` in test files. The `setup` function must … accept a single parameter with inline type definition…”.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@apps/api/src/user/repositories/user-template/user-template.repository.integration.ts`
around lines 469 - 471, The setup helper currently takes no args; change the
setup function to accept a single inline-typed parameter (e.g. {
userTemplateRepository?: UserTemplateRepository }) and use that to override or
resolve dependencies: keep resolving UserTemplateRepository via
container.resolve(UserTemplateRepository) when not provided, and return {
userTemplateRepository } from setup(); update the function signature named setup
to declare the inline type so tests can call setup({ userTemplateRepository: ...
}) per the guideline.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@apps/api/src/user/repositories/user-template/user-template.repository.ts`:
- Around line 128-145: The upsert function may set copiedFromId to a
non-existent or unauthorized template id; modify upsert to verify that the
provided id exists and belongs to the same user (reuse the existing variable
existing from the Templates.findFirst check or add a separate query) before
including copiedFromId in the insert values, and only set copiedFromId when that
check passes; ensure the verification uses Templates.findFirst (or similar) and
eq conditions on this.table.id and this.table.userId to avoid dangling
references.

---

Duplicate comments:
In
`@apps/api/src/user/repositories/user-template/user-template.repository.integration.ts`:
- Around line 469-471: The setup helper currently takes no args; change the
setup function to accept a single inline-typed parameter (e.g. {
userTemplateRepository?: UserTemplateRepository }) and use that to override or
resolve dependencies: keep resolving UserTemplateRepository via
container.resolve(UserTemplateRepository) when not provided, and return {
userTemplateRepository } from setup(); update the function signature named setup
to declare the inline type so tests can call setup({ userTemplateRepository: ...
}) per the guideline.
ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e1a9fe9 and c8300e1.

📒 Files selected for processing (19)
  • apps/api/drizzle/0028_right_red_ghost.sql
  • apps/api/drizzle/meta/0028_snapshot.json
  • apps/api/drizzle/meta/_journal.json
  • apps/api/src/chain/providers/sequelize.provider.ts
  • apps/api/src/core/repositories/base.repository.ts
  • apps/api/src/routers/dashboardRouter.ts
  • apps/api/src/user/model-schemas/index.ts
  • apps/api/src/user/model-schemas/template-favorite/template-favorite.schema.ts
  • apps/api/src/user/model-schemas/template/template.schema.ts
  • apps/api/src/user/model-schemas/user/user.schema.ts
  • apps/api/src/user/repositories/user-template/user-template.repository.integration.ts
  • apps/api/src/user/repositories/user-template/user-template.repository.ts
  • apps/api/src/user/services/user-templates/user-templates.service.spec.ts
  • apps/api/src/user/services/user-templates/user-templates.service.ts
  • packages/database/dbSchemas/index.ts
  • packages/database/dbSchemas/user/index.ts
  • packages/database/dbSchemas/user/template.ts
  • packages/database/dbSchemas/user/templateFavorite.ts
  • packages/database/dbSchemas/user/userSetting.ts
💤 Files with no reviewable changes (5)
  • packages/database/dbSchemas/index.ts
  • packages/database/dbSchemas/user/userSetting.ts
  • packages/database/dbSchemas/user/index.ts
  • packages/database/dbSchemas/user/template.ts
  • packages/database/dbSchemas/user/templateFavorite.ts
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/api/src/core/repositories/base.repository.ts
  • apps/api/src/user/model-schemas/index.ts
  • apps/api/drizzle/meta/0028_snapshot.json
  • apps/api/drizzle/meta/_journal.json
  • apps/api/src/user/services/user-templates/user-templates.service.spec.ts

@stalniy
stalniy added this pull request to the merge queue Feb 23, 2026
Merged via the queue into main with commit 08ec057 Feb 23, 2026
55 of 56 checks passed
@stalniy
stalniy deleted the refactor/user-tables branch February 23, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants