> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Implémenter l’API Bookings à partir de la spécification OpenAPI

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero
  title="Implémenter l’API Bookings à partir de la spécification OpenAPI"
  description="Confie à Devin une spécification YAML et obtiens des gestionnaires de routes Express entièrement implémentés, des modèles Prisma, une validation Zod et des tests d’intégration Supertest — tous alignés sur les conventions existantes de ta base de code."
  prompt="Implémente les endpoints de l’API de réservation suivants en utilisant notre stack Express + Prisma existante. Suis les conventions dans src/api/v2/users/ pour la structure des routes, la gestion des erreurs et le middleware. Dérive les schémas Zod à partir des schémas de la spécification ci‑dessous.

Endpoints :
- GET /api/v2/bookings (liste avec pagination : paramètres de requête page, startDate, endDate)
- POST /api/v2/bookings (création — 201 en cas de succès, 409 en cas de conflit de créneau horaire)
- GET /api/v2/bookings/:id
- PATCH /api/v2/bookings/:id (mise à jour partielle)
- DELETE /api/v2/bookings/:id (suppression logique)
- POST /api/v2/bookings/:id/confirm (200 en cas de succès, 422 si déjà annulée)
- POST /api/v2/bookings/:id/cancel

Schéma CreateBookingInput (obligatoires : title, startTime, endTime, roomId) :
- title : string, maxLength 200
- startTime : string, date-time
- endTime : string, date-time
- roomId : string, uuid
- notes : string, maxLength 1000, optionnel

Écris des tests d’intégration avec Supertest pour chaque endpoint — couvre les cas de succès, les erreurs de validation, les échecs d’authentification et les cas limites comme les créneaux horaires qui se chevauchent. Exécute tous les tests et vérifie que chaque endpoint fonctionne. Si quelque chose échoue, débogue et corrige — continue à itérer jusqu’à ce que tous les tests passent. N’ouvre pas de PR tant que tout ne fonctionne pas de bout en bout."
  category="Développement de fonctionnalités"
  features=""
/>

