الدروس التعليمية

توليد مخططات المعمارية

استخدم IBM Bob لتحليل قاعدة كود Galaxium Travels وتوليد مخططات UML للفئات، ومخططات التسلسل، ومخططات حالة الاستخدام باستخدام Mermaid. تعلم كيفية استخدام mentions السياق في وضع Ask لاستكشاف الكود ووضع Agent لحفظ النتائج في مستودعك.

مخططات المعمارية تمنحك لغة بصرية مشتركة لقاعدة الكود قبل تعديلها. في هذا الدرس، ستستخدم Bob لقراءة ملفات Galaxium Travels المصدرية وتوليد ثلاثة أنواع من مخططات UML: مخطط فئات UML، ومخطط تسلسل، ومخطط حالة استخدام. ستستخدم وضع Ask لاستكشاف الكود بأمان وتوليد ترميز المخطط الذي يستخدم Mermaid. ثم تبدّل إلى وضع Agent لحفظ المخططات في المشروع.

يوفر GitHub دعماً أصلياً لمخططات Mermaid في ملفات Markdown، لذا يمكنك حفظ المخططات المُولَّدة كملفات .md وعرضها مُرنَّدَة على GitHub.

في هذا الدرس، قد تختلف مخرجات Bob عن الأمثلة اعتماداً على الحالة الراهنة لقاعدة الكود. استخدم الترميز المُولَّد كنقطة انطلاق وقم بتحسينه حسب الحاجة.

الميزات الرئيسية التي ستتعلمها

  • Context mentions: الإشارة إلى ملفات ومجلدات محددة في طلباتك باستخدام رمز @. تتيح mentions السياق لـ Bob معرفة الملفات التي يجب تحليلها بالضبط لتوليد مخططات دقيقة.
  • وضع Ask: قراءة وتحليل الكود دون أن يُجري Bob أي تغييرات على ملفاتك.
  • وضع Agent: السماح لـ Bob بكتابة الملفات بشكل مستقل لحفظ النتائج المُولَّدة في مشروعك.

المتطلبات الأساسية

لإكمال هذا الدرس، تحتاج إلى:

  • Bob IDE مثبت.
  • Git مثبت محلياً حتى تتمكن من استنساخ مستودع Galaxium Travels النموذجي.
  • إلمام بأساسيات استخدام Bob. إذا كنت جديداً على Bob، ابدأ بـ درس البدء السريع.

إعداد مساحة عملك

استنساخ مستودع Galaxium Travels

في الـ terminal، نفّذ الأمر التالي لاستنساخ مستودع Galaxium Travels النموذجي:

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

تشغيل IBM Bob

شغّل IBM Bob IDE على حاسوبك.

فتح المشروع النموذجي

في Bob IDE، افتح مجلد galaxium-travels الذي استنسخته. إذا سأل Bob "Do you trust the authors of the files in the folder?"، انقر على Yes, I trust the authors.

راجع ملف README.md في المجلد الجذري للحصول على نظرة عامة على التطبيق ومعماريته. تطبيق Galaxium Travels يحاكي نظام حجز رحلات مع واجهة أمامية React وخلفية Python FastAPI وخدمة جرد Java. قاعدة الكود معقدة عمداً وتمثل التطبيقات الواقعية، مما يجعلها مرشحاً ممتازاً لتوليد مخططات المعمارية.

فتح واجهة دردشة Bob

إذا لم تكن واجهة الدردشة مفتوحة بالفعل، انقر على أيقونة Bob في شريط التنقل أو استخدم الاختصار Option + Command + B (Mac) أو Ctrl + Alt + B (Windows).

تهيئة سياق المشروع

Bob يبدأ في وضع Agent افتراضياً. إذا غيّرت الأوضاع، تأكد من التبديل إلى وضع Agent قبل تشغيل أمر التهيئة. Bob يحتاج إلى كتابة الملفات لإعداد سياق المشروع.

أدخل الأمر /init في حقل إدخال واجهة الدردشة. إذا كان الموافقة التلقائية معطلاً، يطلب Bob إذنك لقراءة الملفات وكتابة ملفات AGENTS.md.

 /init

يقرأ Bob الملفات ذات الصلة في المشروع. ثم يُنشئ Bob ملف AGENTS.md الرئيسي في المجلد الجذري. كما ينشئ Bob مجلد .bob يحتوي على AGENTS.md لكل وضع.

