Visual Paradigm Desktop VP Online

A C4-PlantUML Case Study Aligned with the Bank EA Framework: Architecting Global Hospitality

Using C4-PlantUML with Best Practices from the Bank EA Framework


📝 Introduction

In today’s complex, cloud-native enterprise landscape, architecture documentation must do more than illustrate system structure—it must enable traceability, support governance, and communicate effectively across technical and non-technical stakeholders. Yet too often, architectural diagrams become outdated silos, disconnected from implementation and business strategy.

 

the Bank EA Framework: Architecting Global Hospitality

This case study demonstrates how the C4 model, implemented with C4-PlantUML and aligned with the Bank of England’s Enterprise Architecture Framework, provides a scalable, maintainable approach to documenting a global-scale system: the International Hotel Management System (IHMS). By progressing through four levels of abstraction—from System Context to Code—we illustrate how to:
  • Establish clear system boundaries and stakeholder relationships (Level 1)
  • Define deployable technology containers and integration patterns (Level 2)
  • Decompose critical services into logical components with explicit dependencies (Level 3)
  • Document implementation details only where complexity demands it (Level 4)
Throughout, we embed enterprise architecture best practices: typed metamodel relationships, ownership assignments, governance checkpoints, and traceability to business capabilities. The result is living documentation that evolves with the product, supports architectural review, and accelerates onboarding—without becoming a maintenance burden.
Whether you’re an Enterprise Architect establishing standards, a Solution Architect designing cloud-native platforms, or a Product Manager aligning technical delivery with business outcomes, this guide offers a pragmatic blueprint for architecture documentation that works.

🏨 System Overview

International Hotel Management System (IHMS) is a cloud-native platform that enables global hotel chains to manage reservations, guest experiences, room inventory, pricing, and operations across multiple properties, currencies, and languages.

Key Capabilities:

  • Multi-property, multi-brand hotel management

  • Real-time room availability and dynamic pricing

  • Guest profiles with preferences and loyalty integration

  • Channel management (OTA, direct, corporate bookings)

  • Payment processing with multi-currency support

  • Housekeeping, maintenance, and staff scheduling

  • Analytics and revenue management dashboards


🔹 Level 1: System Context Diagram

Shows the scope of the system and how users and external systems interact with it.

 

 

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml

LAYOUT_WITH_LEGEND()
title System Context Diagram - International Hotel Management System

' === Actors ===
Person(guest, "Hotel Guest", "A traveler booking or staying at a hotel property.")
Person(hotelStaff, "Hotel Staff", "Front desk, housekeeping, or management personnel.")
Person(revenueManager, "Revenue Manager", "Staff responsible for pricing strategy and inventory optimization.")

' === Core System ===
System(ihms, "International Hotel Management System", "Central platform for managing reservations, guest services, inventory, pricing, and operations across global hotel properties.")

' === External Systems ===
System_Ext(ota, "Online Travel Agencies (OTA)", "Expedia, Booking.com, Airbnb - external booking channels.")
System_Ext(paymentGateway, "Payment Gateway", "Stripe, Adyen, PayPal - processes guest payments and refunds.")
System_Ext(emailSystem, "Email & Notification Service", "SendGrid, AWS SES - sends booking confirmations and alerts.")
System_Ext(crm, "Customer Relationship Management", "Salesforce, HubSpot - manages guest loyalty and marketing.")
System_Ext(pms, "Legacy Property Management System", "Existing on-premise PMS at acquired hotel properties.")

' === Relationships ===
Rel(guest, ihms, "Books stays, manages reservations, checks in/out")
Rel(hotelStaff, ihms, "Manages check-ins, room assignments, guest requests")
Rel(revenueManager, ihms, "Sets pricing rules, monitors occupancy, adjusts inventory")

Rel(ihms, ota, "Syncs availability & rates, receives bookings via", "API/XML")
Rel(ihms, paymentGateway, "Processes payments and refunds via", "HTTPS/JSON")
Rel(ihms, emailSystem, "Sends confirmations and alerts via", "SMTP/API")
Rel(ihms, crm, "Syncs guest profiles and loyalty data via", "REST API")
Rel(ihms, pms, "Migrates or syncs property data during transition", "Batch/SOAP")

Rel_Back(guest, ota, "Discovers and books hotels via")
Rel_Back(guest, emailSystem, "Receives booking confirmations from")

@enduml

✅ Enterprise Alignment Tips:

  • Replace generic Person with enterprise role types: Guest, StaffRole, ManagementRole

  • Add Stakeholder relationships compatible with BPMN for process mapping

  • Link ihms to Business Capability: Reservation Management in your EA repository