<div className="uc-detail-wrapper">
  <Tip>Vous ne souhaitez pas effectuer cette configuration manuellement ? Collez un lien vers cette page dans une session Devin et demandez-lui de tout configurer pour vous.</Tip>

  <Steps>
    <Step title="(Facultatif) Étudiez vos modèles d'API existants">
      Si vous ne savez pas comment votre API Express est structurée ni à quels patterns vous référer, utilisez [Ask Devin](https://app.devin.ai/search?utm_source=docs\&utm_medium=use-case-gallery) pour commencer votre analyse :

      <PromptBlock agent="ada">
        ```txt Analyse nos patterns d'API Express theme={null}
        Montre-moi comment notre API Express est structurée :
        1. Quelle est l'arborescence des dossiers sous src/api/v2/ ?
        2. Comment les gestionnaires de routes, contrôleurs et services interagissent-ils ?
        3. Quels middleware utilisons-nous pour l'authentification et la validation ?
        4. Comment les réponses d'erreur sont-elles formatées ?
        5. À quoi ressemble notre configuration de tests (Supertest, configuration de la base de données de test) ?
        ```
      </PromptBlock>

      Vous pouvez aussi utiliser [DeepWiki](https://deepwiki.com) pour explorer des API open source présentant des patterns similaires — par exemple, recherchez des exemples Express + Prisma + Zod pour voir comment d'autres projets structurent leurs gestionnaires de routes et leur validation.

      Vous pouvez démarrer une session Devin directement depuis Ask Devin, et tout ce qu'il a appris sera conservé comme contexte.
    </Step>

    <Step title="Pointez Devin vers votre spécification OpenAPI">
      Commencez par indiquer à Devin où se trouve la spécification et quelle ressource implémenter. Devin lit chaque chemin, schéma et définition d'erreur dans le YAML, puis les compare à vos routes Express existantes afin d'aligner automatiquement les conventions.

      Voici un extrait du type de spécification que Devin utilise — une définition standard OpenAPI 3.0 pour une ressource de réservations :

      ```yaml theme={null}
      # openapi/bookings-v2.yaml (excerpt)
      openapi: "3.0.3"
      info:
        title: Bookings API
        version: "2.0.0"
      paths:
        /api/v2/bookings:
          get:
            summary: List bookings
            parameters:
              - name: page
                in: query
                schema: { type: integer, default: 1 }
              - name: startDate
                in: query
                schema: { type: string, format: date }
              - name: endDate
                in: query
                schema: { type: string, format: date }
            responses:
              "200":
                description: Paginated list of bookings
                content:
                  application/json:
                    schema:
                      $ref: "#/components/schemas/BookingListResponse"
          post:
            summary: Create a booking
            requestBody:
              required: true
              content:
                application/json:
                  schema:
                    $ref: "#/components/schemas/CreateBookingInput"
            responses:
              "201":
                description: Booking created
              "409":
                description: Time slot conflict
        /api/v2/bookings/{id}/confirm:
          post:
            summary: Confirm a booking
            responses:
              "200":
                description: Booking confirmed
              "422":
                description: Booking already cancelled
      components:
        schemas:
          CreateBookingInput:
            type: object
            required: [title, startTime, endTime, roomId]
            properties:
              title:
                type: string
                maxLength: 200
              startTime:
                type: string
                format: date-time
              endTime:
                type: string
                format: date-time
              roomId:
                type: string
                format: uuid
      ```

      <PromptBlock>
        ```txt Implémenter l'API de réservations à partir de la spécification OpenAPI theme={null}
        Implémentez les endpoints définis dans openapi/bookings-v2.yaml pour
        /api/v2/bookings. La spécification définit :

        - GET /api/v2/bookings (liste avec pagination + filtre par plage de dates)
        - POST /api/v2/bookings (création)
        - GET /api/v2/bookings/:id
        - PATCH /api/v2/bookings/:id (mise à jour partielle)
        - DELETE /api/v2/bookings/:id (suppression logique)
        - POST /api/v2/bookings/:id/confirm
        - POST /api/v2/bookings/:id/cancel

        Utilisez notre stack Express + Prisma existante. Suivez les modèles dans
        src/api/v2/users/ pour la structure des routes, la gestion des erreurs et le middleware.
        Déduisez les schémas Zod à partir des définitions de requêtes/réponses OpenAPI.

        ## Testing & verification
        - Write integration tests with Supertest for every endpoint
        - Cover success cases, validation errors, auth failures, and
          business logic edge cases (e.g., overlapping time slots)
        - Run all tests and verify every endpoint works correctly
        - If anything fails — test failures, runtime errors, missing
          middleware — debug and fix it. Keep iterating until all tests pass.
        - Do not open a PR until everything works end-to-end
        ```
      </PromptBlock>

      If your spec isn't checked into the repo yet, paste it directly into the session or attach the YAML/JSON file when starting.
    </Step>

    <Step title="Devin reprend vos patterns Express">
      The single most impactful thing you can do is reference a well-implemented resource in your codebase. Devin studies that code and replicates the folder structure, naming conventions, middleware chain, and error handling — so the new endpoints look like they were written by the same developer.

      For example, Devin reads `src/api/v2/users/router.ts` and produces a matching bookings router:

      ```typescript theme={null}
      // src/api/v2/bookings/router.ts  (generated by Devin)
      import { Router } from "express";
      import { authenticate } from "@/middleware/auth";
      import { validate } from "@/middleware/validate";
      import { BookingsController } from "./controller";
      import {
        createBookingSchema,
        updateBookingSchema,
        listBookingsQuerySchema,
      } from "./schemas";

      const router = Router();
      const ctrl = new BookingsController();

      router.use(authenticate);

      router.get("/", validate({ query: listBookingsQuerySchema }), ctrl.list);
      router.post("/", validate({ body: createBookingSchema }), ctrl.create);
      router.get("/:id", ctrl.getById);
      router.patch("/:id", validate({ body: updateBookingSchema }), ctrl.update);
      router.delete("/:id", ctrl.softDelete);
      router.post("/:id/confirm", ctrl.confirm);
      router.post("/:id/cancel", ctrl.cancel);

      export default router;
      ```

      Devin also derives Zod schemas directly from the OpenAPI component definitions, so request validation stays in sync with the spec:

      ```typescript theme={null}
      // src/api/v2/bookings/schemas.ts  (généré par Devin)
      import { z } from "zod";

      export const createBookingSchema = z.object({
        title: z.string().max(200),
        startTime: z.string().datetime(),
        endTime: z.string().datetime(),
        roomId: z.string().uuid(),
        notes: z.string().max(1000).optional(),
      });

      export const updateBookingSchema = createBookingSchema.partial();

      export const listBookingsQuerySchema = z.object({
        page: z.coerce.number().int().positive().default(1),
        limit: z.coerce.number().int().min(1).max(100).default(20),
        startDate: z.string().date().optional(),
        endDate: z.string().date().optional(),
      });
      ```

      Assurez-vous que la [configuration de l’environnement](/fr/onboard-devin/environment) inclut la configuration de la base de données de test et toutes les variables d’environnement nécessaires afin que Devin puisse exécuter l’ensemble de la suite de tests en local. Si votre API a besoin d’identifiants (URL de base de données, secret JWT, etc.), ajoutez-les en tant que [Secrets](/fr/product-guides/secrets) avant de lancer la session — ou fournissez-les pendant la session via le chat.
    </Step>

    <Step title="Devin delivers a tested PR">
      Devin lit la spécification, étudie votre code existant et implémente chaque endpoint afin de respecter à la fois le contrat OpenAPI et les conventions de votre codebase Express. Voici à quoi ressemble une PR typique :

      ```
      feat: Implement /api/v2/bookings endpoints from OpenAPI spec

      src/api/v2/bookings/
        router.ts              (Express route definitions + middleware)
        controller.ts          (request handling)
        service.ts             (business logic)
        repository.ts          (Prisma queries)
        schemas.ts             (Zod validation from spec)
      prisma/migrations/
        20260219_add_bookings/  (migration)
      src/__tests__/
        bookings.integration.ts (Supertest tests)
      ```

      Devin runs the Supertest suite before opening the PR:

      ```
        /api/v2/bookings
          GET /
            passes returns paginated bookings (42ms)
            passes filters by date range (38ms)
            passes returns 401 without auth (8ms)
          POST /
            passes creates booking with valid data (61ms)
            passes returns 400 for missing required fields (12ms)
            passes returns 409 for overlapping time slot (29ms)
          PATCH /:id
            passes updates booking fields (22ms)
            passes returns 404 for non-existent booking (9ms)
          POST /:id/confirm
            passes transitions status to confirmed (18ms)
            passes returns 422 for already-cancelled booking (11ms)

        16 passing (412ms)
      ```
    </Step>

    <Step title="Approfondissez ce que la spécification ne couvre pas">
      La spécification OpenAPI définit le contrat mais capture rarement les règles métier, la logique d'autorisation ou les exigences de performance. Utilisez des prompts complémentaires pour combler ces lacunes :

      <PromptBlock>
        ```txt Add authorization rules theme={null}
        Seul le créateur de la réservation ou un administrateur doit pouvoir PATCH ou DELETE
        une réservation. Les endpoints confirm et cancel doivent également exiger
        le rôle d'organisateur. Utilisez notre middleware de vérification de rôle existant dans
        src/middleware/authorize.ts.
        ```
      </PromptBlock>

      <PromptBlock>
        ```txt Add rate limiting and caching theme={null}
        Ajoutez une limitation de débit à POST /api/v2/bookings (20 par minute et par utilisateur).
        Mettez en cache les réponses GET /api/v2/bookings dans Redis avec un TTL de 30 secondes,
        invalidé à chaque opération d'écriture.
        ```
      </PromptBlock>
    </Step>

    <Step title="Passez en revue la PR avec Devin Review">
      Une fois que Devin a ouvert la pull request (PR), utilisez [Devin Review](https://app.devin.ai/review?utm_source=docs\&utm_medium=use-case-gallery) pour examiner l'implémentation. Devin Review peut détecter des problèmes comme l'absence de gestion des erreurs, des formats de réponse incohérents ou des endpoints qui ne respectent pas la spécification.

      Si Devin Review signale des problèmes, vous pouvez utiliser **Autofix** pour que Devin corrige automatiquement les problèmes signalés — il ouvre une session de suivi, applique les corrections et pousse un commit mis à jour sans que vous ayez à décrire chaque changement manuellement.
    </Step>
  </Steps>
</div>
