Skip to content

fix: recreate group when the ID changes but the link does not#31

Merged
lorenzocorallo merged 2 commits intomainfrom
fix-groupid-diverge
Apr 11, 2026
Merged

fix: recreate group when the ID changes but the link does not#31
lorenzocorallo merged 2 commits intomainfrom
fix-groupid-diverge

Conversation

@lorenzocorallo
Copy link
Copy Markdown
Member

No description provided.

@lorenzocorallo lorenzocorallo requested a review from toto04 April 11, 2026 15:38
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 11, 2026

Walkthrough

This PR introduces a unique constraint on the tg_groups.link column across the database schema and application code. The change includes a migration, updated schema definition, and modified insertion logic to handle conflicts by deleting existing rows with matching links before upserting new data.

Changes

Cohort / File(s) Summary
Database Migration
drizzle/0009_bouncy_unicorn.sql, drizzle/meta/0009_snapshot.json, drizzle/meta/_journal.json
Adds unique constraint tg_groups_link_unique on the link column in tg_groups table. Includes migration snapshot and journal entry for tracking schema version 0009.
Schema Definition
src/db/schema/tg/groups.ts
Updates the link column definition to include .unique() constraint, enforcing uniqueness at the ORM level.
Router Logic
src/routers/tg/groups.ts
Modifies the create mutation to delete existing tg_groups rows with matching link but different telegramId before performing the bulk insert/update operation. Updates drizzle-orm imports to include and and ne operators.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: adding a unique constraint on the link column and implementing pre-insert cleanup logic to recreate groups when the telegram ID changes but the link remains the same.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (1)
src/routers/tg/groups.ts (1)

79-95: ⚠️ Potential issue | 🔴 Critical

Make delete+upsert atomic to avoid partial data loss and race conditions.

Right now the cleanup delete and the insert/upsert run in separate statements without a transaction. If insert fails (including unique conflicts inside a batch), previously deleted rows are already gone.

🛠️ Suggested direction
- for (const group of input) {
-   await DB.delete(...);
- }
- const rows = await DB.insert(...).onConflictDoUpdate(...).returning()
+ // Wrap cleanup + insert/upsert in a single DB transaction
+ // so either all changes commit or none do.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/routers/tg/groups.ts` around lines 79 - 95, Wrap the cleanup deletes and
the subsequent insert/upsert in a single database transaction so they execute
atomically: open a transaction via DB.transaction (or the project's
transactional API), run the looped DB.delete(GROUPS).where(and(eq(GROUPS.link,
group.link), ne(GROUPS.telegramId, group.telegramId))) calls against the
transaction handle (e.g., trx.delete(...)), then run the
DB.insert(GROUPS).values(input).onConflictDoUpdate({...}).returning() also
against the same trx; return the resulting rows' telegramId and let the
transaction commit/rollback automatically to avoid partial deletes on insert
failure.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/routers/tg/groups.ts`:
- Line 80: Before deleting the old GROUPS row via
DB.delete(GROUPS).where(and(eq(GROUPS.link, group.link), ne(GROUPS.telegramId,
group.telegramId))), first update all dependent references (e.g.,
groupAdmins.groupId which maps to groups.telegramId and any other FKs joined in
src/routers/tg/permissions.ts) to the new group.telegramId; perform these
updates with DB.update on the dependent tables to set their groupId =
group.telegramId where groupId = oldTelegramId, then run the delete, and wrap
the update+delete in a single transaction to avoid race conditions and ensure
referential integrity.

---

Outside diff comments:
In `@src/routers/tg/groups.ts`:
- Around line 79-95: Wrap the cleanup deletes and the subsequent insert/upsert
in a single database transaction so they execute atomically: open a transaction
via DB.transaction (or the project's transactional API), run the looped
DB.delete(GROUPS).where(and(eq(GROUPS.link, group.link), ne(GROUPS.telegramId,
group.telegramId))) calls against the transaction handle (e.g.,
trx.delete(...)), then run the
DB.insert(GROUPS).values(input).onConflictDoUpdate({...}).returning() also
against the same trx; return the resulting rows' telegramId and let the
transaction commit/rollback automatically to avoid partial deletes on insert
failure.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b06795a2-7973-4cd6-9811-05a4d0fee285

📥 Commits

Reviewing files that changed from the base of the PR and between e4a6a8e and 400804c.

📒 Files selected for processing (5)
  • drizzle/0009_bouncy_unicorn.sql
  • drizzle/meta/0009_snapshot.json
  • drizzle/meta/_journal.json
  • src/db/schema/tg/groups.ts
  • src/routers/tg/groups.ts

@lorenzocorallo lorenzocorallo merged commit f6fbc81 into main Apr 11, 2026
2 checks passed
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