راجع ملفات AGENTS.md المُولَّدة لفهم كيفية إعداد Bob لسياق المشروع وما هي القدرات التي يمتلكها Bob في كل وضع.

التبديل إلى وضع Ask

اختر Ask في محدد الوضع أسفل حقل إدخال الدردشة. يمكنك بدلاً من ذلك كتابة /ask في حقل إدخال الدردشة للتبديل بين الأوضاع.

على عكس وضع Agent، وضع Ask للقراءة فقط. يمكن لـ Bob قراءة وتحليل الملفات لكنه لا يستطيع إنشاء أو تعديل أي شيء، مما يجعله آمناً لاستكشاف الكود.

توليد مخطط فئات UML

مخطط فئات UML يرسم خريطة نموذج بيانات التطبيق: الكيانات (الفئات)، وخصائصها، والعلاقات بينها. بالنسبة لـ Galaxium Travels، يغطي هذا النماذج Python SQLAlchemy في الخلفية وفئات Java الخاصة بخدمة الجرد.

أنشئ طلباً لتحليل نماذج البيانات عبر كلتا الخدمتين وإنتاج classDiagram بـ Mermaid. استخدم mentions السياق لتحديد الملفات ذات الصلة لـ Bob للتحليل. بشكل افتراضي، يُخرج Bob مخطط Mermaid كصورة مُرنَّدَة. لمراجعة ترميز Mermaid الخام بدلاً من ذلك، أضف التعليمات "Output only the Mermaid code block. Do not render the Mermaid diagram." إلى طلبك.

في وضع Ask، أدخل الطلب التالي في حقل إدخال الدردشة:

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 كلا الملفين ويُنتج ترميز مخطط مشابهاً للتالي:

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

توليد مخطط تسلسل

مخطط التسلسل يُظهر كيفية تفاعل المكونات في وقت التشغيل في تدفق محدد، مرتبة حسب الوقت. تدفق الحجز في Galaxium Travels يمتد عبر واجهة React الأمامية وخلفية Python FastAPI وخدمة الجرد Java.

أنشئ طلباً لتتبع تدفق الحجز الكامل وإنتاج sequenceDiagram بـ Mermaid. استخدم mentions السياق لتحديد الملفات ذات الصلة لـ Bob للتحليل. كلما كنت أكثر تحديداً في طلبك حول الملفات التي يجب تحليلها والتدفق الذي تريد رسمه، كانت المخرجات أكثر دقة.

في وضع Ask، أدخل الطلب التالي في حقل إدخال الدردشة:

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 سلسلة التفاعل وينتج ترميز مخطط مشابهاً للتالي:

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

توليد مخطط حالة الاستخدام

مخطط حالة الاستخدام يحدد الجهات الفاعلة في النظام والقدرات التي يمكن لكل منها ممارستها. Mermaid لا يمتلك نوع مخطط حالة استخدام أصلياً، لذا تمثله بـ flowchart LR تجمع حالات الاستخدام حسب الجهة الفاعلة.

أنشئ طلباً لتحديد جميع الجهات الفاعلة وحالات استخدامها عبر التطبيق بالكامل. تشمل الجهات الفاعلة أنواع المستخدمين والأنظمة الخارجية. استخدم mentions السياق لتحديد الملفات ذات الصلة لـ Bob للتحليل، بما في ذلك صفحات الواجهة الأمامية ونقاط نهاية REST الخلفية وأدوات MCP. كما وجّه Bob لتهريب الأقواس المجعدة في ترميز Mermaid حتى لا يحاول مُرنِّد Mermaid تفسيرها كبنية قالب.

في وضع Ask، أدخل الطلب التالي في حقل إدخال الدردشة:

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 التطبيق وينتج ترميز مخطط مشابهًا للتالي:

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

حفظ المخططات في المستودع

بدّل Bob إلى وضع Agent واطلب منه حفظ المخططات التي ولّدتها في المستودع. كل مخطط يُحفظ كملف Markdown في مجلد docs/architecture/ جديد.

التبديل إلى وضع Agent

اختر Agent في محدد الوضع، أو اكتب /agent في حقل إدخال الدردشة.

حفظ المخططات الثلاثة

اطلب من Bob إنشاء ملفات توثيق المعمارية.

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 الملفات الثلاثة. انقر على Approve وSave لكل ملف يكتبه Bob.

التحقق من المخرجات

