diff --git a/packages/schemas/alterations/next-1705991158-update-invitation-indices.ts b/packages/schemas/alterations/next-1705991158-update-invitation-indices.ts new file mode 100644 index 000000000..9ec7e6eae --- /dev/null +++ b/packages/schemas/alterations/next-1705991158-update-invitation-indices.ts @@ -0,0 +1,32 @@ +import { sql } from 'slonik'; + +import type { AlterationScript } from '../lib/types/alteration.js'; + +/** + * @fileoverview Separates the index (tenant_id, inviter_id, organization_id) to two indices. Also + * makes the inviter_id nullable. + */ + +const alteration: AlterationScript = { + up: async (pool) => { + await pool.query(sql` + alter table organization_invitations + drop constraint organization_invitations_tenant_id_inviter_id_organization_fkey, + add foreign key (inviter_id) references users (id) on update cascade on delete cascade, + add foreign key (organization_id) references organizations (id) on update cascade on delete cascade, + alter column inviter_id drop not null; + `); + }, + down: async (pool) => { + await pool.query(sql` + alter table organization_invitations + drop constraint organization_invitations_inviter_id_fkey, + drop constraint organization_invitations_organization_id_fkey, + add foreign key (tenant_id, inviter_id, organization_id) references organization_user_relations + (tenant_id, user_id, organization_id) on update cascade on delete cascade, + alter column inviter_id set not null; + `); + }, +}; + +export default alteration; diff --git a/packages/schemas/tables/organization_invitations.sql b/packages/schemas/tables/organization_invitations.sql index 7f71af829..fb3d2af95 100644 --- a/packages/schemas/tables/organization_invitations.sql +++ b/packages/schemas/tables/organization_invitations.sql @@ -9,14 +9,16 @@ create table organization_invitations ( /** The unique identifier of the invitation. */ id varchar(21) not null, /** The user ID who sent the invitation. */ - inviter_id varchar(21) not null, + inviter_id varchar(21) + references users (id) on update cascade on delete cascade, /** The email address or other identifier of the invitee. */ invitee varchar(256) not null, /** The user ID of who accepted the invitation. */ accepted_user_id varchar(21) references users (id) on update cascade on delete cascade, /** The ID of the organization to which the invitee is invited. */ - organization_id varchar(21) not null, + organization_id varchar(21) not null + references organizations (id) on update cascade on delete cascade, /** The status of the invitation. */ status organization_invitation_status not null, /** The ID of the magic link that can be used to accept the invitation. */ @@ -28,10 +30,7 @@ create table organization_invitations ( updated_at timestamptz not null default (now()), /** The time when the invitation expires. */ expires_at timestamptz not null, - primary key (id), - foreign key (tenant_id, inviter_id, organization_id) - references organization_user_relations (tenant_id, user_id, organization_id) - on update cascade on delete cascade + primary key (id) ); -- Ensure there is only one pending invitation for a given invitee and organization.