Skip to content

Examples

Same portable model, backend defaults

These examples use the same portable C4 core elements for each diagram type and intentionally avoid backend-specific styling or layout hints. They show how the same model is rendered by each backend's defaults.

System context diagram

Python diagram
from c4 import (
    EnterpriseBoundary,
    Person,
    Rel,
    System,
    SystemContextDiagram,
    SystemExt,
)


with SystemContextDiagram(title='Retail Platform - System Context') as diagram:
    customer = Person(
        'Customer',
        'Browses products and places orders.',
        alias='customer',
    )
    support_agent = Person(
        'Support Agent',
        'Helps customers with order questions.',
        alias='support_agent',
    )
    payment_provider = SystemExt(
        'Payment Provider',
        'Processes card payments.',
        alias='payment_provider',
    )

    with EnterpriseBoundary(
        'Acme Retail',
        'Systems owned by Acme Retail.',
        alias='acme_retail',
    ):
        retail_platform = System(
            'Retail Platform',
            'Handles catalog browsing, checkout, and order management.',
            alias='retail_platform',
        )
        support_portal = System(
            'Support Portal',
            'Provides order lookup and customer support workflows.',
            alias='support_portal',
        )

    customer >> Rel('Places orders using', technology='HTTPS') >> retail_platform
    support_agent >> Rel('Investigates orders in', technology='HTTPS') >> support_portal
    support_portal >> Rel('Reads order data from', technology='HTTPS') >> retail_platform
    retail_platform >> Rel('Requests payments from', technology='HTTPS') >> payment_provider

PlantUML system context example
PlantUML system context diagram

Mermaid system context example
Mermaid system context diagram

D2 system context example
D2 system context diagram

System landscape diagram

Python diagram
from c4 import (
    EnterpriseBoundary,
    Person,
    Rel,
    System,
    SystemExt,
    SystemLandscapeDiagram,
)


with SystemLandscapeDiagram(title='Acme Retail - System Landscape') as diagram:
    customer = Person(
        'Customer',
        'Places orders through digital channels.',
        alias='customer',
    )
    support_agent = Person(
        'Support Agent',
        'Supports customers after purchase.',
        alias='support_agent',
    )
    payment_provider = SystemExt(
        'Payment Provider',
        'Processes card payments.',
        alias='payment_provider',
    )
    warehouse_system = SystemExt(
        'Warehouse System',
        'Reserves stock and coordinates fulfillment.',
        alias='warehouse_system',
    )

    with EnterpriseBoundary(
        'Acme Retail',
        'Internal systems owned by Acme Retail.',
        alias='acme_retail',
    ):
        retail_platform = System(
            'Retail Platform',
            'Supports browsing, checkout, and order management.',
            alias='retail_platform',
        )
        support_portal = System(
            'Support Portal',
            'Helps support teams investigate customer orders.',
            alias='support_portal',
        )
        reporting_platform = System(
            'Reporting Platform',
            'Provides operational and sales reporting.',
            alias='reporting_platform',
        )

    customer >> Rel('Places orders through', technology='HTTPS') >> retail_platform
    support_agent >> Rel('Uses', technology='HTTPS') >> support_portal
    support_portal >> Rel('Reads order data from', technology='HTTPS') >> retail_platform
    retail_platform >> Rel('Requests payments from', technology='HTTPS') >> payment_provider
    retail_platform >> Rel('Sends fulfillment requests to', technology='HTTPS') >> warehouse_system
    retail_platform >> Rel('Publishes order facts to', technology='Kafka') >> reporting_platform

PlantUML system landscape example
PlantUML system landscape diagram

Mermaid system landscape example
Mermaid system landscape diagram

D2 system landscape example
D2 system landscape diagram

Container diagram

Python diagram
from c4 import (
    Container,
    ContainerDb,
    ContainerDiagram,
    ContainerQueue,
    Person,
    Rel,
    SystemBoundary,
    SystemExt,
)


with ContainerDiagram(title='Retail Platform - Containers') as diagram:
    customer = Person(
        'Customer',
        'Browses products and places orders.',
        alias='customer',
    )
    payment_provider = SystemExt(
        'Payment Provider',
        'Processes card payments.',
        alias='payment_provider',
    )

    with SystemBoundary(
        'Retail Platform',
        'Customer-facing commerce platform.',
        alias='retail_platform',
    ):
        web_app = Container(
            'Web Application',
            'Serves storefront and checkout screens.',
            technology='React',
            alias='web_app',
        )
        api = Container(
            'Backend API',
            'Handles catalog, cart, checkout, and order APIs.',
            technology='Python / FastAPI',
            alias='api',
        )
        database = ContainerDb(
            'Orders Database',
            'Stores orders, payments, and fulfillment status.',
            technology='PostgreSQL',
            alias='database',
        )
        events = ContainerQueue(
            'Order Events',
            'Publishes order lifecycle events.',
            technology='Kafka',
            alias='events',
        )

    customer >> Rel('Uses', technology='HTTPS') >> web_app
    web_app >> Rel('Calls', technology='HTTPS/JSON') >> api
    api >> Rel('Reads and writes', technology='SQL') >> database
    api >> Rel('Publishes events to', technology='Kafka') >> events
    api >> Rel('Creates payment intents with', technology='HTTPS') >> payment_provider

PlantUML container example
PlantUML container diagram

Mermaid container example
Mermaid container diagram

D2 container example
D2 container diagram

Component diagram

Python diagram
from c4 import (
    Component,
    ComponentDb,
    ComponentDiagram,
    ComponentQueue,
    Container,
    ContainerBoundary,
    Rel,
    SystemExt,
)


with ComponentDiagram(title='Checkout API - Components') as diagram:
    web_app = Container(
        'Web Application',
        'Starts checkout from the storefront.',
        technology='React',
        alias='web_app',
    )
    payment_provider = SystemExt(
        'Payment Provider',
        'Authorizes and captures card payments.',
        alias='payment_provider',
    )

    with ContainerBoundary(
        'Checkout API',
        'Components that coordinate checkout.',
        alias='checkout_api',
    ):
        controller = Component(
            'Checkout Controller',
            'Receives checkout requests.',
            technology='FastAPI',
            alias='controller',
        )
        checkout_service = Component(
            'Checkout Service',
            'Validates carts and creates orders.',
            technology='Python',
            alias='checkout_service',
        )
        payment_adapter = Component(
            'Payment Adapter',
            'Wraps payment provider calls.',
            technology='Python',
            alias='payment_adapter',
        )
        order_store = ComponentDb(
            'Order Store',
            'Persists checkout and order records.',
            technology='PostgreSQL',
            alias='order_store',
        )
        event_publisher = ComponentQueue(
            'Event Publisher',
            'Publishes order-created events.',
            technology='Kafka',
            alias='event_publisher',
        )

    web_app >> Rel('Submits checkout to', technology='HTTPS/JSON') >> controller
    controller >> Rel('Delegates to', technology='Python call') >> checkout_service
    checkout_service >> Rel('Authorizes payment through', technology='Python call') >> payment_adapter
    payment_adapter >> Rel('Calls', technology='HTTPS/JSON') >> payment_provider
    checkout_service >> Rel('Stores order in', technology='SQL') >> order_store
    checkout_service >> Rel('Publishes event with', technology='Kafka') >> event_publisher

PlantUML component example
PlantUML component diagram

Mermaid component example
Mermaid component diagram

D2 component example
D2 component diagram

Dynamic diagram

Python diagram
from c4 import (
    DynamicDiagram,
    Person,
    Rel,
    System,
    SystemExt,
)


with DynamicDiagram(title='Checkout Flow') as diagram:
    customer = Person(
        'Customer',
        'Places an order in the online store.',
        alias='customer',
    )
    retail_platform = System(
        'Retail Platform',
        'Coordinates checkout and order processing.',
        alias='retail_platform',
    )
    payment_provider = SystemExt(
        'Payment Provider',
        'Authorizes card payments.',
        alias='payment_provider',
    )
    warehouse_system = SystemExt(
        'Warehouse System',
        'Reserves stock and starts fulfillment.',
        alias='warehouse_system',
    )

    customer >> Rel('Submits checkout', technology='HTTPS') >> retail_platform
    retail_platform >> Rel('Authorizes payment', technology='HTTPS') >> payment_provider
    retail_platform >> Rel('Reserves stock', technology='HTTPS') >> warehouse_system
    retail_platform >> Rel('Confirms order', technology='HTTPS') >> customer

PlantUML dynamic example
PlantUML dynamic diagram

Mermaid dynamic example
Mermaid dynamic diagram

D2 dynamic example
D2 dynamic diagram

Deployment diagram

Python diagram
from c4 import (
    Container,
    ContainerDb,
    DeploymentDiagram,
    DeploymentNode,
    Node,
    Person,
    Rel,
    SystemExt,
)


with DeploymentDiagram(title='Retail Platform - Deployment') as diagram:
    customer = Person(
        'Customer',
        'Uses the online shop through a browser.',
        alias='customer',
    )
    payment_provider = SystemExt(
        'Payment Provider',
        'External service that processes payments.',
        alias='payment_provider',
    )

    with Node(
        'Production Environment',
        'Cloud-hosted production runtime.',
        alias='production',
    ):
        with DeploymentNode(
            'Edge',
            'Public entrypoint for web traffic.',
            alias='edge',
        ):
            web_app = Container(
                'Web Application',
                'Serves the storefront UI.',
                technology='Next.js',
                alias='web_app',
            )

        with DeploymentNode(
            'Application Runtime',
            'Runs backend services.',
            alias='runtime',
        ):
            api = Container(
                'Backend API',
                'Handles catalog, checkout, and orders.',
                technology='Python / FastAPI',
                alias='api',
            )

        with DeploymentNode(
            'Managed Database',
            'Managed relational database service.',
            alias='database_node',
        ):
            database = ContainerDb(
                'Orders Database',
                'Stores orders and payment state.',
                technology='PostgreSQL',
                alias='database',
            )

    customer >> Rel('Uses', technology='HTTPS') >> web_app
    web_app >> Rel('Calls', technology='HTTPS/JSON') >> api
    api >> Rel('Reads and writes', technology='SQL') >> database
    api >> Rel('Requests payment authorization from', technology='HTTPS') >> payment_provider

PlantUML deployment example
PlantUML deployment diagram

Mermaid deployment example
Mermaid deployment diagram

D2 deployment example
D2 deployment diagram

Same model, backend-tuned outputs

These examples keep the same C4 elements and relationships, then apply backend-specific rendering options to make each output easier to read.

Customer support system component view

This compact view focuses on the main customer, expert, ticketing, notification, queue, and database flow.

PlantUML tuned customer support component example
PlantUML tuned customer support component diagram

Python diagram
from c4 import (
    Component,
    ComponentDb,
    ComponentDiagram,
    ComponentExt,
    ComponentQueue,
    ContainerBoundary,
    Person,
    Rel,
)
from c4.contrib.plantuml import (
    LayD,
    LayL,
    RelL,
)
from c4.renderers import (
    PlantUMLRenderOptionsBuilder,
)


with ComponentDiagram(title='Customer Support System - Tuned Component View') as diagram:
    customer = Person(
        'Customer',
        'Reports equipment issues and tracks repair progress.',
        plantuml={'tags': ['User']},
        alias='customer',
    )
    expert = Person(
        'Support Expert',
        'Accepts assignments and records repair updates.',
        plantuml={'tags': ['User']},
        alias='expert',
    )

    auth0 = ComponentExt(
        'Auth0',
        'External identity provider.',
        plantuml={'tags': ['External']},
        technology='OIDC/OAuth2',
        alias='auth0',
    )
    email_system = ComponentExt(
        'E-mail System',
        'Delivers customer and expert notifications.',
        plantuml={'tags': ['External']},
        technology='SMTP',
        alias='email_system',
    )

    with ContainerBoundary(
        'Customer Support System',
        'Components that handle support tickets and expert assignments.',
        plantuml={'tags': ['Boundary']},
        alias='sysops_system',
    ) as sysops_system:
        customer_portal = Component(
            'Customer Portal',
            'Ticket creation and status tracking.',
            plantuml={'tags': ['Frontend']},
            technology='SPA',
            alias='customer_portal',
        )
        mobile_app = Component(
            'Expert Mobile App',
            'Assignment queue and field repair updates.',
            plantuml={'tags': ['Frontend']},
            technology='iOS / Android',
            alias='mobile_app',
        )
        api_gateway = Component(
            'API Gateway',
            'Access control and request routing.',
            plantuml={'tags': ['Gateway']},
            technology='Container Service',
            alias='api_gateway',
        )
        ticket_api = Component(
            'Ticket API',
            'Ticket orchestration, search, and assignment updates.',
            plantuml={'tags': ['Backend']},
            technology='Container Service',
            alias='ticket_api',
        )
        notification_service = Component(
            'Notification Service',
            'Sends customer and expert notifications.',
            plantuml={'tags': ['Backend']},
            technology='Container Service',
            alias='notification_service',
        )
        ticket_processor = Component(
            'Ticket Processor',
            'Creates expert assignments for new tickets.',
            plantuml={'tags': ['Worker']},
            technology='Container Job',
            alias='ticket_processor',
        )
        sysops_database = ComponentDb(
            'Support Database',
            'Tickets, contacts, assignments, and repair history.',
            plantuml={'tags': ['Database']},
            technology='PostgreSQL',
            alias='sysops_database',
        )
        ticket_created_queue = ComponentQueue(
            'Ticket Created',
            'Event stream for new support tickets.',
            plantuml={'tags': ['Queue']},
            technology='Message Queue',
            alias='ticket_created_queue',
        )

    customer >> Rel('Uses', technology='HTTPS', plantuml={'tags': ['Sync']}) >> customer_portal
    expert >> Rel('Uses', technology='HTTPS', plantuml={'tags': ['Sync']}) >> mobile_app

    customer_portal >> Rel('Authenticates', technology='OIDC', plantuml={'tags': ['ExternalCall']}) >> auth0
    mobile_app >> Rel('Authenticates', technology='OIDC', plantuml={'tags': ['ExternalCall']}) >> auth0

    customer_portal >> Rel('Calls', technology='REST/HTTPS', plantuml={'tags': ['Sync']}) >> api_gateway
    mobile_app >> Rel('Calls', technology='REST/HTTPS', plantuml={'tags': ['Sync']}) >> api_gateway
    api_gateway >> Rel('Routes', technology='REST/HTTP', plantuml={'tags': ['Sync']}) >> ticket_api

    ticket_api >> Rel('Reads/writes', technology='SQL/TCP', plantuml={'tags': ['DataAccess']}) >> sysops_database
    ticket_processor >> Rel('Reads/writes', technology='SQL/TCP', plantuml={'tags': ['DataAccess']}) >> sysops_database
    ticket_api >> RelL('Publishes', technology='Queue/Event', plantuml={'tags': ['Async']}) >> ticket_created_queue
    ticket_created_queue >> Rel('Triggers', technology='Queue/Event', plantuml={'tags': ['Async']}) >> ticket_processor
    ticket_processor >> RelL('Requests notification', technology='REST/HTTP', plantuml={'tags': ['Sync']}) >> notification_service
    notification_service >> Rel('Sends e-mail', technology='SMTP', plantuml={'tags': ['ExternalCall']}) >> email_system

    LayD(customer, customer_portal)
    LayD(expert, mobile_app)
    LayL(customer_portal, mobile_app)
    LayL(notification_service, email_system)
    LayL(sysops_system, email_system)


plantuml_render_options = (
    PlantUMLRenderOptionsBuilder()
    .layout_top_down(with_legend=True)
    .show_legend(hide_stereotype=False, details='Normal')
    .update_legend_title('Customer Support Component Legend')
    .add_person_tag(
        tag_stereo='User',
        bg_color='#e8f5e9',
        font_color='#1b5e20',
        border_color='#66bb6a',
        shadowing=False,
        legend_text='Operational user',
        legend_sprite='user',
    )
    .add_component_tag(
        tag_stereo='Frontend',
        bg_color='#e3f2fd',
        font_color='#0d47a1',
        border_color='#42a5f5',
        shadowing=True,
        technology='UI',
        legend_text='User-facing frontend',
        legend_sprite='browser',
        border_style='SolidLine',
        border_thickness='2',
    )
    .add_component_tag(
        tag_stereo='Gateway',
        bg_color='#fce4ec',
        font_color='#880e4f',
        border_color='#ec407a',
        shadowing=True,
        technology='Gateway',
        legend_text='API gateway',
        legend_sprite='server',
        border_style='BoldLine',
        border_thickness='2',
    )
    .add_component_tag(
        tag_stereo='Backend',
        bg_color='#ede7f6',
        font_color='#311b92',
        border_color='#7e57c2',
        shadowing=True,
        technology='Service',
        legend_text='Backend service',
        legend_sprite='server',
        border_style='SolidLine',
        border_thickness='2',
    )
    .add_component_tag(
        tag_stereo='Worker',
        bg_color='#fff3e0',
        font_color='#e65100',
        border_color='#fb8c00',
        shadowing=True,
        technology='Job',
        legend_text='Background worker',
        legend_sprite='server',
        border_style='SolidLine',
        border_thickness='2',
    )
    .add_component_tag(
        tag_stereo='Database',
        bg_color='#fff8e1',
        font_color='#5d4037',
        border_color='#ffb300',
        shadowing=False,
        technology='Database',
        legend_text='Operational datastore',
        legend_sprite='database',
    )
    .add_component_tag(
        tag_stereo='Queue',
        bg_color='#e0f2f1',
        font_color='#004d40',
        border_color='#26a69a',
        shadowing=False,
        technology='Queue',
        legend_text='Asynchronous event stream',
        legend_sprite='queue',
    )
    .add_external_component_tag(
        tag_stereo='External',
        bg_color='#f5f5f5',
        font_color='#424242',
        border_color='#9e9e9e',
        shadowing=False,
        technology='External',
        legend_text='External dependency',
        legend_sprite='cloud',
        border_style='DashedLine',
    )
    .add_boundary_tag(
        tag_stereo='Boundary',
        bg_color='#fafafa',
        font_color='#424242',
        border_color='#9e9e9e',
        shadowing=False,
        legend_text='System boundary',
    )
    .add_rel_tag(
        tag_stereo='Sync',
        text_color='#1565c0',
        line_color='#1e88e5',
        line_style='SolidLine',
        technology='HTTPS',
        legend_text='Synchronous request',
    )
    .add_rel_tag(
        tag_stereo='DataAccess',
        text_color='#6d4c41',
        line_color='#8d6e63',
        line_style='DashedLine',
        technology='SQL',
        legend_text='Database access',
    )
    .add_rel_tag(
        tag_stereo='Async',
        text_color='#00695c',
        line_color='#00897b',
        line_style='DottedLine',
        line_thickness='2',
        technology='Queue/Event',
        legend_text='Asynchronous event flow',
        legend_sprite='queue',
    )
    .add_rel_tag(
        tag_stereo='ExternalCall',
        text_color='#455a64',
        line_color='#78909c',
        line_style='DashedLine',
        technology='External',
        legend_text='External integration',
    )
    .update_element_style(
        element_name='component',
        shape='RoundedBoxShape',
        border_style='SolidLine',
    )
    .build()
)