افتح كل ملف في مستكشف الملفات في Bob للتأكد من وجود كتل Mermaid المسيَّجة. لديك هذه الخيارات للتحقق من المخططات:

  • اطلب من Bob عرض معاينة لملف Markdown.

    في حقل إدخال الدردشة، أدخل الطلب التالي:

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

    يُرنِّد Bob ملف Markdown بما فيه مخطط Mermaid في واجهة الدردشة. انقر على المخطط المُرنَّد لفتحه في عرض أكبر.

    يمكنك فعل هذا لكل من الملفات الثلاثة لرؤية جميع المخططات مُرنَّدة.

  • الصق ترميز المخطط في محرر Mermaid المباشر لمعاينة المخطط المُرنَّد.

  • نفّذ commit وارفع التغييرات إلى مستودع GitHub. ثم اعرض الملفات على GitHub لرؤية المخططات المُرنَّدة.

استكشاف الأخطاء وإصلاحها

Bob يُولِّد ترميز Mermaid لا يُترجَم

محلل Mermaid صارم. حتى حرف غير صالح واحد أو كلمة مفتاحية غير مدعومة أو سطر جديد مفقود يمكن أن يتسبب في فشل المخطط بصمت أو رمي خطأ في التحليل. استخدم النهج التالي لتشخيص المشكلة وإصلاحها.

تحديد السطر الفاشل

عندما ينتج Bob خطأ في التحليل، تتضمن المخرجات رقم السطر ومقتطفاً من الكود المُخالف.

إذا لم يُخرج Bob خطأ في المحلل، الصق الترميز في محرر Mermaid المباشر. يُسلِّط المحرر الضوء على السطر المُخالف ويُظهر خطأ المحلل، مما يساعدك على تحديد المشكلة.

يمكنك أيضاً فحص الترميز بصرياً بحثاً عن مشاكل شائعة مثل الأحرف الخاصة غير المُهرَّبة في التسميات، أو المجموعات الفرعية غير المُغلَّقة، أو أخطاء بنوية في الأسهم.

الأعراضالسبب المحتملالإصلاح
خطأ تحليل قرب { أو }أقواس مجعدة غير مُهرَّبة في تسميات عقد flowchart أو classDiagramاستبدل { بـ &#123; و} بـ &#125;، أو أعد صياغة التسمية
خطأ تحليل قرب ( أو )أقواس في معرف عقدةأحِط التسمية بعلامات اقتباس: A["label (note)"]
خطأ غير متوقع end أو subgraphالمجموعة الفرعية غير مُغلَّقةتأكد من أن كل كتلة subgraph لها end مطابق
نوع السهم غير معروفبنية سهم خاطئة لنوع المخطط--> للـ flowchart؛ classDiagram تستخدم --> و..> و--|> إلخ؛ sequenceDiagram تستخدم ->> و-->>
عقدة مُعرَّفة لكن غير مُتصلةالعقدة اليتيمة لا تسبب خطأ لكن يمكن أن تُربك بعض المُرنِّداتاصل العقدة أو احذفها
المخطط يُرنَّد جزئياً ثم يتوقفالتسمية تحتوي على حرف " مجردتهريب علامات الاقتباس داخل التسميات: A["it\'s a label"]

اطلب من Bob إصلاح المشكلة

أعطِ Bob خطأ المحلل والسطر الفاشل. ثم اطلب من Bob إصلاح أسطر محددة.

على سبيل المثال:

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 استهداف إصلاح ضيق دون إعادة توليد المحتوى الذي راجعته بالفعل.

اطلب من Bob التحقق قبل الإخراج

إذا كنت تُعيد توليد مخطط من الصفر، أضف تعليمات تحقق صريحة إلى الطلب:

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.

قلّص النطاق عندما يكون المخطط كبيراً

إذا استمر مخطط بعقد كثيرة في إنتاج ترميز غير صالح، اطلب من Bob توليده في أقسام، مثل نماذج Python أولاً ثم نماذج Java. بعد ذلك، اطلب من Bob تجميع الكتل. التوليدات الأصغر أسهل لـ Bob للتحقق منها وأسهل لك للمقارنة.

الخطوات التالية

في هذا الدرس، استخدمت mentions السياق ووضع Ask لاستكشاف قاعدة كود Galaxium Travels وتوليد ثلاثة أنواع من مخططات المعمارية مع Bob، ثم استخدمت وضع Agent لحفظها في المستودع. تابع مع الموارد التالية:

ما رأيك في هذا الموضوع؟