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¶
This example keeps the same C4 elements and relationships, then applies backend-specific rendering options to make each output easier to read.
Sysops support system component view¶
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='Sysops Support System - Tuned Component View') as diagram:
customer = Person(
'Customer',
'Reports equipment issues and tracks repair progress.',
plantuml={'tags': ['User']},
alias='customer',
)
expert = Person(
'Sysops 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(
'Sysops 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(
'Sysops 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('Sysops 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("Sysops Component Legend")
title Sysops Support System - Tuned Component View
Person(customer, "Customer", "Reports equipment issues and tracks repair progress.", $tags="User")
Person(expert, "Sysops 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, "Sysops 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, "Sysops 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='Sysops Support System - Tuned Component View') as diagram:
customer = Person(
'Customer',
'Reports equipment issues and tracks repair progress.',
alias='customer',
)
expert = Person(
'Sysops 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(
'Sysops 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(
'Sysops 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 Sysops Support System - Tuned Component View
Person(customer, "Customer", "Reports equipment issues and tracks repair progress.")
Person(expert, "Sysops 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, "Sysops 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, "Sysops 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")
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.