@@ -279,6 +279,88 @@ def upgrade() -> None:
279279 ),
280280 sa .PrimaryKeyConstraint ("role_id" , "scope_id" , name = op .f ("pk_role_scope" )),
281281 )
282+ op .create_table (
283+ "user_role_assignment" ,
284+ sa .Column ("id" , sa .UUID (), nullable = False ),
285+ sa .Column ("organization_id" , sa .UUID (), nullable = False ),
286+ sa .Column ("user_id" , sa .UUID (), nullable = False ),
287+ sa .Column ("workspace_id" , sa .UUID (), nullable = True ),
288+ sa .Column ("role_id" , sa .UUID (), nullable = False ),
289+ sa .Column (
290+ "assigned_at" ,
291+ sa .TIMESTAMP (timezone = True ),
292+ server_default = sa .text ("now()" ),
293+ nullable = False ,
294+ ),
295+ sa .Column ("assigned_by" , sa .UUID (), nullable = True ),
296+ sa .ForeignKeyConstraint (
297+ ["assigned_by" ],
298+ ["user.id" ],
299+ name = op .f ("fk_user_role_assignment_assigned_by_user" ),
300+ ondelete = "SET NULL" ,
301+ ),
302+ sa .ForeignKeyConstraint (
303+ ["organization_id" ],
304+ ["organization.id" ],
305+ name = op .f ("fk_user_role_assignment_organization_id_organization" ),
306+ ondelete = "CASCADE" ,
307+ ),
308+ sa .ForeignKeyConstraint (
309+ ["role_id" ],
310+ ["role.id" ],
311+ name = op .f ("fk_user_role_assignment_role_id_role" ),
312+ ondelete = "RESTRICT" ,
313+ ),
314+ sa .ForeignKeyConstraint (
315+ ["user_id" ],
316+ ["user.id" ],
317+ name = op .f ("fk_user_role_assignment_user_id_user" ),
318+ ondelete = "CASCADE" ,
319+ ),
320+ sa .ForeignKeyConstraint (
321+ ["workspace_id" ],
322+ ["workspace.id" ],
323+ name = op .f ("fk_user_role_assignment_workspace_id_workspace" ),
324+ ondelete = "CASCADE" ,
325+ ),
326+ sa .PrimaryKeyConstraint ("id" , name = op .f ("pk_user_role_assignment" )),
327+ sa .UniqueConstraint (
328+ "user_id" ,
329+ "workspace_id" ,
330+ name = op .f ("uq_user_role_assignment_user_id_workspace_id" ),
331+ ),
332+ )
333+ op .create_index (
334+ op .f ("ix_user_role_assignment_organization_id" ),
335+ "user_role_assignment" ,
336+ ["organization_id" ],
337+ unique = False ,
338+ )
339+ op .create_index (
340+ op .f ("ix_user_role_assignment_role_id" ),
341+ "user_role_assignment" ,
342+ ["role_id" ],
343+ unique = False ,
344+ )
345+ op .create_index (
346+ op .f ("ix_user_role_assignment_user_id" ),
347+ "user_role_assignment" ,
348+ ["user_id" ],
349+ unique = False ,
350+ )
351+ op .create_index (
352+ "ix_user_role_assignment_user_org_unique" ,
353+ "user_role_assignment" ,
354+ ["user_id" ],
355+ unique = True ,
356+ postgresql_where = sa .text ("workspace_id IS NULL" ),
357+ )
358+ op .create_index (
359+ op .f ("ix_user_role_assignment_workspace_id" ),
360+ "user_role_assignment" ,
361+ ["workspace_id" ],
362+ unique = False ,
363+ )
282364 op .sync_enum_values ( # type: ignore[attr-defined]
283365 enum_schema = "public" ,
284366 enum_name = "workspacerole" ,
@@ -318,6 +400,28 @@ def downgrade() -> None:
318400 ],
319401 enum_values_to_rename = [],
320402 )
403+ op .drop_index (
404+ op .f ("ix_user_role_assignment_workspace_id" ),
405+ table_name = "user_role_assignment" ,
406+ )
407+ op .drop_index (
408+ "ix_user_role_assignment_user_org_unique" ,
409+ table_name = "user_role_assignment" ,
410+ postgresql_where = sa .text ("workspace_id IS NULL" ),
411+ )
412+ op .drop_index (
413+ op .f ("ix_user_role_assignment_user_id" ),
414+ table_name = "user_role_assignment" ,
415+ )
416+ op .drop_index (
417+ op .f ("ix_user_role_assignment_role_id" ),
418+ table_name = "user_role_assignment" ,
419+ )
420+ op .drop_index (
421+ op .f ("ix_user_role_assignment_organization_id" ),
422+ table_name = "user_role_assignment" ,
423+ )
424+ op .drop_table ("user_role_assignment" )
321425 op .drop_table ("role_scope" )
322426 op .drop_table ("group_member" )
323427 op .drop_index (
0 commit comments