Initial commit: WaMarket MVP
Marketplace inversée (Next.js 16 App Router + Supabase Cloud) : auth, schéma + RLS, publication de besoins avec upload d'images, feed avec filtres, offres, acceptation via RPC, messagerie temps réel, dashboards, et Dockerfile pour déploiement Coolify.
This commit is contained in:
@@ -0,0 +1,192 @@
|
||||
-- Corrections suite au linter de performance Supabase (get_advisors) :
|
||||
-- 1. Wrap auth.uid() en (select auth.uid()) dans toutes les policies RLS
|
||||
-- (évite une réévaluation par ligne — recommandation officielle Supabase).
|
||||
-- 2. Index sur toutes les clés étrangères signalées.
|
||||
|
||||
-- ---- profiles ----
|
||||
drop policy if exists "profiles_update_own" on public.profiles;
|
||||
create policy "profiles_update_own"
|
||||
on public.profiles for update
|
||||
to authenticated
|
||||
using ((select auth.uid()) = id)
|
||||
with check ((select auth.uid()) = id);
|
||||
|
||||
-- ---- needs ----
|
||||
drop policy if exists "needs_select" on public.needs;
|
||||
create policy "needs_select"
|
||||
on public.needs for select
|
||||
using (status = 'open' or (select auth.uid()) = author_id);
|
||||
|
||||
drop policy if exists "needs_insert_own" on public.needs;
|
||||
create policy "needs_insert_own"
|
||||
on public.needs for insert
|
||||
to authenticated
|
||||
with check ((select auth.uid()) = author_id);
|
||||
|
||||
drop policy if exists "needs_update_own" on public.needs;
|
||||
create policy "needs_update_own"
|
||||
on public.needs for update
|
||||
to authenticated
|
||||
using ((select auth.uid()) = author_id)
|
||||
with check ((select auth.uid()) = author_id);
|
||||
|
||||
-- ---- need_images ----
|
||||
drop policy if exists "need_images_select" on public.need_images;
|
||||
create policy "need_images_select"
|
||||
on public.need_images for select
|
||||
using (
|
||||
exists (
|
||||
select 1 from public.needs n
|
||||
where n.id = need_id and (n.status = 'open' or (select auth.uid()) = n.author_id)
|
||||
)
|
||||
);
|
||||
|
||||
drop policy if exists "need_images_insert_own" on public.need_images;
|
||||
create policy "need_images_insert_own"
|
||||
on public.need_images for insert
|
||||
to authenticated
|
||||
with check (
|
||||
exists (select 1 from public.needs n where n.id = need_id and n.author_id = (select auth.uid()))
|
||||
);
|
||||
|
||||
drop policy if exists "need_images_delete_own" on public.need_images;
|
||||
create policy "need_images_delete_own"
|
||||
on public.need_images for delete
|
||||
to authenticated
|
||||
using (
|
||||
exists (select 1 from public.needs n where n.id = need_id and n.author_id = (select auth.uid()))
|
||||
);
|
||||
|
||||
-- ---- offers ----
|
||||
drop policy if exists "offers_select" on public.offers;
|
||||
create policy "offers_select"
|
||||
on public.offers for select
|
||||
to authenticated
|
||||
using (
|
||||
(select auth.uid()) = merchant_id
|
||||
or exists (select 1 from public.needs n where n.id = need_id and n.author_id = (select auth.uid()))
|
||||
);
|
||||
|
||||
drop policy if exists "offers_insert" on public.offers;
|
||||
create policy "offers_insert"
|
||||
on public.offers for insert
|
||||
to authenticated
|
||||
with check (
|
||||
merchant_id = (select auth.uid())
|
||||
and exists (
|
||||
select 1 from public.needs n
|
||||
where n.id = need_id and n.status = 'open' and n.author_id <> (select auth.uid())
|
||||
)
|
||||
);
|
||||
|
||||
drop policy if exists "offers_update_own_pending" on public.offers;
|
||||
create policy "offers_update_own_pending"
|
||||
on public.offers for update
|
||||
to authenticated
|
||||
using ((select auth.uid()) = merchant_id and status = 'pending')
|
||||
with check ((select auth.uid()) = merchant_id);
|
||||
|
||||
-- ---- offer_images ----
|
||||
drop policy if exists "offer_images_select" on public.offer_images;
|
||||
create policy "offer_images_select"
|
||||
on public.offer_images for select
|
||||
to authenticated
|
||||
using (
|
||||
exists (
|
||||
select 1 from public.offers o
|
||||
where o.id = offer_id
|
||||
and (
|
||||
o.merchant_id = (select auth.uid())
|
||||
or exists (select 1 from public.needs n where n.id = o.need_id and n.author_id = (select auth.uid()))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
drop policy if exists "offer_images_insert_own" on public.offer_images;
|
||||
create policy "offer_images_insert_own"
|
||||
on public.offer_images for insert
|
||||
to authenticated
|
||||
with check (
|
||||
exists (select 1 from public.offers o where o.id = offer_id and o.merchant_id = (select auth.uid()))
|
||||
);
|
||||
|
||||
-- ---- conversations ----
|
||||
drop policy if exists "conversations_select" on public.conversations;
|
||||
create policy "conversations_select"
|
||||
on public.conversations for select
|
||||
to authenticated
|
||||
using ((select auth.uid()) = author_id or (select auth.uid()) = merchant_id);
|
||||
|
||||
-- ---- messages ----
|
||||
drop policy if exists "messages_select" on public.messages;
|
||||
create policy "messages_select"
|
||||
on public.messages for select
|
||||
to authenticated
|
||||
using (
|
||||
exists (
|
||||
select 1 from public.conversations c
|
||||
where c.id = conversation_id and ((select auth.uid()) = c.author_id or (select auth.uid()) = c.merchant_id)
|
||||
)
|
||||
);
|
||||
|
||||
drop policy if exists "messages_insert" on public.messages;
|
||||
create policy "messages_insert"
|
||||
on public.messages for insert
|
||||
to authenticated
|
||||
with check (
|
||||
sender_id = (select auth.uid())
|
||||
and exists (
|
||||
select 1 from public.conversations c
|
||||
where c.id = conversation_id and ((select auth.uid()) = c.author_id or (select auth.uid()) = c.merchant_id)
|
||||
)
|
||||
);
|
||||
|
||||
-- ---- storage.objects (offer-images) ----
|
||||
drop policy if exists "offer_images_bucket_read" on storage.objects;
|
||||
create policy "offer_images_bucket_read"
|
||||
on storage.objects for select
|
||||
to authenticated
|
||||
using (
|
||||
bucket_id = 'offer-images'
|
||||
and exists (
|
||||
select 1
|
||||
from public.offer_images oi
|
||||
join public.offers o on o.id = oi.offer_id
|
||||
where oi.storage_path = storage.objects.name
|
||||
and (
|
||||
o.merchant_id = (select auth.uid())
|
||||
or exists (select 1 from public.needs n where n.id = o.need_id and n.author_id = (select auth.uid()))
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
drop policy if exists "need_images_bucket_write" on storage.objects;
|
||||
create policy "need_images_bucket_write"
|
||||
on storage.objects for insert
|
||||
to authenticated
|
||||
with check (
|
||||
bucket_id = 'need-images'
|
||||
and (storage.foldername(name))[1] = (select auth.uid())::text
|
||||
);
|
||||
|
||||
drop policy if exists "offer_images_bucket_write" on storage.objects;
|
||||
create policy "offer_images_bucket_write"
|
||||
on storage.objects for insert
|
||||
to authenticated
|
||||
with check (
|
||||
bucket_id = 'offer-images'
|
||||
and (storage.foldername(name))[1] = (select auth.uid())::text
|
||||
);
|
||||
|
||||
-- ---- Index sur les clés étrangères ----
|
||||
create index if not exists idx_needs_author_id on public.needs (author_id);
|
||||
create index if not exists idx_needs_category_id on public.needs (category_id);
|
||||
create index if not exists idx_needs_accepted_offer_id on public.needs (accepted_offer_id);
|
||||
create index if not exists idx_need_images_need_id on public.need_images (need_id);
|
||||
create index if not exists idx_offers_merchant_id on public.offers (merchant_id);
|
||||
create index if not exists idx_offer_images_offer_id on public.offer_images (offer_id);
|
||||
create index if not exists idx_conversations_need_id on public.conversations (need_id);
|
||||
create index if not exists idx_conversations_author_id on public.conversations (author_id);
|
||||
create index if not exists idx_conversations_merchant_id on public.conversations (merchant_id);
|
||||
create index if not exists idx_messages_conversation_id on public.messages (conversation_id);
|
||||
create index if not exists idx_messages_sender_id on public.messages (sender_id);
|
||||
Reference in New Issue
Block a user