Coding
PromptBeginner5 minmarkdown
Markdown Converter
Agent skill for markdown-converter
7
Cuando generes código para este repositorio:
Sign in to like and favorite skills
Cuando generes código para este repositorio:
anybun como package managerprisma/schema.prismalib/prisma.db.ts (singleton pattern with libSQL)lib/auth.tsawait getSession() inside Suspense boundaries onlyapp/ ├─ (auth)/ # Auth routes (login, etc) ├─ api/ # API routes (dynamic by default with headers()) ├─ dashboard/ # Protected routes with Suspense pattern │ ├─ _components/ # Dashboard-specific components │ ├─ _actions/ # Server actions │ ├─ assessment/ │ ├─ reports/ │ └─ team/ ├─ _components/ # Global components ├─ _shared/ # Shared utilities ├─ layout.tsx # Root layout └─ page.tsx # Home page components/ ├─ cyber-ui/ # Custom CyberPunk theme components ├─ gamification/ # Gamification system components └─ ui/ # shadcn/ui components lib/ ├─ auth.ts # Authentication utilities ├─ prisma.db.ts # Prisma singleton ├─ cn.ts # classNames utility ├─ actions/ # Server actions ├─ services/ # Business logic ├─ hooks/ # React hooks ├─ types/ # TypeScript types ├─ constants/ # App constants └─ utils/ # Utility functions prisma/ ├─ schema.prisma # Data models ├─ migrations/ # Migration history └─ seeders/ # Database seeders
// CORRECT: Main component is sync, dynamic content wrapped in Suspense export default function Page() { return ( <Suspense fallback={<PageSkeleton />}> <PageContent /> </Suspense> ); } async function PageContent() { const session = await getSession(); // OK - inside Suspense return <div>...</div>; }
// WRONG: Accessing getSession() outside Suspense export default async function Page() { const session = await getSession(); // ERROR during prerendering return <div>{session.user.name}</div>; }
bun run build will show warnings about headers() - THIS IS EXPECTED◐ (Partial Prerender) - THIS IS CORRECTcache-components.md for detailed troubleshootingkebab-case (e.g., user-profile.tsx, db-utils.ts)kebab-case (e.g., app/dashboard/team-tips/)PascalCase (e.g., UserProfile, DatabaseConfig)camelCase (e.g., getUserData(), isLoggedIn)UPPER_SNAKE_CASE (e.g., MAX_RETRIES, DEFAULT_PAGE_SIZE)isLoading, hasPermission, shouldRefresh)PascalCase.tsx (e.g., UserCard.tsx)PascalCase + 'Props' suffix (e.g., UserCardProps)/** * JSDoc comment describing component purpose and usage */ interface ComponentProps { // Props interface with clear types } export function ComponentName({ prop }: ComponentProps) { // Implementation }
app/dashboard/_actions/ or lib/actions/'use server' at top of fileactionName.ts (e.g., create-user.ts, update-profile.ts)Example:
// lib/actions/create-team.ts 'use server' import { prisma } from '@/lib/prisma.db' import { revalidatePath } from 'next/cache' export async function createTeam(name: string) { const team = await prisma.team.create({ data: { name } }) revalidatePath('/dashboard/team') return team }
lib/types/ with descriptive namesExample structure:
// lib/types/user.ts export interface User { id: string name: string email: string createdAt: Date } export interface UserProfile extends User { bio?: string avatar?: string }
User, TeamMember, OrderItem)camelCase (e.g., createdAt, updatedAt, deletedAt)createdAt, updatedAt, optionally deletedAt (soft delete)uuid() for id, auto-increment as fallbackMaturityLevel, QuestStatus)lib/prisma.db.tsglobal.prisma fallbackPrismaLibSql adapter for Turso/SQLiteExample usage:
import { prisma } from '@/lib/prisma.db' const user = await prisma.user.findUnique({ where: { id: userId }, select: { id: true, email: true, name: true } })
SELECT *where precisely - Filter at DB levelfindMany with indexed fieldsinclude or batch queriesimport { useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { z } from 'zod' const schema = z.object({ name: z.string().min(1, 'Name is required'), email: z.string().email('Invalid email'), }) type FormData = z.infer<typeof schema> export function MyForm() { const { register, handleSubmit, formState: { errors }, } = useForm<FormData>({ resolver: zodResolver(schema), }) return ( <form onSubmit={handleSubmit(onSubmit)}> <input {...register('name')} /> {errors.name && <span>{errors.name.message}</span>} </form> ) }
strict: true in tsconfig.jsonany: Always declare explicit types@/* → root directory @/prisma/* → prisma directory @/auth/* → app/(auth) directory @/dashboard/* → app/dashboard directory
z.infer<typeof schema> for Zod typesglobal.css theme variables, NOT hardcoded color classestext-red-500, bg-blue-400, etc.text-error, bg-primary, etc.CyberPunk theme variables in
global.css:
--foreground --background --primary --secondary --muted --border --error --success
cn() from lib/cn.tscn() for merging classesimport { cn } from '@/lib/cn' // ✅ CORRECT <div className={cn('base-class', isActive && 'active-class')} /> // ❌ WRONG <div className={`base-class ${isActive ? 'active-class' : ''}`} />
import { Prisma } from '@/generated/prisma' try { const result = await operation() } catch (error) { if (error instanceof Prisma.PrismaClientKnownRequestError) { // Handle Prisma-specific errors if (error.code === 'P2002') { // Unique constraint violation throw new Error('Record already exists') } } throw error }
.env.local (local), .env.production (production), .env (defaults)NEXT_PUBLIC_ for client-side variablesDATABASE_URL or TURSO_DATABASE_URLBETTER_AUTH_SECRETOPENAI_API_KEY, GOOGLE_API_KEYbun run build
This runs:
prisma generate - Generate Prisma clientnext build - Build Next.js with Cache Componentsheaders() in dashboard routes are EXPECTED◐ (Partial Prerender) are CORRECTbun run lint # Run Biome linter bun run format # Format code bun run check # Full check + write fixes
bun run typecheck # Run TypeScript without emitting
any@param, @returns, @throws@deprecated and suggest alternatives/** * Description of file purpose * * Key exports: * - ExportedFunction * - ExportedClass */
.env.local, use env variables'use client' for interactivityuse cache directivetype(scope): descriptionfeat, fix, refactor, docs, chorefeat(dashboard): add team creation formfeature/descriptionfix/issue-numberrefactor/description# Create migration bun run db:migrate -- --name description # For Turso bun run db:migrate:turso
async function Component() { const data = await fetchData() return <div>{data}</div> }
Components implement error.tsx following Next.js pattern
Implement loading.tsx for streaming UI
Use
redirect() from next/navigation in Server Components
Use
revalidatePath() after mutations
cache-components.md.github/copilot/cache-components.md