diagram.set_render_options(
    plantuml=plantuml_render_options,
)
Rendered PlantUML source
@startuml
' convert it with additional command line argument -DRELATIVE_INCLUDE="relative/absolute" to use locally
!if %variable_exists("RELATIVE_INCLUDE")
    !include %get_variable_value("RELATIVE_INCLUDE")/C4_Component.puml
!else
    !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml
!endif

AddPersonTag("User", $bgColor="#e8f5e9", $fontColor="#1b5e20", $borderColor="#66bb6a", $shadowing="false", $legendText="Operational user", $legendSprite="user")
AddComponentTag("Frontend", $bgColor="#e3f2fd", $fontColor="#0d47a1", $borderColor="#42a5f5", $shadowing="true", $techn="UI", $legendText="User-facing frontend", $legendSprite="browser", $borderStyle=SolidLine(), $borderThickness="2")
AddComponentTag("Gateway", $bgColor="#fce4ec", $fontColor="#880e4f", $borderColor="#ec407a", $shadowing="true", $techn="Gateway", $legendText="API gateway", $legendSprite="server", $borderStyle=BoldLine(), $borderThickness="2")
AddComponentTag("Backend", $bgColor="#ede7f6", $fontColor="#311b92", $borderColor="#7e57c2", $shadowing="true", $techn="Service", $legendText="Backend service", $legendSprite="server", $borderStyle=SolidLine(), $borderThickness="2")
AddComponentTag("Worker", $bgColor="#fff3e0", $fontColor="#e65100", $borderColor="#fb8c00", $shadowing="true", $techn="Job", $legendText="Background worker", $legendSprite="server", $borderStyle=SolidLine(), $borderThickness="2")
AddComponentTag("Database", $bgColor="#fff8e1", $fontColor="#5d4037", $borderColor="#ffb300", $shadowing="false", $techn="Database", $legendText="Operational datastore", $legendSprite="database")
AddComponentTag("Queue", $bgColor="#e0f2f1", $fontColor="#004d40", $borderColor="#26a69a", $shadowing="false", $techn="Queue", $legendText="Asynchronous event stream", $legendSprite="queue")
AddExternalComponentTag("External", $bgColor="#f5f5f5", $fontColor="#424242", $borderColor="#9e9e9e", $shadowing="false", $techn="External", $legendText="External dependency", $legendSprite="cloud", $borderStyle=DashedLine())
AddBoundaryTag("Boundary", $bgColor="#fafafa", $fontColor="#424242", $borderColor="#9e9e9e", $shadowing="false", $legendText="System boundary")
AddRelTag("Sync", $textColor="#1565c0", $lineColor="#1e88e5", $lineStyle=SolidLine(), $techn="HTTPS", $legendText="Synchronous request")
AddRelTag("DataAccess", $textColor="#6d4c41", $lineColor="#8d6e63", $lineStyle=DashedLine(), $techn="SQL", $legendText="Database access")
AddRelTag("Async", $textColor="#00695c", $lineColor="#00897b", $lineStyle=DottedLine(), $techn="Queue/Event", $legendText="Asynchronous event flow", $legendSprite="queue", $lineThickness="2")
AddRelTag("ExternalCall", $textColor="#455a64", $lineColor="#78909c", $lineStyle=DashedLine(), $techn="External", $legendText="External integration")

UpdateElementStyle("component", $shape=RoundedBoxShape(), $borderStyle=SolidLine())

LAYOUT_TOP_DOWN()
LAYOUT_WITH_LEGEND()
UpdateLegendTitle("Customer Support Component Legend")

title Customer Support System - Tuned Component View

Person(customer, "Customer", "Reports equipment issues and tracks repair progress.", $tags="User")

Person(expert, "Support Expert", "Accepts assignments and records repair updates.", $tags="User")

Component_Ext(auth0, "Auth0", "OIDC/OAuth2", "External identity provider.", $tags="External")

Component_Ext(email_system, "E-mail System", "SMTP", "Delivers customer and expert notifications.", $tags="External")

Container_Boundary(sysops_system, "Customer Support System", $tags="Boundary", $descr="Components that handle support tickets and expert assignments.") {
    Component(customer_portal, "Customer Portal", "SPA", "Ticket creation and status tracking.", $tags="Frontend")
    Component(mobile_app, "Expert Mobile App", "iOS / Android", "Assignment queue and field repair updates.", $tags="Frontend")
    Component(api_gateway, "API Gateway", "Container Service", "Access control and request routing.", $tags="Gateway")
    Component(ticket_api, "Ticket API", "Container Service", "Ticket orchestration, search, and assignment updates.", $tags="Backend")
    Component(notification_service, "Notification Service", "Container Service", "Sends customer and expert notifications.", $tags="Backend")
    Component(ticket_processor, "Ticket Processor", "Container Job", "Creates expert assignments for new tickets.", $tags="Worker")
    ComponentDb(sysops_database, "Support Database", "PostgreSQL", "Tickets, contacts, assignments, and repair history.", $tags="Database")
    ComponentQueue(ticket_created_queue, "Ticket Created", "Message Queue", "Event stream for new support tickets.", $tags="Queue")
}

Rel(customer, customer_portal, "Uses", "HTTPS", $tags="Sync")
Rel(expert, mobile_app, "Uses", "HTTPS", $tags="Sync")
Rel(customer_portal, auth0, "Authenticates", "OIDC", $tags="ExternalCall")
Rel(mobile_app, auth0, "Authenticates", "OIDC", $tags="ExternalCall")
Rel(customer_portal, api_gateway, "Calls", "REST/HTTPS", $tags="Sync")
Rel(mobile_app, api_gateway, "Calls", "REST/HTTPS", $tags="Sync")
Rel(api_gateway, ticket_api, "Routes", "REST/HTTP", $tags="Sync")
Rel(ticket_api, sysops_database, "Reads/writes", "SQL/TCP", $tags="DataAccess")
Rel(ticket_processor, sysops_database, "Reads/writes", "SQL/TCP", $tags="DataAccess")
Rel_L(ticket_api, ticket_created_queue, "Publishes", "Queue/Event", $tags="Async")
Rel(ticket_created_queue, ticket_processor, "Triggers", "Queue/Event", $tags="Async")
Rel_L(ticket_processor, notification_service, "Requests notification", "REST/HTTP", $tags="Sync")
Rel(notification_service, email_system, "Sends e-mail", "SMTP", $tags="ExternalCall")
Lay_D(customer, customer_portal)
Lay_D(expert, mobile_app)
Lay_L(customer_portal, mobile_app)
Lay_L(notification_service, email_system)
Lay_L(sysops_system, email_system)

SHOW_LEGEND($hideStereotype="false", $details=Normal())

@enduml

Mermaid tuned customer support component example
Mermaid tuned customer support component diagram

Python diagram
from c4 import (
    Component,
    ComponentDb,
    ComponentDiagram,
    ComponentExt,
    ComponentQueue,
    ContainerBoundary,
    Person,
    Rel,
)
from c4.renderers import (
    MermaidRenderOptionsBuilder,
)


with ComponentDiagram(title='Customer Support System - Tuned Component View') as diagram:
    customer = Person(
        'Customer',
        'Reports equipment issues and tracks repair progress.',
        alias='customer',
    )
    expert = Person(
        'Support Expert',
        'Accepts assignments and records repair updates.',
        alias='expert',
    )

    auth0 = ComponentExt(
        'Auth0',
        'External identity provider.',
        technology='OIDC/OAuth2',
        alias='auth0',
    )
    email_system = ComponentExt(
        'E-mail System',
        'Delivers customer and expert notifications.',
        technology='SMTP',
        alias='email_system',
    )

    with ContainerBoundary(
        'Customer Support System',
        'Components that handle support tickets and expert assignments.',
        mermaid={'type': 'system boundary'},
        alias='sysops_system',
    ):
        api_gateway = Component(
            'API Gateway',
            'Access control and request routing.',
            technology='Container Service',
            alias='api_gateway',
        )
        customer_portal = Component(
            'Customer Portal',
            'Ticket creation and status tracking.',
            technology='SPA',
            alias='customer_portal',
        )
        mobile_app = Component(
            'Expert Mobile App',
            'Assignment queue and field repair updates.',
            technology='iOS / Android',
            alias='mobile_app',
        )
        ticket_api = Component(
            'Ticket API',
            'Ticket orchestration, search, and assignment updates.',
            technology='Container Service',
            alias='ticket_api',
        )
        ticket_processor = Component(
            'Ticket Processor',
            'Creates expert assignments for new tickets.',
            technology='Container Job',
            alias='ticket_processor',
        )
        notification_service = Component(
            'Notification Service',
            'Sends customer and expert notifications.',
            technology='Container Service',
            alias='notification_service',
        )
        sysops_database = ComponentDb(
            'Support Database',
            'Tickets, contacts, assignments, and repair history.',
            technology='PostgreSQL',
            alias='sysops_database',
        )
        ticket_created_queue = ComponentQueue(
            'Ticket Created',
            'Event stream for new support tickets.',
            technology='Message Queue',
            alias='ticket_created_queue',
        )

    customer >> Rel('Uses', technology='HTTPS') >> customer_portal
    expert >> Rel('Uses', technology='HTTPS') >> mobile_app

    customer_portal >> Rel('Authenticates', technology='OIDC') >> auth0
    mobile_app >> Rel('Authenticates', technology='OIDC') >> auth0

    customer_portal >> Rel('Calls', technology='REST/HTTPS') >> api_gateway
    mobile_app >> Rel('Calls', technology='REST/HTTPS') >> api_gateway
    api_gateway >> Rel('Routes', technology='REST/HTTP') >> ticket_api

    ticket_api >> Rel('Reads/writes', technology='SQL/TCP') >> sysops_database
    ticket_processor >> Rel('Reads/writes', technology='SQL/TCP') >> sysops_database
    ticket_api >> Rel('Publishes', technology='Queue/Event') >> ticket_created_queue
    ticket_created_queue >> Rel('Triggers', technology='Queue/Event') >> ticket_processor
    ticket_processor >> Rel('Requests notification', technology='REST/HTTP') >> notification_service
    notification_service >> Rel('Sends e-mail', technology='SMTP') >> email_system


mermaid_render_options = (
    MermaidRenderOptionsBuilder()
    .update_layout_config(
        c4_shape_in_row=3,
        c4_boundary_in_row=1,
    )
    .update_element_style('customer', bg_color='#e8f5e9', font_color='#1b5e20', border_color='#66bb6a')
    .update_element_style('expert', bg_color='#e8f5e9', font_color='#1b5e20', border_color='#66bb6a')
    .update_element_style('customer_portal', bg_color='#e3f2fd', font_color='#0d47a1', border_color='#42a5f5')
    .update_element_style('mobile_app', bg_color='#e3f2fd', font_color='#0d47a1', border_color='#42a5f5')
    .update_element_style('api_gateway', bg_color='#fce4ec', font_color='#880e4f', border_color='#ec407a')
    .update_element_style('ticket_api', bg_color='#ede7f6', font_color='#311b92', border_color='#7e57c2')
    .update_element_style('notification_service', bg_color='#ede7f6', font_color='#311b92', border_color='#7e57c2')
    .update_element_style('ticket_processor', bg_color='#fff3e0', font_color='#e65100', border_color='#fb8c00')
    .update_element_style('sysops_database', bg_color='#fff8e1', font_color='#5d4037', border_color='#ffb300')
    .update_element_style('ticket_created_queue', bg_color='#e0f2f1', font_color='#004d40', border_color='#26a69a')
    .update_element_style('auth0', bg_color='#f5f5f5', font_color='#424242', border_color='#9e9e9e')
    .update_element_style('email_system', bg_color='#f5f5f5', font_color='#424242', border_color='#9e9e9e')
    .update_rel_style('customer_portal', 'auth0', line_color='#78909c', text_color='#455a64', offset_y=-35)
    .update_rel_style('mobile_app', 'auth0', line_color='#78909c', text_color='#455a64', offset_y=35)
    .update_rel_style('customer_portal', 'api_gateway', line_color='#1e88e5', text_color='#1565c0', offset_y=-70)
    .update_rel_style('mobile_app', 'api_gateway', line_color='#1e88e5', text_color='#1565c0', offset_y=70)
    .update_rel_style('api_gateway', 'ticket_api', line_color='#1e88e5', text_color='#1565c0', offset_x=-70)
    .update_rel_style('ticket_api', 'sysops_database', line_color='#8d6e63', text_color='#6d4c41', offset_y=-30)
    .update_rel_style('ticket_processor', 'sysops_database', line_color='#8d6e63', text_color='#6d4c41', offset_y=30)
    .update_rel_style('ticket_api', 'ticket_created_queue', line_color='#00897b', text_color='#00695c', offset_x=45)
    .update_rel_style('ticket_created_queue', 'ticket_processor', line_color='#00897b', text_color='#00695c', offset_x=-65)
    .update_rel_style('ticket_processor', 'notification_service', line_color='#1e88e5', text_color='#1565c0', offset_y=-60)
    .update_rel_style('notification_service', 'email_system', line_color='#78909c', text_color='#455a64', offset_y=-35)
    .build()
)

diagram.set_render_options(
    mermaid=mermaid_render_options,
)
Rendered Mermaid source
C4Component
title Customer Support System - Tuned Component View

Person(customer, "Customer", "Reports equipment issues and tracks repair progress.")

Person(expert, "Support Expert", "Accepts assignments and records repair updates.")

Component_Ext(auth0, "Auth0", "OIDC/OAuth2", "External identity provider.")

Component_Ext(email_system, "E-mail System", "SMTP", "Delivers customer and expert notifications.")

Container_Boundary(sysops_system, "Customer Support System", "Components that handle support tickets and expert assignments.") {
    Component(api_gateway, "API Gateway", "Container Service", "Access control and request routing.")
    Component(customer_portal, "Customer Portal", "SPA", "Ticket creation and status tracking.")
    Component(mobile_app, "Expert Mobile App", "iOS / Android", "Assignment queue and field repair updates.")
    Component(ticket_api, "Ticket API", "Container Service", "Ticket orchestration, search, and assignment updates.")
    Component(ticket_processor, "Ticket Processor", "Container Job", "Creates expert assignments for new tickets.")
    Component(notification_service, "Notification Service", "Container Service", "Sends customer and expert notifications.")
    ComponentDb(sysops_database, "Support Database", "PostgreSQL", "Tickets, contacts, assignments, and repair history.")
    ComponentQueue(ticket_created_queue, "Ticket Created", "Message Queue", "Event stream for new support tickets.")
}

Rel(customer, customer_portal, "Uses", "HTTPS")

Rel(expert, mobile_app, "Uses", "HTTPS")

Rel(customer_portal, auth0, "Authenticates", "OIDC")

Rel(mobile_app, auth0, "Authenticates", "OIDC")

Rel(customer_portal, api_gateway, "Calls", "REST/HTTPS")

Rel(mobile_app, api_gateway, "Calls", "REST/HTTPS")

Rel(api_gateway, ticket_api, "Routes", "REST/HTTP")

Rel(ticket_api, sysops_database, "Reads/writes", "SQL/TCP")

Rel(ticket_processor, sysops_database, "Reads/writes", "SQL/TCP")

Rel(ticket_api, ticket_created_queue, "Publishes", "Queue/Event")

Rel(ticket_created_queue, ticket_processor, "Triggers", "Queue/Event")

Rel(ticket_processor, notification_service, "Requests notification", "REST/HTTP")

Rel(notification_service, email_system, "Sends e-mail", "SMTP")

