Tutoriels

Générer des diagrammes d'architecture

Utilise IBM Bob pour analyser la base de code Galaxium Travels et générer des diagrammes de classes UML Mermaid, des diagrammes de séquence et des diagrammes de cas d'utilisation. Apprends à utiliser les mentions de contexte en mode Ask pour explorer le code et le mode Agent pour enregistrer les résultats dans ton dépôt.

Les diagrammes d'architecture te donnent un langage visuel partagé pour une base de code avant de la modifier. Dans ce tutoriel, tu utilises Bob pour lire les fichiers sources de Galaxium Travels et générer trois types de diagrammes UML : un diagramme de classes UML, un diagramme de séquence et un diagramme de cas d'utilisation. Tu utilises le mode Ask pour explorer le code en toute sécurité et générer le markup du diagramme, qui utilise Mermaid. Ensuite, tu passes au mode Agent pour enregistrer les diagrammes dans le projet.

GitHub fournit un support natif pour les diagrammes Mermaid dans les fichiers Markdown, tu peux donc enregistrer les diagrammes générés sous forme de fichiers .md et les voir rendus sur GitHub.

Dans ce tutoriel, la sortie de Bob peut différer des exemples selon l'état actuel de la base de code. Utilise le markup généré comme point de départ et affine-le selon tes besoins.

Fonctionnalités clés que tu apprendras

  • Mentions de contexte : Référence des fichiers et dossiers spécifiques dans tes prompts en utilisant le symbole @. Les mentions de contexte permettent à Bob de savoir exactement quels fichiers analyser pour générer des diagrammes précis.
  • Mode Ask : Lis et analyse le code sans que Bob n'apporte de modifications à tes fichiers.
  • Mode Agent : Laisse Bob écrire des fichiers de manière autonome pour persister les artefacts générés dans ton projet.

Prérequis

Pour compléter ce tutoriel, tu as besoin de ce qui suit :

  • Bob IDE installé.
  • Git installé localement pour que tu puisses cloner le dépôt d'exemple Galaxium Travels.
  • Familiarité avec les bases de l'utilisation de Bob. Si tu débutes avec Bob, commence par le tutoriel de démarrage rapide.

Configure ton espace de travail

Clone le dépôt Galaxium Travels

Dans ton terminal, exécute la commande suivante pour cloner le dépôt d'exemple Galaxium Travels :

git clone https://github.com/ibm/galaxium-travels.git

Lance IBM Bob

Lance l'IDE IBM Bob sur ton ordinateur.

Ouvre le projet d'exemple

Dans l'IDE Bob, ouvre le dossier galaxium-travels que tu as cloné. Si Bob demande "Fais-tu confiance aux auteurs des fichiers dans le dossier ?", clique sur Oui, je fais confiance aux auteurs.

Consulte le fichier README.md dans le répertoire racine pour obtenir un aperçu de l'application et de son architecture. L'application Galaxium Travels simule un système de réservation de vols avec un frontend React, un backend Python FastAPI et un service de retenue d'inventaire Java. La base de code est intentionnellement complexe et représentative d'applications réelles, ce qui en fait un excellent candidat pour générer des diagrammes d'architecture.

Ouvre l'interface de chat Bob

Si l'interface de chat n'est pas déjà ouverte, clique sur l'icône Bob dans la barre de navigation ou utilise le raccourci Option + Command + B (Mac) ou Ctrl + Alt + B (Windows).

Initialise le contexte du projet

Bob démarre en mode Agent par défaut. Si tu as changé de mode, assure-toi de passer en mode Agent avant d'exécuter la commande d'initialisation. Bob doit écrire des fichiers pour configurer le contexte du projet.

Entre la commande /init dans le champ de saisie de l'interface de chat. Si tu as l'approbation automatique désactivée, Bob te demandera la permission de lire les fichiers et d'écrire les fichiers AGENTS.md.

 /init

