Complete workflow for implementing data services and database architecture after the Implementer Agent has completed use cases...
This skill provides the complete technical workflow for implementing pure data services, designing optimized database schemas, and configuring high-performance Row Level Security policies in Supabase/PostgreSQL environments.
MANDATORY when working as Supabase Expert agent:
Prerequisites:
entities.ts with Zod schemassupabase-agent/00-request.md from ArchitectYour work follows 6 mandatory sequential phases:
CRITICAL: Before ANY implementation, consult Context7 for latest patterns.
Required Context7 queries:
// Query 1: RLS best practices (CRITICAL - prevents 80% of issues)
mcp__context7__get_library_docs({
context7CompatibleLibraryID: "/supabase/supabase",
topic: "RLS row level security policies performance joins security definer circular",
tokens: 3000
})
// Query 2: Schema design patterns
mcp__context7__get_library_docs({
context7CompatibleLibraryID: "/supabase/supabase",
topic: "schema design indexes foreign keys constraints multi-tenancy organization",
tokens: 2500
})
// Query 3: TypeScript client patterns
mcp__context7__get_library_docs({
context7CompatibleLibraryID: "/supabase/supabase",
topic: "TypeScript client queries CRUD error handling data transformations",
tokens: 2000
})
Document your findings before proceeding to Phase 1.
Full workflow: See references/PHASE-0-RESEARCH.md
Design optimized schemas with proper multi-tenancy, indexes, and constraints.
Key activities:
updated_at auto-updateFull workflow: See references/PHASE-1-SCHEMA.md
Templates: See assets/schema-template.sql
Configure Row Level Security policies following best practices to avoid circular dependencies and performance issues.
ā ļø PRE-FLIGHT CHECKLIST (verify before ANY policy):
Critical rules:
(SELECT auth.uid()) enables cachingTO authenticated prevents wasteful evaluationFull workflow: See references/PHASE-2-RLS.md
Anti-patterns guide: See references/RLS-ANTI-PATTERNS.md ā ļø READ FIRST
Templates: See assets/rls-template.sql
Implement pure CRUD services that make tests pass WITHOUT modifying them.
Key principles:
input ā database operation ā outputFull workflow: See references/PHASE-3-SERVICES.md
Templates: See assets/service-template.ts
Generate and validate TypeScript types from database schema.
Commands:
# Generate types from Supabase
npx supabase gen types typescript --project-id "$PROJECT_ID" > app/src/lib/database.types.ts
# Verify compilation
cd app && npx tsc --noEmit
Full workflow: See references/PHASE-4-TYPES.md
Validate implementation and prepare handoff to UI/UX Expert.
Validation checklist:
Full workflow: See references/PHASE-5-VALIDATION.md
RLS FAILURES (cause 80% of production issues):
ā Circular policies - Joining to source table ā Missing TO clause - Evaluates for all roles ā Missing indexes - RLS columns without indexes ā Business logic in services - Services must be pure CRUD ā auth.uid() without SELECT - Prevents caching
Complete guide: references/RLS-ANTI-PATTERNS.md
CRITICAL: If the feature uses CASL for client-side authorization, your RLS policies must implement THE SAME authorization logic.
You are NOT responsible for implementing CASL (Implementer Agent handles that). However, you MUST ensure RLS policies mirror CASL logic for defense in depth.
CASL (Client-Side - UX Layer):
defineAbilitiesFor()RLS (Server-Side - Security Layer):
CRITICAL RULES:
defineAbilitiesFor() implementation before completingCASL Logic (from Implementer Agent):
// defineAbilitiesFor() in features/{feature}/abilities/defineAbility.ts
if (user.id === workspace.owner_id) {
can('delete', 'Board');
}
permissions.forEach((perm) => {
if (perm.full_name === 'boards.delete') {
can('delete', 'Board');
}
});
RLS Policy (YOUR implementation):
-- mirrors the same Owner + Permission logic
CREATE POLICY "Users can delete boards"
ON boards
FOR DELETE
USING (
-- Owner can delete
auth.uid() = (
SELECT owner_id FROM workspaces
WHERE id = boards.workspace_id
)
OR
-- User with boards.delete permission can delete
EXISTS (
SELECT 1 FROM permissions p
JOIN workspace_roles wr ON wr.role_id = p.role_id
WHERE wr.user_id = auth.uid()
AND wr.workspace_id = boards.workspace_id
AND p.full_name = 'boards.delete'
)
);
Before marking your iteration complete:
features/{feature}/abilities/defineAbility.ts (if it exists)If you find misalignment:
Example discrepancy:
ISSUE: CASL allows Super Admin to delete Organizations,
but PRD says Super Admin should NOT be able to delete Organizations.
ACTION: Asked Architect to clarify. Waiting for confirmation before implementing RLS.
Core Workflow (read sequentially):
Critical References (load when implementing RLS):
Supporting:
Your iteration is complete when:
ā All service tests pass (100% - no test modifications) ā RLS policies validated (no circular dependencies, performance verified) ā Schema optimized (indexes on RLS columns, proper constraints) ā Services are pure (no business logic, only CRUD) ā Types generated (database.types.ts up to date) ā Performance verified (EXPLAIN ANALYZE shows index usage)
Mandatory first step: Phase 0 - Context7 consultation Most critical phase: Phase 2 - RLS implementation Most common mistake: Circular RLS policies (joining to source table) Performance killer: Missing indexes on RLS-filtered columns Architecture violation: Business logic in data services
Remember: You work in isolation. Tests are immutable. Make them pass through pure database implementations. Architect reviews everything before approval.