skills/ballee/db-lint-manager/SKILL.md
Lint PostgreSQL functions against schema, analyze usage, and generate fix reports; use when detecting broken functions, validating schema contracts, or cleaning up unused database functions
npx skillsauth add javeedishaq/ai-workflow-orchestrator db-lint-managerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Lint PostgreSQL functions across environments (local, staging, production), analyze function usage in the codebase, and generate actionable reports for fixing or dropping broken functions.
DO use this skill when:
supabase db lint and need to analyze/categorize resultsDO NOT use this skill when:
database-migration-manager)rls-policy-generator)# Local database (requires Docker/Supabase running)
cd apps/web && pnpm supabase db lint --local -s public
# Staging database
pnpm supabase db lint --db-url "postgresql://postgres.PROJECT_REF:[email protected]:5432/postgres" -s public
# Production database (linked project)
cd apps/web && pnpm supabase db lint --linked -s public
# Search for function usage in codebase
grep -rn "\.rpc(['\"]function_name['\"]" apps/web packages/features
# Check if function is called from migrations
grep -rn "function_name" apps/web/supabase/migrations/
# JSON output for parsing
pnpm supabase db lint --linked -o json
# Pretty output for human reading
pnpm supabase db lint --linked -o pretty
Error: column X does not exist
Cause: Function references a column that was renamed, dropped, or never existed
Fix Options:
Error: relation X does not exist
Cause: Function references a table that was renamed or dropped
Fix Options:
Error: structure of query does not match function result type
Cause: Function return type doesn't match actual SELECT columns
Fix Options:
Error: column reference X is ambiguous
Cause: Column name exists in multiple tables in the query
Fix Options:
t.user_id instead of user_id)Warning: never read variable X
Cause: Variable declared but not used in function body
Fix Options:
// Direct RPC call
const { data } = await supabase.rpc('function_name', { param: value });
// Chained RPC
await client.rpc('function_name').single();
// In service files
return this.client.rpc('function_name', params);
-- Direct call
SELECT public.function_name(arg1, arg2);
-- In trigger
EXECUTE FUNCTION public.function_name();
-- In policy
USING (public.function_name())
# Find all RPC calls to a function
grep -rn "rpc(['\"]get_events_with_cast['\"]" apps/web packages/features
# Find SQL references
grep -rn "get_events_with_cast" apps/web/supabase/
# Find in tests
grep -rn "get_events_with_cast" apps/web/app/__tests__/
When generating a lint report, use this format:
# Database Function Lint Report
**Environment**: Production | Staging | Local
**Date**: YYYY-MM-DD HH:MM
**Total Issues**: N (M errors, K warnings)
## Summary
| Category | Count | Used | Unused |
|----------|-------|------|--------|
| Missing Column | N | N | N |
| Missing Table | N | N | N |
| Type Mismatch | N | N | N |
| Ambiguous Reference | N | N | N |
| Unused Variable | N | N | N |
## Critical Issues (Used Functions - Must Fix)
### function_name
- **Error**: Description of the error
- **SQL State**: XXXXX
- **Location**: Migration file where function is defined
- **Line**: Line number in function
- **Usage Found**:
- file/path.ts:123
- file/path2.ts:456
- **Recommended Action**: Create migration to fix X
<details>
<summary>Problematic Query</summary>
```sql
SELECT column_that_doesnt_exist FROM table
</details>
For critical issues, create fix migrations:
pnpm supabase:web migrations new fix_function_name
For unused functions, create drop migrations:
DROP FUNCTION IF EXISTS public.function_name(param_types);
Test locally before deploying:
pnpm supabase:web:reset
pnpm supabase:web db lint --local
---
## Known Issues Reference
These functions were detected as broken in production (2025-12-03):
| Function | Error | Category | Likely Status |
|----------|-------|----------|---------------|
| `get_user_bookmarks` | profile_bookmarks.notes doesn't exist | Missing Column | Legacy/Unused |
| `is_following_profile` | following_profile_id doesn't exist | Missing Column | Legacy/Unused |
| `get_user_following` | following_profile_id doesn't exist | Missing Column | Legacy/Unused |
| `get_user_upcoming_events` | participations table doesn't exist | Missing Table | Legacy/Unused |
| `update_identity_verification_status` | admin_notes doesn't exist | Missing Column | Legacy/Unused |
| `user_has_verified_identity` | iv.status doesn't exist | Missing Column | Legacy/Unused |
| `get_user_identity_verification` | iv.status doesn't exist | Missing Column | Legacy/Unused |
| `get_dancer_availability` | available_date doesn't exist | Missing Column | Legacy/Unused |
| `transfer_team_account_ownership` | accounts_memberships.role doesn't exist | Missing Column | Legacy/Unused |
| `log_role_change` | role_change_audit.user_id doesn't exist | Missing Column | Legacy/Unused |
| `get_dancer_upcoming_events` | return type mismatch | Type Mismatch | Needs Investigation |
| `get_profile_missing_fields` | primary_training_method doesn't exist | Missing Column | Possibly Used |
| `accept_admin_invitation` | ambiguous user_id reference | Ambiguous Reference | Possibly Used |
| `get_events_with_cast` | e.name doesn't exist (should be e.title) | Missing Column | Likely Used |
| `get_event_with_cast_by_id` | e.name doesn't exist | Missing Column | Likely Used |
| `get_user_events` | event_participations table doesn't exist | Missing Table | Legacy/Unused |
| `create_hire_order_with_items` | unit_price column doesn't exist | Missing Column | Needs Investigation |
---
## Environment Configuration
### Local
- Requires Docker and Supabase running (`pnpm supabase:web:start`)
- Uses `--local` flag
- Safe for testing fixes
### Staging
**Project**: `hxpcknyqswetsqmqmeep`
**Connection**:
```bash
# Load password from .env.local (preferred)
source apps/web/.env.local 2>/dev/null
# Or use environment variable directly
export SUPABASE_DB_PASSWORD_STAGING="your_password"
# 1Password fallback (if not in .env.local)
if [ -z "$SUPABASE_DB_PASSWORD_STAGING" ]; then
SUPABASE_DB_PASSWORD_STAGING=$(op item get rkzjnr5ffy5u6iojnsq3clnmia --fields notesPlain --reveal)
fi
Project: csjruhqyqzzqxnfeyiaf
--linked flag (requires supabase link setup)# Run lint on production
cd apps/web && pnpm supabase db lint --linked -s public -o json > lint-report.json
For each function in the report:
# Check codebase for usage
grep -rn "rpc(['\"]function_name['\"]" apps/web packages/features
# Check migrations for references
grep -rn "function_name" apps/web/supabase/migrations/
# Create new migration
pnpm supabase:web migrations new fix_broken_function_name
# Edit the migration file with the fix
pnpm supabase:web:reset
pnpm supabase db lint --local -s public
Follow standard migration deployment process via database-migration-manager skill.
Located at .claude/skills/db-lint-manager/scripts/validate-db-contracts.sh
Located at .claude/skills/db-lint-manager/scripts/validate-function-schema.sh
atomic_profile_update function specificallyThe lint can be integrated into pre-commit hooks for migrations:
# In lefthook.yml
pre-commit:
commands:
db-lint:
glob: "apps/web/supabase/migrations/*.sql"
run: cd apps/web && pnpm supabase db lint --local -s public
-s flag)tools
# Test Patterns Testing patterns for reliable, maintainable, and fast tests. > **Template Usage:** Customize for your test framework (Vitest, Jest, Playwright, etc.) and assertion library. ## Test Structure ```typescript // user.test.ts import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { userService } from '@/services/user.service'; import { createTestUser, cleanupTestData } from '@/tests/helpers'; describe('UserService', () => { let testUserId: string; befor
tools
# State Management Patterns Client-side state management patterns for modern applications. > **Template Usage:** Customize for your state library (React Query, Zustand, Jotai, Redux, etc.). ## State Categories | Type | Description | Solution | |------|-------------|----------| | **Server State** | Data from API/database | React Query, SWR | | **Client State** | UI state, user preferences | Zustand, Jotai, useState | | **Form State** | Form inputs, validation | React Hook Form, Formik | | **U
development
# Service Patterns Service layer patterns for clean architecture with proper error handling, logging, and type safety. > **Template Usage:** Customize for your ORM (Prisma, Drizzle, TypeORM, etc.) and logging solution. ## Result Type Pattern Never throw exceptions from services. Always return a Result type. ```typescript // lib/result.ts export type Result<T, E = Error> = | { success: true; data: T } | { success: false; error: E }; export function ok<T>(data: T): Result<T, never> { r
testing
# Row-Level Security Patterns Database security patterns for multi-tenant and user-scoped data. > **Template Usage:** Customize for your database (PostgreSQL, Supabase, etc.) and auth system. ## RLS Fundamentals ### Enable RLS on Tables ```sql -- Enable RLS (required before policies take effect) ALTER TABLE users ENABLE ROW LEVEL SECURITY; ALTER TABLE posts ENABLE ROW LEVEL SECURITY; ALTER TABLE comments ENABLE ROW LEVEL SECURITY; -- Force RLS for table owners too (recommended) ALTER TABLE