Skip to content

[_]: feat/add unique constraint on member_id and workspace_id in workspace_users and workspace_teams_users#421

Closed
jzunigax2 wants to merge 7 commits into
masterfrom
fix/unique-constraint-workspace-users
Closed

[_]: feat/add unique constraint on member_id and workspace_id in workspace_users and workspace_teams_users#421
jzunigax2 wants to merge 7 commits into
masterfrom
fix/unique-constraint-workspace-users

Conversation

@jzunigax2
Copy link
Copy Markdown
Contributor

@jzunigax2 jzunigax2 commented Nov 4, 2024

Add UNIQUE constraints with workspace_id and member_id in workspace_users and workspace_teams_users to prevent duplicated members

@jzunigax2 jzunigax2 force-pushed the fix/unique-constraint-workspace-users branch from e3596f0 to c0b1203 Compare November 4, 2024 21:19
…into fix/unique-constraint-workspace-users
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud Bot commented Nov 4, 2024

@sg-gs
Copy link
Copy Markdown
Member

sg-gs commented Nov 5, 2024

Please add a description of why you are doing this @jzunigax2. In this case, something like "Add UNIQUE constraint with workspace_id and member_id to prevent duplicated members in a given workspace" would be a good concise description. Otherwise the context of the why of this change, is lost.

Comment thread migrations/20241104161535-add-unique-constraint-memberid-teamid.js Outdated
@jzunigax2 jzunigax2 changed the title [_]: feat/add unique constraint on member_id and workspace_id in workspace_users [_]: feat/add unique constraint on member_id and workspace_id in workspace_users and workspace_teams_users Nov 5, 2024
@jzunigax2 jzunigax2 requested a review from sg-gs November 5, 2024 13:42
…into fix/unique-constraint-workspace-users
… add new constraint for workspace_teams_users
Comment thread migrations/20250512161535-add-unique-constraint-memberid-teamid.js Outdated
Comment thread src/modules/workspaces/repositories/team.repository.spec.ts Outdated
Comment thread src/modules/workspaces/repositories/team.repository.spec.ts Outdated
return this.teamUserToDomain(teamUser);
} catch (error) {
if (
error.name === 'SequelizeUniqueConstraintError' &&
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.

This should be previously checked by the use case. This seems to be business logic

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The use case does check this condition before attempting insertion, but due to the race condition that can sometimes affect this use case whenever this insertion fails it would just throw a 500 error. while this ensures to catch the error and rethrow a 400 which is what frontend handles

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.

If we are doing the proper async management, no race condition should happen, especially on small tables like this one, that is even under a thousand records which is far far less than for instance the files table, which thousands of millions of records. This does not seem logical or fundamented, describe how that happens and which steps need to be done to trigger that race condition.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We have seen this happen twice now. First, back in November, while working on workspace limit adjustments for members, we applied a script that would grant the workspace owner all unassigned space. After doing so, two owners were assigned negative space limits due to the workspace containing more members than its plan allowed. After further investigation, we found back then that these extra members were duplicates, with a createdAt at almost the exact second. If you take a look at the source code you can see that many db calls are made between the check userAlreadyInWorkspace and the actual insertion. This can be replicated by attempting to quickly click on accept invite when prompted in drive-web

Now, more recently, we had a bug report where a workspace owner reported their workspace appeared duplicated on web's workspace selector. In this case, the use case that sets up a workspace was called in repeated succession. If you take a look at the source code you'll see that a couple of db plus one network call are made between the userAlreadyInWorkspace check and the actual user insertion, leaving enough room for a race condition.

We could simply rerun the checks right before insertion, but still, wouldn't there be some chance of a race condition (albeit very slim, probably negligible)?

jzunigax2 added 2 commits May 15, 2025 16:23
…into fix/unique-constraint-workspace-users
…Y for workspace_users and workspace_teams_users
@sonarqubecloud
Copy link
Copy Markdown

@github-actions
Copy link
Copy Markdown

This PR is stale because it has been open for more than 15 days with no activity.

@jzunigax2
Copy link
Copy Markdown
Contributor Author

Closing this as proposed solution was not accepted, we may need to revist this in the future with a different scope. Perhaps only with the migrations that introduce a unique

@jzunigax2 jzunigax2 closed this Jul 1, 2025
@sg-gs sg-gs deleted the fix/unique-constraint-workspace-users branch October 21, 2025 15:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working ready-for-preview stalled

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants