Skip to content

feat: added query to remove orphan user org membership#5233

Merged
maidul98 merged 1 commit intomainfrom
chore/migration-fix
Jan 22, 2026
Merged

feat: added query to remove orphan user org membership#5233
maidul98 merged 1 commit intomainfrom
chore/migration-fix

Conversation

@akhilmhdh
Copy link
Member

@akhilmhdh akhilmhdh commented Jan 22, 2026

Context

This PR removes orphan organisation membership user data where the user field is null. This caused the simplify membership migration to fail because it expects the user ID to be available.

Screenshots

Steps to verify the change

Type

  • Fix
  • Feature
  • Improvement
  • Breaking
  • Docs
  • Chore

Checklist

  • Title follows the conventional commit format: type(scope): short description (scope is optional, e.g., fix: prevent crash on sync or fix(api): handle null response).
  • Tested locally
  • Updated docs (if needed)
  • Read the contributing guide

@akhilmhdh akhilmhdh requested a review from maidul98 January 22, 2026 07:44
@maidul98
Copy link
Collaborator

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@maidul98 maidul98 merged commit 1763d80 into main Jan 22, 2026
11 of 12 checks passed
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Jan 22, 2026

Greptile Summary

This PR adds a deletion query to remove orphan organization membership records where userId is null before migrating the data to the new unified Membership table. The cleanup is necessary because the new table schema has constraints that don't permit null actor IDs.

Key Changes:

  • Added await knex(TableName.OrgMembership).whereNull("userId").del() on line 204 to remove orphan records

Critical Issue:

  • The deletion is placed outside the idempotency check, meaning it will execute every time the migration up() function runs, even when the tables already exist. This violates the idempotency requirement (Rule 8) and could cause unintended data deletion if the migration is re-run.

Confidence Score: 2/5

  • This PR has a critical idempotency issue that could cause data loss if the migration is re-run
  • The deletion of orphan memberships is placed outside the idempotency check (hasToMigrateMembershipTable), violating database migration best practices. If this migration is re-run after initial execution, it will attempt to delete from the old OrgMembership table which may cause unintended data loss or errors.
  • Pay close attention to backend/src/db/migrations/20251005152640_simplify-membership.ts - ensure the deletion is wrapped in the idempotency check

Important Files Changed

Filename Overview
backend/src/db/migrations/20251005152640_simplify-membership.ts Adds deletion of orphan org memberships with null userId before migration. Critical idempotency issue found.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

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

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

};

const migrateMembershipData = async (knex: Knex) => {
await knex(TableName.OrgMembership).whereNull("userId").del();
Copy link
Contributor

Choose a reason for hiding this comment

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

logic: Migration not idempotent - deletion runs every time up() executes, even when tables already exist.

The deletion is outside the idempotency check (if (hasToMigrateMembershipTable)), so re-running will delete from OrgMembership table even after it's been migrated to the new Membership table. This could cause data loss.

Suggested change
await knex(TableName.OrgMembership).whereNull("userId").del();
if (hasToMigrateMembershipTable) {
await knex(TableName.OrgMembership).whereNull("userId").del();
}

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