mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
82 lines
2.7 KiB
PL/PgSQL
82 lines
2.7 KiB
PL/PgSQL
-- Audit Logging System
|
|
-- Creates audit_logs table and RPC function for logging admin actions
|
|
|
|
-- Create action type enum for audit logging
|
|
CREATE TYPE public.audit_action AS ENUM ('INSERT', 'UPDATE', 'DELETE');
|
|
|
|
-- Audit log table
|
|
CREATE TABLE public.audit_logs (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
table_name TEXT NOT NULL,
|
|
record_id UUID NOT NULL,
|
|
action public.audit_action NOT NULL,
|
|
old_values JSONB,
|
|
new_values JSONB,
|
|
changed_fields TEXT[],
|
|
admin_user_id UUID NOT NULL REFERENCES auth.users(id),
|
|
admin_role public.admin_role NOT NULL,
|
|
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
|
|
-- Indexes for querying audit logs
|
|
CREATE INDEX idx_audit_logs_table_name ON public.audit_logs(table_name);
|
|
CREATE INDEX idx_audit_logs_record_id ON public.audit_logs(record_id);
|
|
CREATE INDEX idx_audit_logs_admin_user_id ON public.audit_logs(admin_user_id);
|
|
CREATE INDEX idx_audit_logs_created_at ON public.audit_logs(created_at DESC);
|
|
CREATE INDEX idx_audit_logs_action ON public.audit_logs(action);
|
|
|
|
-- Enable RLS (super_admins only can view logs)
|
|
ALTER TABLE public.audit_logs ENABLE ROW LEVEL SECURITY;
|
|
|
|
-- Policy: Only super admins can view audit logs
|
|
CREATE POLICY "Super admins can view audit logs"
|
|
ON public.audit_logs FOR SELECT
|
|
USING (public.is_super_admin());
|
|
|
|
-- Function to log admin actions (called from frontend via RPC)
|
|
CREATE OR REPLACE FUNCTION public.log_admin_action(
|
|
p_table_name TEXT,
|
|
p_record_id UUID,
|
|
p_action public.audit_action,
|
|
p_old_values JSONB DEFAULT NULL,
|
|
p_new_values JSONB DEFAULT NULL
|
|
)
|
|
RETURNS UUID AS $$
|
|
DECLARE
|
|
log_id UUID;
|
|
admin_role_val public.admin_role;
|
|
changed_fields_arr TEXT[];
|
|
BEGIN
|
|
-- Get admin role
|
|
SELECT role INTO admin_role_val FROM public.admin_users WHERE user_id = auth.uid();
|
|
|
|
IF admin_role_val IS NULL THEN
|
|
RAISE EXCEPTION 'User is not an admin';
|
|
END IF;
|
|
|
|
-- Calculate changed fields for updates
|
|
IF p_action = 'UPDATE' AND p_old_values IS NOT NULL AND p_new_values IS NOT NULL THEN
|
|
SELECT ARRAY(
|
|
SELECT key FROM jsonb_each(p_new_values)
|
|
WHERE p_old_values->key IS DISTINCT FROM p_new_values->key
|
|
) INTO changed_fields_arr;
|
|
END IF;
|
|
|
|
-- Insert audit log
|
|
INSERT INTO public.audit_logs (
|
|
table_name, record_id, action, old_values, new_values,
|
|
changed_fields, admin_user_id, admin_role
|
|
)
|
|
VALUES (
|
|
p_table_name, p_record_id, p_action, p_old_values, p_new_values,
|
|
changed_fields_arr, auth.uid(), admin_role_val
|
|
)
|
|
RETURNING id INTO log_id;
|
|
|
|
RETURN log_id;
|
|
END;
|
|
$$ LANGUAGE plpgsql SECURITY DEFINER;
|
|
|
|
-- Grant execute permission on logging function
|
|
GRANT EXECUTE ON FUNCTION public.log_admin_action TO authenticated;
|