import { PrismaClient } from '@prisma/client' import { PrismaPg } from '@prisma/adapter-pg' import { betterAuth } from 'better-auth' import { emailOTP } from 'better-auth/plugins' const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }) export const prisma = new PrismaClient({ adapter }) export const auth = betterAuth({ database: prismaAdapter(prisma), plugins: [ emailOTP({ otpLength: 6, expiresIn: 300, }), ], }) export async function getPublishedProjects() { return prisma.project.findMany({ where: { status: 'published' }, orderBy: [ { featured: 'desc' }, { sortOrder: 'asc' }, ], }) } "use server" export async function createProjectAction( data: FormData ) { const session = await auth.api .getSession({ headers }) if (!session) throw new Error() const validated = schema.parse(data) const result = await createProject(validated) revalidatePath("/admin/projects") revalidatePath("/") return result } const projectSchema = z.object({ title: z.string().min(1), slug: z.string().min(1), description: z.string().min(10), status: z.enum([ 'draft', 'published', 'archived' ]), techStack: z.array(z.string()), featured: z.boolean(), }) export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="fr"> <body> <ThemeProvider> <MotionProvider> {children} </MotionProvider> </ThemeProvider> </body> </html> ) }import { PrismaClient } from '@prisma/client' import { PrismaPg } from '@prisma/adapter-pg' import { betterAuth } from 'better-auth' import { emailOTP } from 'better-auth/plugins' const adapter = new PrismaPg({ connectionString: process.env.DATABASE_URL }) export const prisma = new PrismaClient({ adapter }) export const auth = betterAuth({ database: prismaAdapter(prisma), plugins: [ emailOTP({ otpLength: 6, expiresIn: 300, }), ], }) export async function getPublishedProjects() { return prisma.project.findMany({ where: { status: 'published' }, orderBy: [ { featured: 'desc' }, { sortOrder: 'asc' }, ], }) } "use server" export async function createProjectAction( data: FormData ) { const session = await auth.api .getSession({ headers }) if (!session) throw new Error() const validated = schema.parse(data) const result = await createProject(validated) revalidatePath("/admin/projects") revalidatePath("/") return result } const projectSchema = z.object({ title: z.string().min(1), slug: z.string().min(1), description: z.string().min(10), status: z.enum([ 'draft', 'published', 'archived' ]), techStack: z.array(z.string()), featured: z.boolean(), }) export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html lang="fr"> <body> <ThemeProvider> <MotionProvider> {children} </MotionProvider> </ThemeProvider> </body> </html> ) }
"use client" import { m, useScroll } from 'motion/react' import { useReducedMotion } from 'motion/react' export function FadeIn({ children, delay = 0, direction = "up", }: FadeInProps) { const prefersReducedMotion = useReducedMotion() return ( <m.div initial={{ opacity: 0, y: 24 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay, ease: "easeOut" }} > {children} </m.div> ) } // Claude Code agent workflow const agent = defineAgent({ name: 'researcher', tools: [Glob, Grep, Read], prompt: 'Explore the codebase', }) await agent.run({ task: 'Find all API routes', maxTurns: 10, }) // Skill definition const skill = defineSkill({ name: 'deploy', steps: [ 'step-00-init.md', 'step-01-build.md', 'step-02-deploy.md', ], }) export function Hero({ profile }) { const name = profile?.name const nameParts = name.split(" ") const firstName = nameParts[0] const lastName = nameParts.at(-1) return ( <section className="min-h-svh"> <h1> {firstName}{" "} <span className="text-gradient"> {lastName} </span> </h1> <p>{profile?.tagline}</p> <Button asChild> <a href="#contact"> Discutons de votre projet </a> </Button> </section> ) } function useScrollProgress() { const { scrollYProgress } = useScroll() return useSpring(scrollYProgress, { stiffness: 100, damping: 30, }) } const config = defineConfig({ schema: "prisma/schema.prisma", datasource: { url: process.env.DATABASE_URL, }, })"use client" import { m, useScroll } from 'motion/react' import { useReducedMotion } from 'motion/react' export function FadeIn({ children, delay = 0, direction = "up", }: FadeInProps) { const prefersReducedMotion = useReducedMotion() return ( <m.div initial={{ opacity: 0, y: 24 }} whileInView={{ opacity: 1, y: 0 }} viewport={{ once: true }} transition={{ duration: 0.5, delay, ease: "easeOut" }} > {children} </m.div> ) } // Claude Code agent workflow const agent = defineAgent({ name: 'researcher', tools: [Glob, Grep, Read], prompt: 'Explore the codebase', }) await agent.run({ task: 'Find all API routes', maxTurns: 10, }) // Skill definition const skill = defineSkill({ name: 'deploy', steps: [ 'step-00-init.md', 'step-01-build.md', 'step-02-deploy.md', ], }) export function Hero({ profile }) { const name = profile?.name const nameParts = name.split(" ") const firstName = nameParts[0] const lastName = nameParts.at(-1) return ( <section className="min-h-svh"> <h1> {firstName}{" "} <span className="text-gradient"> {lastName} </span> </h1> <p>{profile?.tagline}</p> <Button asChild> <a href="#contact"> Discutons de votre projet </a> </Button> </section> ) } function useScrollProgress() { const { scrollYProgress } = useScroll() return useSpring(scrollYProgress, { stiffness: 100, damping: 30, }) } const config = defineConfig({ schema: "prisma/schema.prisma", datasource: { url: process.env.DATABASE_URL, }, })
prapp.dev
Mon ParcoursStackProjetsServicesBlogContact
prapp.dev
BlogMentions légales

© 2026 Pierre Renollet

Construit avec&Claude Code

Blog

Articles sur Claude Code, le développement SaaS et l'IA

TousClaude CodeSaaSTutorielRetour d'expérience
Claude Code
Article

Claude code trop fort

1 min de lecture1 mars 2026