database-migration
Guide for creating idempotent Supabase database migrations with RLS policies and workspace isolation
Best use case
database-migration is best used when you need a repeatable AI agent workflow instead of a one-off prompt. It is especially useful for teams working in multi. Guide for creating idempotent Supabase database migrations with RLS policies and workspace isolation
Guide for creating idempotent Supabase database migrations with RLS policies and workspace isolation
Users should expect a more consistent workflow output, faster repeated execution, and less time spent rewriting prompts from scratch.
Practical example
Example input
Use the "database-migration" skill to help with this workflow task. Context: Guide for creating idempotent Supabase database migrations with RLS policies and workspace isolation
Example output
A structured workflow result with clearer steps, more consistent formatting, and an output that is easier to reuse in the next run.
When to use this skill
- Use this skill when you want a reusable workflow rather than writing the same prompt again and again.
When not to use this skill
- Do not use this when you only need a one-off answer and do not need a reusable workflow.
- Do not use it if you cannot install or maintain the related files, repository context, or supporting tools.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/database-migration/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How database-migration Compares
| Feature / Agent | database-migration | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Guide for creating idempotent Supabase database migrations with RLS policies and workspace isolation
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Database Migration Skill
## Creating Idempotent Supabase Migrations
**When to Use**: Adding tables, modifying schemas, creating RLS policies, adding functions
---
## Process
### 1. Check Existing Schema
**ALWAYS** check before creating:
```bash
# Read schema reference
cat docs/guides/schema-reference.md
# Or check existing migrations
ls supabase/migrations/
```
### 2. Create Migration File
**Location**: `supabase/migrations/YYYYMMDDHHMMSS_description.sql`
**Naming**: Use timestamp + descriptive name
```
20251230120000_add_agent_registry_table.sql
```
### 3. Write Idempotent SQL
**Pattern**: Use `IF NOT EXISTS` and `CREATE OR REPLACE`
```sql
-- Tables
CREATE TABLE IF NOT EXISTS agent_registry (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
agent_id TEXT NOT NULL,
version TEXT NOT NULL,
capabilities JSONB NOT NULL DEFAULT '[]'::jsonb,
created_at TIMESTAMPTZ DEFAULT NOW(),
UNIQUE(workspace_id, agent_id)
);
-- Indexes
CREATE INDEX IF NOT EXISTS idx_agent_registry_workspace
ON agent_registry(workspace_id);
CREATE INDEX IF NOT EXISTS idx_agent_registry_agent
ON agent_registry(agent_id, workspace_id);
-- RLS
ALTER TABLE agent_registry ENABLE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS "Users can view their workspace agents" ON agent_registry;
CREATE POLICY "Users can view their workspace agents" ON agent_registry
FOR SELECT USING (
workspace_id IN (
SELECT w.id FROM workspaces w
INNER JOIN user_organizations uo ON uo.org_id = w.org_id
WHERE uo.user_id = auth.uid()
)
);
DROP POLICY IF EXISTS "System can manage agents" ON agent_registry;
CREATE POLICY "System can manage agents" ON agent_registry
FOR ALL USING (true) WITH CHECK (true);
-- Functions
CREATE OR REPLACE FUNCTION get_agent_count(p_workspace_id UUID)
RETURNS INTEGER AS $$
BEGIN
RETURN (SELECT COUNT(*) FROM agent_registry WHERE workspace_id = p_workspace_id);
END;
$$ LANGUAGE plpgsql STABLE;
-- Comments
COMMENT ON TABLE agent_registry IS 'Registry of all active agents per workspace';
```
### 4. RLS Policy Pattern
**ALWAYS use**: `user_organizations` + `workspaces` join (NOT workspace_members)
```sql
-- Correct pattern
workspace_id IN (
SELECT w.id FROM workspaces w
INNER JOIN user_organizations uo ON uo.org_id = w.org_id
WHERE uo.user_id = auth.uid()
)
-- For admin/owner only
workspace_id IN (
SELECT w.id FROM workspaces w
INNER JOIN user_organizations uo ON uo.org_id = w.org_id
WHERE uo.user_id = auth.uid() AND uo.role IN ('admin', 'owner')
)
```
### 5. Apply Migration
**Method**: Supabase Dashboard → SQL Editor
**Steps**:
1. Copy migration SQL
2. Paste into SQL Editor
3. Click "Run"
4. Verify success
**Alternative**: Use WORKING_MIGRATIONS.sql pattern for combined migrations
---
## Examples
### Example 1: Simple Table
```sql
CREATE TABLE IF NOT EXISTS my_table (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
name TEXT NOT NULL,
data JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_my_table_workspace ON my_table(workspace_id);
ALTER TABLE my_table ENABLE ROW LEVEL SECURITY;
DROP POLICY IF EXISTS "workspace_isolation" ON my_table;
CREATE POLICY "workspace_isolation" ON my_table
FOR ALL USING (
workspace_id IN (
SELECT w.id FROM workspaces w
INNER JOIN user_organizations uo ON uo.org_id = w.org_id
WHERE uo.user_id = auth.uid()
)
);
```
### Example 2: ENUM Type
```sql
DO $$ BEGIN
CREATE TYPE agent_status AS ENUM ('active', 'paused', 'disabled');
EXCEPTION WHEN duplicate_object THEN NULL;
END $$;
```
### Example 3: Trigger
```sql
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
DROP TRIGGER IF EXISTS trigger_update_updated_at ON my_table;
CREATE TRIGGER trigger_update_updated_at
BEFORE UPDATE ON my_table
FOR EACH ROW
EXECUTE FUNCTION update_updated_at();
```
---
## Common Patterns
### Workspace Isolation (MANDATORY)
```sql
CREATE TABLE table_name (
...
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
...
);
-- Always add index on workspace_id
CREATE INDEX IF NOT EXISTS idx_table_workspace ON table_name(workspace_id);
-- Always add RLS
ALTER TABLE table_name ENABLE ROW LEVEL SECURITY;
```
### Constraints
```sql
-- Check constraints
CONSTRAINT valid_status CHECK (status IN ('active', 'inactive')),
CONSTRAINT valid_score CHECK (score >= 0 AND score <= 100),
CONSTRAINT valid_email CHECK (email ~* '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$')
```
### Foreign Keys
```sql
-- With cascade delete
workspace_id UUID NOT NULL REFERENCES workspaces(id) ON DELETE CASCADE,
-- With set null
created_by UUID REFERENCES auth.users(id) ON DELETE SET NULL,
-- With restrict (prevents delete if referenced)
org_id UUID NOT NULL REFERENCES organizations(id) ON DELETE RESTRICT
```
---
## Checklist
Before applying migration:
- [ ] Checked schema-reference.md for conflicts
- [ ] Used `IF NOT EXISTS` on tables
- [ ] Used `CREATE OR REPLACE` on functions
- [ ] Added workspace_id column (if multi-tenant table)
- [ ] Created index on workspace_id
- [ ] Enabled RLS
- [ ] Added RLS policies (user + system)
- [ ] Used correct RLS pattern (user_organizations join)
- [ ] Added constraints where appropriate
- [ ] Added comments for documentation
- [ ] Tested SQL syntax locally
---
## Troubleshooting
**Error**: "relation workspace_members does not exist"
**Fix**: Use `user_organizations` + `workspaces` join (see RLS pattern above)
**Error**: "already exists"
**Fix**: Use `IF NOT EXISTS` or `CREATE OR REPLACE`
**Error**: "permission denied"
**Fix**: Use service role key in Supabase Dashboard, not anon key
---
**Standard**: Idempotent, workspace-isolated, RLS-secured, well-documentedRelated Skills
vector-database-engineer
Expert in vector databases, embedding strategies, and semantic search implementation. Masters Pinecone, Weaviate, Qdrant, Milvus, and pgvector for RAG applications, recommendation systems, and similar
sqlmap-database-pentesting
This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns...
sqlmap-database-penetration-testing
This skill should be used when the user asks to "automate SQL injection testing," "enumerate database structure," "extract database credentials using sqlmap," "dump tables and columns from a vulnerable database," or "perform automated database penetration testing." It provides comprehensive guidance for using SQLMap to detect and exploit SQL injection vulnerabilities.
godot-4-migration
Specialized guide for migrating Godot 3.x projects to Godot 4 (GDScript 2.0), covering syntax changes, Tweens, and exports.
framework-migration-legacy-modernize
Orchestrate a comprehensive legacy system modernization using the strangler fig pattern, enabling gradual replacement of outdated components while maintaining continuous business operations through ex
framework-migration-deps-upgrade
You are a dependency management expert specializing in safe, incremental upgrades of project dependencies. Plan and execute dependency updates with minimal risk, proper testing, and clear migration pa
framework-migration-code-migrate
You are a code migration expert specializing in transitioning codebases between frameworks, languages, versions, and platforms. Generate comprehensive migration plans, automated migration scripts, and
database-optimizer
Expert database optimizer specializing in modern performance tuning, query optimization, and scalable architectures. Masters advanced indexing, N+1 resolution, multi-tier caching, partitioning strategies, and cloud database optimization. Handles complex query analysis, migration strategies, and performance monitoring. Use PROACTIVELY for database optimization, performance issues, or scalability challenges.
database-migrations-sql-migrations
SQL database migrations with zero-downtime strategies for PostgreSQL, MySQL, SQL Server
database-migrations-migration-observability
Migration monitoring, CDC, and observability infrastructure
database-design
Database design principles and decision-making. Schema design, indexing strategy, ORM selection, serverless databases.
database-cloud-optimization-cost-optimize
You are a cloud cost optimization expert specializing in reducing infrastructure expenses while maintaining performance and reliability. Analyze cloud spending, identify savings opportunities, and implement cost-effective architectures across AWS, Azure, and GCP.