Back to list
vperreard

api-patterns

by vperreard

Programme de gestion des plannings équipe d'anesthésie

1🍴 0📅 Jan 23, 2026

SKILL.md


name: api-patterns description: > Patterns standard pour les API Next.js. Utiliser pour créer, modifier ou débugger des endpoints.

AUTO-ACTIVATE when user mentions (FR/EN):

  • API, endpoint, route, /api/, NextResponse
  • GET, POST, PUT, DELETE, PATCH
  • 500 error, 400 error, API error
  • créer API, create API, new endpoint
  • Prisma dans API, fetch, response

API Patterns - Quick Reference

Token Efficiency: ~600 tokens vs 5k+ pour recherche manuelle Last Update: 25 November 2025

Quick Stats

  • 470+ endpoints dans /api/
  • Pattern standard avec error handling uniforme
  • Validation Zod obligatoire sur POST/PUT/PATCH
  • Mapping PascalCase→camelCase pour réponses

Pattern Standard - GET

import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';

export async function GET(req: NextRequest) {
  try {
    // 1. Auth check
    const session = await getServerSession(authOptions);
    if (!session?.user) {
      return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });
    }

    // 2. Parse query params
    const { searchParams } = new URL(req.url);
    const siteId = searchParams.get('siteId');

    // 3. Prisma query avec relations
    const items = await prisma.model.findMany({
      where: { siteId: siteId || undefined },
      include: {
        RelatedModel: true,  // PascalCase from Prisma
      },
      orderBy: { createdAt: 'desc' }
    });

    // 4. Map PascalCase → camelCase pour frontend
    const mapped = items.map(item => ({
      ...item,
      relatedModel: item.RelatedModel,  // camelCase for frontend
      RelatedModel: undefined,
    }));

    return NextResponse.json(mapped);
  } catch (error) {
    console.error('GET /api/xxx error:', error);
    return NextResponse.json(
      { error: 'Erreur serveur' },
      { status: 500 }
    );
  }
}

Pattern Standard - POST avec Validation

import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';
import { z } from 'zod';

// Schema Zod OBLIGATOIRE
const createSchema = z.object({
  name: z.string().min(1, 'Nom requis').max(100),
  siteId: z.string().min(1, 'Site requis'),
  type: z.enum(['TYPE_A', 'TYPE_B']),
  description: z.string().optional(),
});

export async function POST(req: NextRequest) {
  try {
    // 1. Auth check
    const session = await getServerSession(authOptions);
    if (!session?.user) {
      return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });
    }

    // 2. Parse et validate body
    const body = await req.json();
    const validation = createSchema.safeParse(body);

    if (!validation.success) {
      return NextResponse.json(
        { error: 'Données invalides', details: validation.error.flatten() },
        { status: 400 }
      );
    }

    const data = validation.data;

    // 3. Business logic checks
    const exists = await prisma.model.findFirst({
      where: { name: data.name, siteId: data.siteId }
    });

    if (exists) {
      return NextResponse.json(
        { error: 'Un élément avec ce nom existe déjà' },
        { status: 409 }
      );
    }

    // 4. Create avec updatedAt OBLIGATOIRE (pas de @default)
    const created = await prisma.model.create({
      data: {
        ...data,
        createdById: session.user.id,
        updatedAt: new Date(),  // REQUIS - pas de @default
      }
    });

    return NextResponse.json(created, { status: 201 });
  } catch (error) {
    console.error('POST /api/xxx error:', error);
    return NextResponse.json(
      { error: 'Erreur serveur' },
      { status: 500 }
    );
  }
}

Pattern Standard - Dynamic Route [id]

// app/api/items/[id]/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';
import { prisma } from '@/lib/prisma';

type RouteParams = { params: Promise<{ id: string }> };

export async function GET(req: NextRequest, { params }: RouteParams) {
  try {
    const session = await getServerSession(authOptions);
    if (!session?.user) {
      return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });
    }

    const { id } = await params;  // Await params in Next.js 15

    // Parse ID selon le type (Int vs String)
    const numericId = parseInt(id, 10);
    if (isNaN(numericId)) {
      return NextResponse.json({ error: 'ID invalide' }, { status: 400 });
    }

    const item = await prisma.model.findUnique({
      where: { id: numericId },
      include: { RelatedModel: true }
    });

    if (!item) {
      return NextResponse.json({ error: 'Non trouvé' }, { status: 404 });
    }

    // Map pour frontend
    return NextResponse.json({
      ...item,
      relatedModel: item.RelatedModel,
      RelatedModel: undefined,
    });
  } catch (error) {
    console.error('GET /api/items/[id] error:', error);
    return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 });
  }
}

export async function DELETE(req: NextRequest, { params }: RouteParams) {
  try {
    const session = await getServerSession(authOptions);
    if (!session?.user) {
      return NextResponse.json({ error: 'Non autorisé' }, { status: 401 });
    }

    const { id } = await params;
    const numericId = parseInt(id, 10);

    await prisma.model.delete({
      where: { id: numericId }
    });

    return NextResponse.json({ success: true });
  } catch (error) {
    console.error('DELETE /api/items/[id] error:', error);
    return NextResponse.json({ error: 'Erreur serveur' }, { status: 500 });
  }
}

Checklist Création API

  1. Auth check avec getServerSession(authOptions)
  2. Validation Zod pour POST/PUT/PATCH
  3. updatedAt: new Date() sur create/update
  4. siteId inclus si modèle le requiert
  5. Mapping PascalCase→camelCase pour réponses
  6. Error handling avec status codes appropriés
  7. Logs console.error pour debugging

Status Codes Standards

CodeUsage
200GET success, PUT/PATCH success
201POST success (création)
400Validation error, bad request
401Non authentifié
403Non autorisé (permission)
404Ressource non trouvée
409Conflit (doublon)
500Erreur serveur

Ressources Progressives

  • resources/error-handling.md - Patterns d'erreur détaillés
  • resources/pagination.md - Pagination avec cursors
  • resources/batch-operations.md - Opérations en lot

Reference: PRISMA_RELATIONS_MAPPING.md, ARCHITECTURE_INDEX.md

Score

Total Score

50/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

0/10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

3ヶ月以内に更新がある

0/10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

0/5

Reviews

💬

Reviews coming soon