workspace "IRoM architecture" "Intelligent all-season road maintenance platform" { !identifiers hierarchical model { properties { "structurizr.groupSeparator" "." } group "Municipality" { financialResponsible = person "Responsible for financial resources" roadResponsible = person "Responsible for road maintenance" } group "Road Maintenance" { roadMaintainer = person "Road Maintenance" lvc = person "Latvian State Roads" } roadExpert = person "Maintenance Recommendations Analyst" user = person "User" erpSystem = softwareSystem "ERP Module" "Municipal Resource Management System" { properties { "fr" "ERP-F-01,ERP-F-02,ERP-F-03" "nfr" "ERP-NF-01" } tags "external" } mobileApplication = softwareSystem "Mobile Application" "Films the roadway and sends video streams to the platform" { tags "external" } externalSystem = softwareSystem "External System" "Sends or retrieves data from the platform" { properties { "fr""ERP-NF-01" } tags "external" } // CONTAINER DIAGRAM iromPlatform = softwareSystem "IRoM platform" "Intelligent all-season road maintenance platform" { optimizationService = container "Optimization service (KPI calculations)" { kpiReportingService = component "KPI management service" "Provides KPI report generation for visualization" kpiCalculationService = component "KPI calculation service" "Provides KPI calculation" kpiDataBase = component "KPI database" "Stores KPI calculation formulas, calculated KPIs and reports" { tags "DB" technology "Postgres SQL" } } platformServices = container "Platform services" "Services that ensure the operation of the platform" { tags "MainContainer" properties { "fr" "SA-F-03" } loadBalancer = component "Load balancer and proxy" "Provides request services and secure, centralized access to system components" { technology "Traefik Ingress" properties { "fr" "SA-F-01" } } dataPipeline = component "Data flow queue" "Provides storage and reading of data flow" { technology "Apache Kafka" tags "Pipeline" } database = component "Database" "Provides data storage" { technology "Postgres SQL" tags "DB" } monitoring = component "Monitoring system" "Provides platform monitoring" { technology "Zabbix" properties { "fr" "SA-F-03" } } securityManagement = component "Security Management" "Provides user creation, roles and access" { technology "Keycloak" } containerManager = component "Container Orchestrator" "Provides container deployment and scaling"{ technology "Docker Swarm + Portainer" properties { "fr" "SA-F-01,SA-F-02,SA-F-03,SA-F-04" "nfr" "SA-NF-01,SA-NF-02" } } anonymizationService = component "Anonymization Service" "Anonymizes sensitive data" secretDataManager = component "Secret Data Management Service" "Ensures secure storage, access, and secure management of secret data" { technology "HashiCorp Vault" properties { "nfr" "DP-NF-03" } } dataArchiver = component "Data Archiving Service" "Saves data submitted by data providers from the queue" } dataVisualizationService = container "Data Visualization Service" "Enables data visualization"{ dataVisualizationServiceModel = component "Data Visualization Service" "Enables internal users to visualize data." dataVisualizationServiceDatabase = component "Road condition data" "Stores data about road conditions" { technology "Postgres SQL" tags "DB" } dataVisualizationServiceAccessControl = component "Access control module" "Verifies user rights to access data"{ technology "Keycloak" } } decisionMakingModule = container "Decision support module" "Generates road maintenance recommendations"{ group "Law engine" { decisionMakingModuleFramework = component "Law engine" "Selects law(s) (recommendations) appropriate to the input data" decisionMakingModuleWeb = component "Law definition website" "Web page allows the user to view/define decisions." } decisionMakingModuleRoadPipeline = component "Road condition data queue" "Stores information about the condition of identified roads"{ technology "Kafka" tags "Pipeline" } decisionMakingModuleRecomendationPipeline = component "Recommendation data queue" "Stores recommendations generated by the rule engine"{ technology "Kafka" tags "Pipeline" } decisionMakingModuleArchivator = component "Recommendation management service" "Reads recommendations obtained by the decision engine from the data queue" decisionMakingModuleDatabase = component "Recommendation database" "Stores recommendations obtained by the decision engine" { technology "Postgres SQL" tags "DB" } } analysisModule = container "Analysis and Classification Module" "Analyzes and interprets road conditions and hazards" { dataPreprocessingComponent = component "Data Preprocessing Service" "Cleans and prepares input data for models" modelManager = component "Model Management Component" "Manages model versions, loading, configuration" { properties { "hint" "ML models can be defined in code or a repository of ML models can be created and model execution can be initiated from the repository. If models are run from code, this component is not needed." } } mlModel = component "Machine Learning Model Execution Engine" "Performs model execution and results classification" { properties { "nfr" "DP-NF-01" } } analysisModuleRoadDataPipeline = component "Road Image Queue" "Stores road images"{ technology "Kafka" tags "Pipeline" properties { "fr" "M-F-01" } } analysisModuleRoadResultPipeline = component "Model Result Queue" "Stores information about the state of identified roads" { technology "Kafka" tags "Pipeline" } analysisModuleManagerLoaderDb = component "ML Model Data" "Stores information about available ML models" { technology "Postgres SQL" tags "DB" } } dataIngestionService = container "Data Ingestion Service" "Enables external systems to transfer data to the platform"{ dataIngestionServiceModel = component "Data Ingestion Module" "Ensures data ingest from various sources" { properties { "nfr" "DP-NF-01" } } dataIngestionServiceAnonymization = component "Data Anonymizer" "Anonymizes incoming sensitive data" dataIngestionServiceDatabase = component "Anonymized data" "Stores incoming, anonymized data" { technology "Postgres SQL" tags "DB" } dataIngestionServiceDataPipeline = component "Road state data queue" "Stores information for further processing about the current road state"{ technology "Kafka" tags "Pipeline" } dataIngestionServiceAccessControl = component "Access control module" "Checks user rights to access data"{ technology "Keycloak" } dataIngestionServiceDataArchiver = component "Data archiver" "Reads data from the queue and stores it in the database."{ technology "NodeJs" } } dataSharingService = container "Data sharing service" "Enables external systems to request data from the platform"{ dataSharingModule = component "Data Sharing Component" "Enables access to data and checks data access rights for external users" { properties { hint "reactive delivery - data by query or pull principle" } } dataSharingServiceDatabase = component "Road condition data" "Stores information about road conditions" { technology "Postgres SQL" tags "DB" } dataSharingServiceNotificationDatabase = component "Notification database" "Enables storage of notifications generated by the service" { technology "Postgres SQL" tags "DB" } dataSharingAccessControl = component "Access Management Module" "Checks user rights to access data"{ technology "Keycloak" } } erpIntegrationModule = container "ERP Integration Module" "Enables data exchange with the ERP system"{ properties { "fr" "SA-F-05,DP-F-01" } erpIntegrationModuleComponent = component "ERP integration module" "Provides access to data and checks data access rights for ERP system users" erpIntegrationModuleDatabase = component "Road condition data" "Stores information about road conditions" { technology "Postgres SQL" tags "DB" } erpIntegrationModuleNotificationDatabase = component "Notification database" "Provides storage of service-generated notifications" { technology "Postgres SQL" tags "DB" } erpIntegrationModuleAccessControl = component "Access management module" "Checks user rights to access data"{ technology "Keycloak" } kpiDataExchangeDb = component "KPI database" "Work management database for KPI calculations" { technology "Postgres SQL" tags "DB" } } notificationService = container "Notification service" "Provides creation of notifications" { notificationGenerator = component "Notification Generator" "Generates notifications using templates and recipients" // ?? notificationPermissonManager = component "Notification Rights Manager" "Manages recipients, rights, topics, etc." roadConditionPipeline = component "Road Condition Data Queue" "Stores information about the condition of identified roads"{ technology "Kafka" tags "Pipeline" } notificationDatabase = component "Notification Database" "Provides storage of service-generated notifications" { technology "Postgres SQL" tags "DB" } notificationTemplateDatabase = component "Notification template database" "Provides storage of service notification templates" { technology "Postgres SQL" tags "DB" } notificationServiceIntegrationModuleAccessControl = component "Access management module" "Verifies user rights to receive notifications"{ technology "Keycloak" } } } // ------------- Context level relationships ---------------- financialResponsible -> iromPlatform "uses the platform" roadResponsible -> iromPlatform "uses the platform" financialResponsible -> erpSystem "uses the system" //erpSystem -> iromPlatform "receives data for repair planning" //externalSystemPull -> dataSharingService "retrieves data via API" //dataIngestionService -> externalSystemPush "sends data" mobileApplication -> iromPlatform "sends video stream data" roadMaintainer -> mobileApplication "uses to survey the road condition" roadMaintainer -> externalSystem "sends or retrieves data" externalSystem -> lvc "retrieves data via API" roadExpert -> iromPlatform.decisionMakingModule "manages road maintenance recommendations" // -----------Container level relationships-------- iromPlatform.dataVisualizationService -> iromPlatform.platformServices "requests data for maps, reports, layers" iromPlatform.notificationService -> iromPlatform.platformServices "uses platform services to store data" iromPlatform.dataSharingService -> iromPlatform.platformServices "uses platform services to share data with external systems" iromPlatform.erpIntegrationModule -> iromPlatform.platformServices "uses platform services to exchange data with ERP system" iromPlatform.analysisModule -> iromPlatform.platformServices "requests data and sends the obtained results" iromPlatform.decisionMakingModule -> iromPlatform.platformServices "requests data and sends the generated recommendations" //iromPlatform.notificationService -> externalSystem "prepares data for retrieval" externalSystem -> iromPlatform.dataSharingService "requests and/or sends data" mobileApplication -> iromPlatform.dataIngestionService "sends data" externalSystem -> iromPlatform.dataIngestionService "sends data" iromPlatform.dataIngestionService -> iromPlatform.platformServices "sends data for analysis" erpSystem -> iromPlatform.erpIntegrationModule "requests data for work planning" //iromPlatform.optimizationService -> iromPlatform.erpIntegrationModule "requests data for KPI calculations" iromPlatform.optimizationService -> iromPlatform.platformServices "requests data for KPI calculations" //iromPlatform.dataVisualizationService -> iromPlatform.optimizationService "requests KPI data for visualization" // -------- Component "Analysis and Classification Module" relationships ------------ iromPlatform.analysisModule.modelManager -> iromPlatform.analysisModule.mlModel "loads ML models" iromPlatform.analysisModule.mlModel -> iromPlatform.analysisModule.analysisModuleRoadResultPipeline "sends results" iromPlatform.analysisModule.analysisModuleRoadDataPipeline -> iromPlatform.analysisModule.dataPreprocessingComponent "receives road images for preprocessing" iromPlatform.analysisModule.dataPreprocessingComponent -> iromPlatform.analysisModule.mlModel "transfers cleaned and prepared data for further analysis and processing" iromPlatform.analysisModule.analysisModuleManagerLoaderDb -> iromPlatform.analysisModule.modelManager "loads models" // ------------ Component "Notification Service" relationships --------------- iromPlatform.notificationService.notificationGenerator -> iromPlatform.notificationService.roadConditionPipeline "Reads current road condition" iromPlatform.notificationService.notificationGenerator -> iromPlatform.notificationService.notificationDatabase "Saves generated notifications" iromPlatform.notificationService.notificationGenerator -> iromPlatform.notificationService.notificationTemplateDatabase "Requests notification templates" iromPlatform.notificationService.notificationGenerator -> externalSystem "Sends notifications" iromPlatform.notificationService.notificationGenerator -> iromPlatform.notificationService.notificationServiceIntegrationModuleAccessControl "Checks external system access rights" // ------------ Component "Data Sharing Service" relationships --------------- iromPlatform.dataSharingService.dataSharingModule -> iromPlatform.dataSharingService.dataSharingServiceDatabase "Requests path state data" iromPlatform.dataSharingService.dataSharingModule -> iromPlatform.dataSharingService.dataSharingServiceNotificationDatabase "Requests saved notification data" iromPlatform.dataSharingService.dataSharingModule -> iromPlatform.dataSharingService.dataSharingAccessControl "Checks permissions" //externalSystemPull -> iromPlatform.dataSharingService.dataSharingModule "Requests data" // ------------ Component "Data Ingestion Service" relationships -------------- iromPlatform.dataIngestionService.dataIngestionServiceModel -> iromPlatform.dataIngestionService.dataIngestionServiceAnonymization "Sends data" iromPlatform.dataIngestionService.dataIngestionServiceDataArchiver -> iromPlatform.dataIngestionService.dataIngestionServiceDatabase "Saves data" iromPlatform.dataIngestionService.dataIngestionServiceDataArchiver -> iromPlatform.dataIngestionService.dataIngestionServiceDataPipeline "Reads data from a queue" iromPlatform.dataIngestionService.dataIngestionServiceAnonymization -> iromPlatform.dataIngestionService.dataIngestionServiceDataPipeline "Sends data to a queue" iromPlatform.dataIngestionService.dataIngestionServiceModel -> iromPlatform.dataIngestionService.dataIngestionServiceAccessControl "Checks permissions" externalSystem -> iromPlatform.dataIngestionService.dataIngestionServiceModel "Sends data" mobileApplication -> iromPlatform.dataIngestionService.dataIngestionServiceModel "Sends data" // ------------ Component "ERP integration model" relationships --------------- iromPlatform.erpIntegrationModule.erpIntegrationModuleComponent -> iromPlatform.erpIntegrationModule.erpIntegrationModuleDatabase "Requests path state data" iromPlatform.erpIntegrationModule.erpIntegrationModuleComponent -> iromPlatform.erpIntegrationModule.erpIntegrationModuleNotificationDatabase "Requests saved notification data" iromPlatform.erpIntegrationModule.erpIntegrationModuleComponent -> iromPlatform.erpIntegrationModule.erpIntegrationModuleAccessControl "Checks permissions" erpSystem -> iromPlatform.erpIntegrationModule.erpIntegrationModuleComponent "Requests data" iromPlatform.erpIntegrationModule.erpIntegrationModuleComponent -> iromPlatform.erpIntegrationModule.kpiDataExchangeDb "Requests data for KPI calculations from the ERP system" // ------------ Component "Data visualization service" relationships --------------- iromPlatform.dataVisualizationService.dataVisualizationServiceModel -> iromPlatform.dataVisualizationService.dataVisualizationServiceDatabase "Requests road condition data" iromPlatform.dataVisualizationService.dataVisualizationServiceModel -> iromPlatform.dataVisualizationService.dataVisualizationServiceAccessControl "Checks permissions" user -> iromPlatform.dataVisualizationService.dataVisualizationServiceModel "Uses visualization tools for report visualization" // ------------ Component "Decision support model" relationships --------------- iromPlatform.decisionMakingModule.decisionMakingModuleFramework -> iromPlatform.decisionMakingModule.decisionMakingModuleRoadPipeline "Reads data" iromPlatform.decisionMakingModule.decisionMakingModuleWeb -> iromPlatform.decisionMakingModule.decisionMakingModuleFramework "Monitors laws" iromPlatform.decisionMakingModule.decisionMakingModuleFramework -> iromPlatform.decisionMakingModule.decisionMakingModuleRecomendationPipeline "Sends data" iromPlatform.decisionMakingModule.decisionMakingModuleArchivator -> iromPlatform.decisionMakingModule.decisionMakingModuleRecomendationPipeline "Reads data" iromPlatform.decisionMakingModule.decisionMakingModuleArchivator -> iromPlatform.decisionMakingModule.decisionMakingModuleDatabase "Saves data" // ---------- Component "Optimization Service" relationsjips ---------------- iromPlatform.optimizationService.kpiDataBase -> iromPlatform.optimizationService.kpiReportingService "retrieves calculated KPIs and generates reports for visualization" iromPlatform.optimizationService.kpiCalculationService -> iromPlatform.optimizationService.kpiDataBase "uses predefined formulas and calculates KPI" //iromPlatform.dataVisualizationService -> iromPlatform.optimizationService.kpiDataBase "gets KPI reports for visualization" } views { systemContext iromPlatform { include * include iromPlatform exclude user //autolayout no } systemLandscape "SystemLandscape" { include erpSystem include mobileApplication include externalSystem include iromPlatform include lvc include roadMaintainer include financialResponsible include roadResponsible include roadExpert exclude user } container iromPlatform { include * include erpSystem include externalSystem include mobileApplication include iromPlatform.optimizationService exclude roadExpert exclude user //autolayout tb } component iromPlatform.platformServices "Platform-Services-view" { include * //autoLayout lr } component iromPlatform.analysisModule "Analysis-and-classification-model-containers" { include * //autoLayout no } component iromPlatform.notificationService "notificatin-service-view" { include * //autoLayout lr } component iromPlatform.dataSharingService "Data-Sharing-Service-view" { include * //autoLayout no } component iromPlatform.dataIngestionService "Data-Ingestion-Service-view" { include * //autoLayout no } component iromPlatform.erpIntegrationModule "ERP-Integration-Model-view" { include * //autoLayout lr } component iromPlatform.dataVisualizationService "Data-Visualization-Service-view" { include * //autoLayout no } component iromPlatform.decisionMakingModule "Decision-Making-Module-view" { include * //autoLayout no } component iromPlatform.optimizationService "Optimization-Module-view" { include * //autoLayout no } terminology { person "Person" softwareSystem "System" container "Container" component "Component" relationship "Link" } styles { // Noklusējuma teksts visiem elementiem element "Element" { color "#000000" } element "System" { color black } element "Group" { color black } element "Node" { color black } // Noklusējuma teksts visām attiecībām (bultiņu etiķetēm) relationship "Relationship" { color "#000000" } // Konteineri (ietekmē arī komponentu skata apakšējo caption) element "Container" { background "#23d98d" stroke "#666666" color "#000000" } // Ja modelī pievienosi šim konteineram tagu "AnalysisContainer", // šis noteikums piespiedīs melnu tekstu arī captionam element "AnalysisContainer" { color "#000000" } element "Person" { background "#d46a6a" shape person } element "SoftwareSystem" { background "#82A77D" stroke "#666666" } element "MainContainer" { background "#C41E3A" stroke "#666666" } element "Pipeline" { background "#777F8C" shape pipe stroke "#666666" } element "external" { background "#813EB5" stroke "#666666" } element "Component" { background "#58BDD6" stroke "#666666" color "#000000" } element "DB" { background "#777F8C" shape Cylinder stroke "#666666" color "#000000" } } } // <-- beidzas views } // <-- beidzas workspace