Bob lit les fichiers pertinents dans le projet. Bob génère ensuite le fichier principal AGENTS.md dans le répertoire racine. Bob crée également un dossier .bob qui contient un AGENTS.md pour chaque mode.

Consulte les fichiers AGENTS.md générés pour comprendre comment Bob a configuré le contexte du projet et quelles capacités Bob a dans chaque mode.

Passe en mode Ask

Sélectionne Ask dans le sélecteur de mode sous le champ de saisie du chat. Tu peux aussi taper /ask dans le champ de saisie du chat pour changer de mode.

Contrairement au mode Agent, le mode Ask est en lecture seule. Bob peut lire et analyser les fichiers mais ne peut rien créer ni modifier, ce qui le rend sûr pour l'exploration du code.

Génère un diagramme de classes UML

Un diagramme de classes UML cartographie le modèle de données d'une application : les entités (classes), leurs attributs et les relations entre elles. Pour Galaxium Travels, cela couvre les modèles Python SQLAlchemy dans le backend et les classes de domaine Java dans le service de retenue d'inventaire.

Crée un prompt pour analyser les modèles de données des deux services et produire un classDiagram Mermaid. Utilise les mentions de contexte pour spécifier les fichiers pertinents pour que Bob les analyse. Par défaut, Bob génère le diagramme Mermaid sous forme d'image rendue. Pour consulter le markup Mermaid brut à la place, ajoute l'instruction "Génère uniquement le bloc de code Mermaid. Ne rends pas le diagramme Mermaid." à ton prompt.

En mode Ask, entre le prompt suivant dans le champ de saisie du chat :

Analyse les modèles de données dans @booking_system_backend/models.py et les 
classes de domaine Java dans @booking_system_inventory_hold_service/src/main/java/com/galaxium/holdservice/domain.

Génère un classDiagram Mermaid qui montre toutes les classes, leurs attributs,
leurs méthodes (le cas échéant) et les relations entre elles. 
Inclus l'enum BookingStatus.

Génère le markup Mermaid. Ne rends pas le diagramme Mermaid.

Bob lit les deux fichiers et produit un markup de diagramme similaire au suivant :

classDiagram
    direction LR

    %% ── Python / SQLAlchemy (booking_system_backend/models.py) ──────────

    class User {
        +int user_id PK
        +str name
        +str email
    }

    class Flight {
        +int flight_id PK
        +str origin
        +str destination
        +str departure_time
        +str arrival_time
        +int base_price
        +int economy_seats_available
        +int business_seats_available
        +int galaxium_seats_available
    }

    class Booking {
        +int booking_id PK
        +int user_id FK
        +int flight_id FK
        +str status
        +str booking_time
        +str seat_class
        +int price_paid
    }

    class BookingStatus {
        <<enumeration>>
        BOOKED = "booked"
        CANCELLED = "cancelled"
        CANCELED = "cancelled"
        COMPLETED = "completed"
    }

    %% ── Java / JPA (holdservice/domain) ────────────────────────────────

    class Quote {
        +String quoteId PK
        +Integer flightId
        +String seatClass
        +Integer quantity
        +Integer travelerId
        +String travelerName
        +Long pricePerSeat
        +Long totalPrice
        +Instant expiresAt
        +QuoteStatus status
        +Instant createdAt
        #onCreate() void
    }

    class QuoteStatus {
        <<enumeration>>
        CREATED
    }

    class Hold {
        +String holdId PK
        +String quoteId FK
        +HoldStatus status
        +Instant reservedUntil
        +String externalBookingReference
        +String errorMessage
        +Instant createdAt
        +Instant updatedAt
        #onCreate() void
        #onUpdate() void
    }

    class HoldStatus {
        <<enumeration>>
        HELD
        EXPIRED
        CONFIRMED
        RELEASED
        CONFIRMATION_FAILED
    }

    class AuditEvent {
        +String eventId PK
        +String entityType
        +String entityId
        +String eventType
        +String details
        +Instant createdAt
        #onCreate() void
    }

    %% ── Relationships ───────────────────────────────────────────────────

    User        "1" --> "0..*" Booking      : places
    Flight      "1" --> "0..*" Booking      : booked on
    Booking          ..>        BookingStatus : status

    Quote       "1" --> "0..*" Hold         : generates
    Quote            ..>        QuoteStatus  : status
    Hold             ..>        HoldStatus   : status

    AuditEvent       ..>        Quote        : references entityId
    AuditEvent       ..>        Hold         : references entityId

