template-saas-database-v2/ddl/schemas/users/tables/03-invitations.sql
rckrdmrd 3ce06fbce4 Initial commit - Database de template-saas migrado desde monorepo
Migración desde workspace-v2/projects/template-saas/apps/database
Este repositorio es parte del estándar multi-repo v2

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-16 08:07:11 -06:00

66 lines
2.0 KiB
PL/PgSQL

-- ============================================
-- TEMPLATE-SAAS: User Invitations
-- Schema: users
-- Version: 1.0.0
-- ============================================
CREATE TABLE users.invitations (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tenant_id UUID NOT NULL REFERENCES tenants.tenants(id) ON DELETE CASCADE,
-- Invitation details
email VARCHAR(255) NOT NULL,
token VARCHAR(255) UNIQUE NOT NULL,
-- Role assignment
role_id UUID REFERENCES users.roles(id),
-- Status
status users.invitation_status DEFAULT 'pending' NOT NULL,
-- Expiration
expires_at TIMESTAMPTZ NOT NULL,
-- Result
accepted_at TIMESTAMPTZ,
accepted_by_user_id UUID REFERENCES users.users(id),
-- Metadata
message TEXT, -- Custom message from inviter
metadata JSONB DEFAULT '{}'::jsonb,
-- Audit
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL,
created_by UUID NOT NULL REFERENCES users.users(id),
-- Constraints
CONSTRAINT valid_invitation_email CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
);
-- Indexes
CREATE INDEX idx_invitations_tenant ON users.invitations(tenant_id);
CREATE INDEX idx_invitations_email ON users.invitations(tenant_id, email);
CREATE INDEX idx_invitations_token ON users.invitations(token);
CREATE INDEX idx_invitations_status ON users.invitations(tenant_id, status) WHERE status = 'pending';
-- RLS
ALTER TABLE users.invitations ENABLE ROW LEVEL SECURITY;
CREATE POLICY invitations_tenant_isolation ON users.invitations
USING (tenant_id = current_setting('app.current_tenant_id', true)::UUID);
-- Function to auto-expire invitations
CREATE OR REPLACE FUNCTION users.expire_old_invitations()
RETURNS void AS $$
BEGIN
UPDATE users.invitations
SET status = 'expired'
WHERE status = 'pending'
AND expires_at < NOW();
END;
$$ LANGUAGE plpgsql;
-- Comments
COMMENT ON TABLE users.invitations IS 'User invitations to join tenant';
COMMENT ON COLUMN users.invitations.token IS 'Secure token for invitation link';