Loading...
Loading...
Supabase backend development workflow. Use for ANY backend work in Supabase projects — schema changes, API endpoints, database functions, RLS policies, edge functions, auth, storage, business logic, or data access. Activate whenever the task involves server-side logic, data layer, or Supabase features.
npx skill4agent add tomaspozo/skills backend-developmentsupabase-jssupabase/schemas/
├── 10_types/ # Enums, composite types, domains
├── 20_tables/ # Table definitions
├── 30_constraints/ # Check constraints, foreign keys
├── 40_indexes/ # Index definitions
├── 50_functions/ # RPCs, auth functions, internal utils
│ ├── _internal/ # Infrastructure utilities
│ └── _auth/ # RLS policy functions
├── 60_triggers/ # Trigger definitions
├── 70_policies/ # RLS policies
└── 80_views/ # View definitionscharts.sqlreadings.sqlsupabase startexecute_sqlexecute_sqlsupabase gen types typescript --local > src/types/database.tssupabase db diff| Tool | Purpose |
|---|---|
| Supabase CLI | Local development, type generation, migrations |
| Supabase MCP | |
| Edge Functions | See Edge Functions for project structure and withSupabase for wrapper usage |
// ❌ WRONG
const { data } = await supabase.from("charts").select("*");
// ✅ CORRECT
const { data } = await supabase.rpc("chart_get_by_user", { p_user_id: userId });-- ❌ WRONG — bypasses RLS then reimplements filtering manually
CREATE FUNCTION chart_get_by_id(p_chart_id uuid)
RETURNS jsonb LANGUAGE plpgsql SECURITY DEFINER SET search_path = '' AS $$
BEGIN
SELECT ... FROM public.charts WHERE id = p_chart_id AND user_id = auth.uid(); -- manual filter = fragile
END; $$;
-- ✅ CORRECT — RLS handles access control automatically
CREATE FUNCTION chart_get_by_id(p_chart_id uuid)
RETURNS jsonb LANGUAGE plpgsql SECURITY INVOKER SET search_path = '' AS $$
BEGIN
SELECT ... FROM public.charts WHERE id = p_chart_id; -- RLS enforces permissions
END; $$;_auth_*_internal_*-- SECURITY DEFINER: required because ...{entity}_{action}chart_create_auth_{entity}_{check}_auth_chart_can_read_internal_{name}_internal_get_secret