Génère un diagramme de séquence

Un diagramme de séquence montre comment les composants interagissent à l'exécution dans un flux spécifique, ordonné par le temps. Le flux de réservation Galaxium Travels s'étend sur le frontend React, le backend Python FastAPI et le service de retenue d'inventaire Java.

Crée un prompt pour tracer le flux de réservation complet et produire un sequenceDiagram Mermaid. Utilise les mentions de contexte pour spécifier les fichiers pertinents pour que Bob les analyse. Plus tu es spécifique dans ton prompt sur les fichiers à analyser et le flux que tu veux diagrammer, plus la sortie est précise.

En mode Ask, entre le prompt suivant dans le champ de saisie du chat :

Analyse le flux de réservation dans @booking_system_frontend/src/services,
@booking_system_backend/server.py, @booking_system_backend/services/booking.py,
et @booking_system_inventory_hold_service/src/main/java/com/galaxium/holdservice/api.

Génère un sequenceDiagram Mermaid montrant le flux complet pour un
utilisateur réservant un vol, incluant les étapes de devis et de retenue avec le service Java.

Génère le markup Mermaid. Ne rends pas le diagramme Mermaid.

Bob trace la chaîne d'interaction et produit un markup de diagramme similaire au suivant :

sequenceDiagram
    autonumber
    participant U  as User (Browser)
    participant FE as Frontend<br/>(api.ts)
    participant PY as Python Backend<br/>(server.py)
    participant BS as BookingService<br/>(booking.py)
    participant QC as QuoteController<br/>(Java)
    participant QS as QuoteService<br/>(Java)
    participant HC as HoldController<br/>(Java)
    participant HS as HoldService<br/>(Java)
    participant DB as Python SQLite
    participant JDB as Java SQLite

    Note over U,JDB: ── Phase 1: Create Quote ──────────────────────────────────

    U->>FE: createQuote({ flightId, seatClass,<br/>quantity, travelerId, travelerName })
    FE->>PY: POST /quotes
    PY->>QC: POST /api/v1/quotes
    QC->>QS: createQuote(request)
    QS->>QS: generateQuoteId() → "Q-2025-000001"
    QS->>QS: pricingService.calculatePrice(flightId, seatClass)
    QS->>JDB: save Quote (status=CREATED, expiresAt=+24h)
    QS->>JDB: save AuditEvent (QUOTE / CREATED)
    QC-->>PY: 201 Quote
    Note right of PY: Returns {"error":"..."} HTTP 200<br/>if Java service unreachable
    PY-->>FE: Quote JSON
    FE->>FE: assertNotProxyError(response.data)
    FE-->>U: quoteId

    Note over U,JDB: ── Phase 2: Create Hold ───────────────────────────────────

    U->>FE: createHold(quoteId)
    FE->>PY: POST /quotes/{quoteId}/holds
    PY->>HC: POST /api/v1/quotes/{quoteId}/holds
    HC->>HS: createHold(quoteId)
    HS->>JDB: findById(quoteId)
    JDB-->>HS: Quote
    HS->>HS: check quote not expired
    HS->>HS: generateHoldId() → "H-2025-000001"
    HS->>JDB: save Hold (status=HELD,<br/>reservedUntil=+15min)
    HS->>JDB: save AuditEvent (HOLD / CREATED)
    HC-->>PY: 201 Hold
    PY-->>FE: Hold JSON
    FE->>FE: assertNotProxyError(response.data)
    FE-->>U: holdId

    Note over U,JDB: ── Phase 3: Confirm Hold → Create Booking ─────────────────

    U->>FE: confirmHold(holdId)
    FE->>PY: POST /holds/{holdId}/confirm
    PY->>HC: POST /api/v1/holds/{holdId}/confirm
    HC->>HS: confirmHold(holdId)
    HS->>JDB: findById(holdId)
    JDB-->>HS: Hold
    HS->>HS: check status == HELD
    HS->>HS: check reservedUntil not passed
    HS->>JDB: findById(hold.quoteId)
    JDB-->>HS: Quote

    HS->>PY: POST /internal/bookings/from-hold<br/>{ travelerId, travelerName, flightId, seatClass }
    PY->>BS: book_flight(db, user_id, name,<br/>flight_id, seat_class)
    BS->>DB: query Flight (check seats available)
    BS->>DB: query User (validate user_id + name match)
    BS->>DB: decrement {seat_class}_seats_available
    BS->>DB: insert Booking (status="booked")
    DB-->>BS: Booking row
    BS-->>PY: BookingOut

    alt booking succeeded
        PY-->>HS: 200 { booking_id, ... }
        HS->>JDB: update Hold (status=CONFIRMED,<br/>externalBookingReference=booking_id)
        HS->>JDB: save AuditEvent (HOLD / CONFIRMED)
        HC-->>PY: 200 Hold (CONFIRMED)
        PY-->>FE: Hold JSON
        FE->>FE: assertNotProxyError(response.data)
        FE-->>U: Booking confirmed ✓
    else booking failed (name mismatch / no seats / user not found)
        PY-->>HS: 400 { error, error_code, details }
        HS->>JDB: update Hold (status=CONFIRMATION_FAILED,<br/>errorMessage=...)
        HS->>JDB: save AuditEvent (HOLD / CONFIRMATION_FAILED)
        HC-->>PY: 400 Bad Request
        PY-->>FE: error response
        FE-->>U: Error shown to user ✗
    end

