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
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
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
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
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
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
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.
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
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")
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.
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
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")
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.