Tutorials

Generate architecture diagrams

Use IBM Bob to analyze the Galaxium Travels codebase and generate Mermaid UML class diagrams, sequence diagrams, and use case diagrams. Learn how to use context mentions in Ask mode to explore code and Agent mode to save the results to your repository.

Architecture diagrams give you a shared visual language for a codebase before you modify it. In this tutorial, you use Bob to read the Galaxium Travels source files and generate three types of UML diagrams: a UML class diagram, a sequence diagram, and a use case diagram. You use Ask mode to safely explore the code and generate the diagram markup, which uses Mermaid . Then you switch to Agent mode to save the diagrams to the project.

GitHub provides native support for Mermaid diagrams in Markdown files, so you can save the generated diagrams as .md files and view them rendered on GitHub.

In this tutorial, Bob's output may differ from the examples depending on the current state of the codebase. Use the generated markup as a starting point and refine it as needed.

Key features you learn

  • Context mentions: Reference specific files and folders in your prompts using the @ symbol. Context mentions let Bob know exactly which files to analyze for generating accurate diagrams.
  • Ask mode: Read and analyze code without Bob making any changes to your files.
  • Agent mode: Let Bob write files autonomously to persist generated artifacts to your project.

Prerequisites

To complete this tutorial, you need the following:

  • Bob IDE installed.
  • Git installed locally so you can clone the Galaxium Travels example repository.
  • Familiarity with the basics of using Bob. If you are new to Bob, start with the Quickstart tutorial.

Set up your workspace

Clone the Galaxium Travels repository

In your terminal, run the following command to clone the Galaxium Travels example repository:

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

Launch IBM Bob

Launch the IBM Bob IDE on your computer.

Open the example project

In the Bob IDE, open the galaxium-travels folder you cloned. If Bob asks "Do you trust the authors of the files in the folder?", click Yes, I trust the authors.

Review the README.md file in the root directory to get an overview of the application and its architecture. The Galaxium Travels app simulates a flight booking system with a React frontend, a Python FastAPI backend, and a Java inventory hold service. The codebase is intentionally complex and representative of real-world applications, making it a great candidate for generating architecture diagrams.

Open the Bob chat interface

If the chat interface is not already open, click the Bob icon in the navigation bar or use the shortcut Option + Command + B (Mac) or Ctrl + Alt + B (Windows).

Initialize project context

Bob defaults to Agent mode on startup. If you have changed modes, make sure to switch to Agent mode before running the initialization command. Bob needs to write files to set up the project context.

Enter the /init command in the chat interface input field. If you have auto-approval disabled, Bob asks your permission to read files and write the AGENTS.md files.

 /init

Bob reads the relevant files in the project. Bob then generates the main AGENTS.md file in the root directory. Bob also creates a .bob folder that contains an AGENTS.md for each mode.

Review the generated AGENTS.md files to understand how Bob has set up the project context and what capabilities Bob has in each mode.

Switch to Ask mode

Select Ask in the mode selector below the chat input field. You may instead type /ask in the chat input field to switch modes.

Unlike Agent mode, Ask mode is read-only. Bob can read and analyze files but cannot create or modify anything, making it safe for code exploration.

Generate a UML class diagram

A UML class diagram maps the data model of an application: the entities (classes), their attributes, and the relationships between them. For Galaxium Travels, this covers the Python SQLAlchemy models in the backend and the Java domain classes in the inventory hold service.

Create a prompt to analyze the data models across both services and produce a Mermaid classDiagram. Use context mentions to specify the relevant files for Bob to analyze. By default, Bob outputs the Mermaid diagram as a rendered image. To review the raw Mermaid markup instead, add the instruction "Output only the Mermaid code block. Do not render the Mermaid diagram." to your prompt.

In Ask mode, enter the following prompt in the chat input field:

Analyze the data models in @booking_system_backend/models.py and the 
Java domain classes in @booking_system_inventory_hold_service/src/main/java/com/galaxium/holdservice/domain.

Generate a Mermaid classDiagram that shows all classes, their attributes,
their methods (if any), and the relationships between them. 
Include the BookingStatus enum.

Output the Mermaid markup. Do not render the Mermaid diagram.

Bob reads both files and produces diagram markup similar to the following:

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

Generate a sequence diagram

A sequence diagram shows how components interact at runtime in a specific flow, ordered by time. The Galaxium Travels booking flow spans the React frontend, the Python FastAPI backend, and the Java inventory hold service.

Create a prompt to trace the full booking flow and produce a Mermaid sequenceDiagram. Use context mentions to specify the relevant files for Bob to analyze. The more specific you are in your prompt about which files to analyze and what flow you want to diagram, the more accurate the output is.

In Ask mode, enter the following prompt in the chat input field:

Analyze the booking flow across @booking_system_frontend/src/services,
@booking_system_backend/server.py, @booking_system_backend/services/booking.py,
and @booking_system_inventory_hold_service/src/main/java/com/galaxium/holdservice/api.

Generate a Mermaid sequenceDiagram showing the complete flow for a
user booking a flight, including the quote and hold steps with the Java service.

Output the Mermaid markup. Do not render the Mermaid diagram.

Bob traces the interaction chain and produces diagram markup similar to the following:

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

