Files
braidsbymira/supabase/tests/database/rls.test.sql
belviskhoremk 8c1522a2b4 chore: deploy Phase 2A backend to live Supabase project (Task 9)
Substitutes the real admin UID everywhere the placeholder appeared,
points the Edge Functions base URL at the deployed project, and adds
production JWT verification: trigger functions now send the anon key
as a bearer token so verify_jwt can stay enabled instead of leaving
the functions open to unauthenticated calls from the public internet.

Also adds scripts/create-admin.ts (one-off helper used to create
Mira's admin auth user), documents the seed script's non-VITE env
vars in .env.example, and closes a gitignore gap where plain .env
wasn't excluded alongside .env.local.

Claude-Session: https://claude.ai/code/session_01NhxA4npAXAxmCDEJt6kxSH
2026-08-12 09:59:33 +02:00

106 lines
3.3 KiB
PL/PgSQL

begin;
select plan(12);
-- Seed reference data as service_role (bypasses RLS)
set local role service_role;
insert into public.services (id, name, duration_minutes, price_from, description, image)
values ('knotless', 'Knotless Braids', 240, 150, 'Tension-free braids.', 'styles/knotless.jpg');
insert into public.products (id, name, category, price, image, description, in_stock)
values ('edge-control', 'Silk Edge Control', 'hair-care', 12, 'products/edge-control.jpg', 'Hold with shine.', true);
reset role;
-- Anyone can read services
set local role anon;
select isnt_empty(
$$ select * from public.services $$,
'anon can read services'
);
-- Anyone can read products
select isnt_empty(
$$ select * from public.products $$,
'anon can read products'
);
-- Anon cannot write to services
select throws_ok(
$$ insert into public.services (id, name, duration_minutes, price_from, description, image)
values ('hack', 'Hack', 1, 1, 'x', 'x') $$,
'42501',
null,
'anon cannot insert into services'
);
-- Anyone can create a booking
select lives_ok(
$$ insert into public.bookings (service_id, date, time, contact_name, contact_phone, contact_email, contact_notes)
values ('knotless', '2026-09-15', '10:00 AM', 'Jane Doe', '555-0100', 'jane@example.com', '') $$,
'anon can create a booking'
);
-- Anon cannot read bookings (PII protection). No SELECT privilege is granted
-- to anon on this table at all now, so this is blocked at the grant layer
-- (permission denied) rather than merely filtered to empty rows by RLS.
select throws_ok(
$$ select * from public.bookings $$,
'42501',
null,
'anon cannot read bookings'
);
-- Anon cannot update bookings (no UPDATE privilege granted, regardless of RLS)
select throws_ok(
$$ update public.bookings set contact_notes = 'hacked' $$,
'42501',
null,
'anon cannot update bookings'
);
-- Anyone can create an inquiry
select lives_ok(
$$ insert into public.inquiries (product_id, contact_name, contact_email, contact_notes)
values ('edge-control', 'Jane Doe', 'jane@example.com', 'Is this in stock?') $$,
'anon can create an inquiry'
);
-- Anon cannot read inquiries (PII protection). Same as bookings above: no
-- SELECT privilege is granted, so this fails at the grant layer.
select throws_ok(
$$ select * from public.inquiries $$,
'42501',
null,
'anon cannot read inquiries'
);
-- Anyone can read booked_slots (no PII there)
select isnt_empty(
$$ select * from public.booked_slots $$,
'anon can read booked_slots (populated by the trigger from the booking above)'
);
-- Anon cannot write booked_slots directly
select throws_ok(
$$ insert into public.booked_slots (date, time) values ('2026-09-16', '1:00 PM') $$,
'42501',
null,
'anon cannot insert into booked_slots directly'
);
-- The admin (matching UID) can read bookings
set local role authenticated;
set local request.jwt.claim.sub = '21c90224-e0b2-412e-a431-8e7f097c1cef';
select isnt_empty(
$$ select * from public.bookings $$,
'admin can read bookings'
);
-- The admin can write to services
select lives_ok(
$$ insert into public.services (id, name, duration_minutes, price_from, description, image)
values ('cornrows', 'Cornrows', 120, 90, 'Classic style.', 'styles/cornrows.jpg') $$,
'admin can insert into services'
);
select * from finish();
rollback;