botserver/migrations/6.0.24-01-core/up.sql

58 lines
2.4 KiB
MySQL
Raw Normal View History

-- Organization Invitations Table
-- Manages user invitations to organizations
CREATE TABLE IF NOT EXISTS organization_invitations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL REFERENCES organizations(org_id) ON DELETE CASCADE,
email VARCHAR(255) NOT NULL,
role VARCHAR(50) NOT NULL DEFAULT 'member',
status VARCHAR(20) NOT NULL DEFAULT 'pending',
message TEXT,
invited_by UUID NOT NULL REFERENCES users(id) ON DELETE SET NULL,
token VARCHAR(255) UNIQUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
accepted_at TIMESTAMPTZ,
accepted_by UUID REFERENCES users(id) ON DELETE SET NULL,
-- Constraint to prevent duplicate pending invitations
CONSTRAINT unique_pending_invitation UNIQUE (org_id, email)
);
-- Index for looking up invitations by organization
CREATE INDEX IF NOT EXISTS idx_org_invitations_org_id ON organization_invitations(org_id);
-- Index for looking up invitations by email
CREATE INDEX IF NOT EXISTS idx_org_invitations_email ON organization_invitations(email);
-- Index for looking up pending invitations
CREATE INDEX IF NOT EXISTS idx_org_invitations_status ON organization_invitations(status) WHERE status = 'pending';
-- Index for token lookups (for invitation acceptance)
CREATE INDEX IF NOT EXISTS idx_org_invitations_token ON organization_invitations(token) WHERE token IS NOT NULL;
-- Index for cleanup of expired invitations
CREATE INDEX IF NOT EXISTS idx_org_invitations_expires ON organization_invitations(expires_at) WHERE status = 'pending';
-- Add updated_at trigger
CREATE OR REPLACE FUNCTION update_org_invitation_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trigger_org_invitation_updated_at ON organization_invitations;
CREATE TRIGGER trigger_org_invitation_updated_at
BEFORE UPDATE ON organization_invitations
FOR EACH ROW
EXECUTE FUNCTION update_org_invitation_updated_at();
-- Comments
COMMENT ON TABLE organization_invitations IS 'Stores pending and historical organization invitations';
COMMENT ON COLUMN organization_invitations.status IS 'pending, accepted, cancelled, expired';
COMMENT ON COLUMN organization_invitations.token IS 'Secure token for invitation acceptance via email link';
COMMENT ON COLUMN organization_invitations.role IS 'Role to assign upon acceptance: member, admin, owner, etc.';