Generate a use case diagram

A use case diagram identifies the actors in a system and the capabilities each actor can exercise. Mermaid does not have a native use case diagram type, so you represent this with a flowchart LR that groups use cases by actor.

Create a prompt to identify all actors and their use cases across the full application. Actors include user types and external systems. Use context mentions to specify the relevant files for Bob to analyze, including the frontend pages, backend REST endpoints, and MCP tools. The more specific you are in your prompt about which files to analyze, the more accurate the output is. Additionally, instruct Bob to escape curly braces in the Mermaid markup so that the Mermaid renderer does not attempt to interpret the curly braces as template syntax.

In Ask mode, enter the following prompt in the chat input field:

Analyze the full Galaxium Travels application. 

Identify all actors (user types or external systems) and the use cases each
actor can perform, based on the frontend pages, backend REST endpoints,
and MCP tools.

Generate a Mermaid flowchart LR that represents this as a use case diagram,
grouping use cases under their respective actors using subgraphs.

Escape curly braces in Mermaid markup so that the Mermaid renderer does not
attempt to interpret the curly braces as template syntax.

Output the Mermaid markup. Do not render the Mermaid diagram.

Bob analyzes the application and produces diagram markup similar to the following:

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

Save diagrams to the repository

Switch Bob to Agent mode and ask it to save the diagrams you generated into the repository. Each diagram is saved as a Markdown file in a new docs/architecture/ folder.

Switch to Agent mode

Select Agent in the mode selector, or type /agent in the chat input field.

Save all three diagrams

Ask Bob to create the architecture documentation files.

Create a docs/architecture/ folder in the repository root.

Save each of the three diagrams we generated as individual Markdown files:
- class-diagram.md — the UML class diagram
- sequence-diagram.md — the booking flow sequence diagram
- use-case-diagram.md — the use case flowchart

Each file should have a short title heading, the Mermaid code block we
generated, and a brief description of the diagram.

Bob creates the three files. Click Approve and Save for each file Bob writes.

Verify the output

Open each file in the Bob file explorer to confirm the Mermaid fenced code blocks are present. You have these options for verifying the diagrams:

  • Ask Bob to show you a preview of the Markdown file.

    In the chat input field, enter the following prompt:

      Show me a preview of docs/architecture/class-diagram.md

    Bob renders the Markdown file, including the Mermaid diagram, in the chat interface. Click on the rendered diagram to open it in a larger view.

    You can do this for each of the three files to see all the diagrams rendered.

  • Paste the diagram markup into Mermaid Live Editor to preview the rendered diagram.

  • Commit and push the changes to a GitHub repository. Then view the files on GitHub to see the rendered diagrams.

Troubleshooting

Bob generates Mermaid markup that does not compile

Mermaid's parser is strict. Even a single invalid character, an unsupported keyword, or a missing newline can cause a diagram to silently fail or throw a parse error. Use the following approach to diagnose and fix the problem.

Identify the failing line

When Bob produces a parse error, the output includes the line number and a snippet of the offending code.

If Bob doesn't output a parser error, paste the markup into Mermaid Live Editor. The editor highlights the offending line and shows the parser error, which can help you identify the issue.

You can also visually inspect the markup for common issues such as unescaped special characters in labels, unclosed subgraphs, or syntax errors in arrows.

SymptomLikely causeFix
Parse error near { or }Curly braces unescaped in flowchart or classDiagram node labelsReplace { with &#123; and } with &#125;, or reword the label
Parse error near ( or )Parentheses in a node IDWrap the label in quotes: A["label (note)"]
Unexpected end or subgraph errorSubgraph not closedEnsure every subgraph block has a matching end
Arrow type not recognizedWrong arrow syntax for the diagram type--> is for flowchart; classDiagram uses -->, ..>, --|> etc.; sequenceDiagram uses ->>, -->>
Node defined but not connectedOrphan node causes no error but can confuse some renderersConnect the node or remove it
Diagram renders partially then stopsLabel contains a bare " characterEscape quotes inside labels: A["it\'s a label"]

Ask Bob to fix the issue

Give Bob the parser error and the failing line. Then ask Bob to fix specific lines.

For example:

The Mermaid classDiagram fails to parse with this error:
Parse error on line 42: ...unexpected token 'NEWLINE'

Here is the relevant block:
    Booking ..> BookingStatus : status (active)

Fix the syntax so it compiles without changing the diagram structure.

Bob can target a narrow fix without regenerating content you already reviewed.

Ask Bob to validate before outputting

If you are regenerating a diagram from scratch, add an explicit validation instruction to the prompt:

Before outputting the Mermaid block, mentally parse it and confirm every node ID
is valid, every subgraph is closed, and all special characters in labels are escaped.

Narrow the scope when the diagram is large

If a diagram with many nodes keeps producing invalid markup, ask Bob to generate it in sections, such as the Python models first and then the Java models. Afterwards, ask Bob to assemble the blocks. Smaller generations are easier for Bob to validate and easier for you to diff.

Next steps

In this tutorial, you used context mentions and Ask mode to explore the Galaxium Travels codebase and generate three types of architecture diagrams with Bob, then used Agent mode to save them to the repository. Continue with the following resources:

How is this topic?