mirror of
https://github.com/supabase/agent-skills.git
synced 2026-03-27 10:09:26 +08:00
more two scenarios and claude code cli is now a dependency
This commit is contained in:
@@ -49,3 +49,121 @@ The agent initializes a Supabase project and creates a migration file that:
|
||||
| index on user_id | `CREATE INDEX` on the FK column |
|
||||
| IF NOT EXISTS | Idempotent migration |
|
||||
| overall quality | At least 4/5 best-practice signals present |
|
||||
|
||||
## Scenario 2: team-rls-security-definer
|
||||
|
||||
**Description:** Create a SQL migration for a team-based project management app
|
||||
where users belong to organizations via a membership table. The migration must
|
||||
define tables for organizations, memberships, and projects, then secure them
|
||||
with RLS policies that use a `security definer` helper function in a private
|
||||
schema to efficiently resolve team membership without per-row joins.
|
||||
|
||||
**Setup:** The workspace starts with a pre-initialized Supabase project
|
||||
(`supabase/config.toml` exists, empty `supabase/migrations/` directory). The
|
||||
agent creates migration files within this structure.
|
||||
|
||||
**Expected skill files read:**
|
||||
|
||||
- `SKILL.md` (skill body with reference file index)
|
||||
- `references/db-rls-mandatory.md`
|
||||
- `references/db-rls-policy-types.md`
|
||||
- `references/db-rls-common-mistakes.md`
|
||||
- `references/db-rls-performance.md`
|
||||
- `references/db-security-functions.md`
|
||||
- `references/db-schema-auth-fk.md`
|
||||
- `references/db-schema-timestamps.md`
|
||||
- `references/db-perf-indexes.md`
|
||||
- `references/db-migrations-idempotent.md`
|
||||
|
||||
**Expected result:**
|
||||
|
||||
The agent creates a migration file that:
|
||||
|
||||
- Creates organizations, memberships, and projects tables with `timestamptz` columns
|
||||
- Has `user_id` FK to `auth.users(id)` with `ON DELETE CASCADE` on memberships
|
||||
- Has `org_id` FK on projects referencing organizations
|
||||
- Enables RLS on all three tables
|
||||
- Creates a private schema with a `security definer` helper function (`SET search_path = ''`)
|
||||
- Creates RLS policies using `(select auth.uid())` with `TO authenticated`
|
||||
- Creates indexes on membership lookup columns (user_id, org_id)
|
||||
- Has a delete policy on projects restricted to owner role
|
||||
- Uses `IF NOT EXISTS` for idempotency
|
||||
|
||||
**Scorer:** Binary pass/fail (16 vitest assertions)
|
||||
|
||||
| Test | What it checks |
|
||||
| --- | --- |
|
||||
| migration file exists | A `.sql` file exists in `supabase/migrations/` |
|
||||
| creates organizations table | SQL contains `CREATE TABLE` for organizations |
|
||||
| creates memberships table | SQL contains `CREATE TABLE` for memberships |
|
||||
| creates projects table | SQL contains `CREATE TABLE` for projects |
|
||||
| enables RLS on all tables | `ALTER TABLE ... ENABLE ROW LEVEL SECURITY` for all three tables |
|
||||
| FK to auth.users with ON DELETE CASCADE | memberships references `auth.users` with cascade |
|
||||
| org_id FK on projects | projects references organizations |
|
||||
| private schema created | `CREATE SCHEMA ... private` present |
|
||||
| security_definer helper function | Function in private schema with `SECURITY DEFINER` and `SET search_path = ''` |
|
||||
| policies use (select auth.uid()) | Subselect form in all policies referencing auth.uid() |
|
||||
| policies use TO authenticated | All policies scoped to authenticated role |
|
||||
| index on membership lookup columns | `CREATE INDEX` on user_id and/or org_id in memberships |
|
||||
| uses timestamptz | No plain `timestamp` for time columns |
|
||||
| idempotent DDL | Uses `IF NOT EXISTS` or `DROP ... IF EXISTS` patterns |
|
||||
| delete policy restricted to owner role | A delete policy on projects checks for owner/admin role |
|
||||
| overall quality score | At least 10/14 best-practice signals present |
|
||||
|
||||
## Scenario 3: storage-rls-user-folders
|
||||
|
||||
**Description:** Create a SQL migration that sets up Supabase Storage buckets
|
||||
with RLS policies for user-content. An avatars bucket (public reads,
|
||||
authenticated uploads restricted to user folders) and a documents bucket (fully
|
||||
private, user-isolated), with file type restrictions, storage helper functions
|
||||
in policies, and a file_metadata tracking table secured with RLS.
|
||||
|
||||
**Setup:** Pre-initialized Supabase project (`supabase/config.toml` exists)
|
||||
with an empty `supabase/migrations/` directory. The agent creates migration
|
||||
files within this structure.
|
||||
|
||||
**Expected skill files read:**
|
||||
|
||||
- `SKILL.md` (skill body with reference file index)
|
||||
- `references/storage-access-control.md`
|
||||
- `references/db-rls-mandatory.md`
|
||||
- `references/db-rls-common-mistakes.md`
|
||||
- `references/db-rls-performance.md`
|
||||
- `references/db-schema-auth-fk.md`
|
||||
- `references/db-schema-timestamps.md`
|
||||
- `references/db-perf-indexes.md`
|
||||
- `references/db-migrations-idempotent.md`
|
||||
|
||||
**Expected result:**
|
||||
|
||||
The agent creates a migration file that:
|
||||
|
||||
- Inserts avatars bucket into `storage.buckets` with `public = true`, MIME type restrictions, and file size limit
|
||||
- Inserts documents bucket with `public = false`
|
||||
- Creates RLS policies on `storage.objects` using `storage.foldername(name)` with `auth.uid()::text`
|
||||
- Scopes upload policies `TO authenticated` and avatars SELECT policy `TO public`
|
||||
- Creates `file_metadata` table with FK to `auth.users` with `ON DELETE CASCADE`
|
||||
- Enables RLS on `file_metadata` with policies using `(select auth.uid())`
|
||||
- Uses `timestamptz` for time columns, indexes `user_id`, and `IF NOT EXISTS` for idempotency
|
||||
|
||||
**Scorer:** Binary pass/fail (17 vitest assertions)
|
||||
|
||||
| Test | What it checks |
|
||||
| --- | --- |
|
||||
| migration file exists | A `.sql` file exists in `supabase/migrations/` |
|
||||
| creates avatars bucket | SQL inserts into `storage.buckets` with id 'avatars' and `public = true` |
|
||||
| creates documents bucket | SQL inserts into `storage.buckets` with id 'documents' and `public = false` |
|
||||
| avatars bucket has mime type restriction | `allowed_mime_types` includes image types (jpeg, png, webp) |
|
||||
| avatars bucket has file size limit | `file_size_limit` set (around 2MB / 2097152 bytes) |
|
||||
| storage policy uses foldername or path for user isolation | Policy references `storage.foldername(name)` with `auth.uid()::text` |
|
||||
| storage policy uses TO authenticated | Storage upload/delete policies scoped to `TO authenticated` |
|
||||
| public read policy for avatars | A SELECT policy on storage.objects for avatars allows public/anon access |
|
||||
| documents bucket is fully private | Policies for documents restrict all operations to authenticated owner |
|
||||
| creates file_metadata table | SQL contains `CREATE TABLE` for file_metadata |
|
||||
| file_metadata has FK to auth.users with CASCADE | `REFERENCES auth.users` with `ON DELETE CASCADE` |
|
||||
| RLS enabled on file_metadata | `ALTER TABLE file_metadata ENABLE ROW LEVEL SECURITY` |
|
||||
| file_metadata policies use (select auth.uid()) | Subselect form in policies |
|
||||
| uses timestamptz for time columns | No plain `timestamp` in file_metadata |
|
||||
| index on file_metadata user_id | `CREATE INDEX` on user_id column |
|
||||
| idempotent DDL | Uses `IF NOT EXISTS` patterns |
|
||||
| overall quality score | At least 11/15 best-practice signals present |
|
||||
|
||||
Reference in New Issue
Block a user