🔹 Level 2: Container Diagram

Zooms into the IHMS boundary, showing high-level deployable technology components.

 

 

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

LAYOUT_WITH_LEGEND()
title Container Diagram - International Hotel Management System

' === Actors ===
Person(guest, "Hotel Guest", "A traveler booking or staying at a hotel property.")
Person(hotelStaff, "Hotel Staff", "Front desk, housekeeping, or management personnel.")
Person(revenueManager, "Revenue Manager", "Staff responsible for pricing strategy.")

' === External Systems ===
System_Ext(ota, "Online Travel Agencies (OTA)", "Expedia, Booking.com - external booking channels.")
System_Ext(paymentGateway, "Payment Gateway", "Stripe, Adyen - processes payments.")
System_Ext(emailSystem, "Email Service", "SendGrid - sends notifications.")
System_Ext(crm, "CRM System", "Salesforce - guest loyalty and marketing.")

' === System Boundary ===
System_Boundary(ihms, "International Hotel Management System") {
    
    Container(webPortal, "Guest Web Portal", "React/Node.js", "Responsive web app for guests to search, book, and manage stays.")
    Container(mobileApp, "Mobile App", "React Native", "iOS/Android app for booking, digital key, and in-stay services.")
    Container(staffPortal, "Staff Operations Portal", "Vue.js/Spring Boot", "Web interface for front desk, housekeeping, and management.")
    
    Container(apiGateway, "API Gateway", "Kong/Node.js", "Central entry point for all client requests; handles auth, rate limiting, routing.")
    
    Container(bookingService, "Booking Service", "Java/Spring Boot", "Manages reservation lifecycle, availability checks, and booking rules.")
    Container(inventoryService, "Inventory & Pricing Service", "Java/Spring Boot", "Manages room inventory, dynamic pricing, and rate plans.")
    Container(guestService, "Guest Profile Service", "Java/Spring Boot", "Manages guest identities, preferences, and loyalty data.")
    Container(paymentService, "Payment Service", "Java/Spring Boot", "Orchestrates payment processing, refunds, and invoicing.")
    
    ContainerDb(primaryDb, "Primary Database", "PostgreSQL Cluster", "Stores reservations, guest profiles, inventory, and transactions.")
    ContainerDb(cacheDb, "Cache Layer", "Redis Cluster", "Caches availability, pricing, and session data for performance.")
    
    Container(analyticsService, "Analytics & Reporting Service", "Python/Spark", "Generates occupancy reports, revenue forecasts, and KPIs.")
}

' === Guest Interactions ===
Rel(guest, webPortal, "Searches hotels, books stays, manages reservations", "HTTPS")
Rel(guest, mobileApp, "Checks in digitally, requests services, uses digital key", "HTTPS")
Rel(webPortal, apiGateway, "Makes API calls to", "JSON/HTTPS")
Rel(mobileApp, apiGateway, "Makes API calls to", "JSON/HTTPS")

' === Staff Interactions ===
Rel(hotelStaff, staffPortal, "Manages check-ins, room assignments, guest requests", "HTTPS")
Rel(revenueManager, staffPortal, "Adjusts pricing rules, monitors dashboards", "HTTPS")
Rel(staffPortal, apiGateway, "Makes API calls to", "JSON/HTTPS")

' === Internal Service Communication ===
Rel(apiGateway, bookingService, "Routes booking requests to", "gRPC/Protobuf")
Rel(apiGateway, inventoryService, "Routes availability/pricing queries to", "gRPC/Protobuf")
Rel(apiGateway, guestService, "Routes guest profile requests to", "gRPC/Protobuf")
Rel(apiGateway, paymentService, "Routes payment requests to", "gRPC/Protobuf")

Rel(bookingService, inventoryService, "Checks/updates room availability via", "gRPC")
Rel(bookingService, paymentService, "Initiates payment authorization via", "gRPC")
Rel(bookingService, guestService, "Retrieves/updates guest preferences via", "gRPC")

' === Data Persistence ===
Rel(bookingService, primaryDb, "Reads/writes reservations via", "JDBC")
Rel(inventoryService, primaryDb, "Reads/writes inventory/pricing via", "JDBC")
Rel(guestService, primaryDb, "Reads/writes guest profiles via", "JDBC")
Rel(paymentService, primaryDb, "Records transactions via", "JDBC")

Rel(bookingService, cacheDb, "Caches availability data via", "Redis Protocol")
Rel(inventoryService, cacheDb, "Caches pricing rules via", "Redis Protocol")

