more two scenarios and claude code cli is now a dependency

This commit is contained in:
Pedro Rodrigues
2026-02-20 15:02:59 +00:00
parent 9a23c6b021
commit e03bc99ebb
24 changed files with 1766 additions and 21 deletions

View File

@@ -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 |