Génère un diagramme de cas d'utilisation

Un diagramme de cas d'utilisation identifie les acteurs dans un système et les capacités que chaque acteur peut exercer. Mermaid n'a pas de type de diagramme de cas d'utilisation natif, tu représentes donc cela avec un flowchart LR qui regroupe les cas d'utilisation par acteur.

Crée un prompt pour identifier tous les acteurs et leurs cas d'utilisation dans toute l'application. Les acteurs incluent les types d'utilisateurs et les systèmes externes. Utilise les mentions de contexte pour spécifier les fichiers pertinents pour que Bob les analyse, y compris les pages frontend, les endpoints REST backend et les outils MCP. Plus tu es spécifique dans ton prompt sur les fichiers à analyser, plus la sortie est précise. De plus, demande à Bob d'échapper les accolades dans le markup Mermaid pour que le moteur de rendu Mermaid n'essaie pas d'interpréter les accolades comme une syntaxe de template.

En mode Ask, entre le prompt suivant dans le champ de saisie du chat :

Analyse l'application complète Galaxium Travels. 

Identifie tous les acteurs (types d'utilisateurs ou systèmes externes) et les cas d'utilisation que chaque
acteur peut effectuer, en te basant sur les pages frontend, les endpoints REST backend
et les outils MCP.

Génère un flowchart LR Mermaid qui représente cela comme un diagramme de cas d'utilisation,
en regroupant les cas d'utilisation sous leurs acteurs respectifs en utilisant des sous-graphes.

Échappe les accolades dans le markup Mermaid pour que le moteur de rendu Mermaid n'essaie pas
d'interpréter les accolades comme une syntaxe de template.

Génère le markup Mermaid. Ne rends pas le diagramme Mermaid.

Bob analyse l'application et produit un markup de diagramme similaire au suivant :

flowchart LR

    subgraph Traveller["👤 Traveller (Browser)"]
        T1[Browse available flights]
        T2[Search flights by origin / destination]
        T3[Filter flights by date, price, seat class,\nduration, route category, time period]
        T4[Register account]
        T5[Sign in with name and email]
        T6[Select seat class\neconomy / business / galaxium]
        T7[Get price quote]
        T8[Place seat hold - 15-minute timer]
        T9[Confirm hold and create booking]
        T10[Release hold]
        T11[View active bookings]
        T12[View past bookings]
        T13[Cancel booking]
        T14[View pending holds with countdown]
        T15[Dismiss expired hold]
    end

    subgraph AIAgent["🤖 AI Agent (MCP Client)"]
        A1[list_flights]
        A2[register_user]
        A3[get_user_id]
        A4[book_flight]
        A5[get_bookings]
        A6[cancel_booking]
    end

    subgraph JavaService["☕ Java Hold Service\n(Internal System)"]
        J1[Confirm hold via POST /internal/bookings/from-hold]
        J2[Auto-expire holds after timeout]
    end

    subgraph RestAPI["🐍 Python REST API\n(External Consumers / Swagger)"]
        R1[GET  /flights — list and filter flights]
        R2[POST /register — register user]
        R3[GET  /user — look up user by name and email]
        R4[POST /book — book a flight]
        R5[GET  /bookings/&#123;user_id&#125; — get user bookings]
        R6[POST /cancel/&#123;booking_id&#125; — cancel booking]
        R7[POST /quotes — create quote proxy]
        R8[GET  /quotes/&#123;id&#125; — get quote proxy]
        R9[POST /quotes/&#123;id&#125;/holds — create hold proxy]
        R10[GET  /holds/&#123;id&#125; — get hold proxy]
        R11[POST /holds/&#123;id&#125;/confirm — confirm hold proxy]
        R12[POST /holds/&#123;id&#125;/release — release hold proxy]
        R13[GET  / — health check]
    end

    Traveller   -->|uses frontend which calls| RestAPI
    AIAgent     -->|MCP over HTTP at /mcp| RestAPI
    JavaService -->|calls back via internal endpoint| RestAPI

Enregistre les diagrammes dans le dépôt

Passe Bob en mode Agent et demande-lui d'enregistrer les diagrammes que tu as générés dans le dépôt. Chaque diagramme est enregistré sous forme de fichier Markdown dans un nouveau dossier docs/architecture/.

Passe en mode Agent

Sélectionne Agent dans le sélecteur de mode, ou tape /agent dans le champ de saisie du chat.

Enregistre les trois diagrammes

Demande à Bob de créer les fichiers de documentation d'architecture.

Crée un dossier docs/architecture/ à la racine du dépôt.

Enregistre chacun des trois diagrammes que nous avons générés sous forme de fichiers Markdown individuels :
- class-diagram.md — le diagramme de classes UML
- sequence-diagram.md — le diagramme de séquence du flux de réservation
- use-case-diagram.md — le diagramme de flux de cas d'utilisation

Chaque fichier doit avoir un titre court, le bloc de code Mermaid que nous avons
généré et une brève description du diagramme.

Bob crée les trois fichiers. Clique sur Approve et Save pour chaque fichier que Bob écrit.

Vérifie la sortie

Ouvre chaque fichier dans l'explorateur de fichiers Bob pour confirmer que les blocs de code Mermaid délimités sont présents. Tu as ces options pour vérifier les diagrammes :

  • Demande à Bob de te montrer un aperçu du fichier Markdown.

    Dans le champ de saisie du chat, entre le prompt suivant :

      Montre-moi un aperçu de docs/architecture/class-diagram.md

    Bob rend le fichier Markdown, y compris le diagramme Mermaid, dans l'interface de chat. Clique sur le diagramme rendu pour l'ouvrir dans une vue plus grande.

    Tu peux faire cela pour chacun des trois fichiers pour voir tous les diagrammes rendus.

  • Colle le markup du diagramme dans Mermaid Live Editor pour prévisualiser le diagramme rendu.

  • Commite et pousse les modifications vers un dépôt GitHub. Ensuite, consulte les fichiers sur GitHub pour voir les diagrammes rendus.

Dépannage

Bob génère un markup Mermaid qui ne compile pas

L'analyseur de Mermaid est strict. Même un seul caractère invalide, un mot-clé non pris en charge ou un saut de ligne manquant peut faire échouer silencieusement un diagramme ou générer une erreur d'analyse. Utilise l'approche suivante pour diagnostiquer et résoudre le problème.

Identifie la ligne défaillante

Lorsque Bob produit une erreur d'analyse, la sortie inclut le numéro de ligne et un extrait du code problématique.

Si Bob ne génère pas d'erreur d'analyseur, colle le markup dans Mermaid Live Editor. L'éditeur met en évidence la ligne problématique et affiche l'erreur d'analyseur, ce qui peut t'aider à identifier le problème.

Tu peux également inspecter visuellement le markup pour détecter les problèmes courants tels que les caractères spéciaux non échappés dans les étiquettes, les sous-graphes non fermés ou les erreurs de syntaxe dans les flèches.

SymptômeCause probableSolution
Erreur d'analyse près de { ou }Accolades non échappées dans les étiquettes de nœuds flowchart ou classDiagramRemplace { par &#123; et } par &#125;, ou reformule l'étiquette
Erreur d'analyse près de ( ou )Parenthèses dans un ID de nœudEntoure l'étiquette de guillemets : A["label (note)"]
Erreur end ou subgraph inattendueSous-graphe non ferméAssure-toi que chaque bloc subgraph a un end correspondant
Type de flèche non reconnuMauvaise syntaxe de flèche pour le type de diagramme--> est pour flowchart ; classDiagram utilise -->, ..>, --|> etc. ; sequenceDiagram utilise ->>, -->>
Nœud défini mais non connectéLe nœud orphelin ne cause pas d'erreur mais peut confondre certains moteurs de renduConnecte le nœud ou supprime-le
Le diagramme se rend partiellement puis s'arrêteL'étiquette contient un caractère " nuÉchappe les guillemets dans les étiquettes : A["it\'s a label"]

Demande à Bob de corriger le problème

Donne à Bob l'erreur d'analyseur et la ligne défaillante. Ensuite, demande à Bob de corriger des lignes spécifiques.

Par exemple :

Le classDiagram Mermaid ne parvient pas à analyser avec cette erreur :
Parse error on line 42: ...unexpected token 'NEWLINE'

Voici le bloc pertinent :
    Booking ..> BookingStatus : status (active)

Corrige la syntaxe pour qu'elle compile sans changer la structure du diagramme.

Bob peut cibler une correction étroite sans régénérer le contenu que tu as déjà examiné.

Demande à Bob de valider avant de générer

Si tu régénères un diagramme à partir de zéro, ajoute une instruction de validation explicite au prompt :

Avant de générer le bloc Mermaid, analyse-le mentalement et confirme que chaque ID de nœud
est valide, que chaque sous-graphe est fermé et que tous les caractères spéciaux dans les étiquettes sont échappés.

Réduis la portée lorsque le diagramme est grand

Si un diagramme avec de nombreux nœuds continue de produire un markup invalide, demande à Bob de le générer en sections, comme les modèles Python d'abord puis les modèles Java. Ensuite, demande à Bob d'assembler les blocs. Les générations plus petites sont plus faciles pour Bob à valider et plus faciles pour toi à comparer.

Prochaines étapes

Dans ce tutoriel, tu as utilisé les mentions de contexte et le mode Ask pour explorer la base de code Galaxium Travels et générer trois types de diagrammes d'architecture avec Bob, puis tu as utilisé le mode Agent pour les enregistrer dans le dépôt. Continue avec les ressources suivantes :

Comment trouvez-vous ce sujet ?