' === External Integrations ===
Rel(bookingService, ota, "Syncs availability and receives bookings via", "XML/HTTPS")
Rel(paymentService, paymentGateway, "Processes payments via", "REST/JSON")
Rel(bookingService, emailSystem, "Sends booking confirmations via", "SMTP/API")
Rel(guestService, crm, "Syncs guest loyalty data via", "REST API")
Rel(analyticsService, primaryDb, "Reads data for reporting via", "Read Replica JDBC")

@enduml

🔗 Metamodel Integration: Add Deployed on relationships to link containers to Kubernetes clusters, cloud regions, or infrastructure platforms.


🔹 Level 3: Component Diagram

Zooms into the Booking Service container to show its internal logical components.

PlantUML Diagram

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml

LAYOUT_WITH_LEGEND()
title Component Diagram - Booking Service (IHMS)

' === External Dependencies ===
Container(apiGateway, "API Gateway", "Kong/Node.js", "Central entry point for all client requests.")
Container(inventoryService, "Inventory & Pricing Service", "Java/Spring Boot", "Manages room inventory and dynamic pricing.")
Container(guestService, "Guest Profile Service", "Java/Spring Boot", "Manages guest identities and preferences.")
Container(paymentService, "Payment Service", "Java/Spring Boot", "Orchestrates payment processing.")
ContainerDb(primaryDb, "Primary Database", "PostgreSQL Cluster", "Stores reservations and transactional data.")

' === Booking Service Boundary ===
Container_Boundary(bookingSvc, "Booking Service") {
    
    Component(bookingController, "Booking Controller", "Spring MVC RestController", "Handles HTTP/gRPC requests for reservation CRUD operations.")
    Component(validationComponent, "Booking Validation Engine", "Spring Bean", "Validates booking rules: dates, rates, guest eligibility, channel policies.")
    Component(pricingComponent, "Pricing Calculator", "Spring Bean", "Computes final price including taxes, fees, discounts, and loyalty benefits.")
    Component(availabilityChecker, "Availability Checker", "Spring Bean", "Coordinates with Inventory Service to verify room availability.")
    Component(notificationComponent, "Notification Orchestrator", "Spring Bean", "Triggers confirmation emails, SMS, and CRM updates post-booking.")
    
    Component(reservationRepository, "Reservation Repository", "Spring Data JPA", "Data access layer for reservation entities.")
    Component(bookingEventPublisher, "Booking Event Publisher", "Spring Cloud Stream", "Publishes domain events: BookingCreated, BookingModified, BookingCancelled.")
}

' === Inbound Requests ===
Rel(apiGateway, bookingController, "Forwards booking requests to", "gRPC/Protobuf")

' === Controller to Internal Components ===
Rel(bookingController, validationComponent, "Validates booking request via")
Rel(bookingController, pricingComponent, "Calculates final price via")
Rel(bookingController, availabilityChecker, "Checks room availability via")

' === Component Collaborations ===
Rel(validationComponent, guestService, "Verifies guest status and loyalty tier via", "gRPC")
Rel(pricingComponent, inventoryService, "Fetches applicable rate plans via", "gRPC")
Rel(availabilityChecker, inventoryService, "Checks real-time room availability via", "gRPC")

Rel(bookingController, reservationRepository, "Persists reservation via", "JDBC")
Rel(reservationRepository, primaryDb, "Reads/writes to", "PostgreSQL Protocol")

' === Post-Booking Actions ===
Rel(bookingController, paymentService, "Initiates payment authorization via", "gRPC")
Rel(bookingController, notificationComponent, "Triggers guest notifications via")
Rel(notificationComponent, apiGateway, "Sends confirmation events to", "Async Events")

' === Event Publishing ===
Rel(bookingEventPublisher, primaryDb, "Reads reservation changes via", "CDC/Debezium")
Rel(bookingEventPublisher, apiGateway, "Publishes domain events to", "Kafka/gRPC")

@enduml

🛡 Governance Tip: Component diagrams should be owned by Tech Leads and updated during sprint planning or when modifying service boundaries.


🔹 Level 4: Code / Class Diagram

Shows the implementation structure of the BookingController with interfaces, dependencies, and domain models.

 

@startuml
title Code Diagram - BookingController Dependencies (IHMS)

' === Interfaces ===
interface IBookingController {
  +createBooking(request: BookingRequest): BookingResponse
  +getBooking(bookingId: String): BookingDetails
  +modifyBooking(bookingId: String, changes: BookingChanges): BookingResponse
  +cancelBooking(bookingId: String, reason: String): CancellationResponse
}

