1271 lines
40 KiB
PL/PgSQL
1271 lines
40 KiB
PL/PgSQL
set check_function_bodies = off;
|
|
|
|
CREATE OR REPLACE FUNCTION gis.nearby_units(lat double precision, lon double precision, max_results integer DEFAULT 5)
|
|
RETURNS TABLE(code_unit character varying, name text, type text, address text, district_id character varying, lat_unit double precision, lon_unit double precision, distance_km double precision)
|
|
LANGUAGE sql
|
|
AS $function$
|
|
select
|
|
u.code_unit,
|
|
u.name,
|
|
u.type,
|
|
u.address,
|
|
u.district_id,
|
|
gis.ST_Y(u.location::gis.geometry) as lat_unit,
|
|
gis.ST_X(u.location::gis.geometry) as lon_unit,
|
|
gis.ST_Distance(
|
|
u.location::gis.geography,
|
|
gis.ST_SetSRID(gis.ST_MakePoint(lon, lat), 4326)::gis.geography
|
|
) / 1000 as distance_km
|
|
from units u
|
|
order by gis.ST_Distance(
|
|
u.location::gis.geography,
|
|
gis.ST_SetSRID(gis.ST_MakePoint(lon, lat), 4326)::gis.geography
|
|
)
|
|
limit max_results
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION gis.update_location_distance_to_unit()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $function$
|
|
DECLARE
|
|
loc_lat FLOAT;
|
|
loc_lng FLOAT;
|
|
unit_lat FLOAT;
|
|
unit_lng FLOAT;
|
|
loc_point gis.GEOGRAPHY;
|
|
unit_point gis.GEOGRAPHY;
|
|
BEGIN
|
|
-- Ambil lat/lng dari location yang baru
|
|
SELECT gis.ST_Y(NEW.location::gis.geometry), gis.ST_X(NEW.location::gis.geometry)
|
|
INTO loc_lat, loc_lng;
|
|
|
|
-- Ambil lat/lng dari unit di distrik yang sama
|
|
SELECT gis.ST_Y(u.location::gis.geometry), gis.ST_X(u.location::gis.geometry)
|
|
INTO unit_lat, unit_lng
|
|
FROM units u
|
|
WHERE u.district_id = NEW.district_id
|
|
LIMIT 1;
|
|
|
|
-- Jika tidak ada unit di distrik yang sama, kembalikan NEW tanpa perubahan
|
|
IF unit_lat IS NULL OR unit_lng IS NULL THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
-- Buat point geography dari lat/lng
|
|
loc_point := gis.ST_SetSRID(gis.ST_MakePoint(loc_lng, loc_lat), 4326)::gis.geography;
|
|
unit_point := gis.ST_SetSRID(gis.ST_MakePoint(unit_lng, unit_lat), 4326)::gis.geography;
|
|
|
|
-- Update jaraknya ke kolom distance_to_unit
|
|
NEW.distance_to_unit := gis.ST_Distance(loc_point, unit_point) / 1000;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION gis.update_land_area()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $function$
|
|
BEGIN
|
|
NEW.land_area := ROUND((ST_Area(NEW.geometry::geography) / 1000000.0)::numeric, 2);
|
|
RETURN NEW;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
|
|
drop trigger if exists "trg_update_land_area" on "public"."geographics";
|
|
|
|
drop trigger if exists "location_distance_to_unit_trigger" on "public"."locations";
|
|
|
|
-- Drop the trigger first
|
|
drop trigger if exists location_distance_to_unit_trigger on public.locations;
|
|
|
|
-- Drop all triggers on public.locations that use public.update_location_distance_to_unit()
|
|
DO $$
|
|
DECLARE
|
|
trig record;
|
|
BEGIN
|
|
FOR trig IN
|
|
SELECT tgname
|
|
FROM pg_trigger
|
|
WHERE tgrelid = 'public.locations'::regclass
|
|
AND NOT tgisinternal
|
|
AND tgfoid = 'public.update_location_distance_to_unit()'::regprocedure
|
|
LOOP
|
|
EXECUTE format('DROP TRIGGER IF EXISTS %I ON public.locations;', trig.tgname);
|
|
END LOOP;
|
|
END
|
|
$$;
|
|
|
|
-- Now drop the trigger function
|
|
drop function if exists public.update_location_distance_to_unit();
|
|
|
|
-- Now we can safely alter the column type
|
|
alter table "public"."locations" alter column "location" set data type gis.geography using "location"::gis.geography;
|
|
|
|
-- Recreate the trigger function
|
|
CREATE OR REPLACE FUNCTION public.update_location_distance_to_unit()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $function$
|
|
DECLARE
|
|
loc_lat FLOAT;
|
|
loc_lng FLOAT;
|
|
unit_lat FLOAT;
|
|
unit_lng FLOAT;
|
|
loc_point gis.GEOGRAPHY;
|
|
unit_point gis.GEOGRAPHY;
|
|
BEGIN
|
|
-- Ambil lat/lng dari location yang baru
|
|
SELECT gis.ST_Y(NEW.location::gis.geometry), gis.ST_X(NEW.location::gis.geometry)
|
|
INTO loc_lat, loc_lng;
|
|
|
|
-- Ambil lat/lng dari unit di distrik yang sama
|
|
SELECT gis.ST_Y(u.location::gis.geometry), gis.ST_X(u.location::gis.geometry)
|
|
INTO unit_lat, unit_lng
|
|
FROM units u
|
|
WHERE u.district_id = NEW.district_id
|
|
LIMIT 1;
|
|
|
|
-- Jika tidak ada unit di distrik yang sama, kembalikan NEW tanpa perubahan
|
|
IF unit_lat IS NULL OR unit_lng IS NULL THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
-- Buat point geography dari lat/lng
|
|
loc_point := gis.ST_SetSRID(gis.ST_MakePoint(loc_lng, loc_lat), 4326)::gis.geography;
|
|
unit_point := gis.ST_SetSRID(gis.ST_MakePoint(unit_lng, unit_lat), 4326)::gis.geography;
|
|
|
|
-- Update jaraknya ke kolom distance_to_unit
|
|
NEW.distance_to_unit := gis.ST_Distance(loc_point, unit_point) / 1000;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
-- Recreate the trigger
|
|
CREATE TRIGGER location_distance_to_unit_trigger
|
|
BEFORE INSERT OR UPDATE OF location ON public.locations
|
|
FOR EACH ROW
|
|
EXECUTE FUNCTION public.update_location_distance_to_unit();
|
|
|
|
-- drop policy "give all access to users" on "public"."geographics";
|
|
|
|
-- Check if constraint exists before attempting to drop it
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (
|
|
SELECT 1
|
|
FROM information_schema.table_constraints
|
|
WHERE constraint_name = 'unit_statistics_unit_id_fkey'
|
|
AND table_name = 'unit_statistics'
|
|
) THEN
|
|
ALTER TABLE "public"."unit_statistics" DROP CONSTRAINT "unit_statistics_unit_id_fkey";
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
drop view if exists "public"."location_paths";
|
|
|
|
drop function if exists "public"."update_land_area"();
|
|
|
|
drop function if exists "public"."update_timestamp"();
|
|
|
|
alter table "public"."units" drop constraint "units_pkey";
|
|
|
|
drop index if exists "public"."unit_statistics_unit_id_month_year_key";
|
|
|
|
drop index if exists "public"."units_pkey";
|
|
|
|
-- Check if _prisma_migrations table exists before trying to create it
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT FROM pg_tables
|
|
WHERE schemaname = 'public'
|
|
AND tablename = '_prisma_migrations'
|
|
) THEN
|
|
CREATE TABLE "public"."_prisma_migrations" (
|
|
"id" character varying(36) not null,
|
|
"checksum" character varying(64) not null,
|
|
"finished_at" timestamp with time zone,
|
|
"migration_name" character varying(255) not null,
|
|
"logs" text,
|
|
"rolled_back_at" timestamp with time zone,
|
|
"started_at" timestamp with time zone not null default now(),
|
|
"applied_steps_count" integer not null default 0
|
|
);
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
-- Also wrap other table creations with existence checks
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT FROM pg_tables
|
|
WHERE schemaname = 'public'
|
|
AND tablename = 'evidence'
|
|
) THEN
|
|
create table "public"."evidence" (
|
|
"incident_id" uuid not null,
|
|
"type" character varying(50) not null,
|
|
"url" text not null,
|
|
"uploaded_at" timestamp(6) with time zone default CURRENT_TIMESTAMP,
|
|
"caption" character varying(255),
|
|
"description" character varying(255),
|
|
"metadata" jsonb,
|
|
"id" character varying(20) not null
|
|
);
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT FROM pg_tables
|
|
WHERE schemaname = 'public'
|
|
AND tablename = 'officers'
|
|
) THEN
|
|
create table "public"."officers" (
|
|
"unit_id" character varying(20) not null,
|
|
"role_id" uuid not null,
|
|
"nrp" character varying(100) not null,
|
|
"name" character varying(100) not null,
|
|
"rank" character varying(100),
|
|
"position" character varying(100),
|
|
"phone" character varying(20),
|
|
"email" character varying(255),
|
|
"avatar" text,
|
|
"valid_until" timestamp(3) without time zone,
|
|
"qr_code" text,
|
|
"created_at" timestamp(6) with time zone default CURRENT_TIMESTAMP,
|
|
"updated_at" timestamp(6) with time zone default CURRENT_TIMESTAMP,
|
|
"patrol_unit_id" character varying(100) not null,
|
|
"id" uuid not null default gen_random_uuid(),
|
|
"banned_reason" character varying(255),
|
|
"banned_until" timestamp(3) without time zone,
|
|
"is_banned" boolean not null default false,
|
|
"panic_strike" integer not null default 0,
|
|
"spoofing_attempts" integer not null default 0
|
|
);
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT FROM pg_tables
|
|
WHERE schemaname = 'public'
|
|
AND tablename = 'panic_button_logs'
|
|
) THEN
|
|
create table "public"."panic_button_logs" (
|
|
"id" uuid not null default gen_random_uuid(),
|
|
"user_id" uuid not null,
|
|
"officer_id" uuid,
|
|
"incident_id" uuid not null,
|
|
"timestamp" timestamp(6) with time zone not null
|
|
);
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT FROM pg_tables
|
|
WHERE schemaname = 'public'
|
|
AND tablename = 'patrol_units'
|
|
) THEN
|
|
create table "public"."patrol_units" (
|
|
"unit_id" character varying(20) not null,
|
|
"location_id" uuid not null,
|
|
"name" character varying(100) not null,
|
|
"type" character varying(50) not null,
|
|
"status" character varying(50) not null,
|
|
"radius" double precision not null,
|
|
"created_at" timestamp(6) with time zone not null default CURRENT_TIMESTAMP,
|
|
"id" character varying(100) not null
|
|
);
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
alter table "public"."crimes" add column "avg_crime" double precision not null default 0;
|
|
|
|
alter table "public"."crimes" add column "crime_cleared" integer not null default 0;
|
|
|
|
alter table "public"."crimes" add column "source_type" character varying(100);
|
|
|
|
alter table "public"."crimes" alter column "year" drop not null;
|
|
|
|
alter table "public"."geographics" alter column "location" set data type gis.geography using "location"::gis.geography;
|
|
|
|
alter table "public"."location_logs" alter column "created_at" set default CURRENT_TIMESTAMP;
|
|
|
|
alter table "public"."location_logs" alter column "created_at" set data type timestamp(6) with time zone using "created_at"::timestamp(6) with time zone;
|
|
|
|
alter table "public"."location_logs" alter column "location" set data type gis.geography using "location"::gis.geography;
|
|
|
|
alter table "public"."location_logs" alter column "timestamp" set data type timestamp(6) with time zone using "timestamp"::timestamp(6) with time zone;
|
|
|
|
alter table "public"."location_logs" alter column "updated_at" set default CURRENT_TIMESTAMP;
|
|
|
|
alter table "public"."location_logs" alter column "updated_at" set data type timestamp(6) with time zone using "updated_at"::timestamp(6) with time zone;
|
|
|
|
alter table "public"."locations" add column "distance_to_unit" double precision;
|
|
|
|
-- First, drop any triggers on the locations table that might use the location column
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (
|
|
SELECT 1 FROM pg_trigger
|
|
WHERE tgrelid = 'public.locations'::regclass
|
|
AND tgname = 'location_distance_to_unit_trigger'
|
|
) THEN
|
|
DROP TRIGGER location_distance_to_unit_trigger ON public.locations;
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
-- Now we can safely alter the column type
|
|
alter table "public"."locations" alter column "location" set data type gis.geography using "location"::gis.geography;
|
|
|
|
alter table "public"."profiles" add column "nik" character varying(100) not null default ''::character varying;
|
|
|
|
-- Safely drop unit_id column if it exists
|
|
DO $$
|
|
BEGIN
|
|
IF EXISTS (
|
|
SELECT 1
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'unit_statistics'
|
|
AND column_name = 'unit_id'
|
|
) THEN
|
|
ALTER TABLE "public"."unit_statistics" DROP COLUMN "unit_id";
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
-- Safely add code_unit column if it does not exist
|
|
DO $$
|
|
BEGIN
|
|
IF NOT EXISTS (
|
|
SELECT 1
|
|
FROM information_schema.columns
|
|
WHERE table_schema = 'public'
|
|
AND table_name = 'unit_statistics'
|
|
AND column_name = 'code_unit'
|
|
) THEN
|
|
ALTER TABLE "public"."unit_statistics" ADD COLUMN "code_unit" character varying(20) NOT NULL;
|
|
END IF;
|
|
END
|
|
$$;
|
|
|
|
alter table "public"."units" drop column "id";
|
|
|
|
alter table "public"."units" add column "city_id" character varying(20) not null;
|
|
|
|
alter table "public"."units" add column "phone" character varying(20);
|
|
|
|
alter table "public"."units" alter column "district_id" drop not null;
|
|
|
|
alter table "public"."units" alter column "location" set data type gis.geography using "location"::gis.geography;
|
|
|
|
alter table "public"."users" add column "banned_reason" character varying(255);
|
|
|
|
alter table "public"."users" add column "is_banned" boolean not null default false;
|
|
|
|
alter table "public"."users" add column "panic_strike" integer not null default 0;
|
|
|
|
alter table "public"."users" add column "spoofing_attempts" integer not null default 0;
|
|
|
|
CREATE UNIQUE INDEX _prisma_migrations_pkey ON public._prisma_migrations USING btree (id);
|
|
|
|
CREATE UNIQUE INDEX evidence_id_key ON public.evidence USING btree (id);
|
|
|
|
CREATE UNIQUE INDEX evidence_pkey ON public.evidence USING btree (id);
|
|
|
|
CREATE INDEX idx_evidence_incident_id ON public.evidence USING btree (incident_id);
|
|
|
|
CREATE INDEX idx_officers_name ON public.officers USING btree (name);
|
|
|
|
CREATE INDEX idx_officers_nrp ON public.officers USING btree (nrp);
|
|
|
|
CREATE INDEX idx_officers_position ON public.officers USING btree ("position");
|
|
|
|
CREATE INDEX idx_officers_rank ON public.officers USING btree (rank);
|
|
|
|
CREATE INDEX idx_officers_unit_id ON public.officers USING btree (unit_id);
|
|
|
|
CREATE INDEX idx_panic_buttons_user_id ON public.panic_button_logs USING btree (user_id);
|
|
|
|
CREATE INDEX idx_patrol_units_location_id ON public.patrol_units USING btree (location_id);
|
|
|
|
CREATE INDEX idx_patrol_units_name ON public.patrol_units USING btree (name);
|
|
|
|
CREATE INDEX idx_patrol_units_status ON public.patrol_units USING btree (status);
|
|
|
|
CREATE INDEX idx_patrol_units_type ON public.patrol_units USING btree (type);
|
|
|
|
CREATE INDEX idx_patrol_units_unit_id ON public.patrol_units USING btree (unit_id);
|
|
|
|
CREATE INDEX idx_profiles_nik ON public.profiles USING btree (nik);
|
|
|
|
CREATE UNIQUE INDEX officers_nrp_key ON public.officers USING btree (nrp);
|
|
|
|
CREATE UNIQUE INDEX officers_pkey ON public.officers USING btree (id);
|
|
|
|
CREATE UNIQUE INDEX panic_button_logs_pkey ON public.panic_button_logs USING btree (id);
|
|
|
|
CREATE UNIQUE INDEX patrol_units_id_key ON public.patrol_units USING btree (id);
|
|
|
|
CREATE UNIQUE INDEX patrol_units_pkey ON public.patrol_units USING btree (id);
|
|
|
|
CREATE UNIQUE INDEX profiles_nik_key ON public.profiles USING btree (nik);
|
|
|
|
CREATE UNIQUE INDEX unit_statistics_code_unit_month_year_key ON public.unit_statistics USING btree (code_unit, month, year);
|
|
|
|
CREATE UNIQUE INDEX units_pkey ON public.units USING btree (code_unit);
|
|
|
|
alter table "public"."_prisma_migrations" add constraint "_prisma_migrations_pkey" PRIMARY KEY using index "_prisma_migrations_pkey";
|
|
|
|
alter table "public"."evidence" add constraint "evidence_pkey" PRIMARY KEY using index "evidence_pkey";
|
|
|
|
alter table "public"."officers" add constraint "officers_pkey" PRIMARY KEY using index "officers_pkey";
|
|
|
|
alter table "public"."panic_button_logs" add constraint "panic_button_logs_pkey" PRIMARY KEY using index "panic_button_logs_pkey";
|
|
|
|
alter table "public"."patrol_units" add constraint "patrol_units_pkey" PRIMARY KEY using index "patrol_units_pkey";
|
|
|
|
alter table "public"."units" add constraint "units_pkey" PRIMARY KEY using index "units_pkey";
|
|
|
|
alter table "public"."evidence" add constraint "evidence_incident_id_fkey" FOREIGN KEY (incident_id) REFERENCES incident_logs(id) ON UPDATE CASCADE ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."evidence" validate constraint "evidence_incident_id_fkey";
|
|
|
|
alter table "public"."officers" add constraint "officers_patrol_unit_id_fkey" FOREIGN KEY (patrol_unit_id) REFERENCES patrol_units(id) ON UPDATE CASCADE ON DELETE RESTRICT not valid;
|
|
|
|
alter table "public"."officers" validate constraint "officers_patrol_unit_id_fkey";
|
|
|
|
alter table "public"."officers" add constraint "officers_role_id_fkey" FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."officers" validate constraint "officers_role_id_fkey";
|
|
|
|
alter table "public"."officers" add constraint "officers_unit_id_fkey" FOREIGN KEY (unit_id) REFERENCES units(code_unit) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."officers" validate constraint "officers_unit_id_fkey";
|
|
|
|
alter table "public"."panic_button_logs" add constraint "panic_button_logs_incident_id_fkey" FOREIGN KEY (incident_id) REFERENCES incident_logs(id) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."panic_button_logs" validate constraint "panic_button_logs_incident_id_fkey";
|
|
|
|
alter table "public"."panic_button_logs" add constraint "panic_button_logs_officer_id_fkey" FOREIGN KEY (officer_id) REFERENCES officers(id) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."panic_button_logs" validate constraint "panic_button_logs_officer_id_fkey";
|
|
|
|
alter table "public"."panic_button_logs" add constraint "panic_button_logs_user_id_fkey" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."panic_button_logs" validate constraint "panic_button_logs_user_id_fkey";
|
|
|
|
alter table "public"."patrol_units" add constraint "patrol_units_location_id_fkey" FOREIGN KEY (location_id) REFERENCES locations(id) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."patrol_units" validate constraint "patrol_units_location_id_fkey";
|
|
|
|
alter table "public"."patrol_units" add constraint "patrol_units_unit_id_fkey" FOREIGN KEY (unit_id) REFERENCES units(code_unit) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."patrol_units" validate constraint "patrol_units_unit_id_fkey";
|
|
|
|
alter table "public"."unit_statistics" add constraint "unit_statistics_code_unit_fkey" FOREIGN KEY (code_unit) REFERENCES units(code_unit) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."unit_statistics" validate constraint "unit_statistics_code_unit_fkey";
|
|
|
|
alter table "public"."units" add constraint "units_city_id_fkey" FOREIGN KEY (city_id) REFERENCES cities(id) ON DELETE CASCADE not valid;
|
|
|
|
alter table "public"."units" validate constraint "units_city_id_fkey";
|
|
|
|
set check_function_bodies = off;
|
|
|
|
CREATE OR REPLACE FUNCTION public.delete_user()
|
|
RETURNS void
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
SET search_path TO ''
|
|
AS $function$
|
|
begin
|
|
delete from auth.users where id = (select auth.uid());
|
|
end;
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION public.generate_username(email text)
|
|
RETURNS text
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $function$
|
|
DECLARE
|
|
result_username TEXT;
|
|
username_base TEXT;
|
|
random_number INTEGER;
|
|
username_exists BOOLEAN;
|
|
BEGIN
|
|
-- Extract the part before @ from email
|
|
username_base := split_part(email, '@', 1);
|
|
|
|
-- Remove any special characters and replace with underscore
|
|
username_base := regexp_replace(username_base, '[^a-zA-Z0-9]', '_', 'g');
|
|
|
|
-- Generate a random number between 100 and 9999
|
|
random_number := floor(random() * 9900 + 100)::integer;
|
|
|
|
-- Combine the base and random number
|
|
result_username := username_base || random_number;
|
|
|
|
-- Check if username already exists
|
|
LOOP
|
|
SELECT EXISTS(SELECT 1 FROM public.profiles WHERE username = result_username) INTO username_exists;
|
|
|
|
IF NOT username_exists THEN
|
|
EXIT;
|
|
END IF;
|
|
|
|
-- Generate a different random number
|
|
random_number := floor(random() * 9900 + 100)::integer;
|
|
result_username := username_base || random_number;
|
|
END LOOP;
|
|
|
|
RETURN result_username;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION public.handle_new_user()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $function$
|
|
DECLARE
|
|
role_id UUID;
|
|
officer_role_id UUID;
|
|
is_officer BOOLEAN;
|
|
officer_data JSONB;
|
|
unit_id VARCHAR;
|
|
BEGIN
|
|
-- Check if the user is registering as an officer
|
|
is_officer := FALSE;
|
|
|
|
-- Check user_metadata for officer flag
|
|
IF NEW.raw_user_meta_data ? 'is_officer' THEN
|
|
is_officer := (NEW.raw_user_meta_data->>'is_officer')::boolean;
|
|
END IF;
|
|
|
|
IF is_officer THEN
|
|
-- Get officer role ID
|
|
SELECT id INTO officer_role_id FROM public.roles WHERE name = 'officer' LIMIT 1;
|
|
IF officer_role_id IS NULL THEN
|
|
RAISE EXCEPTION 'Officer role not found';
|
|
END IF;
|
|
|
|
-- Extract officer data from metadata
|
|
officer_data := NEW.raw_user_meta_data->'officer_data';
|
|
|
|
-- Get unit ID from metadata
|
|
unit_id := officer_data->>'unit_id';
|
|
IF unit_id IS NULL THEN
|
|
RAISE EXCEPTION 'Unit ID is required for officer registration';
|
|
END IF;
|
|
|
|
-- Insert into officers table
|
|
INSERT INTO public.officers (
|
|
id,
|
|
unit_id,
|
|
role_id,
|
|
nrp,
|
|
name,
|
|
rank,
|
|
position,
|
|
phone,
|
|
email,
|
|
created_at,
|
|
updated_at
|
|
) VALUES (
|
|
NEW.id,
|
|
unit_id,
|
|
officer_role_id,
|
|
officer_data->>'nrp',
|
|
COALESCE(officer_data->>'name', NEW.email),
|
|
officer_data->>'rank',
|
|
officer_data->>'position',
|
|
COALESCE(NEW.phone, officer_data->>'phone'),
|
|
NEW.email,
|
|
NEW.created_at,
|
|
NEW.updated_at
|
|
);
|
|
|
|
-- Return early since we've handled the officer case
|
|
RETURN NEW;
|
|
ELSE
|
|
-- Standard user registration - Get viewer role ID
|
|
SELECT id INTO role_id FROM public.roles WHERE name = 'viewer' LIMIT 1;
|
|
IF role_id IS NULL THEN
|
|
RAISE EXCEPTION 'Viewer role not found';
|
|
END IF;
|
|
|
|
-- Insert into users table
|
|
INSERT INTO public.users (
|
|
id,
|
|
roles_id,
|
|
email,
|
|
phone,
|
|
encrypted_password,
|
|
invited_at,
|
|
confirmed_at,
|
|
email_confirmed_at,
|
|
recovery_sent_at,
|
|
last_sign_in_at,
|
|
app_metadata,
|
|
user_metadata,
|
|
created_at,
|
|
updated_at,
|
|
banned_until,
|
|
is_anonymous
|
|
) VALUES (
|
|
NEW.id,
|
|
role_id,
|
|
NEW.email,
|
|
NEW.phone,
|
|
NEW.encrypted_password,
|
|
NEW.invited_at,
|
|
NEW.confirmed_at,
|
|
NEW.email_confirmed_at,
|
|
NEW.recovery_sent_at,
|
|
NEW.last_sign_in_at,
|
|
NEW.raw_app_meta_data,
|
|
NEW.raw_user_meta_data,
|
|
NEW.created_at,
|
|
NEW.updated_at,
|
|
NEW.banned_until,
|
|
NEW.is_anonymous
|
|
);
|
|
|
|
-- Insert into profiles table
|
|
INSERT INTO public.profiles (
|
|
id,
|
|
user_id,
|
|
avatar,
|
|
username,
|
|
first_name,
|
|
last_name,
|
|
bio,
|
|
address,
|
|
birth_date
|
|
) VALUES (
|
|
gen_random_uuid(),
|
|
NEW.id,
|
|
NULL,
|
|
public.generate_username(NEW.email),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
RETURN NEW;
|
|
END IF;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION public.handle_user_delete()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $function$
|
|
DECLARE
|
|
is_officer BOOLEAN;
|
|
BEGIN
|
|
-- Check if the user is an officer
|
|
is_officer := EXISTS (SELECT 1 FROM public.officers WHERE id = OLD.id);
|
|
|
|
IF is_officer THEN
|
|
-- Delete officer record
|
|
DELETE FROM public.officers WHERE id = OLD.id;
|
|
ELSE
|
|
-- Delete standard user data
|
|
DELETE FROM public.profiles WHERE user_id = OLD.id;
|
|
DELETE FROM public.users WHERE id = OLD.id;
|
|
END IF;
|
|
|
|
RETURN OLD;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION public.handle_user_type_change()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $function$
|
|
DECLARE
|
|
is_officer_before BOOLEAN;
|
|
is_officer_after BOOLEAN;
|
|
officer_role_id UUID;
|
|
viewer_role_id UUID;
|
|
officer_data JSONB;
|
|
unit_id VARCHAR;
|
|
BEGIN
|
|
-- Determine officer status before and after update
|
|
is_officer_before := EXISTS (SELECT 1 FROM public.officers WHERE id = NEW.id);
|
|
|
|
-- Check if user_metadata indicates officer status after update
|
|
is_officer_after := FALSE;
|
|
IF NEW.raw_user_meta_data ? 'is_officer' THEN
|
|
is_officer_after := (NEW.raw_user_meta_data->>'is_officer')::boolean;
|
|
END IF;
|
|
|
|
-- If status changed from regular user to officer
|
|
IF NOT is_officer_before AND is_officer_after THEN
|
|
-- Get officer role ID
|
|
SELECT id INTO officer_role_id FROM public.roles WHERE name = 'officer' LIMIT 1;
|
|
IF officer_role_id IS NULL THEN
|
|
RAISE EXCEPTION 'Officer role not found';
|
|
END IF;
|
|
|
|
-- Extract officer data from metadata
|
|
officer_data := NEW.raw_user_meta_data->'officer_data';
|
|
|
|
-- Get unit ID from metadata
|
|
unit_id := officer_data->>'unit_id';
|
|
IF unit_id IS NULL THEN
|
|
RAISE EXCEPTION 'Unit ID is required for officer registration';
|
|
END IF;
|
|
|
|
-- Insert into officers table
|
|
INSERT INTO public.officers (
|
|
id,
|
|
unit_id,
|
|
role_id,
|
|
nrp,
|
|
name,
|
|
rank,
|
|
position,
|
|
phone,
|
|
email,
|
|
created_at,
|
|
updated_at
|
|
) VALUES (
|
|
NEW.id,
|
|
unit_id,
|
|
officer_role_id,
|
|
officer_data->>'nrp',
|
|
COALESCE(officer_data->>'name', NEW.email),
|
|
officer_data->>'rank',
|
|
officer_data->>'position',
|
|
COALESCE(NEW.phone, officer_data->>'phone'),
|
|
NEW.email,
|
|
NEW.created_at,
|
|
NEW.updated_at
|
|
);
|
|
|
|
-- Delete regular user data
|
|
DELETE FROM public.profiles WHERE user_id = NEW.id;
|
|
DELETE FROM public.users WHERE id = NEW.id;
|
|
|
|
-- If status changed from officer to regular user
|
|
ELSIF is_officer_before AND NOT is_officer_after THEN
|
|
-- Get viewer role ID
|
|
SELECT id INTO viewer_role_id FROM public.roles WHERE name = 'viewer' LIMIT 1;
|
|
IF viewer_role_id IS NULL THEN
|
|
RAISE EXCEPTION 'Viewer role not found';
|
|
END IF;
|
|
|
|
-- Insert into users table
|
|
INSERT INTO public.users (
|
|
id,
|
|
roles_id,
|
|
email,
|
|
phone,
|
|
encrypted_password,
|
|
invited_at,
|
|
confirmed_at,
|
|
email_confirmed_at,
|
|
recovery_sent_at,
|
|
last_sign_in_at,
|
|
app_metadata,
|
|
user_metadata,
|
|
created_at,
|
|
updated_at,
|
|
banned_until,
|
|
is_anonymous
|
|
) VALUES (
|
|
NEW.id,
|
|
viewer_role_id,
|
|
NEW.email,
|
|
NEW.phone,
|
|
NEW.encrypted_password,
|
|
NEW.invited_at,
|
|
NEW.confirmed_at,
|
|
NEW.email_confirmed_at,
|
|
NEW.recovery_sent_at,
|
|
NEW.last_sign_in_at,
|
|
NEW.raw_app_meta_data,
|
|
NEW.raw_user_meta_data,
|
|
NEW.created_at,
|
|
NEW.updated_at,
|
|
NEW.banned_until,
|
|
NEW.is_anonymous
|
|
);
|
|
|
|
-- Insert into profiles table
|
|
INSERT INTO public.profiles (
|
|
id,
|
|
user_id,
|
|
avatar,
|
|
username,
|
|
first_name,
|
|
last_name,
|
|
bio,
|
|
address,
|
|
birth_date
|
|
) VALUES (
|
|
gen_random_uuid(),
|
|
NEW.id,
|
|
NULL,
|
|
public.generate_username(NEW.email),
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
-- Delete officer record
|
|
DELETE FROM public.officers WHERE id = NEW.id;
|
|
END IF;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION public.handle_user_update()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
SECURITY DEFINER
|
|
AS $function$
|
|
DECLARE
|
|
is_officer BOOLEAN;
|
|
officer_data JSONB;
|
|
BEGIN
|
|
-- Check if the user is an officer
|
|
is_officer := EXISTS (SELECT 1 FROM public.officers WHERE id = NEW.id);
|
|
|
|
-- Also check if user_metadata indicates officer status (for cases where metadata was updated)
|
|
IF NOT is_officer AND NEW.raw_user_meta_data ? 'is_officer' THEN
|
|
is_officer := (NEW.raw_user_meta_data->>'is_officer')::boolean;
|
|
END IF;
|
|
|
|
IF is_officer THEN
|
|
-- Extract officer data from metadata if it exists
|
|
IF NEW.raw_user_meta_data ? 'officer_data' THEN
|
|
officer_data := NEW.raw_user_meta_data->'officer_data';
|
|
|
|
-- Update officer record
|
|
UPDATE public.officers
|
|
SET
|
|
nrp = COALESCE(officer_data->>'nrp', nrp),
|
|
name = COALESCE(officer_data->>'name', name),
|
|
rank = COALESCE(officer_data->>'rank', rank),
|
|
position = COALESCE(officer_data->>'position', position),
|
|
phone = COALESCE(NEW.phone, officer_data->>'phone', phone),
|
|
email = COALESCE(NEW.email, email),
|
|
updated_at = NOW()
|
|
WHERE id = NEW.id;
|
|
ELSE
|
|
-- Basic update with available auth data
|
|
UPDATE public.officers
|
|
SET
|
|
phone = COALESCE(NEW.phone, phone),
|
|
email = COALESCE(NEW.email, email),
|
|
updated_at = NOW()
|
|
WHERE id = NEW.id;
|
|
END IF;
|
|
ELSE
|
|
-- Standard user update
|
|
UPDATE public.users
|
|
SET
|
|
email = COALESCE(NEW.email, email),
|
|
phone = COALESCE(NEW.phone, phone),
|
|
encrypted_password = COALESCE(NEW.encrypted_password, encrypted_password),
|
|
invited_at = COALESCE(NEW.invited_at, invited_at),
|
|
confirmed_at = COALESCE(NEW.confirmed_at, confirmed_at),
|
|
email_confirmed_at = COALESCE(NEW.email_confirmed_at, email_confirmed_at),
|
|
recovery_sent_at = COALESCE(NEW.recovery_sent_at, recovery_sent_at),
|
|
last_sign_in_at = COALESCE(NEW.last_sign_in_at, last_sign_in_at),
|
|
app_metadata = COALESCE(NEW.raw_app_meta_data, app_metadata),
|
|
user_metadata = COALESCE(NEW.raw_user_meta_data, user_metadata),
|
|
created_at = COALESCE(NEW.created_at, created_at),
|
|
updated_at = NOW(),
|
|
banned_until = CASE
|
|
WHEN NEW.banned_until IS NULL THEN NULL
|
|
ELSE COALESCE(NEW.banned_until, banned_until)
|
|
END,
|
|
is_anonymous = COALESCE(NEW.is_anonymous, is_anonymous)
|
|
WHERE id = NEW.id;
|
|
|
|
-- Create profile if it doesn't exist
|
|
INSERT INTO public.profiles (id, user_id, username)
|
|
SELECT gen_random_uuid(), NEW.id, public.generate_username(NEW.email)
|
|
WHERE NOT EXISTS (
|
|
SELECT 1 FROM public.profiles WHERE user_id = NEW.id
|
|
)
|
|
ON CONFLICT (user_id) DO NOTHING;
|
|
END IF;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION public.nearby_units(lat double precision, lon double precision, max_results integer DEFAULT 5)
|
|
RETURNS TABLE(code_unit character varying, name text, type text, address text, district_id character varying, lat_unit double precision, lon_unit double precision, distance_km double precision)
|
|
LANGUAGE sql
|
|
AS $function$
|
|
select
|
|
u.code_unit,
|
|
u.name,
|
|
u.type,
|
|
u.address,
|
|
u.district_id,
|
|
gis.ST_Y(u.location::gis.geometry) as lat_unit,
|
|
gis.ST_X(u.location::gis.geometry) as lon_unit,
|
|
gis.ST_Distance(
|
|
u.location::gis.geography,
|
|
gis.ST_SetSRID(gis.ST_MakePoint(lon, lat), 4326)::gis.geography
|
|
) / 1000 as distance_km
|
|
from units u
|
|
order by gis.ST_Distance(
|
|
u.location::gis.geography,
|
|
gis.ST_SetSRID(gis.ST_MakePoint(lon, lat), 4326)::gis.geography
|
|
)
|
|
limit max_results
|
|
$function$
|
|
;
|
|
|
|
CREATE OR REPLACE FUNCTION public.update_location_distance_to_unit()
|
|
RETURNS trigger
|
|
LANGUAGE plpgsql
|
|
AS $function$
|
|
DECLARE
|
|
loc_lat FLOAT;
|
|
loc_lng FLOAT;
|
|
unit_lat FLOAT;
|
|
unit_lng FLOAT;
|
|
loc_point gis.GEOGRAPHY;
|
|
unit_point gis.GEOGRAPHY;
|
|
BEGIN
|
|
-- Ambil lat/lng dari location yang baru
|
|
SELECT gis.ST_Y(NEW.location::gis.geometry), gis.ST_X(NEW.location::gis.geometry)
|
|
INTO loc_lat, loc_lng;
|
|
|
|
-- Ambil lat/lng dari unit di distrik yang sama
|
|
SELECT gis.ST_Y(u.location::gis.geometry), gis.ST_X(u.location::gis.geometry)
|
|
INTO unit_lat, unit_lng
|
|
FROM units u
|
|
WHERE u.district_id = NEW.district_id
|
|
LIMIT 1;
|
|
|
|
-- Jika tidak ada unit di distrik yang sama, kembalikan NEW tanpa perubahan
|
|
IF unit_lat IS NULL OR unit_lng IS NULL THEN
|
|
RETURN NEW;
|
|
END IF;
|
|
|
|
-- Buat point geography dari lat/lng
|
|
loc_point := gis.ST_SetSRID(gis.ST_MakePoint(loc_lng, loc_lat), 4326)::gis.geography;
|
|
unit_point := gis.ST_SetSRID(gis.ST_MakePoint(unit_lng, unit_lat), 4326)::gis.geography;
|
|
|
|
-- Update jaraknya ke kolom distance_to_unit
|
|
NEW.distance_to_unit := gis.ST_Distance(loc_point, unit_point) / 1000;
|
|
|
|
RETURN NEW;
|
|
END;
|
|
$function$
|
|
;
|
|
|
|
grant delete on table "public"."_prisma_migrations" to "anon";
|
|
|
|
grant insert on table "public"."_prisma_migrations" to "anon";
|
|
|
|
grant references on table "public"."_prisma_migrations" to "anon";
|
|
|
|
grant select on table "public"."_prisma_migrations" to "anon";
|
|
|
|
grant trigger on table "public"."_prisma_migrations" to "anon";
|
|
|
|
grant truncate on table "public"."_prisma_migrations" to "anon";
|
|
|
|
grant update on table "public"."_prisma_migrations" to "anon";
|
|
|
|
grant delete on table "public"."_prisma_migrations" to "authenticated";
|
|
|
|
grant insert on table "public"."_prisma_migrations" to "authenticated";
|
|
|
|
grant references on table "public"."_prisma_migrations" to "authenticated";
|
|
|
|
grant select on table "public"."_prisma_migrations" to "authenticated";
|
|
|
|
grant trigger on table "public"."_prisma_migrations" to "authenticated";
|
|
|
|
grant truncate on table "public"."_prisma_migrations" to "authenticated";
|
|
|
|
grant update on table "public"."_prisma_migrations" to "authenticated";
|
|
|
|
grant delete on table "public"."_prisma_migrations" to "prisma";
|
|
|
|
grant insert on table "public"."_prisma_migrations" to "prisma";
|
|
|
|
grant references on table "public"."_prisma_migrations" to "prisma";
|
|
|
|
grant select on table "public"."_prisma_migrations" to "prisma";
|
|
|
|
grant trigger on table "public"."_prisma_migrations" to "prisma";
|
|
|
|
grant truncate on table "public"."_prisma_migrations" to "prisma";
|
|
|
|
grant update on table "public"."_prisma_migrations" to "prisma";
|
|
|
|
grant delete on table "public"."_prisma_migrations" to "service_role";
|
|
|
|
grant insert on table "public"."_prisma_migrations" to "service_role";
|
|
|
|
grant references on table "public"."_prisma_migrations" to "service_role";
|
|
|
|
grant select on table "public"."_prisma_migrations" to "service_role";
|
|
|
|
grant trigger on table "public"."_prisma_migrations" to "service_role";
|
|
|
|
grant truncate on table "public"."_prisma_migrations" to "service_role";
|
|
|
|
grant update on table "public"."_prisma_migrations" to "service_role";
|
|
|
|
grant delete on table "public"."evidence" to "anon";
|
|
|
|
grant insert on table "public"."evidence" to "anon";
|
|
|
|
grant references on table "public"."evidence" to "anon";
|
|
|
|
grant select on table "public"."evidence" to "anon";
|
|
|
|
grant trigger on table "public"."evidence" to "anon";
|
|
|
|
grant truncate on table "public"."evidence" to "anon";
|
|
|
|
grant update on table "public"."evidence" to "anon";
|
|
|
|
grant delete on table "public"."evidence" to "authenticated";
|
|
|
|
grant insert on table "public"."evidence" to "authenticated";
|
|
|
|
grant references on table "public"."evidence" to "authenticated";
|
|
|
|
grant select on table "public"."evidence" to "authenticated";
|
|
|
|
grant trigger on table "public"."evidence" to "authenticated";
|
|
|
|
grant truncate on table "public"."evidence" to "authenticated";
|
|
|
|
grant update on table "public"."evidence" to "authenticated";
|
|
|
|
grant delete on table "public"."evidence" to "prisma";
|
|
|
|
grant insert on table "public"."evidence" to "prisma";
|
|
|
|
grant references on table "public"."evidence" to "prisma";
|
|
|
|
grant select on table "public"."evidence" to "prisma";
|
|
|
|
grant trigger on table "public"."evidence" to "prisma";
|
|
|
|
grant truncate on table "public"."evidence" to "prisma";
|
|
|
|
grant update on table "public"."evidence" to "prisma";
|
|
|
|
grant delete on table "public"."evidence" to "service_role";
|
|
|
|
grant insert on table "public"."evidence" to "service_role";
|
|
|
|
grant references on table "public"."evidence" to "service_role";
|
|
|
|
grant select on table "public"."evidence" to "service_role";
|
|
|
|
grant trigger on table "public"."evidence" to "service_role";
|
|
|
|
grant truncate on table "public"."evidence" to "service_role";
|
|
|
|
grant update on table "public"."evidence" to "service_role";
|
|
|
|
grant delete on table "public"."officers" to "anon";
|
|
|
|
grant insert on table "public"."officers" to "anon";
|
|
|
|
grant references on table "public"."officers" to "anon";
|
|
|
|
grant select on table "public"."officers" to "anon";
|
|
|
|
grant trigger on table "public"."officers" to "anon";
|
|
|
|
grant truncate on table "public"."officers" to "anon";
|
|
|
|
grant update on table "public"."officers" to "anon";
|
|
|
|
grant delete on table "public"."officers" to "authenticated";
|
|
|
|
grant insert on table "public"."officers" to "authenticated";
|
|
|
|
grant references on table "public"."officers" to "authenticated";
|
|
|
|
grant select on table "public"."officers" to "authenticated";
|
|
|
|
grant trigger on table "public"."officers" to "authenticated";
|
|
|
|
grant truncate on table "public"."officers" to "authenticated";
|
|
|
|
grant update on table "public"."officers" to "authenticated";
|
|
|
|
grant delete on table "public"."officers" to "prisma";
|
|
|
|
grant insert on table "public"."officers" to "prisma";
|
|
|
|
grant references on table "public"."officers" to "prisma";
|
|
|
|
grant select on table "public"."officers" to "prisma";
|
|
|
|
grant trigger on table "public"."officers" to "prisma";
|
|
|
|
grant truncate on table "public"."officers" to "prisma";
|
|
|
|
grant update on table "public"."officers" to "prisma";
|
|
|
|
grant delete on table "public"."officers" to "service_role";
|
|
|
|
grant insert on table "public"."officers" to "service_role";
|
|
|
|
grant references on table "public"."officers" to "service_role";
|
|
|
|
grant select on table "public"."officers" to "service_role";
|
|
|
|
grant trigger on table "public"."officers" to "service_role";
|
|
|
|
grant truncate on table "public"."officers" to "service_role";
|
|
|
|
grant update on table "public"."officers" to "service_role";
|
|
|
|
grant delete on table "public"."panic_button_logs" to "anon";
|
|
|
|
grant insert on table "public"."panic_button_logs" to "anon";
|
|
|
|
grant references on table "public"."panic_button_logs" to "anon";
|
|
|
|
grant select on table "public"."panic_button_logs" to "anon";
|
|
|
|
grant trigger on table "public"."panic_button_logs" to "anon";
|
|
|
|
grant truncate on table "public"."panic_button_logs" to "anon";
|
|
|
|
grant update on table "public"."panic_button_logs" to "anon";
|
|
|
|
grant delete on table "public"."panic_button_logs" to "authenticated";
|
|
|
|
grant insert on table "public"."panic_button_logs" to "authenticated";
|
|
|
|
grant references on table "public"."panic_button_logs" to "authenticated";
|
|
|
|
grant select on table "public"."panic_button_logs" to "authenticated";
|
|
|
|
grant trigger on table "public"."panic_button_logs" to "authenticated";
|
|
|
|
grant truncate on table "public"."panic_button_logs" to "authenticated";
|
|
|
|
grant update on table "public"."panic_button_logs" to "authenticated";
|
|
|
|
grant delete on table "public"."panic_button_logs" to "prisma";
|
|
|
|
grant insert on table "public"."panic_button_logs" to "prisma";
|
|
|
|
grant references on table "public"."panic_button_logs" to "prisma";
|
|
|
|
grant select on table "public"."panic_button_logs" to "prisma";
|
|
|
|
grant trigger on table "public"."panic_button_logs" to "prisma";
|
|
|
|
grant truncate on table "public"."panic_button_logs" to "prisma";
|
|
|
|
grant update on table "public"."panic_button_logs" to "prisma";
|
|
|
|
grant delete on table "public"."patrol_units" to "anon";
|
|
|
|
grant insert on table "public"."patrol_units" to "anon";
|
|
|
|
grant references on table "public"."patrol_units" to "anon";
|
|
|
|
grant select on table "public"."patrol_units" to "anon";
|
|
|
|
grant trigger on table "public"."patrol_units" to "anon";
|
|
|
|
grant truncate on table "public"."patrol_units" to "anon";
|
|
|
|
grant update on table "public"."patrol_units" to "anon";
|
|
|
|
grant delete on table "public"."patrol_units" to "authenticated";
|
|
|
|
grant insert on table "public"."patrol_units" to "authenticated";
|
|
|
|
grant references on table "public"."patrol_units" to "authenticated";
|
|
|
|
grant select on table "public"."patrol_units" to "authenticated";
|
|
|
|
grant trigger on table "public"."patrol_units" to "authenticated";
|
|
|
|
grant truncate on table "public"."patrol_units" to "authenticated";
|
|
|
|
grant update on table "public"."patrol_units" to "authenticated";
|
|
|
|
grant delete on table "public"."patrol_units" to "prisma";
|
|
|
|
grant insert on table "public"."patrol_units" to "prisma";
|
|
|
|
grant references on table "public"."patrol_units" to "prisma";
|
|
|
|
grant select on table "public"."patrol_units" to "prisma";
|
|
|
|
grant trigger on table "public"."patrol_units" to "prisma";
|
|
|
|
grant truncate on table "public"."patrol_units" to "prisma";
|
|
|
|
grant update on table "public"."patrol_units" to "prisma";
|
|
|
|
grant delete on table "public"."patrol_units" to "service_role";
|
|
|
|
grant insert on table "public"."patrol_units" to "service_role";
|
|
|
|
grant references on table "public"."patrol_units" to "service_role";
|
|
|
|
grant select on table "public"."patrol_units" to "service_role";
|
|
|
|
grant trigger on table "public"."patrol_units" to "service_role";
|
|
|
|
grant truncate on table "public"."patrol_units" to "service_role";
|
|
|
|
grant update on table "public"."patrol_units" to "service_role";
|
|
|
|
|