CREATE TABLE user_groups ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), name text NOT NULL, name_normalized text NOT NULL UNIQUE, description text NOT NULL DEFAULT '', created_by uuid REFERENCES users(id), updated_by uuid REFERENCES users(id), created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CHECK (char_length(btrim(name)) BETWEEN 1 AND 80), CHECK (char_length(description) <= 1000) ); CREATE TABLE user_group_members ( group_id uuid NOT NULL REFERENCES user_groups(id) ON DELETE CASCADE, user_id uuid NOT NULL REFERENCES users(id) ON DELETE CASCADE, created_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (group_id, user_id) ); CREATE INDEX user_group_members_user_idx ON user_group_members(user_id, group_id); CREATE TABLE user_group_permissions ( group_id uuid NOT NULL REFERENCES user_groups(id) ON DELETE CASCADE, permission text NOT NULL, granted_by uuid REFERENCES users(id), created_at timestamptz NOT NULL DEFAULT now(), PRIMARY KEY (group_id, permission), CHECK (permission IN ( 'users.read','users.write','memberships.manage','cards.manage','invites.manage', 'requests.manage','tickets.manage','notifications.manage','security.manage', 'operations.manage','e.manage','plugins.manage','audit.read','logs.read', 'backups.manage','updates.manage','settings.manage','licenses.manage' )) );