interface IBookingValidator {
  +validateDates(checkIn: LocalDate, checkOut: LocalDate): ValidationResult
  +validateGuestEligibility(guestId: String, ratePlanId: String): ValidationResult
  +validateChannelPolicy(channel: BookingChannel, request: BookingRequest): ValidationResult
}

interface IPricingCalculator {
  +calculateTotal(roomRate: BigDecimal, nights: int, guestTier: LoyaltyTier, promoCode: String): PriceBreakdown
}

interface IAvailabilityService {
  +checkAvailability(propertyId: String, roomType: String, dates: DateRange): AvailabilityResult
  +reserveInventory(reservationId: String, items: List<InventoryItem>): Boolean
}

' === Core Classes ===
class BookingController {
  -validator: IBookingValidator
  -pricingCalculator: IPricingCalculator
  -availabilityService: IAvailabilityService
  -reservationRepo: IReservationRepository
  -eventPublisher: IBookingEventPublisher
  -logger: ILogger
  
  +createBooking(request: BookingRequest): BookingResponse
  +getBooking(bookingId: String): BookingDetails
  +modifyBooking(bookingId: String, changes: BookingChanges): BookingResponse
  +cancelBooking(bookingId: String, reason: String): CancellationResponse
  -validateAndPrice(request: BookingRequest): PricedBooking
}

class BookingRequest {
  +propertyId: String
  +roomTypeId: String
  +checkInDate: LocalDate
  +checkOutDate: LocalDate
  +guestId: String
  +channel: BookingChannel
  +promoCode: String
  +paymentMethod: PaymentToken
}

class BookingResponse {
  +bookingId: String
  +confirmationNumber: String
  +totalPrice: BigDecimal
  +currency: Currency
  +status: BookingStatus
  +checkInInstructions: String
}

class Reservation {
  +id: String
  +propertyId: String
  +roomId: String
  +guestId: String
  +checkIn: LocalDateTime
  +checkOut: LocalDateTime
  +totalAmount: BigDecimal
  +currency: Currency
  +status: ReservationStatus
  +createdAt: Instant
  +modifiedAt: Instant
}

' === Supporting Classes ===
class PriceBreakdown {
  +baseRate: BigDecimal
  +taxes: BigDecimal
  +fees: BigDecimal
  +discounts: BigDecimal
  +loyaltyPointsEarned: int
  +finalTotal: BigDecimal
}

class AvailabilityResult {
  +isAvailable: boolean
  +availableRooms: int
  +alternativeDates: List<DateRange>
  +ratePlanId: String
}

' === Relationships ===
IBookingController <|-- BookingController

BookingController --> IBookingValidator : uses
BookingController --> IPricingCalculator : uses
BookingController --> IAvailabilityService : uses
BookingController --> IReservationRepository : persists
BookingController --> IBookingEventPublisher : publishes

BookingController ..> BookingRequest : accepts
BookingController ..> BookingResponse : returns
BookingController ..> Reservation : maps to

IPricingCalculator ..> PriceBreakdown : returns
IAvailabilityService ..> AvailabilityResult : returns

note right of BookingController
  Thread-safe, stateless controller
  Uses dependency injection (Spring)
  Validates input before business logic
  Publishes domain events after commit
end note

@enduml

⚠️ Best Practice: Level 4 diagrams should only be created for complex, critical, or frequently changed components. Avoid over-diagramming to reduce maintenance overhead.


🎨 Optional: Styling & Theming Example

Customize your C4 diagrams with a professional light theme:

!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!define FONTAWESOME https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/font-awesome-5

!include DEVICONS/react.puml
!include DEVICONS/java.puml
!include FONTAWESOME/hotel.puml
!include FONTAWESOME/database.puml

SkinParam backgroundColor #FFFFFF
SkinParam shadowing false
SkinParam defaultFontSize 13
SkinParam defaultFontName "Segoe UI"

' Professional color palette
!define PRIMARY #2563EB        ' Blue
!define SECONDARY #7C3AED      ' Purple
!define SUCCESS #10B981        ' Green
!define WARNING #F59E0B        ' Amber
!define DANGER #EF4444         ' Red

' Apply semantic colors
skinparam rectangle {
  BackgroundColor<<Person>> #FEF3C7
  BackgroundColor<<System>> #DBEAFE
  BackgroundColor<<Container>> #D1FAE5
  BackgroundColor<<Component>> #EDE9FE
  BorderColor<<External>> #9CA3AF
  BorderThickness<<External>> 2
}

' Relationship styling
skinparam arrow {
  Color #6B7280
  Thickness 1.5
}

