fix(edge-fn): use user.id instead of claims.sub; fixes 500s and false cert_required fix(migrations): drop broad reservations SELECT policy; add reservation_slots view with security_invoker=false fix(tests): correct weekSlot() keys from start/end to start_time/end_time fix(tests): spread overlap test slots across separate ISO weeks fix(tests): update e2e assertion to match actual authenticated home text fix(app): hide IonMenu before user is authenticated feat(dx): add test:all script running unit, integration, and e2e in sequence docs(claude-md): document SELinux fix, Edge Function auth pattern, security_invoker behaviour
55 lines
1.5 KiB
PL/PgSQL
55 lines
1.5 KiB
PL/PgSQL
-- Overlap prevention for reservations using btree_gist exclusion constraint
|
|
create extension if not exists btree_gist;
|
|
|
|
alter table public.reservations
|
|
add constraint no_overlapping_reservations
|
|
exclude using gist (
|
|
boat_id with =,
|
|
tstzrange(start_time, end_time, '[)') with &&
|
|
);
|
|
|
|
-- Function: check member has required certs for a boat
|
|
create or replace function public.member_has_cert_for_boat(p_user_id uuid, p_boat_id uuid)
|
|
returns boolean
|
|
language sql
|
|
stable
|
|
security definer
|
|
set search_path = public
|
|
as $$
|
|
select
|
|
case
|
|
when array_length(b.required_certs, 1) is null or array_length(b.required_certs, 1) = 0
|
|
then true
|
|
else
|
|
coalesce(
|
|
(select m.certifications @> b.required_certs
|
|
from public.members m
|
|
where m.user_id = p_user_id),
|
|
false
|
|
)
|
|
end
|
|
from public.boats b
|
|
where b.id = p_boat_id;
|
|
$$;
|
|
|
|
-- Trigger: enforce cert check on reservation insert
|
|
create or replace function public.enforce_reservation_cert_check()
|
|
returns trigger
|
|
language plpgsql
|
|
security definer
|
|
set search_path = public
|
|
as $$
|
|
begin
|
|
if not coalesce(public.member_has_cert_for_boat(new.user_id, new.boat_id), false) then
|
|
raise exception 'Member does not have required certifications for this boat';
|
|
end if;
|
|
return new;
|
|
end;
|
|
$$;
|
|
|
|
create trigger check_reservation_certs
|
|
before insert on public.reservations
|
|
for each row execute function public.enforce_reservation_cert_check();
|
|
|
|
grant execute on function public.member_has_cert_for_boat(uuid, uuid) to authenticated;
|