supabase-database
Supabase Database
Quick Start
When working with Supabase:
- Always use Supabase client from
@/lib/supabase/serveror@/lib/supabase/client - Never make queries without filtering by
tenant_idin multitenant tables - Always enable RLS on tables and include tenant verification in policies
- Use prepared parameters (Supabase client methods, never string concatenation)
- Use migrations in
supabase/migrations/for schema changes
Key Files
src/lib/supabase/- Supabase client utilitiessrc/lib/integrations/supabase/- Supabase integrationsupabase/migrations/- Database migrationssupabase/functions/- Edge functionssrc/lib/auth/enterprise-rls-utils.ts- RLS utilities
Common Patterns
Basic Query with Tenant
import { createClient } from '@/lib/supabase/server';
import { getTenantFromRequest } from '@/lib/tenant/tenant-service';
const supabase = createClient();
const tenant = await getTenantFromRequest(request);
const { data, error } = await supabase
.from('products')
.select('id, name, price, category_id')
.eq('tenant_id', tenant.id)
.eq('active', true)
.order('created_at', { ascending: false })
.limit(20);
if (error) {
console.error('Query error:', error);
return NextResponse.json({ error: error.message }, { status: 500 });
}
Insert with Tenant
const { data, error } = await supabase
.from('products')
.insert({
name: 'Pintura Blanca',
price: 5000,
tenant_id: tenant.id,
category_id: categoryId,
active: true,
})
.select()
.single();
Update with Tenant
const { data, error } = await supabase
.from('products')
.update({ price: 5500 })
.eq('id', productId)
.eq('tenant_id', tenant.id)
.select()
.single();
RLS Policy Example
-- Enable RLS
ALTER TABLE products ENABLE ROW LEVEL SECURITY;
-- Policy for tenant isolation
CREATE POLICY "tenant_isolation_products" ON products
FOR ALL
USING (
tenant_id = (
SELECT id FROM tenants
WHERE slug = current_setting('app.tenant_slug', true)
)
);
-- Policy for public read (if needed)
CREATE POLICY "public_read_products" ON products
FOR SELECT
USING (active = true);
Using RLS Utils
import { executeWithRLS } from '@/lib/auth/enterprise-rls-utils';
const result = await executeWithRLS(
enterpriseContext,
async (client, rlsContext) => {
return await client
.from('products')
.select('*')
.eq('tenant_id', rlsContext.tenantId);
}
);
Migration Template
-- Migration: add_new_column_to_products
-- Created: 2026-01-23
BEGIN;
-- Add new column
ALTER TABLE products
ADD COLUMN IF NOT EXISTS new_field VARCHAR(255);
-- Create index if needed
CREATE INDEX IF NOT EXISTS idx_products_new_field
ON products(new_field)
WHERE new_field IS NOT NULL;
-- Update RLS policy if needed
-- (Add to existing policy or create new one)
COMMIT;
Best Practices
- Always filter by tenant_id in multitenant tables
- Use
.select()with specific fields instead of* - Enable RLS on all tables
- Use migrations for all schema changes
- Test migrations in development first
- Use transactions for multiple related operations
- Index frequently queried fields (tenant_id, foreign keys)
Commands
# Create new migration
supabase migration new migration_name
# Apply migrations
supabase db push
# Reset database (development)
supabase db reset
# Generate TypeScript types
supabase gen types typescript --local > src/types/database.ts
More from santiagoxor/pintureria-digital
postgres-best-practices
Postgres performance optimization guidelines from Supabase. Contains rules across 8 categories prioritized by impact. Use when writing SQL queries, designing schemas, implementing indexes, optimizing queries, reviewing database performance, configuring connection pooling, or working with Row-Level Security (RLS).
29testing-qa
Specialized skill for writing and maintaining tests including unit tests, integration tests, E2E tests with Playwright, and accessibility tests. Use when writing tests for new features, debugging failed tests, improving test coverage, or setting up E2E tests.
18error-handling
Specialized skill for implementing proper error handling, logging, user-friendly error messages, and error recovery strategies. Use when implementing error handling in APIs, components, or when debugging error issues.
17build-start
Specialized skill for building and starting Next.js applications, handling build errors, verifying production builds, and managing development servers. Use when building the application, starting development servers, troubleshooting build issues, or verifying production readiness.
16supabase-mcp-db
Apply Supabase migrations and manage the database using the Supabase MCP (user-supabase-SantiagoXOR). Use when the user asks to apply migrations, run migrations with MCP, manage the DB with Supabase MCP, list migrations, execute SQL, or inspect schema.
15multitenant-development
Specialized skill for working with the multitenant system including tenant detection, data isolation, tenant-specific configuration, and RLS policies. Use when implementing multitenant features, creating APIs that handle multiple tenants, configuring tenant assets, or debugging data isolation issues.
15