148 lines
5.1 KiB
PL/PgSQL
148 lines
5.1 KiB
PL/PgSQL
|
|
-- 1) Tipos (enums) para os campos de seleção
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'atribuicao_frequencia') THEN
|
|
CREATE TYPE public.atribuicao_frequencia AS ENUM ('horaria','2xdia','diaria','2xsemanal','semanal','quinzenal','mensal');
|
|
END IF;
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'atribuicao_metodo') THEN
|
|
CREATE TYPE public.atribuicao_metodo AS ENUM ('impresso','sistema','sistema-impresso','email','verbal');
|
|
END IF;
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'atribuicao_cliente') THEN
|
|
CREATE TYPE public.atribuicao_cliente AS ENUM ('interno','processo','obra','contrato','geral');
|
|
END IF;
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'atribuicao_importancia') THEN
|
|
CREATE TYPE public.atribuicao_importancia AS ENUM ('essencial','estrategico','suporte','informativo');
|
|
END IF;
|
|
|
|
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'atribuicao_duracao') THEN
|
|
CREATE TYPE public.atribuicao_duracao AS ENUM ('<=1 hora','2 horas','4 horas','8 horas');
|
|
END IF;
|
|
END$$;
|
|
|
|
-- 2) Função para checar admin ou função Diretoria
|
|
CREATE OR REPLACE FUNCTION public.is_admin_or_diretoria(_user_id uuid)
|
|
RETURNS boolean
|
|
LANGUAGE sql
|
|
STABLE
|
|
SECURITY DEFINER
|
|
SET search_path TO 'public'
|
|
AS $$
|
|
SELECT public.has_role(_user_id, 'admin'::app_role)
|
|
OR EXISTS (
|
|
SELECT 1
|
|
FROM public.profiles p
|
|
JOIN public.functions f ON f.id = p.function_id
|
|
WHERE p.id = _user_id
|
|
AND lower(f.name) LIKE 'diretoria%'
|
|
);
|
|
$$;
|
|
|
|
-- 3) Função para gerar abreviação (3 letras) do usuário
|
|
CREATE OR REPLACE FUNCTION public.generate_user_abbrev(_user_id uuid)
|
|
RETURNS text
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
SET search_path TO 'public'
|
|
AS $function$
|
|
DECLARE
|
|
name_text text;
|
|
abbrev text;
|
|
BEGIN
|
|
SELECT COALESCE(NULLIF(trim(p.full_name), ''), split_part(p.email, '@', 1))
|
|
INTO name_text
|
|
FROM public.profiles p
|
|
WHERE p.id = _user_id;
|
|
|
|
IF name_text IS NULL OR name_text = '' THEN
|
|
RETURN 'USR';
|
|
END IF;
|
|
|
|
abbrev := upper(substring(regexp_replace(name_text, '[^A-Za-z0-9]', '', 'g') from 1 for 3));
|
|
IF length(abbrev) < 3 THEN
|
|
abbrev := rpad(abbrev, 3, 'X');
|
|
END IF;
|
|
|
|
RETURN abbrev;
|
|
END;
|
|
$function$;
|
|
|
|
-- 4) Tabela de Atribuições
|
|
CREATE TABLE IF NOT EXISTS public.atribuicoes (
|
|
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
user_id uuid NOT NULL REFERENCES public.profiles(id) ON DELETE CASCADE,
|
|
user_abbrev char(3) NOT NULL DEFAULT 'USR',
|
|
attribution varchar(300) NOT NULL,
|
|
frequency public.atribuicao_frequencia NOT NULL,
|
|
method public.atribuicao_metodo NOT NULL,
|
|
client public.atribuicao_cliente NOT NULL,
|
|
importance public.atribuicao_importancia NOT NULL,
|
|
duration public.atribuicao_duracao NOT NULL,
|
|
created_by uuid NOT NULL REFERENCES public.profiles(id),
|
|
created_at timestamptz NOT NULL DEFAULT now(),
|
|
updated_at timestamptz NOT NULL DEFAULT now()
|
|
);
|
|
|
|
-- Índices úteis
|
|
CREATE INDEX IF NOT EXISTS idx_atribuicoes_user_id ON public.atribuicoes(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_atribuicoes_created_by ON public.atribuicoes(created_by);
|
|
CREATE INDEX IF NOT EXISTS idx_atribuicoes_created_at ON public.atribuicoes(created_at);
|
|
|
|
-- 5) Trigger para defaults (abreviação + updated_at)
|
|
CREATE OR REPLACE FUNCTION public.set_atribuicoes_defaults()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $function$
|
|
BEGIN
|
|
-- Ajustar abreviação se vier vazia ou inválida
|
|
IF NEW.user_abbrev IS NULL OR length(btrim(NEW.user_abbrev)) <> 3 THEN
|
|
NEW.user_abbrev := upper(substring(public.generate_user_abbrev(NEW.user_id) from 1 for 3));
|
|
ELSE
|
|
NEW.user_abbrev := upper(NEW.user_abbrev);
|
|
END IF;
|
|
|
|
NEW.updated_at := now();
|
|
RETURN NEW;
|
|
END;
|
|
$function$;
|
|
|
|
DROP TRIGGER IF EXISTS trg_atribuicoes_defaults ON public.atribuicoes;
|
|
CREATE TRIGGER trg_atribuicoes_defaults
|
|
BEFORE INSERT OR UPDATE ON public.atribuicoes
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.set_atribuicoes_defaults();
|
|
|
|
-- 6) RLS
|
|
ALTER TABLE public.atribuicoes ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- SELECT: Admin/Diretoria veem tudo; demais apenas suas próprias
|
|
DROP POLICY IF EXISTS "View own or admin/diretoria all" ON public.atribuicoes;
|
|
CREATE POLICY "View own or admin/diretoria all"
|
|
ON public.atribuicoes
|
|
FOR SELECT
|
|
USING ( public.is_admin_or_diretoria(auth.uid()) OR user_id = auth.uid() );
|
|
|
|
-- INSERT: apenas Admin/Diretoria e exige created_by = auth.uid()
|
|
DROP POLICY IF EXISTS "Only admin/diretoria can insert atribuições" ON public.atribuicoes;
|
|
CREATE POLICY "Only admin/diretoria can insert atribuições"
|
|
ON public.atribuicoes
|
|
FOR INSERT
|
|
WITH CHECK ( public.is_admin_or_diretoria(auth.uid()) AND created_by = auth.uid() );
|
|
|
|
-- UPDATE: apenas Admin/Diretoria
|
|
DROP POLICY IF EXISTS "Only admin/diretoria can update atribuições" ON public.atribuicoes;
|
|
CREATE POLICY "Only admin/diretoria can update atribuições"
|
|
ON public.atribuicoes
|
|
FOR UPDATE
|
|
USING ( public.is_admin_or_diretoria(auth.uid()) );
|
|
|
|
-- DELETE: apenas Admin/Diretoria
|
|
DROP POLICY IF EXISTS "Only admin/diretoria can delete atribuições" ON public.atribuicoes;
|
|
CREATE POLICY "Only admin/diretoria can delete atribuições"
|
|
ON public.atribuicoes
|
|
FOR DELETE
|
|
USING ( public.is_admin_or_diretoria(auth.uid()) );
|