-
Notifications
You must be signed in to change notification settings - Fork 0
Supabase Voting
This page describes the current Supabase setup for Proton Pulse report voting.
Right now the plugin uses a public Supabase client key from the frontend and stores votes in public.report_votes.
- Client file:
src/lib/voting.ts - Vote table:
public.report_votes - Aggregate view:
public.report_vote_totals - Current identity model: hashed
voter_id
This is still a frontend-only voting flow. There is no server-side secret in the plugin.
create table if not exists public.report_votes (
voter_id text not null,
app_id text not null,
report_key text not null,
vote smallint not null,
voted_at timestamp with time zone not null default now(),
updated_at timestamp with time zone not null default now(),
primary key (voter_id, app_id, report_key)
);
create index if not exists idx_report_votes_app
on public.report_votes (app_id);create or replace view public.report_vote_totals as
select
app_id,
report_key,
coalesce(sum(case when vote = 1 then 1 else 0 end), 0)::integer as upvotes,
coalesce(sum(case when vote = -1 then 1 else 0 end), 0)::integer as downvotes
from public.report_votes
group by app_id, report_key;The public client flow needs:
grant usage on schema public to anon, authenticated;
grant select, insert, update on table public.report_votes to anon, authenticated;
grant select on table public.report_vote_totals to anon, authenticated;If RLS is enabled on report_votes, the current flow also needs policies like:
alter table public.report_votes enable row level security;
create policy "public read votes"
on public.report_votes
for select
to anon, authenticated
using (true);
create policy "public insert votes"
on public.report_votes
for insert
to anon, authenticated
with check (true);
create policy "public update votes"
on public.report_votes
for update
to anon, authenticated
using (true)
with check (true);These policies match the current voter_id browser flow. They are not the final design.
The plugin uses a Supabase publishable key. That key is safe to embed in the client.
Do not put these in the plugin:
service_rolesb_secret
Those are server-side secrets and must stay out of the frontend.
The better long-term setup is:
- enable Supabase anonymous auth
- sign in anonymously from the plugin
- store
user_id uuid - use
auth.uid()in RLS policies
That gives the app a real anonymous user identity and a cleaner security model than the current local hash.