✅ Implementation Checklist for Enterprise Adoption

Area Action Item Owner
Metamodel Embed C4 elements into EA repository with typed relationships (Uses, Deployed on, Is part of) Enterprise Architect
Governance Require Self-Explanatory Diagram Checklist for all Architecture Review Board submissions Architecture Governance
Ownership Assign layer owners: L1 (Business Arch), L2 (Solution Arch), L3 (Tech Lead), L4 (Senior Dev) Delivery Leadership
Tooling Standardize on C4-PlantUML + version control (Git) for diagram-as-code Platform Engineering
Traceability Link C4 elements to business capabilities, value streams, and epics in Jira/ADO Product Management
Maintenance Schedule quarterly diagram audits; tie updates to sprint retrospectives Engineering Managers

🏁 Conclusion

The International Hotel Management System case study illustrates that rigorous architecture documentation and agile delivery are not opposing forces—they are mutually reinforcing when grounded in the right framework. By adopting the C4 model with PlantUML and embedding it within an enterprise metamodel inspired by the Bank of England EA Framework, organizations can achieve:
✅ Clarity at every level: Stakeholders engage with the abstraction that matters to them, from executives reviewing system context to developers implementing domain logic.
✅ Traceability by design: Typed relationships (Uses, Deployed on, Is part of)  link diagrams to business capabilities, value streams, and delivery epics.
✅ Maintainability through discipline: Limiting Level 4 diagrams to critical components, assigning layer ownership, and scheduling quarterly audits prevent documentation drift.
✅ Governance without bureaucracy: Self-explanatory checklists and ARB integration ensure diagrams support decision-making, not just compliance.
Critically, this approach treats architecture documentation as code: version-controlled, peer-reviewed, and updated incrementally alongside feature development. The result is not a static artifact, but a living knowledge base that scales with your system and your team.
As cloud-native systems grow in complexity and regulatory expectations rise, the ability to communicate architecture clearly, consistently, and credibly becomes a strategic advantage. Start with Level 1 and 2 diagrams during solution design. Add Level 3 for complex services during sprint 0. Reserve Level 4 for onboarding or high-risk components. And always anchor your diagrams to business outcomes.
In the words of Simon Field’s Bank of England case study: “The C4 model isn’t just a diagramming technique—it’s the glue between enterprise strategy and software delivery.” For global platforms like IHMS, that glue is what turns architectural vision into operational reality.

💡 Final Thought: Great architecture documentation doesn’t describe what was built—it enables what comes next. Keep it lean, keep it linked, and keep it living.

📚 References & Resources

  1. C4 Model Official Site
  2. PlantUML Live Editor
  3. C4-PlantUML Studio | AI-Powered C4 Diagram Generator (matches “AI-Powered C4 PlantUML Studio (C4-PlantUML Studio)” and “AI-Powered C4 Diagram Generator”)
  4. AI-Powered C4 Diagram Generator | Create Architecture Diagrams from Text (related AI tool entry point)
  5. C4 Component Diagram: A Definitive Guide to Your Code’s Internal Structure with AI (linked in multiple guide pages, e.g., from C4 System Context Guide)
  6. C4 Container Diagram: A Definitive Guide to Visualizing Your Software’s Building Blocks with AI (linked in multiple guide pages, e.g., from C4 System Context Guide)
  7. C4 Deployment Diagram (direct AI tool page for generating C4 Deployment Diagrams)
  8. C4 System Context Diagram: A Definitive Guide to Seeing the Big Picture with AI
  9. Generate the Complete C4 Model Instantly with Visual Paradigm’s AI Diagram Generator (featured in product updates, e.g., Visual Paradigm Desktop Updates)
  10. Streamline C4 Diagrams with Our New AI-Powered Markdown Editor (no exact matching page found; may be an older or internal feature reference)
  11. The Ultimate AI C4 Diagram Tool & Modeling Software
  12. New: Full C4 Model Support Added to Visual Paradigm Desktop (announced in AI Diagram Generator Release)
  13. C4 Diagram Tool & Modeling Software (core landing page for C4 tools)

💡 Pro Tip: Start with Level 1 and 2 diagrams during solution design. Add Level 3 during sprint 0 for complex services. Use Level 4 only for onboarding docs or critical component deep-dives.

This case study demonstrates how the C4 model—when embedded in an enterprise metamodel—creates traceable, maintainable, and stakeholder-aligned architecture documentation for complex global systems.

Turn every software project into a successful one.

We use cookies to offer you a better experience. By visiting our website, you agree to the use of cookies as described in our Cookie Policy.

OK