UpdateElementStyle(customer, $fontColor="#1b5e20", $bgColor="#e8f5e9", $borderColor="#66bb6a")
UpdateElementStyle(expert, $fontColor="#1b5e20", $bgColor="#e8f5e9", $borderColor="#66bb6a")
UpdateElementStyle(customer_portal, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(mobile_app, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(api_gateway, $fontColor="#880e4f", $bgColor="#fce4ec", $borderColor="#ec407a")
UpdateElementStyle(ticket_api, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(notification_service, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(ticket_processor, $fontColor="#e65100", $bgColor="#fff3e0", $borderColor="#fb8c00")
UpdateElementStyle(sysops_database, $fontColor="#5d4037", $bgColor="#fff8e1", $borderColor="#ffb300")
UpdateElementStyle(ticket_created_queue, $fontColor="#004d40", $bgColor="#e0f2f1", $borderColor="#26a69a")
UpdateElementStyle(auth0, $fontColor="#424242", $bgColor="#f5f5f5", $borderColor="#9e9e9e")
UpdateElementStyle(email_system, $fontColor="#424242", $bgColor="#f5f5f5", $borderColor="#9e9e9e")
UpdateRelStyle(customer_portal, auth0, $textColor="#455a64", $lineColor="#78909c", $offsetY="-35")
UpdateRelStyle(mobile_app, auth0, $textColor="#455a64", $lineColor="#78909c", $offsetY="35")
UpdateRelStyle(customer_portal, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5", $offsetY="-70")
UpdateRelStyle(mobile_app, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5", $offsetY="70")
UpdateRelStyle(api_gateway, ticket_api, $textColor="#1565c0", $lineColor="#1e88e5", $offsetX="-70")
UpdateRelStyle(ticket_api, sysops_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-30")
UpdateRelStyle(ticket_processor, sysops_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="30")
UpdateRelStyle(ticket_api, ticket_created_queue, $textColor="#00695c", $lineColor="#00897b", $offsetX="45")
UpdateRelStyle(ticket_created_queue, ticket_processor, $textColor="#00695c", $lineColor="#00897b", $offsetX="-65")
UpdateRelStyle(ticket_processor, notification_service, $textColor="#1565c0", $lineColor="#1e88e5", $offsetY="-60")
UpdateRelStyle(notification_service, email_system, $textColor="#455a64", $lineColor="#78909c", $offsetY="-35")
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")

D2 tuned customer support component example
D2 tuned customer support component diagram

Python diagram
from c4 import (
    Component,
    ComponentDb,
    ComponentDiagram,
    ComponentExt,
    ComponentQueue,
    ContainerBoundary,
    Person,
    Rel,
)
from c4.renderers import (
    D2Legend,
    D2LegendElement,
    D2LegendRel,
    D2RenderOptionsBuilder,
)

USER_STYLE = {
    'fill': '#e8f5e9',
    'font_color': '#1b5e20',
    'stroke': '#66bb6a',
}
FRONTEND_STYLE = {
    'fill': '#e3f2fd',
    'font_color': '#0d47a1',
    'stroke': '#42a5f5',
}
GATEWAY_STYLE = {
    'fill': '#fce4ec',
    'font_color': '#880e4f',
    'stroke': '#ec407a',
    'stroke_width': 2,
}
BACKEND_STYLE = {
    'fill': '#ede7f6',
    'font_color': '#311b92',
    'stroke': '#7e57c2',
}
WORKER_STYLE = {
    'fill': '#fff3e0',
    'font_color': '#e65100',
    'stroke': '#fb8c00',
}
DATABASE_STYLE = {
    'fill': '#fff8e1',
    'font_color': '#5d4037',
    'stroke': '#ffb300',
}
QUEUE_STYLE = {
    'fill': '#e0f2f1',
    'font_color': '#004d40',
    'stroke': '#26a69a',
}
EXTERNAL_STYLE = {
    'fill': '#f5f5f5',
    'font_color': '#424242',
    'stroke': '#9e9e9e',
    'stroke_dash': 5,
}
SYNC_REL_STYLE = {
    'stroke': '#1e88e5',
    'font_color': '#1565c0',
}
DATA_REL_STYLE = {
    'stroke': '#8d6e63',
    'font_color': '#6d4c41',
}
ASYNC_REL_STYLE = {
    'stroke': '#00897b',
    'font_color': '#00695c',
    'stroke_dash': 3,
}
EXTERNAL_REL_STYLE = {
    'stroke': '#78909c',
    'font_color': '#455a64',
    'stroke_dash': 5,
}

with ComponentDiagram(title='Customer Support System - Tuned Component View') as diagram:
    customer = Person(
        'Customer',
        'Reports equipment issues and tracks repair progress.',
        d2={'style': USER_STYLE},
        alias='customer',
    )
    expert = Person(
        'Support Expert',
        'Accepts assignments and records repair updates.',
        d2={'style': USER_STYLE},
        alias='expert',
    )

    auth0 = ComponentExt(
        'Auth0',
        'External identity provider.',
        technology='OIDC/OAuth2',
        d2={'style': EXTERNAL_STYLE},
        alias='auth0',
    )
    email_system = ComponentExt(
        'E-mail System',
        'Delivers customer and expert notifications.',
        technology='SMTP',
        d2={'style': EXTERNAL_STYLE},
        alias='email_system',
    )

    with ContainerBoundary(
        'Customer Support System',
        'Components that handle support tickets and expert assignments.',
        d2={
            'direction': 'right',
            'style': {
                'fill': '#fafafa',
                'stroke': '#90a4ae',
                'stroke_dash': 4,
            },
        },
        alias='sysops_system',
    ):
        customer_portal = Component(
            'Customer Portal',
            'Ticket creation and status tracking.',
            technology='SPA',
            d2={'style': FRONTEND_STYLE},
            alias='customer_portal',
        )
        mobile_app = Component(
            'Expert Mobile App',
            'Assignment queue and field repair updates.',
            technology='iOS / Android',
            d2={'style': FRONTEND_STYLE},
            alias='mobile_app',
        )
        api_gateway = Component(
            'API Gateway',
            'Access control and request routing.',
            technology='Container Service',
            d2={'style': GATEWAY_STYLE},
            alias='api_gateway',
        )
        ticket_api = Component(
            'Ticket API',
            'Ticket orchestration, search, and assignment updates.',
            technology='Container Service',
            d2={'style': BACKEND_STYLE},
            alias='ticket_api',
        )
        ticket_processor = Component(
            'Ticket Processor',
            'Creates expert assignments for new tickets.',
            technology='Container Job',
            d2={'style': WORKER_STYLE},
            alias='ticket_processor',
        )
        notification_service = Component(
            'Notification Service',
            'Sends customer and expert notifications.',
            technology='Container Service',
            d2={'style': BACKEND_STYLE},
            alias='notification_service',
        )
        sysops_database = ComponentDb(
            'Support Database',
            'Tickets, contacts, assignments, and repair history.',
            technology='PostgreSQL',
            d2={'style': DATABASE_STYLE},
            alias='sysops_database',
        )
        ticket_created_queue = ComponentQueue(
            'Ticket Created',
            'Event stream for new support tickets.',
            technology='Message Queue',
            d2={'style': QUEUE_STYLE},
            alias='ticket_created_queue',
        )

    customer >> Rel('Uses', technology='HTTPS', d2={'style': SYNC_REL_STYLE}) >> customer_portal
    expert >> Rel('Uses', technology='HTTPS', d2={'style': SYNC_REL_STYLE}) >> mobile_app

    customer_portal >> Rel('Authenticates', technology='OIDC', d2={'style': EXTERNAL_REL_STYLE}) >> auth0
    mobile_app >> Rel('Authenticates', technology='OIDC', d2={'style': EXTERNAL_REL_STYLE}) >> auth0

    customer_portal >> Rel('Calls', technology='REST/HTTPS', d2={'style': SYNC_REL_STYLE}) >> api_gateway
    mobile_app >> Rel('Calls', technology='REST/HTTPS', d2={'style': SYNC_REL_STYLE}) >> api_gateway
    api_gateway >> Rel('Routes', technology='REST/HTTP', d2={'style': SYNC_REL_STYLE}) >> ticket_api

    ticket_api >> Rel('Reads/writes', technology='SQL/TCP', d2={'style': DATA_REL_STYLE}) >> sysops_database
    ticket_processor >> Rel('Reads/writes', technology='SQL/TCP', d2={'style': DATA_REL_STYLE}) >> sysops_database
    ticket_api >> Rel('Publishes', technology='Queue/Event', d2={'style': ASYNC_REL_STYLE}) >> ticket_created_queue
    ticket_created_queue >> Rel('Triggers', technology='Queue/Event', d2={'style': ASYNC_REL_STYLE}) >> ticket_processor
    ticket_processor >> Rel('Requests notification', technology='REST/HTTP',
                            d2={'style': SYNC_REL_STYLE}) >> notification_service
    notification_service >> Rel('Sends e-mail', technology='SMTP', d2={'style': EXTERNAL_REL_STYLE}) >> email_system

d2_render_options = (
    D2RenderOptionsBuilder()
    .direction('down')
    .legend(
        D2Legend(
            label='Customer Support Component Legend',
            items=[
                D2LegendElement('Operational user', shape='person', style=USER_STYLE),
                D2LegendElement('User-facing frontend', style=FRONTEND_STYLE),
                D2LegendElement('API gateway', style=GATEWAY_STYLE),
                D2LegendElement('Backend service', style=BACKEND_STYLE),
                D2LegendElement('Background worker', style=WORKER_STYLE),
                D2LegendElement('Operational datastore', shape='cylinder', style=DATABASE_STYLE),
                D2LegendElement('Asynchronous event stream', shape='queue', style=QUEUE_STYLE),
                D2LegendElement('External dependency', style=EXTERNAL_STYLE),
                D2LegendRel('Synchronous call', style=SYNC_REL_STYLE),
                D2LegendRel('Asynchronous event', style=ASYNC_REL_STYLE),
                D2LegendRel('External call', style=EXTERNAL_REL_STYLE),
            ],
        ),
    )
    .build()
)

diagram.set_render_options(
    d2=d2_render_options,
)
Rendered D2 source
direction: down
__title: ||md
  # Customer Support System - Tuned Component View
|| {
  near: top-center
}
vars: {
  d2-legend: "Customer Support Component Legend" {
    legend_1: {
      label: "Operational user"
      shape: person
      style.fill: "#e8f5e9"
      style.font-color: "#1b5e20"
      style.stroke: "#66bb6a"
    }
    legend_2: {
      label: "User-facing frontend"
      style.fill: "#e3f2fd"
      style.font-color: "#0d47a1"
      style.stroke: "#42a5f5"
    }
    legend_3: {
      label: "API gateway"
      style.fill: "#fce4ec"
      style.font-color: "#880e4f"
      style.stroke: "#ec407a"
      style.stroke-width: 2
    }
    legend_4: {
      label: "Backend service"
      style.fill: "#ede7f6"
      style.font-color: "#311b92"
      style.stroke: "#7e57c2"
    }
    legend_5: {
      label: "Background worker"
      style.fill: "#fff3e0"
      style.font-color: "#e65100"
      style.stroke: "#fb8c00"
    }
    legend_6: {
      label: "Operational datastore"
      shape: cylinder
      style.fill: "#fff8e1"
      style.font-color: "#5d4037"
      style.stroke: "#ffb300"
    }
    legend_7: {
      label: "Asynchronous event stream"
      shape: queue
      style.fill: "#e0f2f1"
      style.font-color: "#004d40"
      style.stroke: "#26a69a"
    }
    legend_8: {
      label: "External dependency"
      style.fill: "#f5f5f5"
      style.font-color: "#424242"
      style.stroke: "#9e9e9e"
      style.stroke-dash: 5
    }
    legend_9_source -> legend_9_target: {
      label: "Synchronous call"
      style.stroke: "#1e88e5"
      style.font-color: "#1565c0"
    }
    legend_10_source -> legend_10_target: {
      label: "Asynchronous event"
      style.stroke: "#00897b"
      style.font-color: "#00695c"
      style.stroke-dash: 3
    }
    legend_11_source -> legend_11_target: {
      label: "External call"
      style.stroke: "#78909c"
      style.font-color: "#455a64"
      style.stroke-dash: 5
    }
    legend_9_source.style.opacity: 0
    legend_9_target.style.opacity: 0
    legend_10_source.style.opacity: 0
    legend_10_target.style.opacity: 0
    legend_11_source.style.opacity: 0
    legend_11_target.style.opacity: 0
  }
}
classes: {
  c4_person: {
    style.fill: "#f5f1ff"
    style.stroke: "#6f4bb2"
    style.font-color: "#211436"
  }
  c4_external: {
    style.fill: "#f7f7f7"
    style.stroke: "#767676"
    style.stroke-dash: "5"
  }
  c4_database: {
    style.fill: "#edf7ff"
    style.stroke: "#2d6f9f"
  }
  c4_queue: {
    style.fill: "#fff6e5"
    style.stroke: "#9b6500"
  }
}
customer: ||md
  ## Customer

  [Person]

  Reports equipment issues and tracks repair progress.
|| {
  shape: c4-person
  class: ["c4_person"]
  style.fill: "#e8f5e9"
  style.font-color: "#1b5e20"
  style.stroke: "#66bb6a"
}
expert: ||md
  ## Support Expert

  [Person]

  Accepts assignments and records repair updates.
|| {
  shape: c4-person
  class: ["c4_person"]
  style.fill: "#e8f5e9"
  style.font-color: "#1b5e20"
  style.stroke: "#66bb6a"
}
auth0: ||md
  ## Auth0

  [Component: OIDC/OAuth2]

  External identity provider.
|| {
  shape: rectangle
  class: ["c4_external"]
  style.fill: "#f5f5f5"
  style.font-color: "#424242"
  style.stroke: "#9e9e9e"
  style.stroke-dash: 5
}
email_system: ||md
  ## E-mail System

  [Component: SMTP]

  Delivers customer and expert notifications.
|| {
  shape: rectangle
  class: ["c4_external"]
  style.fill: "#f5f5f5"
  style.font-color: "#424242"
  style.stroke: "#9e9e9e"
  style.stroke-dash: 5
}
sysops_system: {
  label: ||md
    ## Customer Support System

    [Container]

    Components that handle support tickets and expert assignments.
  ||
  shape: rectangle
  direction: right
  style.fill: "#fafafa"
  style.stroke: "#90a4ae"
  style.stroke-dash: 4
  customer_portal: ||md
    ## Customer Portal

    [Component: SPA]

    Ticket creation and status tracking.
  || {
    shape: rectangle
    style.fill: "#e3f2fd"
    style.font-color: "#0d47a1"
    style.stroke: "#42a5f5"
  }
  mobile_app: ||md
    ## Expert Mobile App

    [Component: iOS / Android]

    Assignment queue and field repair updates.
  || {
    shape: rectangle
    style.fill: "#e3f2fd"
    style.font-color: "#0d47a1"
    style.stroke: "#42a5f5"
  }
  api_gateway: ||md
    ## API Gateway

    [Component: Container Service]

    Access control and request routing.
  || {
    shape: rectangle
    style.fill: "#fce4ec"
    style.font-color: "#880e4f"
    style.stroke: "#ec407a"
    style.stroke-width: 2
  }
  ticket_api: ||md
    ## Ticket API

    [Component: Container Service]

    Ticket orchestration, search, and assignment updates.
  || {
    shape: rectangle
    style.fill: "#ede7f6"
    style.font-color: "#311b92"
    style.stroke: "#7e57c2"
  }
  ticket_processor: ||md
    ## Ticket Processor

    [Component: Container Job]

    Creates expert assignments for new tickets.
  || {
    shape: rectangle
    style.fill: "#fff3e0"
    style.font-color: "#e65100"
    style.stroke: "#fb8c00"
  }
  notification_service: ||md
    ## Notification Service

    [Component: Container Service]

    Sends customer and expert notifications.
  || {
    shape: rectangle
    style.fill: "#ede7f6"
    style.font-color: "#311b92"
    style.stroke: "#7e57c2"
  }
  sysops_database: ||md
    ## Support Database

    [Component: PostgreSQL]

    Tickets, contacts, assignments, and repair history.
  || {
    shape: cylinder
    class: ["c4_database"]
    style.fill: "#fff8e1"
    style.font-color: "#5d4037"
    style.stroke: "#ffb300"
  }
  ticket_created_queue: ||md
    ## Ticket Created

    [Component: Message Queue]

    Event stream for new support tickets.
  || {
    shape: queue
    class: ["c4_queue"]
    style.fill: "#e0f2f1"
    style.font-color: "#004d40"
    style.stroke: "#26a69a"
  }
}
customer -> sysops_system.customer_portal: {
  label: "Uses\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
expert -> sysops_system.mobile_app: {
  label: "Uses\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
sysops_system.customer_portal -> auth0: {
  label: "Authenticates\n[OIDC]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}
sysops_system.mobile_app -> auth0: {
  label: "Authenticates\n[OIDC]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}
sysops_system.customer_portal -> sysops_system.api_gateway: {
  label: "Calls\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
sysops_system.mobile_app -> sysops_system.api_gateway: {
  label: "Calls\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
sysops_system.api_gateway -> sysops_system.ticket_api: {
  label: "Routes\n[REST/HTTP]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
sysops_system.ticket_api -> sysops_system.sysops_database: {
  label: "Reads/writes\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
sysops_system.ticket_processor -> sysops_system.sysops_database: {
  label: "Reads/writes\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
sysops_system.ticket_api -> sysops_system.ticket_created_queue: {
  label: "Publishes\n[Queue/Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
sysops_system.ticket_created_queue -> sysops_system.ticket_processor: {
  label: "Triggers\n[Queue/Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
sysops_system.ticket_processor -> sysops_system.notification_service: {
  label: "Requests notification\n[REST/HTTP]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
sysops_system.notification_service -> email_system: {
  label: "Sends e-mail\n[SMTP]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}

Customer support system extended component view

This deeper view uses the same domain model with more operational surfaces: admin, billing, analytics, knowledge base, payment, notification, and queue flows.

PlantUML extended customer support component example
PlantUML extended customer support component diagram

Python diagram
from __future__ import annotations

from c4 import (
    Component,
    ComponentDb,
    ComponentDiagram,
    ComponentExt,
    ComponentQueue,
    Person,
    Rel,
)
from c4.renderers import (
    PlantUMLRenderOptionsBuilder,
)


def plantuml_attrs(tag: str) -> dict[str, object]:
    return {"plantuml": {"tags": [tag]}}


def plantuml_rel(tag: str) -> dict[str, object]:
    return {"plantuml": {"tags": [tag]}}


with ComponentDiagram(
    title="Customer Support System - Extended Component View",
) as diagram:
    admin_api = Component(
        "Admin API",
        "User management and reference-data management.",
        technology="Container Service",
        alias="admin_api",
        **plantuml_attrs("Backend"),
    )
    admin_portal = Component(
        "Admin Portal",
        "Manages system users and reference data.",
        technology="Single-page Application",
        alias="admin_portal",
        **plantuml_attrs("Frontend"),
    )
    administrator = Person(
        "Administrator",
        "Internal user with administrative access.",
        alias="administrator",
        **plantuml_attrs("User"),
    )
    analytics_api = Component(
        "Analytics API",
        "Ticket status reports, survey analysis and performance reports.",
        technology="Container Service",
        alias="analytics_api",
        **plantuml_attrs("Backend"),
    )
    api_gateway = Component(
        "API Gateway",
        "Performs access control, security checks and request routing.",
        technology="Container Service",
        alias="api_gateway",
        **plantuml_attrs("Gateway"),
    )
    auth0 = ComponentExt(
        "Auth0",
        "External identity provider for authentication.",
        technology="OIDC/OAuth2",
        alias="auth0",
        **plantuml_attrs("External"),
    )
    billing_api = Component(
        "Billing API",
        "Billing management and financial reports.",
        technology="Container Service",
        alias="billing_api",
        **plantuml_attrs("Backend"),
    )
    billing_portal = Component(
        "Billing Portal",
        "Supports billing processing.",
        technology="Single-page Application",
        alias="billing_portal",
        **plantuml_attrs("Frontend"),
    )
    customer = Person(
        "Customer",
        "Owner of electronic equipment and support plan; reports issues.",
        alias="customer",
        **plantuml_attrs("User"),
    )
    customer_api = Component(
        "Customer API",
        "Handles registration, profiles, tickets, surveys and billing history.",
        technology="Container Service",
        alias="customer_api",
        **plantuml_attrs("Backend"),
    )
    customer_notifications_queue = ComponentQueue(
        "Customer Notifications",
        "Asynchronous message channel for customer notifications.",
        technology="Message Queue",
        alias="customer_notifications_queue",
        **plantuml_attrs("Queue"),
    )
    customer_portal = Component(
        "Customer Portal",
        "Provides access to customer profile, billing, ticket creation and history.",
        technology="Single-page Application",
        alias="customer_portal",
        **plantuml_attrs("Frontend"),
    )
    email_system = ComponentExt(
        "E-mail System",
        "Internal mail system used for e-mail delivery.",
        technology="SMTP",
        alias="email_system",
        **plantuml_attrs("External"),
    )
    expert_notifications_queue = ComponentQueue(
        "Expert Notifications",
        "Asynchronous message channel for expert notifications.",
        technology="Message Queue",
        alias="expert_notifications_queue",
        **plantuml_attrs("Queue"),
    )
    helpdesk = Person(
        "Helpdesk",
        "First line of support; provides direct phone support.",
        alias="helpdesk",
        **plantuml_attrs("User"),
    )
    helpdesk_portal = Component(
        "Helpdesk Portal",
        "Provides access to tickets and status.",
        technology="Single-page Application",
        alias="helpdesk_portal",
        **plantuml_attrs("Frontend"),
    )
    invoice_queue = ComponentQueue(
        "Invoice",
        "Asynchronous message channel for invoice processing.",
        technology="Message Queue",
        alias="invoice_queue",
        **plantuml_attrs("Queue"),
    )
    knowledge_base = Component(
        "Knowledge Base",
        "Supports searching and updating knowledge-base articles.",
        technology="Single-page Application",
        alias="knowledge_base",
        **plantuml_attrs("Frontend"),
    )
    manager = Person(
        "Manager",
        "Monitors expert performance and customer satisfaction.",
        alias="manager",
        **plantuml_attrs("User"),
    )
    mobile_app = Component(
        "Mobile App",
        "Provides access to assigned tickets and knowledge-base search.",
        technology="iOS / Android App",
        alias="mobile_app",
        **plantuml_attrs("Frontend"),
    )
    notification_service = Component(
        "Notification Service",
        "Sends SMS and e-mail messages based on notification preferences.",
        technology="Container Service",
        alias="notification_service",
        **plantuml_attrs("Backend"),
    )
    payment_job = Component(
        "Payment",
        "Runs monthly and performs payment operations.",
        technology="Container Job",
        alias="payment_job",
        **plantuml_attrs("Worker"),
    )
    payment_provider = ComponentExt(
        "Payment Service Provider",
        "External online payment service.",
        technology="HTTPS/API",
        alias="payment_provider",
        **plantuml_attrs("External"),
    )
    sms_provider = ComponentExt(
        "SMS Service Provider",
        "Provides SMS text messaging.",
        technology="SMS API",
        alias="sms_provider",
        **plantuml_attrs("External"),
    )
    support_api = Component(
        "Support API",
        "Ticket orchestration, search, assignment handling and knowledge-base updates.",
        technology="Container Service",
        alias="support_api",
        **plantuml_attrs("Backend"),
    )
    support_dashboard = Component(
        "Support Dashboard",
        "Provides analytics and operational reports.",
        technology="Single-page Application",
        alias="support_dashboard",
        **plantuml_attrs("Frontend"),
    )
    support_database = ComponentDb(
        "Support Database",
        "Stores tickets, users, customer contacts and knowledge-base content.",
        technology="Relational Database",
        alias="support_database",
        **plantuml_attrs("Database"),
    )
    support_expert = Person(
        "Support Expert",
        "Technology expert who fixes customer electronic devices.",
        alias="support_expert",
        **plantuml_attrs("User"),
    )
    ticket_assigned_queue = ComponentQueue(
        "Ticket Assigned",
        "Asynchronous message channel for assigned tickets.",
        technology="Message Queue",
        alias="ticket_assigned_queue",
        **plantuml_attrs("Queue"),
    )
    ticket_created_queue = ComponentQueue(
        "Ticket Created",
        "Asynchronous message channel for created tickets.",
        technology="Message Queue",
        alias="ticket_created_queue",
        **plantuml_attrs("Queue"),
    )
    ticket_progress_queue = ComponentQueue(
        "Ticket In-Progress/Closed",
        "Asynchronous message channel for ticket progress and closure notifications.",
        technology="Message Queue",
        alias="ticket_progress_queue",
        **plantuml_attrs("Queue"),
    )
    ticket_processor = Component(
        "Ticket Processor",
        "Runs periodically, scans ticket statuses, and creates assignments.",
        technology="Container Job",
        alias="ticket_processor",
        **plantuml_attrs("Worker"),
    )

    (
        admin_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        admin_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            **plantuml_rel("Sync"),
        )
        >> api_gateway
    )
    (
        analytics_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            **plantuml_rel("Sync"),
        )
        >> customer_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            **plantuml_rel("Sync"),
        )
        >> support_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            **plantuml_rel("Sync"),
        )
        >> admin_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            **plantuml_rel("Sync"),
        )
        >> billing_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            **plantuml_rel("Sync"),
        )
        >> analytics_api
    )
    (
        billing_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        billing_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            **plantuml_rel("Sync"),
        )
        >> api_gateway
    )
    (
        customer_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        customer_api
        >> Rel(
            "Sends ticket created event",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> ticket_created_queue
    )
    (
        customer_portal
        >> Rel(
            "Authenticates using",
            technology="OIDC/OAuth2",
            **plantuml_rel("ExternalCall"),
        )
        >> auth0
    )
    (
        customer_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            **plantuml_rel("Sync"),
        )
        >> api_gateway
    )
    (
        helpdesk_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            **plantuml_rel("Sync"),
        )
        >> api_gateway
    )
    (
        knowledge_base
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            **plantuml_rel("Sync"),
        )
        >> api_gateway
    )
    (
        mobile_app
        >> Rel(
            "Authenticates using",
            technology="OIDC/OAuth2",
            **plantuml_rel("ExternalCall"),
        )
        >> auth0
    )
    (
        mobile_app
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            **plantuml_rel("Sync"),
        )
        >> api_gateway
    )
    (
        notification_service
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        notification_service
        >> Rel(
            "Sends e-mail using",
            technology="SMTP",
            **plantuml_rel("ExternalCall"),
        )
        >> email_system
    )
    (
        notification_service
        >> Rel(
            "Sends SMS using",
            technology="SMS API",
            **plantuml_rel("ExternalCall"),
        )
        >> sms_provider
    )
    (
        payment_job
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        payment_job
        >> Rel(
            "Sends invoice event",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> invoice_queue
    )
    (
        payment_job
        >> Rel(
            "Executes payments using",
            technology="HTTPS/API",
            **plantuml_rel("ExternalCall"),
        )
        >> payment_provider
    )
    (
        support_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        support_api
        >> Rel(
            "Sends expert notification event",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> expert_notifications_queue
    )
    (
        support_api
        >> Rel(
            "Sends customer notification event",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> customer_notifications_queue
    )
    (
        support_api
        >> Rel(
            "Sends progress/closed event",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> ticket_progress_queue
    )
    (
        support_dashboard
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            **plantuml_rel("Sync"),
        )
        >> api_gateway
    )
    (
        ticket_processor
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            **plantuml_rel("DataAccess"),
        )
        >> support_database
    )
    (
        ticket_processor
        >> Rel(
            "Sends ticket assignment event",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> ticket_assigned_queue
    )
    (
        administrator
        >> Rel(
            "Maintains users and reference data",
            technology="HTTPS",
            **plantuml_rel("Sync"),
        )
        >> admin_portal
    )
    (
        administrator
        >> Rel(
            "Manages billing operations",
            technology="HTTPS",
            **plantuml_rel("Sync"),
        )
        >> billing_portal
    )
    (
        customer
        >> Rel("Uses", technology="HTTPS", **plantuml_rel("Sync"))
        >> customer_portal
    )
    (
        customer
        >> Rel("Uses", technology="HTTPS", **plantuml_rel("Sync"))
        >> mobile_app
    )
    (
        helpdesk
        >> Rel(
            "Creates/searches tickets",
            technology="HTTPS",
            **plantuml_rel("Sync"),
        )
        >> helpdesk_portal
    )
    (
        manager
        >> Rel(
            "Tracks operations and generates reports",
            technology="HTTPS",
            **plantuml_rel("Sync"),
        )
        >> support_dashboard
    )
    (
        support_expert
        >> Rel("Uses", technology="HTTPS", **plantuml_rel("Sync"))
        >> mobile_app
    )
    (
        support_expert
        >> Rel(
            "Updates articles",
            technology="HTTPS",
            **plantuml_rel("Sync"),
        )
        >> knowledge_base
    )
    (
        customer_notifications_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> notification_service
    )
    (
        expert_notifications_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> notification_service
    )
    (
        invoice_queue
        >> Rel(
            "Calls billing APIs through",
            technology="REST/HTTP",
            **plantuml_rel("Async"),
        )
        >> api_gateway
    )
    (
        ticket_assigned_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> support_api
    )
    (
        ticket_created_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> ticket_processor
    )
    (
        ticket_progress_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            **plantuml_rel("Async"),
        )
        >> customer_api
    )

plantuml_render_options = (
    PlantUMLRenderOptionsBuilder()
    .layout_top_down(with_legend=True)
    .show_legend(hide_stereotype=False, details="Normal")
    .update_legend_title("Customer Support Component Legend")
    .add_person_tag(
        tag_stereo="User",
        bg_color="#e8f5e9",
        font_color="#1b5e20",
        border_color="#66bb6a",
        shadowing=False,
        legend_text="Operational user",
        legend_sprite="user",
    )
    .add_component_tag(
        tag_stereo="Frontend",
        bg_color="#e3f2fd",
        font_color="#0d47a1",
        border_color="#42a5f5",
        shadowing=True,
        technology="UI",
        legend_text="User-facing frontend",
        legend_sprite="browser",
        border_style="SolidLine",
        border_thickness="2",
    )
    .add_component_tag(
        tag_stereo="Gateway",
        bg_color="#fce4ec",
        font_color="#880e4f",
        border_color="#ec407a",
        shadowing=True,
        technology="Gateway",
        legend_text="API gateway",
        legend_sprite="server",
        border_style="BoldLine",
        border_thickness="2",
    )
    .add_component_tag(
        tag_stereo="Backend",
        bg_color="#ede7f6",
        font_color="#311b92",
        border_color="#7e57c2",
        shadowing=True,
        technology="Service",
        legend_text="Backend service",
        legend_sprite="server",
        border_style="SolidLine",
        border_thickness="2",
    )
    .add_component_tag(
        tag_stereo="Worker",
        bg_color="#fff3e0",
        font_color="#e65100",
        border_color="#fb8c00",
        shadowing=True,
        technology="Job",
        legend_text="Background worker",
        legend_sprite="server",
        border_style="SolidLine",
        border_thickness="2",
    )
    .add_component_tag(
        tag_stereo="Database",
        bg_color="#fff8e1",
        font_color="#5d4037",
        border_color="#ffb300",
        shadowing=False,
        technology="Database",
        legend_text="Operational datastore",
        legend_sprite="database",
    )
    .add_component_tag(
        tag_stereo="Queue",
        bg_color="#e0f2f1",
        font_color="#004d40",
        border_color="#26a69a",
        shadowing=False,
        technology="Queue",
        legend_text="Asynchronous event stream",
        legend_sprite="queue",
    )
    .add_external_component_tag(
        tag_stereo="External",
        bg_color="#f5f5f5",
        font_color="#424242",
        border_color="#9e9e9e",
        shadowing=False,
        technology="External",
        legend_text="External dependency",
        legend_sprite="cloud",
        border_style="DashedLine",
    )
    .add_rel_tag(
        tag_stereo="Sync",
        text_color="#1565c0",
        line_color="#1e88e5",
        line_style="SolidLine",
        technology="HTTPS",
        legend_text="Synchronous request",
    )
    .add_rel_tag(
        tag_stereo="DataAccess",
        text_color="#6d4c41",
        line_color="#8d6e63",
        line_style="DashedLine",
        technology="SQL",
        legend_text="Database access",
    )
    .add_rel_tag(
        tag_stereo="Async",
        text_color="#00695c",
        line_color="#00897b",
        line_style="DottedLine",
        line_thickness="2",
        technology="Queue/Event",
        legend_text="Asynchronous event flow",
        legend_sprite="queue",
    )
    .add_rel_tag(
        tag_stereo="ExternalCall",
        text_color="#455a64",
        line_color="#78909c",
        line_style="DashedLine",
        technology="External",
        legend_text="External integration",
    )
    .update_element_style(
        element_name="component",
        shape="RoundedBoxShape",
        border_style="SolidLine",
    )
    .build()
)

diagram.set_render_options(
    plantuml=plantuml_render_options,
)
Rendered PlantUML source
@startuml
' convert it with additional command line argument -DRELATIVE_INCLUDE="relative/absolute" to use locally
!if %variable_exists("RELATIVE_INCLUDE")
    !include %get_variable_value("RELATIVE_INCLUDE")/C4_Component.puml
!else
    !include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml
!endif

AddPersonTag("User", $bgColor="#e8f5e9", $fontColor="#1b5e20", $borderColor="#66bb6a", $shadowing="false", $legendText="Operational user", $legendSprite="user")
AddComponentTag("Frontend", $bgColor="#e3f2fd", $fontColor="#0d47a1", $borderColor="#42a5f5", $shadowing="true", $techn="UI", $legendText="User-facing frontend", $legendSprite="browser", $borderStyle=SolidLine(), $borderThickness="2")
AddComponentTag("Gateway", $bgColor="#fce4ec", $fontColor="#880e4f", $borderColor="#ec407a", $shadowing="true", $techn="Gateway", $legendText="API gateway", $legendSprite="server", $borderStyle=BoldLine(), $borderThickness="2")
AddComponentTag("Backend", $bgColor="#ede7f6", $fontColor="#311b92", $borderColor="#7e57c2", $shadowing="true", $techn="Service", $legendText="Backend service", $legendSprite="server", $borderStyle=SolidLine(), $borderThickness="2")
AddComponentTag("Worker", $bgColor="#fff3e0", $fontColor="#e65100", $borderColor="#fb8c00", $shadowing="true", $techn="Job", $legendText="Background worker", $legendSprite="server", $borderStyle=SolidLine(), $borderThickness="2")
AddComponentTag("Database", $bgColor="#fff8e1", $fontColor="#5d4037", $borderColor="#ffb300", $shadowing="false", $techn="Database", $legendText="Operational datastore", $legendSprite="database")
AddComponentTag("Queue", $bgColor="#e0f2f1", $fontColor="#004d40", $borderColor="#26a69a", $shadowing="false", $techn="Queue", $legendText="Asynchronous event stream", $legendSprite="queue")
AddExternalComponentTag("External", $bgColor="#f5f5f5", $fontColor="#424242", $borderColor="#9e9e9e", $shadowing="false", $techn="External", $legendText="External dependency", $legendSprite="cloud", $borderStyle=DashedLine())
AddRelTag("Sync", $textColor="#1565c0", $lineColor="#1e88e5", $lineStyle=SolidLine(), $techn="HTTPS", $legendText="Synchronous request")
AddRelTag("DataAccess", $textColor="#6d4c41", $lineColor="#8d6e63", $lineStyle=DashedLine(), $techn="SQL", $legendText="Database access")
AddRelTag("Async", $textColor="#00695c", $lineColor="#00897b", $lineStyle=DottedLine(), $techn="Queue/Event", $legendText="Asynchronous event flow", $legendSprite="queue", $lineThickness="2")
AddRelTag("ExternalCall", $textColor="#455a64", $lineColor="#78909c", $lineStyle=DashedLine(), $techn="External", $legendText="External integration")

UpdateElementStyle("component", $shape=RoundedBoxShape(), $borderStyle=SolidLine())

LAYOUT_TOP_DOWN()
LAYOUT_WITH_LEGEND()
UpdateLegendTitle("Customer Support Component Legend")

title Customer Support System - Extended Component View

Component(admin_api, "Admin API", "Container Service", "User management and reference-data management.", $tags="Backend")

Component(admin_portal, "Admin Portal", "Single-page Application", "Manages system users and reference data.", $tags="Frontend")

Person(administrator, "Administrator", "Internal user with administrative access.", $tags="User")

Component(analytics_api, "Analytics API", "Container Service", "Ticket status reports, survey analysis and performance reports.", $tags="Backend")

Component(api_gateway, "API Gateway", "Container Service", "Performs access control, security checks and request routing.", $tags="Gateway")

Component_Ext(auth0, "Auth0", "OIDC/OAuth2", "External identity provider for authentication.", $tags="External")

Component(billing_api, "Billing API", "Container Service", "Billing management and financial reports.", $tags="Backend")

Component(billing_portal, "Billing Portal", "Single-page Application", "Supports billing processing.", $tags="Frontend")

Person(customer, "Customer", "Owner of electronic equipment and support plan; reports issues.", $tags="User")

Component(customer_api, "Customer API", "Container Service", "Handles registration, profiles, tickets, surveys and billing history.", $tags="Backend")

ComponentQueue(customer_notifications_queue, "Customer Notifications", "Message Queue", "Asynchronous message channel for customer notifications.", $tags="Queue")

Component(customer_portal, "Customer Portal", "Single-page Application", "Provides access to customer profile, billing, ticket creation and history.", $tags="Frontend")

Component_Ext(email_system, "E-mail System", "SMTP", "Internal mail system used for e-mail delivery.", $tags="External")

ComponentQueue(expert_notifications_queue, "Expert Notifications", "Message Queue", "Asynchronous message channel for expert notifications.", $tags="Queue")

Person(helpdesk, "Helpdesk", "First line of support; provides direct phone support.", $tags="User")

Component(helpdesk_portal, "Helpdesk Portal", "Single-page Application", "Provides access to tickets and status.", $tags="Frontend")

ComponentQueue(invoice_queue, "Invoice", "Message Queue", "Asynchronous message channel for invoice processing.", $tags="Queue")

Component(knowledge_base, "Knowledge Base", "Single-page Application", "Supports searching and updating knowledge-base articles.", $tags="Frontend")

Person(manager, "Manager", "Monitors expert performance and customer satisfaction.", $tags="User")

Component(mobile_app, "Mobile App", "iOS / Android App", "Provides access to assigned tickets and knowledge-base search.", $tags="Frontend")

Component(notification_service, "Notification Service", "Container Service", "Sends SMS and e-mail messages based on notification preferences.", $tags="Backend")

Component(payment_job, "Payment", "Container Job", "Runs monthly and performs payment operations.", $tags="Worker")

Component_Ext(payment_provider, "Payment Service Provider", "HTTPS/API", "External online payment service.", $tags="External")

Component_Ext(sms_provider, "SMS Service Provider", "SMS API", "Provides SMS text messaging.", $tags="External")

Component(support_api, "Support API", "Container Service", "Ticket orchestration, search, assignment handling and knowledge-base updates.", $tags="Backend")

Component(support_dashboard, "Support Dashboard", "Single-page Application", "Provides analytics and operational reports.", $tags="Frontend")

ComponentDb(support_database, "Support Database", "Relational Database", "Stores tickets, users, customer contacts and knowledge-base content.", $tags="Database")

Person(support_expert, "Support Expert", "Technology expert who fixes customer electronic devices.", $tags="User")

ComponentQueue(ticket_assigned_queue, "Ticket Assigned", "Message Queue", "Asynchronous message channel for assigned tickets.", $tags="Queue")

ComponentQueue(ticket_created_queue, "Ticket Created", "Message Queue", "Asynchronous message channel for created tickets.", $tags="Queue")

ComponentQueue(ticket_progress_queue, "Ticket In-Progress/Closed", "Message Queue", "Asynchronous message channel for ticket progress and closure notifications.", $tags="Queue")

Component(ticket_processor, "Ticket Processor", "Container Job", "Runs periodically, scans ticket statuses, and creates assignments.", $tags="Worker")

Rel(admin_api, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(admin_portal, api_gateway, "Makes API calls to", "REST/HTTPS", $tags="Sync")
Rel(analytics_api, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(api_gateway, customer_api, "Routes API calls to", "REST/HTTP", $tags="Sync")
Rel(api_gateway, support_api, "Routes API calls to", "REST/HTTP", $tags="Sync")
Rel(api_gateway, admin_api, "Routes API calls to", "REST/HTTP", $tags="Sync")
Rel(api_gateway, billing_api, "Routes API calls to", "REST/HTTP", $tags="Sync")
Rel(api_gateway, analytics_api, "Routes API calls to", "REST/HTTP", $tags="Sync")
Rel(billing_api, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(billing_portal, api_gateway, "Makes API calls to", "REST/HTTPS", $tags="Sync")
Rel(customer_api, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(customer_api, ticket_created_queue, "Sends ticket created event", "Queue / Event", $tags="Async")
Rel(customer_portal, auth0, "Authenticates using", "OIDC/OAuth2", $tags="ExternalCall")
Rel(customer_portal, api_gateway, "Makes API calls to", "REST/HTTPS", $tags="Sync")
Rel(helpdesk_portal, api_gateway, "Makes API calls to", "REST/HTTPS", $tags="Sync")
Rel(knowledge_base, api_gateway, "Makes API calls to", "REST/HTTPS", $tags="Sync")
Rel(mobile_app, auth0, "Authenticates using", "OIDC/OAuth2", $tags="ExternalCall")
Rel(mobile_app, api_gateway, "Makes API calls to", "REST/HTTPS", $tags="Sync")
Rel(notification_service, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(notification_service, email_system, "Sends e-mail using", "SMTP", $tags="ExternalCall")
Rel(notification_service, sms_provider, "Sends SMS using", "SMS API", $tags="ExternalCall")
Rel(payment_job, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(payment_job, invoice_queue, "Sends invoice event", "Queue / Event", $tags="Async")
Rel(payment_job, payment_provider, "Executes payments using", "HTTPS/API", $tags="ExternalCall")
Rel(support_api, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(support_api, expert_notifications_queue, "Sends expert notification event", "Queue / Event", $tags="Async")
Rel(support_api, customer_notifications_queue, "Sends customer notification event", "Queue / Event", $tags="Async")
Rel(support_api, ticket_progress_queue, "Sends progress/closed event", "Queue / Event", $tags="Async")
Rel(support_dashboard, api_gateway, "Makes API calls to", "REST/HTTPS", $tags="Sync")
Rel(ticket_processor, support_database, "Reads from and writes to", "SQL/TCP", $tags="DataAccess")
Rel(ticket_processor, ticket_assigned_queue, "Sends ticket assignment event", "Queue / Event", $tags="Async")
Rel(administrator, admin_portal, "Maintains users and reference data", "HTTPS", $tags="Sync")
Rel(administrator, billing_portal, "Manages billing operations", "HTTPS", $tags="Sync")
Rel(customer, customer_portal, "Uses", "HTTPS", $tags="Sync")
Rel(customer, mobile_app, "Uses", "HTTPS", $tags="Sync")
Rel(helpdesk, helpdesk_portal, "Creates/searches tickets", "HTTPS", $tags="Sync")
Rel(manager, support_dashboard, "Tracks operations and generates reports", "HTTPS", $tags="Sync")
Rel(support_expert, mobile_app, "Uses", "HTTPS", $tags="Sync")
Rel(support_expert, knowledge_base, "Updates articles", "HTTPS", $tags="Sync")
Rel(customer_notifications_queue, notification_service, "Consumed by", "Queue / Event", $tags="Async")
Rel(expert_notifications_queue, notification_service, "Consumed by", "Queue / Event", $tags="Async")
Rel(invoice_queue, api_gateway, "Calls billing APIs through", "REST/HTTP", $tags="Async")
Rel(ticket_assigned_queue, support_api, "Consumed by", "Queue / Event", $tags="Async")
Rel(ticket_created_queue, ticket_processor, "Consumed by", "Queue / Event", $tags="Async")
Rel(ticket_progress_queue, customer_api, "Consumed by", "Queue / Event", $tags="Async")
SHOW_LEGEND($hideStereotype="false", $details=Normal())

@enduml

Mermaid extended customer support component example
Mermaid extended customer support component diagram

Python diagram
from __future__ import annotations

from c4 import (
    Component,
    ComponentDb,
    ComponentDiagram,
    ComponentExt,
    ComponentQueue,
    Person,
    Rel,
)
from c4.renderers import (
    MermaidRenderOptionsBuilder,
)


def mermaid_node(fill: str, stroke: str, font_color: str) -> dict[str, str]:
    return {
        "bg_color": fill,
        "border_color": stroke,
        "font_color": font_color,
    }


def mermaid_edge(color: str, text_color: str | None = None) -> dict[str, str]:
    return {
        "line_color": color,
        "text_color": text_color or color,
    }


MERMAID_USER = mermaid_node("#e8f5e9", "#66bb6a", "#1b5e20")
MERMAID_FRONTEND = mermaid_node("#e3f2fd", "#42a5f5", "#0d47a1")
MERMAID_GATEWAY = mermaid_node("#fce4ec", "#ec407a", "#880e4f")
MERMAID_BACKEND = mermaid_node("#ede7f6", "#7e57c2", "#311b92")
MERMAID_JOB = mermaid_node("#fff3e0", "#fb8c00", "#e65100")
MERMAID_DATABASE = mermaid_node("#fff8e1", "#ffb300", "#5d4037")
MERMAID_QUEUE = mermaid_node("#e0f2f1", "#26a69a", "#004d40")
MERMAID_EXTERNAL = mermaid_node("#f5f5f5", "#9e9e9e", "#424242")

MERMAID_SYNC = mermaid_edge("#1e88e5", "#1565c0")
MERMAID_ASYNC = mermaid_edge("#00897b", "#00695c")
MERMAID_DATA_ACCESS = mermaid_edge("#8d6e63", "#6d4c41")
MERMAID_EXTERNAL_CALL = mermaid_edge("#78909c", "#455a64")

with ComponentDiagram(
    title="Customer Support System - Extended Component View",
) as diagram:
    admin_api = Component(
        "Admin API",
        "User management and reference-data management.",
        technology="Container Service",
        alias="admin_api",
    )
    admin_portal = Component(
        "Admin Portal",
        "Manages system users and reference data.",
        technology="Single-page Application",
        alias="admin_portal",
    )
    administrator = Person(
        "Administrator",
        "Internal user with administrative access.",
        alias="administrator",
    )
    analytics_api = Component(
        "Analytics API",
        "Ticket status reports, survey analysis and performance reports.",
        technology="Container Service",
        alias="analytics_api",
    )
    api_gateway = Component(
        "API Gateway",
        "Performs access control, security checks and request routing.",
        technology="Container Service",
        alias="api_gateway",
    )
    auth0 = ComponentExt(
        "Auth0",
        "External identity provider for authentication.",
        technology="OIDC/OAuth2",
        alias="auth0",
    )
    billing_api = Component(
        "Billing API",
        "Billing management and financial reports.",
        technology="Container Service",
        alias="billing_api",
    )
    billing_portal = Component(
        "Billing Portal",
        "Supports billing processing.",
        technology="Single-page Application",
        alias="billing_portal",
    )
    customer = Person(
        "Customer",
        "Owner of electronic equipment and support plan; reports issues.",
        alias="customer",
    )
    customer_api = Component(
        "Customer API",
        "Handles registration, profiles, tickets, surveys and billing history.",
        technology="Container Service",
        alias="customer_api",
    )
    customer_notifications_queue = ComponentQueue(
        "Customer Notifications",
        "Asynchronous message channel for customer notifications.",
        technology="Message Queue",
        alias="customer_notifications_queue",
    )
    customer_portal = Component(
        "Customer Portal",
        "Provides access to customer profile, billing, ticket creation and history.",
        technology="Single-page Application",
        alias="customer_portal",
    )
    email_system = ComponentExt(
        "E-mail System",
        "Internal mail system used for e-mail delivery.",
        technology="SMTP",
        alias="email_system",
    )
    expert_notifications_queue = ComponentQueue(
        "Expert Notifications",
        "Asynchronous message channel for expert notifications.",
        technology="Message Queue",
        alias="expert_notifications_queue",
    )
    helpdesk = Person(
        "Helpdesk",
        "First line of support; provides direct phone support.",
        alias="helpdesk",
    )
    helpdesk_portal = Component(
        "Helpdesk Portal",
        "Provides access to tickets and status.",
        technology="Single-page Application",
        alias="helpdesk_portal",
    )
    invoice_queue = ComponentQueue(
        "Invoice",
        "Asynchronous message channel for invoice processing.",
        technology="Message Queue",
        alias="invoice_queue",
    )
    knowledge_base = Component(
        "Knowledge Base",
        "Supports searching and updating knowledge-base articles.",
        technology="Single-page Application",
        alias="knowledge_base",
    )
    manager = Person(
        "Manager",
        "Monitors expert performance and customer satisfaction.",
        alias="manager",
    )
    mobile_app = Component(
        "Mobile App",
        "Provides access to assigned tickets and knowledge-base search.",
        technology="iOS / Android App",
        alias="mobile_app",
    )
    notification_service = Component(
        "Notification Service",
        "Sends SMS and e-mail messages based on notification preferences.",
        technology="Container Service",
        alias="notification_service",
    )
    payment_job = Component(
        "Payment",
        "Runs monthly and performs payment operations.",
        technology="Container Job",
        alias="payment_job",
    )
    payment_provider = ComponentExt(
        "Payment Service Provider",
        "External online payment service.",
        technology="HTTPS/API",
        alias="payment_provider",
    )
    sms_provider = ComponentExt(
        "SMS Service Provider",
        "Provides SMS text messaging.",
        technology="SMS API",
        alias="sms_provider",
    )
    support_api = Component(
        "Support API",
        "Ticket orchestration, search, assignment handling and knowledge-base updates.",
        technology="Container Service",
        alias="support_api",
    )
    support_dashboard = Component(
        "Support Dashboard",
        "Provides analytics and operational reports.",
        technology="Single-page Application",
        alias="support_dashboard",
    )
    support_database = ComponentDb(
        "Support Database",
        "Stores tickets, users, customer contacts and knowledge-base content.",
        technology="Relational Database",
        alias="support_database",
    )
    support_expert = Person(
        "Support Expert",
        "Technology expert who fixes customer electronic devices.",
        alias="support_expert",
    )
    ticket_assigned_queue = ComponentQueue(
        "Ticket Assigned",
        "Asynchronous message channel for assigned tickets.",
        technology="Message Queue",
        alias="ticket_assigned_queue",
    )
    ticket_created_queue = ComponentQueue(
        "Ticket Created",
        "Asynchronous message channel for created tickets.",
        technology="Message Queue",
        alias="ticket_created_queue",
    )
    ticket_progress_queue = ComponentQueue(
        "Ticket In-Progress/Closed",
        "Asynchronous message channel for ticket progress and closure notifications.",
        technology="Message Queue",
        alias="ticket_progress_queue",
    )
    ticket_processor = Component(
        "Ticket Processor",
        "Runs periodically, scans ticket statuses, and creates assignments.",
        technology="Container Job",
        alias="ticket_processor",
    )

    (
        admin_api
        >> Rel("Reads from and writes to", technology="SQL/TCP")
        >> support_database
    )
    (
        admin_portal
        >> Rel("Makes API calls to", technology="REST/HTTPS")
        >> api_gateway
    )
    (
        analytics_api
        >> Rel("Reads from and writes to", technology="SQL/TCP")
        >> support_database
    )
    (
        api_gateway
        >> Rel("Routes API calls to", technology="REST/HTTP")
        >> customer_api
    )
    (
        api_gateway
        >> Rel("Routes API calls to", technology="REST/HTTP")
        >> support_api
    )
    (
        api_gateway
        >> Rel("Routes API calls to", technology="REST/HTTP")
        >> admin_api
    )
    (
        api_gateway
        >> Rel("Routes API calls to", technology="REST/HTTP")
        >> billing_api
    )
    (
        api_gateway
        >> Rel("Routes API calls to", technology="REST/HTTP")
        >> analytics_api
    )
    (
        billing_api
        >> Rel("Reads from and writes to", technology="SQL/TCP")
        >> support_database
    )
    (
        billing_portal
        >> Rel("Makes API calls to", technology="REST/HTTPS")
        >> api_gateway
    )
    (
        customer_api
        >> Rel("Reads from and writes to", technology="SQL/TCP")
        >> support_database
    )
    (
        customer_api
        >> Rel("Sends ticket created event", technology="Queue / Event")
        >> ticket_created_queue
    )
    (
        customer_portal
        >> Rel(
            "Authenticates using",
            technology="OIDC/OAuth2",
        )
        >> auth0
    )
    (
        customer_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
        )
        >> api_gateway
    )
    (
        helpdesk_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
        )
        >> api_gateway
    )
    (
        knowledge_base
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
        )
        >> api_gateway
    )
    (
        mobile_app
        >> Rel(
            "Authenticates using",
            technology="OIDC/OAuth2",
        )
        >> auth0
    )
    (
        mobile_app
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
        )
        >> api_gateway
    )
    (
        notification_service
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
        )
        >> support_database
    )
    (
        notification_service
        >> Rel(
            "Sends e-mail using",
            technology="SMTP",
        )
        >> email_system
    )
    (
        notification_service
        >> Rel(
            "Sends SMS using",
            technology="SMS API",
        )
        >> sms_provider
    )
    (
        payment_job
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
        )
        >> support_database
    )
    (
        payment_job
        >> Rel(
            "Sends invoice event",
            technology="Queue / Event",
        )
        >> invoice_queue
    )
    (
        payment_job
        >> Rel(
            "Executes payments using",
            technology="HTTPS/API",
        )
        >> payment_provider
    )
    (
        support_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
        )
        >> support_database
    )
    (
        support_api
        >> Rel(
            "Sends expert notification event",
            technology="Queue / Event",
        )
        >> expert_notifications_queue
    )
    (
        support_api
        >> Rel(
            "Sends customer notification event",
            technology="Queue / Event",
        )
        >> customer_notifications_queue
    )
    (
        support_api
        >> Rel(
            "Sends progress/closed event",
            technology="Queue / Event",
        )
        >> ticket_progress_queue
    )
    (
        support_dashboard
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
        )
        >> api_gateway
    )
    (
        ticket_processor
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
        )
        >> support_database
    )
    (
        ticket_processor
        >> Rel(
            "Sends ticket assignment event",
            technology="Queue / Event",
        )
        >> ticket_assigned_queue
    )
    (
        administrator
        >> Rel(
            "Maintains users and reference data",
            technology="HTTPS",
        )
        >> admin_portal
    )
    (
        administrator
        >> Rel(
            "Manages billing operations",
            technology="HTTPS",
        )
        >> billing_portal
    )
    customer >> Rel("Uses", technology="HTTPS") >> customer_portal
    customer >> Rel("Uses", technology="HTTPS") >> mobile_app
    (
        helpdesk
        >> Rel(
            "Creates/searches tickets",
            technology="HTTPS",
        )
        >> helpdesk_portal
    )
    (
        manager
        >> Rel(
            "Tracks operations and generates reports",
            technology="HTTPS",
        )
        >> support_dashboard
    )
    support_expert >> Rel("Uses", technology="HTTPS") >> mobile_app
    (
        support_expert
        >> Rel(
            "Updates articles",
            technology="HTTPS",
        )
        >> knowledge_base
    )
    (
        customer_notifications_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
        )
        >> notification_service
    )
    (
        expert_notifications_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
        )
        >> notification_service
    )
    (
        invoice_queue
        >> Rel(
            "Calls billing APIs through",
            technology="REST/HTTP",
        )
        >> api_gateway
    )
    (
        ticket_assigned_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
        )
        >> support_api
    )
    (
        ticket_created_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
        )
        >> ticket_processor
    )
    (
        ticket_progress_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
        )
        >> customer_api
    )

mermaid_render_options_builder = (
    MermaidRenderOptionsBuilder().update_layout_config(
        c4_shape_in_row=5,
        c4_boundary_in_row=1,
    )
)

for element in (administrator, customer, helpdesk, manager, support_expert):
    mermaid_render_options_builder.update_element_style(element, **MERMAID_USER)

for element in (
    admin_portal,
    billing_portal,
    customer_portal,
    helpdesk_portal,
    knowledge_base,
    mobile_app,
    support_dashboard,
):
    mermaid_render_options_builder.update_element_style(
        element, **MERMAID_FRONTEND
    )

for element in (
    admin_api,
    analytics_api,
    billing_api,
    customer_api,
    notification_service,
    support_api,
):
    mermaid_render_options_builder.update_element_style(
        element, **MERMAID_BACKEND
    )

for element in (auth0, email_system, payment_provider, sms_provider):
    mermaid_render_options_builder.update_element_style(
        element, **MERMAID_EXTERNAL
    )

for element in (
    customer_notifications_queue,
    expert_notifications_queue,
    invoice_queue,
    ticket_assigned_queue,
    ticket_created_queue,
    ticket_progress_queue,
):
    mermaid_render_options_builder.update_element_style(
        element, **MERMAID_QUEUE
    )

mermaid_render_options_builder.update_element_style(
    api_gateway, **MERMAID_GATEWAY
)
mermaid_render_options_builder.update_element_style(payment_job, **MERMAID_JOB)
mermaid_render_options_builder.update_element_style(
    ticket_processor, **MERMAID_JOB
)
mermaid_render_options_builder.update_element_style(
    support_database, **MERMAID_DATABASE
)

for source, target in (
    (admin_api, support_database),
    (analytics_api, support_database),
    (billing_api, support_database),
    (customer_api, support_database),
    (notification_service, support_database),
    (payment_job, support_database),
    (support_api, support_database),
    (ticket_processor, support_database),
):
    mermaid_render_options_builder.update_rel_style(
        source,
        target,
        offset_y=-35,
        **MERMAID_DATA_ACCESS,
    )

for source, target in (
    (customer_api, ticket_created_queue),
    (payment_job, invoice_queue),
    (support_api, expert_notifications_queue),
    (support_api, customer_notifications_queue),
    (support_api, ticket_progress_queue),
    (ticket_processor, ticket_assigned_queue),
    (customer_notifications_queue, notification_service),
    (expert_notifications_queue, notification_service),
    (invoice_queue, api_gateway),
    (ticket_assigned_queue, support_api),
    (ticket_created_queue, ticket_processor),
    (ticket_progress_queue, customer_api),
):
    mermaid_render_options_builder.update_rel_style(
        source,
        target,
        offset_y=35,
        **MERMAID_ASYNC,
    )

for source, target in (
    (customer_portal, auth0),
    (mobile_app, auth0),
    (notification_service, email_system),
    (notification_service, sms_provider),
    (payment_job, payment_provider),
):
    mermaid_render_options_builder.update_rel_style(
        source,
        target,
        offset_y=-35,
        **MERMAID_EXTERNAL_CALL,
    )

for source, target in (
    (admin_portal, api_gateway),
    (api_gateway, customer_api),
    (api_gateway, support_api),
    (api_gateway, admin_api),
    (api_gateway, billing_api),
    (api_gateway, analytics_api),
    (billing_portal, api_gateway),
    (customer_portal, api_gateway),
    (helpdesk_portal, api_gateway),
    (knowledge_base, api_gateway),
    (mobile_app, api_gateway),
    (support_dashboard, api_gateway),
    (administrator, admin_portal),
    (administrator, billing_portal),
    (customer, customer_portal),
    (customer, mobile_app),
    (helpdesk, helpdesk_portal),
    (manager, support_dashboard),
    (support_expert, mobile_app),
    (support_expert, knowledge_base),
):
    mermaid_render_options_builder.update_rel_style(
        source, target, **MERMAID_SYNC
    )

diagram.set_render_options(
    mermaid=mermaid_render_options_builder.build(),
)
Rendered Mermaid source
C4Component
title Customer Support System - Extended Component View

Component(admin_api, "Admin API", "Container Service", "User management and reference-data management.")

Component(admin_portal, "Admin Portal", "Single-page Application", "Manages system users and reference data.")

Person(administrator, "Administrator", "Internal user with administrative access.")

Component(analytics_api, "Analytics API", "Container Service", "Ticket status reports, survey analysis and performance reports.")

Component(api_gateway, "API Gateway", "Container Service", "Performs access control, security checks and request routing.")

Component_Ext(auth0, "Auth0", "OIDC/OAuth2", "External identity provider for authentication.")

Component(billing_api, "Billing API", "Container Service", "Billing management and financial reports.")

Component(billing_portal, "Billing Portal", "Single-page Application", "Supports billing processing.")

Person(customer, "Customer", "Owner of electronic equipment and support plan; reports issues.")

Component(customer_api, "Customer API", "Container Service", "Handles registration, profiles, tickets, surveys and billing history.")

ComponentQueue(customer_notifications_queue, "Customer Notifications", "Message Queue", "Asynchronous message channel for customer notifications.")

Component(customer_portal, "Customer Portal", "Single-page Application", "Provides access to customer profile, billing, ticket creation and history.")

Component_Ext(email_system, "E-mail System", "SMTP", "Internal mail system used for e-mail delivery.")

ComponentQueue(expert_notifications_queue, "Expert Notifications", "Message Queue", "Asynchronous message channel for expert notifications.")

Person(helpdesk, "Helpdesk", "First line of support; provides direct phone support.")

Component(helpdesk_portal, "Helpdesk Portal", "Single-page Application", "Provides access to tickets and status.")

ComponentQueue(invoice_queue, "Invoice", "Message Queue", "Asynchronous message channel for invoice processing.")

Component(knowledge_base, "Knowledge Base", "Single-page Application", "Supports searching and updating knowledge-base articles.")

Person(manager, "Manager", "Monitors expert performance and customer satisfaction.")

Component(mobile_app, "Mobile App", "iOS / Android App", "Provides access to assigned tickets and knowledge-base search.")

Component(notification_service, "Notification Service", "Container Service", "Sends SMS and e-mail messages based on notification preferences.")

Component(payment_job, "Payment", "Container Job", "Runs monthly and performs payment operations.")

Component_Ext(payment_provider, "Payment Service Provider", "HTTPS/API", "External online payment service.")

Component_Ext(sms_provider, "SMS Service Provider", "SMS API", "Provides SMS text messaging.")

Component(support_api, "Support API", "Container Service", "Ticket orchestration, search, assignment handling and knowledge-base updates.")

Component(support_dashboard, "Support Dashboard", "Single-page Application", "Provides analytics and operational reports.")

ComponentDb(support_database, "Support Database", "Relational Database", "Stores tickets, users, customer contacts and knowledge-base content.")

Person(support_expert, "Support Expert", "Technology expert who fixes customer electronic devices.")

ComponentQueue(ticket_assigned_queue, "Ticket Assigned", "Message Queue", "Asynchronous message channel for assigned tickets.")

ComponentQueue(ticket_created_queue, "Ticket Created", "Message Queue", "Asynchronous message channel for created tickets.")

ComponentQueue(ticket_progress_queue, "Ticket In-Progress/Closed", "Message Queue", "Asynchronous message channel for ticket progress and closure notifications.")

Component(ticket_processor, "Ticket Processor", "Container Job", "Runs periodically, scans ticket statuses, and creates assignments.")

Rel(admin_api, support_database, "Reads from and writes to", "SQL/TCP")

Rel(admin_portal, api_gateway, "Makes API calls to", "REST/HTTPS")

Rel(analytics_api, support_database, "Reads from and writes to", "SQL/TCP")

Rel(api_gateway, customer_api, "Routes API calls to", "REST/HTTP")

Rel(api_gateway, support_api, "Routes API calls to", "REST/HTTP")

Rel(api_gateway, admin_api, "Routes API calls to", "REST/HTTP")

Rel(api_gateway, billing_api, "Routes API calls to", "REST/HTTP")

Rel(api_gateway, analytics_api, "Routes API calls to", "REST/HTTP")

Rel(billing_api, support_database, "Reads from and writes to", "SQL/TCP")

Rel(billing_portal, api_gateway, "Makes API calls to", "REST/HTTPS")

Rel(customer_api, support_database, "Reads from and writes to", "SQL/TCP")

Rel(customer_api, ticket_created_queue, "Sends ticket created event", "Queue / Event")

Rel(customer_portal, auth0, "Authenticates using", "OIDC/OAuth2")

Rel(customer_portal, api_gateway, "Makes API calls to", "REST/HTTPS")

Rel(helpdesk_portal, api_gateway, "Makes API calls to", "REST/HTTPS")

Rel(knowledge_base, api_gateway, "Makes API calls to", "REST/HTTPS")

Rel(mobile_app, auth0, "Authenticates using", "OIDC/OAuth2")

Rel(mobile_app, api_gateway, "Makes API calls to", "REST/HTTPS")

Rel(notification_service, support_database, "Reads from and writes to", "SQL/TCP")

Rel(notification_service, email_system, "Sends e-mail using", "SMTP")

Rel(notification_service, sms_provider, "Sends SMS using", "SMS API")

Rel(payment_job, support_database, "Reads from and writes to", "SQL/TCP")

Rel(payment_job, invoice_queue, "Sends invoice event", "Queue / Event")

Rel(payment_job, payment_provider, "Executes payments using", "HTTPS/API")

Rel(support_api, support_database, "Reads from and writes to", "SQL/TCP")

Rel(support_api, expert_notifications_queue, "Sends expert notification event", "Queue / Event")

Rel(support_api, customer_notifications_queue, "Sends customer notification event", "Queue / Event")

Rel(support_api, ticket_progress_queue, "Sends progress/closed event", "Queue / Event")

Rel(support_dashboard, api_gateway, "Makes API calls to", "REST/HTTPS")

Rel(ticket_processor, support_database, "Reads from and writes to", "SQL/TCP")

Rel(ticket_processor, ticket_assigned_queue, "Sends ticket assignment event", "Queue / Event")

Rel(administrator, admin_portal, "Maintains users and reference data", "HTTPS")

Rel(administrator, billing_portal, "Manages billing operations", "HTTPS")

Rel(customer, customer_portal, "Uses", "HTTPS")

Rel(customer, mobile_app, "Uses", "HTTPS")

Rel(helpdesk, helpdesk_portal, "Creates/searches tickets", "HTTPS")

Rel(manager, support_dashboard, "Tracks operations and generates reports", "HTTPS")

Rel(support_expert, mobile_app, "Uses", "HTTPS")

Rel(support_expert, knowledge_base, "Updates articles", "HTTPS")

Rel(customer_notifications_queue, notification_service, "Consumed by", "Queue / Event")

Rel(expert_notifications_queue, notification_service, "Consumed by", "Queue / Event")

Rel(invoice_queue, api_gateway, "Calls billing APIs through", "REST/HTTP")

Rel(ticket_assigned_queue, support_api, "Consumed by", "Queue / Event")

Rel(ticket_created_queue, ticket_processor, "Consumed by", "Queue / Event")

Rel(ticket_progress_queue, customer_api, "Consumed by", "Queue / Event")

UpdateElementStyle(administrator, $fontColor="#1b5e20", $bgColor="#e8f5e9", $borderColor="#66bb6a")
UpdateElementStyle(customer, $fontColor="#1b5e20", $bgColor="#e8f5e9", $borderColor="#66bb6a")
UpdateElementStyle(helpdesk, $fontColor="#1b5e20", $bgColor="#e8f5e9", $borderColor="#66bb6a")
UpdateElementStyle(manager, $fontColor="#1b5e20", $bgColor="#e8f5e9", $borderColor="#66bb6a")
UpdateElementStyle(support_expert, $fontColor="#1b5e20", $bgColor="#e8f5e9", $borderColor="#66bb6a")
UpdateElementStyle(admin_portal, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(billing_portal, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(customer_portal, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(helpdesk_portal, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(knowledge_base, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(mobile_app, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(support_dashboard, $fontColor="#0d47a1", $bgColor="#e3f2fd", $borderColor="#42a5f5")
UpdateElementStyle(admin_api, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(analytics_api, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(billing_api, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(customer_api, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(notification_service, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(support_api, $fontColor="#311b92", $bgColor="#ede7f6", $borderColor="#7e57c2")
UpdateElementStyle(auth0, $fontColor="#424242", $bgColor="#f5f5f5", $borderColor="#9e9e9e")
UpdateElementStyle(email_system, $fontColor="#424242", $bgColor="#f5f5f5", $borderColor="#9e9e9e")
UpdateElementStyle(payment_provider, $fontColor="#424242", $bgColor="#f5f5f5", $borderColor="#9e9e9e")
UpdateElementStyle(sms_provider, $fontColor="#424242", $bgColor="#f5f5f5", $borderColor="#9e9e9e")
UpdateElementStyle(customer_notifications_queue, $fontColor="#004d40", $bgColor="#e0f2f1", $borderColor="#26a69a")
UpdateElementStyle(expert_notifications_queue, $fontColor="#004d40", $bgColor="#e0f2f1", $borderColor="#26a69a")
UpdateElementStyle(invoice_queue, $fontColor="#004d40", $bgColor="#e0f2f1", $borderColor="#26a69a")
UpdateElementStyle(ticket_assigned_queue, $fontColor="#004d40", $bgColor="#e0f2f1", $borderColor="#26a69a")
UpdateElementStyle(ticket_created_queue, $fontColor="#004d40", $bgColor="#e0f2f1", $borderColor="#26a69a")
UpdateElementStyle(ticket_progress_queue, $fontColor="#004d40", $bgColor="#e0f2f1", $borderColor="#26a69a")
UpdateElementStyle(api_gateway, $fontColor="#880e4f", $bgColor="#fce4ec", $borderColor="#ec407a")
UpdateElementStyle(payment_job, $fontColor="#e65100", $bgColor="#fff3e0", $borderColor="#fb8c00")
UpdateElementStyle(ticket_processor, $fontColor="#e65100", $bgColor="#fff3e0", $borderColor="#fb8c00")
UpdateElementStyle(support_database, $fontColor="#5d4037", $bgColor="#fff8e1", $borderColor="#ffb300")
UpdateRelStyle(admin_api, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(analytics_api, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(billing_api, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(customer_api, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(notification_service, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(payment_job, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(support_api, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(ticket_processor, support_database, $textColor="#6d4c41", $lineColor="#8d6e63", $offsetY="-35")
UpdateRelStyle(customer_api, ticket_created_queue, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(payment_job, invoice_queue, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(support_api, expert_notifications_queue, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(support_api, customer_notifications_queue, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(support_api, ticket_progress_queue, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(ticket_processor, ticket_assigned_queue, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(customer_notifications_queue, notification_service, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(expert_notifications_queue, notification_service, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(invoice_queue, api_gateway, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(ticket_assigned_queue, support_api, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(ticket_created_queue, ticket_processor, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(ticket_progress_queue, customer_api, $textColor="#00695c", $lineColor="#00897b", $offsetY="35")
UpdateRelStyle(customer_portal, auth0, $textColor="#455a64", $lineColor="#78909c", $offsetY="-35")
UpdateRelStyle(mobile_app, auth0, $textColor="#455a64", $lineColor="#78909c", $offsetY="-35")
UpdateRelStyle(notification_service, email_system, $textColor="#455a64", $lineColor="#78909c", $offsetY="-35")
UpdateRelStyle(notification_service, sms_provider, $textColor="#455a64", $lineColor="#78909c", $offsetY="-35")
UpdateRelStyle(payment_job, payment_provider, $textColor="#455a64", $lineColor="#78909c", $offsetY="-35")
UpdateRelStyle(admin_portal, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(api_gateway, customer_api, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(api_gateway, support_api, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(api_gateway, admin_api, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(api_gateway, billing_api, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(api_gateway, analytics_api, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(billing_portal, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(customer_portal, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(helpdesk_portal, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(knowledge_base, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(mobile_app, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(support_dashboard, api_gateway, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(administrator, admin_portal, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(administrator, billing_portal, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(customer, customer_portal, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(customer, mobile_app, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(helpdesk, helpdesk_portal, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(manager, support_dashboard, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(support_expert, mobile_app, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateRelStyle(support_expert, knowledge_base, $textColor="#1565c0", $lineColor="#1e88e5")
UpdateLayoutConfig($c4ShapeInRow="5", $c4BoundaryInRow="1")

D2 extended customer support component example
D2 extended customer support component diagram

Python diagram
from __future__ import annotations

from c4 import (
    Component,
    ComponentDb,
    ComponentDiagram,
    ComponentExt,
    ComponentQueue,
    Person,
    Rel,
)
from c4.renderers import (
    D2Legend,
    D2LegendElement,
    D2LegendRel,
    D2RenderOptionsBuilder,
)


def d2_node(
    fill: str,
    stroke: str,
    font_color: str,
    shape: str | None = None,
    stroke_dash: int | None = None,
) -> dict[str, object]:
    style: dict[str, object] = {
        "fill": fill,
        "stroke": stroke,
        "font_color": font_color,
        "stroke_width": 2,
    }
    if stroke_dash is not None:
        style["stroke_dash"] = stroke_dash

    node: dict[str, object] = {"style": style}
    if shape:
        node["shape"] = shape

    return node


def d2_edge(
    color: str,
    text_color: str | None = None,
    stroke_dash: int | None = None,
) -> dict[str, object]:
    style: dict[str, object] = {
        "stroke": color,
        "font_color": text_color or color,
    }
    if stroke_dash is not None:
        style["stroke_dash"] = stroke_dash

    return {"style": style}


USER = d2_node("#e8f5e9", "#66bb6a", "#1b5e20", shape="c4-person")
FRONTEND = d2_node("#e3f2fd", "#42a5f5", "#0d47a1")
GATEWAY = d2_node("#fce4ec", "#ec407a", "#880e4f")
BACKEND = d2_node("#ede7f6", "#7e57c2", "#311b92")
JOB = d2_node("#fff3e0", "#fb8c00", "#e65100")
DATABASE = d2_node("#fff8e1", "#ffb300", "#5d4037")
QUEUE = d2_node("#e0f2f1", "#26a69a", "#004d40")
EXTERNAL = d2_node("#f5f5f5", "#9e9e9e", "#424242", stroke_dash=5)

SYNC = d2_edge("#1e88e5", "#1565c0")
ASYNC = d2_edge("#00897b", "#00695c", stroke_dash=3)
DATA_ACCESS = d2_edge("#8d6e63", "#6d4c41")
EXTERNAL_CALL = d2_edge("#78909c", "#455a64", stroke_dash=5)

with ComponentDiagram(
    title="Customer Support System - Extended Component View",
) as diagram:
    admin_api = Component(
        "Admin API",
        "User management and reference-data management.",
        technology="Container Service",
        alias="admin_api",
        d2=BACKEND,
    )
    admin_portal = Component(
        "Admin Portal",
        "Manages system users and reference data.",
        technology="Single-page Application",
        alias="admin_portal",
        d2=FRONTEND,
    )
    administrator = Person(
        "Administrator",
        "Internal user with administrative access.",
        alias="administrator",
        d2=USER,
    )
    analytics_api = Component(
        "Analytics API",
        "Ticket status reports, survey analysis and performance reports.",
        technology="Container Service",
        alias="analytics_api",
        d2=BACKEND,
    )
    api_gateway = Component(
        "API Gateway",
        "Performs access control, security checks and request routing.",
        technology="Container Service",
        alias="api_gateway",
        d2=GATEWAY,
    )
    auth0 = ComponentExt(
        "Auth0",
        "External identity provider for authentication.",
        technology="OIDC/OAuth2",
        alias="auth0",
        d2=EXTERNAL,
    )
    billing_api = Component(
        "Billing API",
        "Billing management and financial reports.",
        technology="Container Service",
        alias="billing_api",
        d2=BACKEND,
    )
    billing_portal = Component(
        "Billing Portal",
        "Supports billing processing.",
        technology="Single-page Application",
        alias="billing_portal",
        d2=FRONTEND,
    )
    customer = Person(
        "Customer",
        "Owner of electronic equipment and support plan; reports issues.",
        alias="customer",
        d2=USER,
    )
    customer_api = Component(
        "Customer API",
        "Handles registration, profiles, tickets, surveys and billing history.",
        technology="Container Service",
        alias="customer_api",
        d2=BACKEND,
    )
    customer_notifications_queue = ComponentQueue(
        "Customer Notifications",
        "Asynchronous message channel for customer notifications.",
        technology="Message Queue",
        alias="customer_notifications_queue",
        d2=QUEUE,
    )
    customer_portal = Component(
        "Customer Portal",
        "Provides access to customer profile, billing, ticket creation and history.",
        technology="Single-page Application",
        alias="customer_portal",
        d2=FRONTEND,
    )
    email_system = ComponentExt(
        "E-mail System",
        "Internal mail system used for e-mail delivery.",
        technology="SMTP",
        alias="email_system",
        d2=EXTERNAL,
    )
    expert_notifications_queue = ComponentQueue(
        "Expert Notifications",
        "Asynchronous message channel for expert notifications.",
        technology="Message Queue",
        alias="expert_notifications_queue",
        d2=QUEUE,
    )
    helpdesk = Person(
        "Helpdesk",
        "First line of support; provides direct phone support.",
        alias="helpdesk",
        d2=USER,
    )
    helpdesk_portal = Component(
        "Helpdesk Portal",
        "Provides access to tickets and status.",
        technology="Single-page Application",
        alias="helpdesk_portal",
        d2=FRONTEND,
    )
    invoice_queue = ComponentQueue(
        "Invoice",
        "Asynchronous message channel for invoice processing.",
        technology="Message Queue",
        alias="invoice_queue",
        d2=QUEUE,
    )
    knowledge_base = Component(
        "Knowledge Base",
        "Supports searching and updating knowledge-base articles.",
        technology="Single-page Application",
        alias="knowledge_base",
        d2=FRONTEND,
    )
    manager = Person(
        "Manager",
        "Monitors expert performance and customer satisfaction.",
        alias="manager",
        d2=USER,
    )
    mobile_app = Component(
        "Mobile App",
        "Provides access to assigned tickets and knowledge-base search.",
        technology="iOS / Android App",
        alias="mobile_app",
        d2=FRONTEND,
    )
    notification_service = Component(
        "Notification Service",
        "Sends SMS and e-mail messages based on notification preferences.",
        technology="Container Service",
        alias="notification_service",
        d2=BACKEND,
    )
    payment_job = Component(
        "Payment",
        "Runs monthly and performs payment operations.",
        technology="Container Job",
        alias="payment_job",
        d2=JOB,
    )
    payment_provider = ComponentExt(
        "Payment Service Provider",
        "External online payment service.",
        technology="HTTPS/API",
        alias="payment_provider",
        d2=EXTERNAL,
    )
    sms_provider = ComponentExt(
        "SMS Service Provider",
        "Provides SMS text messaging.",
        technology="SMS API",
        alias="sms_provider",
        d2=EXTERNAL,
    )
    support_api = Component(
        "Support API",
        "Ticket orchestration, search, assignment handling and knowledge-base updates.",
        technology="Container Service",
        alias="support_api",
        d2=BACKEND,
    )
    support_dashboard = Component(
        "Support Dashboard",
        "Provides analytics and operational reports.",
        technology="Single-page Application",
        alias="support_dashboard",
        d2=FRONTEND,
    )
    support_database = ComponentDb(
        "Support Database",
        "Stores tickets, users, customer contacts and knowledge-base content.",
        technology="Relational Database",
        alias="support_database",
        d2=DATABASE,
    )
    support_expert = Person(
        "Support Expert",
        "Technology expert who fixes customer electronic devices.",
        alias="support_expert",
        d2=USER,
    )
    ticket_assigned_queue = ComponentQueue(
        "Ticket Assigned",
        "Asynchronous message channel for assigned tickets.",
        technology="Message Queue",
        alias="ticket_assigned_queue",
        d2=QUEUE,
    )
    ticket_created_queue = ComponentQueue(
        "Ticket Created",
        "Asynchronous message channel for created tickets.",
        technology="Message Queue",
        alias="ticket_created_queue",
        d2=QUEUE,
    )
    ticket_progress_queue = ComponentQueue(
        "Ticket In-Progress/Closed",
        "Asynchronous message channel for ticket progress and closure notifications.",
        technology="Message Queue",
        alias="ticket_progress_queue",
        d2=QUEUE,
    )
    ticket_processor = Component(
        "Ticket Processor",
        "Runs periodically, scans ticket statuses, and creates assignments.",
        technology="Container Job",
        alias="ticket_processor",
        d2=JOB,
    )

    (
        admin_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        admin_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            d2=SYNC,
        )
        >> api_gateway
    )
    (
        analytics_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            d2=SYNC,
        )
        >> customer_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            d2=SYNC,
        )
        >> support_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            d2=SYNC,
        )
        >> admin_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            d2=SYNC,
        )
        >> billing_api
    )
    (
        api_gateway
        >> Rel(
            "Routes API calls to",
            technology="REST/HTTP",
            d2=SYNC,
        )
        >> analytics_api
    )
    (
        billing_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        billing_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            d2=SYNC,
        )
        >> api_gateway
    )
    (
        customer_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        customer_api
        >> Rel(
            "Sends ticket created event",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> ticket_created_queue
    )
    (
        customer_portal
        >> Rel(
            "Authenticates using",
            technology="OIDC/OAuth2",
            d2=EXTERNAL_CALL,
        )
        >> auth0
    )
    (
        customer_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            d2=SYNC,
        )
        >> api_gateway
    )
    (
        helpdesk_portal
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            d2=SYNC,
        )
        >> api_gateway
    )
    (
        knowledge_base
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            d2=SYNC,
        )
        >> api_gateway
    )
    (
        mobile_app
        >> Rel(
            "Authenticates using",
            technology="OIDC/OAuth2",
            d2=EXTERNAL_CALL,
        )
        >> auth0
    )
    (
        mobile_app
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            d2=SYNC,
        )
        >> api_gateway
    )
    (
        notification_service
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        notification_service
        >> Rel(
            "Sends e-mail using",
            technology="SMTP",
            d2=EXTERNAL_CALL,
        )
        >> email_system
    )
    (
        notification_service
        >> Rel(
            "Sends SMS using",
            technology="SMS API",
            d2=EXTERNAL_CALL,
        )
        >> sms_provider
    )
    (
        payment_job
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        payment_job
        >> Rel(
            "Sends invoice event",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> invoice_queue
    )
    (
        payment_job
        >> Rel(
            "Executes payments using",
            technology="HTTPS/API",
            d2=EXTERNAL_CALL,
        )
        >> payment_provider
    )
    (
        support_api
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        support_api
        >> Rel(
            "Sends expert notification event",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> expert_notifications_queue
    )
    (
        support_api
        >> Rel(
            "Sends customer notification event",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> customer_notifications_queue
    )
    (
        support_api
        >> Rel(
            "Sends progress/closed event",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> ticket_progress_queue
    )
    (
        support_dashboard
        >> Rel(
            "Makes API calls to",
            technology="REST/HTTPS",
            d2=SYNC,
        )
        >> api_gateway
    )
    (
        ticket_processor
        >> Rel(
            "Reads from and writes to",
            technology="SQL/TCP",
            d2=DATA_ACCESS,
        )
        >> support_database
    )
    (
        ticket_processor
        >> Rel(
            "Sends ticket assignment event",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> ticket_assigned_queue
    )
    (
        administrator
        >> Rel(
            "Maintains users and reference data",
            technology="HTTPS",
            d2=SYNC,
        )
        >> admin_portal
    )
    (
        administrator
        >> Rel(
            "Manages billing operations",
            technology="HTTPS",
            d2=SYNC,
        )
        >> billing_portal
    )
    customer >> Rel("Uses", technology="HTTPS", d2=SYNC) >> customer_portal
    customer >> Rel("Uses", technology="HTTPS", d2=SYNC) >> mobile_app
    (
        helpdesk
        >> Rel(
            "Creates/searches tickets",
            technology="HTTPS",
            d2=SYNC,
        )
        >> helpdesk_portal
    )
    (
        manager
        >> Rel(
            "Tracks operations and generates reports",
            technology="HTTPS",
            d2=SYNC,
        )
        >> support_dashboard
    )
    support_expert >> Rel("Uses", technology="HTTPS", d2=SYNC) >> mobile_app
    (
        support_expert
        >> Rel(
            "Updates articles",
            technology="HTTPS",
            d2=SYNC,
        )
        >> knowledge_base
    )
    (
        customer_notifications_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> notification_service
    )
    (
        expert_notifications_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> notification_service
    )
    (
        invoice_queue
        >> Rel(
            "Calls billing APIs through",
            technology="REST/HTTP",
            d2=ASYNC,
        )
        >> api_gateway
    )
    (
        ticket_assigned_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> support_api
    )
    (
        ticket_created_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> ticket_processor
    )
    (
        ticket_progress_queue
        >> Rel(
            "Consumed by",
            technology="Queue / Event",
            d2=ASYNC,
        )
        >> customer_api
    )

d2_render_options = (
    D2RenderOptionsBuilder()
    .direction("down")
    .include_technology()
    .legend(
        D2Legend(
            label="Customer Support Component Legend",
            items=[
                D2LegendElement(
                    "Operational user", shape="person", style=USER["style"]
                ),
                D2LegendElement(
                    "User-facing frontend", style=FRONTEND["style"]
                ),
                D2LegendElement("API gateway", style=GATEWAY["style"]),
                D2LegendElement("Backend service", style=BACKEND["style"]),
                D2LegendElement("Background worker", style=JOB["style"]),
                D2LegendElement(
                    "Operational datastore",
                    shape="cylinder",
                    style=DATABASE["style"],
                ),
                D2LegendElement(
                    "Asynchronous event stream",
                    shape="queue",
                    style=QUEUE["style"],
                ),
                D2LegendElement("External dependency", style=EXTERNAL["style"]),
                D2LegendRel("Synchronous request", style=SYNC["style"]),
                D2LegendRel("Database access", style=DATA_ACCESS["style"]),
                D2LegendRel("Asynchronous event", style=ASYNC["style"]),
                D2LegendRel(
                    "External integration", style=EXTERNAL_CALL["style"]
                ),
            ],
        ),
    )
    .build()
)

diagram.set_render_options(
    d2=d2_render_options,
)
Rendered D2 source
direction: down
__title: ||md
  # Customer Support System - Extended Component View
|| {
  near: top-center
}
vars: {
  d2-legend: "Customer Support Component Legend" {
    legend_1: {
      label: "Operational user"
      shape: person
      style.fill: "#e8f5e9"
      style.stroke: "#66bb6a"
      style.font-color: "#1b5e20"
      style.stroke-width: 2
    }
    legend_2: {
      label: "User-facing frontend"
      style.fill: "#e3f2fd"
      style.stroke: "#42a5f5"
      style.font-color: "#0d47a1"
      style.stroke-width: 2
    }
    legend_3: {
      label: "API gateway"
      style.fill: "#fce4ec"
      style.stroke: "#ec407a"
      style.font-color: "#880e4f"
      style.stroke-width: 2
    }
    legend_4: {
      label: "Backend service"
      style.fill: "#ede7f6"
      style.stroke: "#7e57c2"
      style.font-color: "#311b92"
      style.stroke-width: 2
    }
    legend_5: {
      label: "Background worker"
      style.fill: "#fff3e0"
      style.stroke: "#fb8c00"
      style.font-color: "#e65100"
      style.stroke-width: 2
    }
    legend_6: {
      label: "Operational datastore"
      shape: cylinder
      style.fill: "#fff8e1"
      style.stroke: "#ffb300"
      style.font-color: "#5d4037"
      style.stroke-width: 2
    }
    legend_7: {
      label: "Asynchronous event stream"
      shape: queue
      style.fill: "#e0f2f1"
      style.stroke: "#26a69a"
      style.font-color: "#004d40"
      style.stroke-width: 2
    }
    legend_8: {
      label: "External dependency"
      style.fill: "#f5f5f5"
      style.stroke: "#9e9e9e"
      style.font-color: "#424242"
      style.stroke-width: 2
      style.stroke-dash: 5
    }
    legend_9_source -> legend_9_target: {
      label: "Synchronous request"
      style.stroke: "#1e88e5"
      style.font-color: "#1565c0"
    }
    legend_10_source -> legend_10_target: {
      label: "Database access"
      style.stroke: "#8d6e63"
      style.font-color: "#6d4c41"
    }
    legend_11_source -> legend_11_target: {
      label: "Asynchronous event"
      style.stroke: "#00897b"
      style.font-color: "#00695c"
      style.stroke-dash: 3
    }
    legend_12_source -> legend_12_target: {
      label: "External integration"
      style.stroke: "#78909c"
      style.font-color: "#455a64"
      style.stroke-dash: 5
    }
    legend_9_source.style.opacity: 0
    legend_9_target.style.opacity: 0
    legend_10_source.style.opacity: 0
    legend_10_target.style.opacity: 0
    legend_11_source.style.opacity: 0
    legend_11_target.style.opacity: 0
    legend_12_source.style.opacity: 0
    legend_12_target.style.opacity: 0
  }
}
classes: {
  c4_person: {
    style.fill: "#f5f1ff"
    style.stroke: "#6f4bb2"
    style.font-color: "#211436"
  }
  c4_external: {
    style.fill: "#f7f7f7"
    style.stroke: "#767676"
    style.stroke-dash: "5"
  }
  c4_database: {
    style.fill: "#edf7ff"
    style.stroke: "#2d6f9f"
  }
  c4_queue: {
    style.fill: "#fff6e5"
    style.stroke: "#9b6500"
  }
}
admin_api: ||md
  ## Admin API

  [Component: Container Service]

  User management and reference-data management.
|| {
  shape: rectangle
  style.fill: "#ede7f6"
  style.stroke: "#7e57c2"
  style.font-color: "#311b92"
  style.stroke-width: 2
}
admin_portal: ||md
  ## Admin Portal

  [Component: Single-page Application]

  Manages system users and reference data.
|| {
  shape: rectangle
  style.fill: "#e3f2fd"
  style.stroke: "#42a5f5"
  style.font-color: "#0d47a1"
  style.stroke-width: 2
}
administrator: ||md
  ## Administrator

  [Person]

  Internal user with administrative access.
|| {
  shape: c4-person
  class: ["c4_person"]
  style.fill: "#e8f5e9"
  style.stroke: "#66bb6a"
  style.font-color: "#1b5e20"
  style.stroke-width: 2
}
analytics_api: ||md
  ## Analytics API

  [Component: Container Service]

  Ticket status reports, survey analysis and performance reports.
|| {
  shape: rectangle
  style.fill: "#ede7f6"
  style.stroke: "#7e57c2"
  style.font-color: "#311b92"
  style.stroke-width: 2
}
api_gateway: ||md
  ## API Gateway

  [Component: Container Service]

  Performs access control, security checks and request routing.
|| {
  shape: rectangle
  style.fill: "#fce4ec"
  style.stroke: "#ec407a"
  style.font-color: "#880e4f"
  style.stroke-width: 2
}
auth0: ||md
  ## Auth0

  [Component: OIDC/OAuth2]

  External identity provider for authentication.
|| {
  shape: rectangle
  class: ["c4_external"]
  style.fill: "#f5f5f5"
  style.stroke: "#9e9e9e"
  style.font-color: "#424242"
  style.stroke-width: 2
  style.stroke-dash: 5
}
billing_api: ||md
  ## Billing API

  [Component: Container Service]

  Billing management and financial reports.
|| {
  shape: rectangle
  style.fill: "#ede7f6"
  style.stroke: "#7e57c2"
  style.font-color: "#311b92"
  style.stroke-width: 2
}
billing_portal: ||md
  ## Billing Portal

  [Component: Single-page Application]

  Supports billing processing.
|| {
  shape: rectangle
  style.fill: "#e3f2fd"
  style.stroke: "#42a5f5"
  style.font-color: "#0d47a1"
  style.stroke-width: 2
}
customer: ||md
  ## Customer

  [Person]

  Owner of electronic equipment and support plan; reports issues.
|| {
  shape: c4-person
  class: ["c4_person"]
  style.fill: "#e8f5e9"
  style.stroke: "#66bb6a"
  style.font-color: "#1b5e20"
  style.stroke-width: 2
}
customer_api: ||md
  ## Customer API

  [Component: Container Service]

  Handles registration, profiles, tickets, surveys and billing history.
|| {
  shape: rectangle
  style.fill: "#ede7f6"
  style.stroke: "#7e57c2"
  style.font-color: "#311b92"
  style.stroke-width: 2
}
customer_notifications_queue: ||md
  ## Customer Notifications

  [Component: Message Queue]

  Asynchronous message channel for customer notifications.
|| {
  shape: queue
  class: ["c4_queue"]
  style.fill: "#e0f2f1"
  style.stroke: "#26a69a"
  style.font-color: "#004d40"
  style.stroke-width: 2
}
customer_portal: ||md
  ## Customer Portal

  [Component: Single-page Application]

  Provides access to customer profile, billing, ticket creation and history.
|| {
  shape: rectangle
  style.fill: "#e3f2fd"
  style.stroke: "#42a5f5"
  style.font-color: "#0d47a1"
  style.stroke-width: 2
}
email_system: ||md
  ## E-mail System

  [Component: SMTP]

  Internal mail system used for e-mail delivery.
|| {
  shape: rectangle
  class: ["c4_external"]
  style.fill: "#f5f5f5"
  style.stroke: "#9e9e9e"
  style.font-color: "#424242"
  style.stroke-width: 2
  style.stroke-dash: 5
}
expert_notifications_queue: ||md
  ## Expert Notifications

  [Component: Message Queue]

  Asynchronous message channel for expert notifications.
|| {
  shape: queue
  class: ["c4_queue"]
  style.fill: "#e0f2f1"
  style.stroke: "#26a69a"
  style.font-color: "#004d40"
  style.stroke-width: 2
}
helpdesk: ||md
  ## Helpdesk

  [Person]

  First line of support; provides direct phone support.
|| {
  shape: c4-person
  class: ["c4_person"]
  style.fill: "#e8f5e9"
  style.stroke: "#66bb6a"
  style.font-color: "#1b5e20"
  style.stroke-width: 2
}
helpdesk_portal: ||md
  ## Helpdesk Portal

  [Component: Single-page Application]

  Provides access to tickets and status.
|| {
  shape: rectangle
  style.fill: "#e3f2fd"
  style.stroke: "#42a5f5"
  style.font-color: "#0d47a1"
  style.stroke-width: 2
}
invoice_queue: ||md
  ## Invoice

  [Component: Message Queue]

  Asynchronous message channel for invoice processing.
|| {
  shape: queue
  class: ["c4_queue"]
  style.fill: "#e0f2f1"
  style.stroke: "#26a69a"
  style.font-color: "#004d40"
  style.stroke-width: 2
}
knowledge_base: ||md
  ## Knowledge Base

  [Component: Single-page Application]

  Supports searching and updating knowledge-base articles.
|| {
  shape: rectangle
  style.fill: "#e3f2fd"
  style.stroke: "#42a5f5"
  style.font-color: "#0d47a1"
  style.stroke-width: 2
}
manager: ||md
  ## Manager

  [Person]

  Monitors expert performance and customer satisfaction.
|| {
  shape: c4-person
  class: ["c4_person"]
  style.fill: "#e8f5e9"
  style.stroke: "#66bb6a"
  style.font-color: "#1b5e20"
  style.stroke-width: 2
}
mobile_app: ||md
  ## Mobile App

  [Component: iOS / Android App]

  Provides access to assigned tickets and knowledge-base search.
|| {
  shape: rectangle
  style.fill: "#e3f2fd"
  style.stroke: "#42a5f5"
  style.font-color: "#0d47a1"
  style.stroke-width: 2
}
notification_service: ||md
  ## Notification Service

  [Component: Container Service]

  Sends SMS and e-mail messages based on notification preferences.
|| {
  shape: rectangle
  style.fill: "#ede7f6"
  style.stroke: "#7e57c2"
  style.font-color: "#311b92"
  style.stroke-width: 2
}
payment_job: ||md
  ## Payment

  [Component: Container Job]

  Runs monthly and performs payment operations.
|| {
  shape: rectangle
  style.fill: "#fff3e0"
  style.stroke: "#fb8c00"
  style.font-color: "#e65100"
  style.stroke-width: 2
}
payment_provider: ||md
  ## Payment Service Provider

  [Component: HTTPS/API]

  External online payment service.
|| {
  shape: rectangle
  class: ["c4_external"]
  style.fill: "#f5f5f5"
  style.stroke: "#9e9e9e"
  style.font-color: "#424242"
  style.stroke-width: 2
  style.stroke-dash: 5
}
sms_provider: ||md
  ## SMS Service Provider

  [Component: SMS API]

  Provides SMS text messaging.
|| {
  shape: rectangle
  class: ["c4_external"]
  style.fill: "#f5f5f5"
  style.stroke: "#9e9e9e"
  style.font-color: "#424242"
  style.stroke-width: 2
  style.stroke-dash: 5
}
support_api: ||md
  ## Support API

  [Component: Container Service]

  Ticket orchestration, search, assignment handling and knowledge-base updates.
|| {
  shape: rectangle
  style.fill: "#ede7f6"
  style.stroke: "#7e57c2"
  style.font-color: "#311b92"
  style.stroke-width: 2
}
support_dashboard: ||md
  ## Support Dashboard

  [Component: Single-page Application]

  Provides analytics and operational reports.
|| {
  shape: rectangle
  style.fill: "#e3f2fd"
  style.stroke: "#42a5f5"
  style.font-color: "#0d47a1"
  style.stroke-width: 2
}
support_database: ||md
  ## Support Database

  [Component: Relational Database]

  Stores tickets, users, customer contacts and knowledge-base content.
|| {
  shape: cylinder
  class: ["c4_database"]
  style.fill: "#fff8e1"
  style.stroke: "#ffb300"
  style.font-color: "#5d4037"
  style.stroke-width: 2
}
support_expert: ||md
  ## Support Expert

  [Person]

  Technology expert who fixes customer electronic devices.
|| {
  shape: c4-person
  class: ["c4_person"]
  style.fill: "#e8f5e9"
  style.stroke: "#66bb6a"
  style.font-color: "#1b5e20"
  style.stroke-width: 2
}
ticket_assigned_queue: ||md
  ## Ticket Assigned

  [Component: Message Queue]

  Asynchronous message channel for assigned tickets.
|| {
  shape: queue
  class: ["c4_queue"]
  style.fill: "#e0f2f1"
  style.stroke: "#26a69a"
  style.font-color: "#004d40"
  style.stroke-width: 2
}
ticket_created_queue: ||md
  ## Ticket Created

  [Component: Message Queue]

  Asynchronous message channel for created tickets.
|| {
  shape: queue
  class: ["c4_queue"]
  style.fill: "#e0f2f1"
  style.stroke: "#26a69a"
  style.font-color: "#004d40"
  style.stroke-width: 2
}
ticket_progress_queue: ||md
  ## Ticket In-Progress/Closed

  [Component: Message Queue]

  Asynchronous message channel for ticket progress and closure notifications.
|| {
  shape: queue
  class: ["c4_queue"]
  style.fill: "#e0f2f1"
  style.stroke: "#26a69a"
  style.font-color: "#004d40"
  style.stroke-width: 2
}
ticket_processor: ||md
  ## Ticket Processor

  [Component: Container Job]

  Runs periodically, scans ticket statuses, and creates assignments.
|| {
  shape: rectangle
  style.fill: "#fff3e0"
  style.stroke: "#fb8c00"
  style.font-color: "#e65100"
  style.stroke-width: 2
}
admin_api -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
admin_portal -> api_gateway: {
  label: "Makes API calls to\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
analytics_api -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
api_gateway -> customer_api: {
  label: "Routes API calls to\n[REST/HTTP]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
api_gateway -> support_api: {
  label: "Routes API calls to\n[REST/HTTP]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
api_gateway -> admin_api: {
  label: "Routes API calls to\n[REST/HTTP]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
api_gateway -> billing_api: {
  label: "Routes API calls to\n[REST/HTTP]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
api_gateway -> analytics_api: {
  label: "Routes API calls to\n[REST/HTTP]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
billing_api -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
billing_portal -> api_gateway: {
  label: "Makes API calls to\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
customer_api -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
customer_api -> ticket_created_queue: {
  label: "Sends ticket created event\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
customer_portal -> auth0: {
  label: "Authenticates using\n[OIDC/OAuth2]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}
customer_portal -> api_gateway: {
  label: "Makes API calls to\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
helpdesk_portal -> api_gateway: {
  label: "Makes API calls to\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
knowledge_base -> api_gateway: {
  label: "Makes API calls to\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
mobile_app -> auth0: {
  label: "Authenticates using\n[OIDC/OAuth2]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}
mobile_app -> api_gateway: {
  label: "Makes API calls to\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
notification_service -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
notification_service -> email_system: {
  label: "Sends e-mail using\n[SMTP]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}
notification_service -> sms_provider: {
  label: "Sends SMS using\n[SMS API]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}
payment_job -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
payment_job -> invoice_queue: {
  label: "Sends invoice event\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
payment_job -> payment_provider: {
  label: "Executes payments using\n[HTTPS/API]"
  style.stroke: "#78909c"
  style.font-color: "#455a64"
  style.stroke-dash: 5
}
support_api -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
support_api -> expert_notifications_queue: {
  label: "Sends expert notification event\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
support_api -> customer_notifications_queue: {
  label: "Sends customer notification event\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
support_api -> ticket_progress_queue: {
  label: "Sends progress/closed event\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
support_dashboard -> api_gateway: {
  label: "Makes API calls to\n[REST/HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
ticket_processor -> support_database: {
  label: "Reads from and writes to\n[SQL/TCP]"
  style.stroke: "#8d6e63"
  style.font-color: "#6d4c41"
}
ticket_processor -> ticket_assigned_queue: {
  label: "Sends ticket assignment event\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
administrator -> admin_portal: {
  label: "Maintains users and reference data\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
administrator -> billing_portal: {
  label: "Manages billing operations\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
customer -> customer_portal: {
  label: "Uses\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
customer -> mobile_app: {
  label: "Uses\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
helpdesk -> helpdesk_portal: {
  label: "Creates/searches tickets\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
manager -> support_dashboard: {
  label: "Tracks operations and generates reports\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
support_expert -> mobile_app: {
  label: "Uses\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
support_expert -> knowledge_base: {
  label: "Updates articles\n[HTTPS]"
  style.stroke: "#1e88e5"
  style.font-color: "#1565c0"
}
customer_notifications_queue -> notification_service: {
  label: "Consumed by\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
expert_notifications_queue -> notification_service: {
  label: "Consumed by\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
invoice_queue -> api_gateway: {
  label: "Calls billing APIs through\n[REST/HTTP]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
ticket_assigned_queue -> support_api: {
  label: "Consumed by\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
ticket_created_queue -> ticket_processor: {
  label: "Consumed by\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}
ticket_progress_queue -> customer_api: {
  label: "Consumed by\n[Queue / Event]"
  style.stroke: "#00897b"
  style.font-color: "#00695c"
  style.stroke-dash: 3
}

PlantUML is useful when you need rich C4 styling, legends, tags, and stronger layout nudges. Mermaid is useful when you want simple text output that embeds well in Markdown-centric tools, but its C4 support has fewer tuning controls. D2 is useful when you want readable text output plus local rendering with D2's layout engine, themes, links, tooltips, icons, classes, and structured legends.