From cklph-nextjs
Peter's cross-cutting house rules for Next.js + Supabase projects. Use at the start of any task and before pushing any code. These are non-negotiable.
How this skill is triggered — by the user, by Claude, or both
Slash command
/cklph-nextjs:disciplineThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
These rules apply to every cklph-stack project (MailPrism, SendBriefs, BeforeMerge, ApertureStack). They are not suggestions. Most are catch-once-then-they-stick.
These rules apply to every cklph-stack project (MailPrism, SendBriefs, BeforeMerge, ApertureStack). They are not suggestions. Most are catch-once-then-they-stick.
wa-* classes, var(--wa-*) variables). If you see them, they're being removed.components/mp/atoms/, molecules/, organisms/, templates/) and form wrappers in components/ui/forms/.Five steps, in order — rate-limit → CSRF → getUser() (NEVER getSession()) → Zod → correct Supabase client. See security for the full mutation checklist.
createServerSupabaseClient — server components, API routes, server actions.createClient — client components.createServiceRoleClient — cron jobs, admin paths after isAdmin(). Bypasses RLS — danger zone.Read from a DB table (in MailPrism it's pricing_tiers; pick the right name per project) for price IDs and tier metadata. Never hardcode a PRICING_PLANS constant — environment drift between staging and prod will burn you.
supabase migration new then supabase db push. Migrations are checked-in source. The Supabase MCP is for read-only research (querying data, inspecting schema), never for DDL. After every migration, regenerate types — supabase gen types typescript --linked > lib/types/database.ts — and commit the regenerated file in the same commit as the migration. See data-model for how to consume them.
One copy is fine. Two is a watch-list. Three is an extraction. Extract to lib/utils/, lib/services/, lib/hooks/, or components/mp/ depending on type.
NEVER commit directly to dev or main. Before any code, git checkout dev && git pull && git checkout -b <type>/<short-description>. Applies to one-liners too.
bg-, text-, border- class with a dark: variant.<label> or aria-label. Error messages associate via aria-describedby. Modals trap focus.anyUse specific types, generics, or unknown with narrowing. as any and : any are both review-blockers. If a third-party type is wrong, declare a proper override.
lib/data/Never raw fetch("/api/…") from a component or hook. Use authFetcher, useAuthQuery, or useAuthMutation. See data-layer for why.
Hard ceiling 500 lines per file. At 400 you're already planning the split. Cohesion goes down past 500 and reviewers stop reading thoroughly.
Run through this list at the START of a task, not the end. Pair with architecture for layer rules, pitfalls for the recurring bug catalog.
Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub chykalophia/cklph-marketplace --plugin cklph-nextjs