Browse 354 rules, 42 knowledge articles, and 28 prompt templates across security, performance, architecture, and quality.
BeforeMerge scans your pull requests against these rules automatically. Get actionable feedback before code ships to production.
354 rules
The any type disables all type checking. Use unknown and narrow the type, or use a specific type.
createAdminClient() bypasses RLS. Use it only for writes that need service_role privileges. For reads, use createClient().
Server actions are public HTTP endpoints. Validate all inputs with Zod or similar before any database operation.
Public pages (explore, content detail) should use createReadOnlyClient() with the anon key, not the service_role.
Every insert/update/delete must include organization_id from requireAuth(). RLS is defense-in-depth, not the only defense.
Use the Image component from next/image instead of raw HTML img tags. It auto-optimizes format, size, and loading.
Per Supabase docs: do not run code between createServerClient and supabase.auth.getUser(). A simple mistake could cause random logouts.
Every server action that modifies data must call requireAuth() first to validate the user session and get orgId.
Use atomic design to structure components: atoms (Button, Input), molecules (SearchBar, FormField), organisms (Header, Sidebar).
Centralize shared logic (auth, database clients, formatters) in a lib/ directory to avoid duplication.
Creating a new NextResponse without copying Supabase cookies breaks session management and causes random logouts.
Always use environment variables for API keys, database credentials, and other secrets.
Files with "use client" must never import server-only modules like database clients, API keys, or service role credentials.
Supabase client calls are NOT automatically deduplicated like fetch(). Querying the same data in layout.tsx and page.tsx doubles database load.
When a dynamic route param doesn't match any record, call notFound() from next/navigation to show the 404 page.
Place server actions in separate *-actions.ts files rather than inline in page components.
Name files and directories in kebab-case (lowercase with hyphens) to avoid cross-platform case sensitivity issues.
Use createClient() for authenticated pages (RLS enforced), createAdminClient() for server-side writes (service_role), and createReadOnlyClient() for public pages (anon key).
Write tests that verify: User A cannot read User B's data. Anon users cannot read private data. RLS bugs are data breaches.
For data that changes frequently (notifications, dashboards), use SWR or React Query instead of manual useEffect + fetch.
Call revalidatePath() or revalidateTag() after insert/update/delete operations to refresh cached pages.
Always check the error field from Supabase queries. The client returns { data, error } and never throws.
Wrapping auth.uid() in (select ...) ensures it's evaluated once per query instead of once per row.
Keep page.tsx, layout.tsx, loading.tsx, and error.tsx together in the same route segment directory.