Aller au contenu principal

Skill: dev-supabase

Inline

Backend development with Supabase. Trigger when the user wants to configure auth, the database, or Supabase storage.

Configuration​

PropertyValue
Contextinline
Pre-approved toolsNone declared: the project's permission settings apply
Triggerkeywords: dev, supabase, supabase —

Detailed description​

Supabase (pointer)

Supabase publishes the canonical agent skills at supabase/agent-skills — maintained by the Supabase team, in sync with current API (Auth, DB, Edge Functions, Realtime, Storage). The repo ships two skills that stay current with every API release; the prior foundation skill (224 lines) drifted on each Supabase version.

Delegate to the vendor skills​

# Vendor publishes via marketplace (verify on their README):
claude plugin install supabase@supabase

# Fallback — clone and symlink both skills:
git clone --depth 1 https://github.com/supabase/agent-skills ~/dev/vendor-skills/supabase
ln -s ~/dev/vendor-skills/supabase/skills/supabase ./.claude/skills/supabase
ln -s ~/dev/vendor-skills/supabase/skills/supabase-postgres-best-practices \
./.claude/skills/supabase-postgres-best-practices
  • supabase — Auth, DB, Edge Functions, Realtime, Storage with current API patterns.
  • supabase-postgres-best-practices — 30 rules across 8 categories (indexing, RLS perf, schema design, pg_* extensions).

Recipe entry: docs/recipes/recommended-vendor-skills.md §"Supabase — supabase/agent-skills". Reduction rationale: specs/foundation-positioning-review/spec.md Wave 1.

Foundation-unique angle preserved: cross-cutting discipline​

The vendor covers the Supabase API surface. The foundation enforces version-agnostic conventions that survive across releases:

  • Auth: Supabase Auth is one option among many — cross-ref the dev-auth skill for framework-agnostic patterns (sessions, OAuth, magic links) before deciding on Supabase-specific flows.
  • ORM interop: Prisma operates against the same Postgres, and Supabase RLS coexists with Prisma queries — cross-ref the dev-prisma skill.
  • General Postgres: the vendor's supabase-postgres-best-practices skill is useful for any Postgres project, not just Supabase-managed — cross-ref the ops-database skill.
  • Security: RLS on every public table, service_role key server-side only — .claude/rules/supabase.md (below) and .claude/rules/security.md.

Foundation rules: .claude/rules/supabase.md​

The RLS, service_role, secret and query rules this pointer used to carry live in .claude/rules/supabase.md, scoped to the Supabase files. Installed next to the vendor's skills, only one side fires (measured 2026-10-03: Supabase's own skill alone 3/3; Prisma's pointer used to win 3/3 until its description stepped aside, now prisma-cli fires 3/3), so a rule kept in a skill reaches the session only when that skill wins — a rule loaded by the files holds whichever skill fires.

Automatic triggering​

This skill is automatically activated when:

  • The matching keywords are detected in the conversation
  • The task context matches the skill's domain

Triggering examples​

  • "I want to dev..."
  • "I want to supabase..."
  • "I want to supabase — ..."

Context inline​

Inline means the skill runs in the conversation (the default, no context key):

  • Sees the full history
  • Its work is visible as it happens
  • Right for almost every skill

Practical examples​

1. Example: Supabase Auth + Row Level Security​

Example: Supabase Auth + Row Level Security

Scenario​

A multi-tenant task management app where users can only see their own tasks and team-shared tasks.

Database Schema​

-- Create tables
CREATE TABLE profiles (
id UUID REFERENCES auth.users(id) PRIMARY KEY,
team_id UUID REFERENCES teams(id),
display_name TEXT NOT NULL,
role TEXT NOT NULL DEFAULT 'member' CHECK (role IN ('admin', 'member'))
);

CREATE TABLE tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL,
completed BOOLEAN DEFAULT false,
owner_id UUID REFERENCES auth.users(id) NOT NULL,
team_id UUID REFERENCES teams(id),
created_at TIMESTAMPTZ DEFAULT now()
);

Row Level Security Policies​

-- Enable RLS
ALTER TABLE tasks ENABLE ROW LEVEL SECURITY;

-- Users can read their own tasks + team tasks
CREATE POLICY "Users can view own and team tasks"
ON tasks FOR SELECT
USING (
owner_id = auth.uid()
OR team_id IN (
SELECT team_id FROM profiles WHERE id = auth.uid()
)
);

-- Users can only insert tasks they own
CREATE POLICY "Users can create own tasks"
ON tasks FOR INSERT
WITH CHECK (owner_id = auth.uid());

-- Users can update only their own tasks
CREATE POLICY "Users can update own tasks"
ON tasks FOR UPDATE
USING (owner_id = auth.uid());

-- Admins can delete any team task
CREATE POLICY "Admins can delete team tasks"
ON tasks FOR DELETE
USING (
owner_id = auth.uid()
OR EXISTS (
SELECT 1 FROM profiles
WHERE id = auth.uid() AND role = 'admin'
AND team_id = tasks.team_id
)
);

Client Usage (TypeScript)​

// lib/supabase.ts
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);

// Sign up - profile created via trigger
const { data } = await supabase.auth.signUp({
email: 'user@example.com',
password: 'securepassword123',
});

// Fetch tasks - RLS automatically filters to user's own + team tasks
const { data: tasks } = await supabase
.from('tasks')
.select('id, title, completed, owner_id')
.order('created_at', { ascending: false });

// Insert task - RLS ensures owner_id matches auth.uid()
const { error } = await supabase
.from('tasks')
.insert({ title: 'New task', owner_id: user.id, team_id: user.team_id });

Key Decisions​

  • RLS over application-level filtering: Security enforced at database level, not bypassable
  • auth.uid() function: Built-in Supabase function, no need to pass user ID manually
  • Team visibility: Users see team tasks via profile lookup, not task-level ACL
  • Role-based delete: Only admins can delete others' tasks within their team
  • Anon key on client: Safe because RLS restricts all access by authenticated user

See also​