├── .devcontainer
└── devcontainer.json
├── .flox
├── .gitignore
├── env.json
└── env
│ ├── manifest.lock
│ └── manifest.toml
├── .gitattributes
├── .github
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ ├── Bug_report.md
│ ├── Feature_proposal.md
│ ├── Meeting.md
│ ├── Office_Hours.md
│ ├── Project_proposal.md
│ ├── Schema_change_proposal.md
│ └── Support_question.md
├── labeler.yml
├── maven-cve-ignore-list.xml
├── node-cve-ignore-list.xml
└── workflows
│ ├── auto-comment.yml
│ ├── build-calm-hub-coverage.yml
│ ├── build-calm-hub-ui.yml
│ ├── build-calm-hub.yml
│ ├── build-cli.yml
│ ├── build-docs.yml
│ ├── build-shared.yml
│ ├── cve-scanning-maven.yml
│ ├── cve-scanning-node.yml
│ ├── docker-publish-calm-hub.yml
│ ├── license-scanning-maven.yml
│ ├── license-scanning-node.yml
│ ├── pr-labelling.yml
│ ├── publish-cli-to-npm.yml
│ ├── s3-docs-sync.yml
│ ├── s3-sync.yml
│ ├── s3-video-sync.yml
│ ├── semgrep-ci.yml
│ └── validate-spectral.yml
├── .gitignore
├── .mvn
└── wrapper
│ ├── MavenWrapperDownloader.java
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .vscode
└── settings.json
├── LICENSE
├── LICENSE.spdx
├── NOTICE
├── README.md
├── brand
├── 2025_CALM_Logo.pdf
├── Horizontal
│ ├── 2025_CALM_Horizontal.eps
│ ├── 2025_CALM_Horizontal.jpg
│ ├── 2025_CALM_Horizontal.png
│ ├── 2025_CALM_Horizontal.svg
│ ├── 2025_CALM_Horizontal_BLK.eps
│ ├── 2025_CALM_Horizontal_BLK.jpg
│ ├── 2025_CALM_Horizontal_BLK.png
│ ├── 2025_CALM_Horizontal_BLK.svg
│ ├── 2025_CALM_Horizontal_WHT.eps
│ ├── 2025_CALM_Horizontal_WHT.png
│ └── 2025_CALM_Horizontal_WHT.svg
├── Icon
│ ├── 2025_CALM_Icon.eps
│ ├── 2025_CALM_Icon.jpg
│ ├── 2025_CALM_Icon.png
│ ├── 2025_CALM_Icon.svg
│ ├── 2025_CALM_Icon_BLK.eps
│ ├── 2025_CALM_Icon_BLK.jpg
│ ├── 2025_CALM_Icon_BLK.png
│ ├── 2025_CALM_Icon_BLK.svg
│ ├── 2025_CALM_Icon_WHT.eps
│ ├── 2025_CALM_Icon_WHT.png
│ └── 2025_CALM_Icon_WHT.svg
├── Stacked
│ ├── 2025_CALM_Stacked.eps
│ ├── 2025_CALM_Stacked.jpg
│ ├── 2025_CALM_Stacked.png
│ ├── 2025_CALM_Stacked.svg
│ ├── 2025_CALM_Stacked_BLK.eps
│ ├── 2025_CALM_Stacked_BLK.jpg
│ ├── 2025_CALM_Stacked_BLK.png
│ ├── 2025_CALM_Stacked_BLK.svg
│ ├── 2025_CALM_Stacked_WHT.eps
│ ├── 2025_CALM_Stacked_WHT.png
│ └── 2025_CALM_Stacked_WHT.svg
└── Wordmark
│ ├── 2025_CALM_Wordmark.eps
│ ├── 2025_CALM_Wordmark.jpg
│ ├── 2025_CALM_Wordmark.png
│ ├── 2025_CALM_Wordmark.svg
│ ├── 2025_CALM_Wordmark_BLK.eps
│ ├── 2025_CALM_Wordmark_BLK.jpg
│ ├── 2025_CALM_Wordmark_BLK.png
│ ├── 2025_CALM_Wordmark_BLK.svg
│ ├── 2025_CALM_Wordmark_WHT.eps
│ ├── 2025_CALM_Wordmark_WHT.png
│ └── 2025_CALM_Wordmark_WHT.svg
├── calm-hub-ui
├── .gitignore
├── .prettierrc
├── README.md
├── eslint.config.js
├── index.html
├── package.json
├── postcss.config.cjs
├── prettier.config.js
├── src
│ ├── App.css
│ ├── App.tsx
│ ├── ProtectedRoute.tsx
│ ├── authService.tsx
│ ├── components
│ │ └── navbar
│ │ │ ├── Navbar.css
│ │ │ └── Navbar.tsx
│ ├── hub
│ │ ├── Hub.tsx
│ │ └── components
│ │ │ ├── json-renderer
│ │ │ ├── JsonRenderer.test.tsx
│ │ │ └── JsonRenderer.tsx
│ │ │ └── value-table
│ │ │ ├── ValueTable.test.tsx
│ │ │ └── ValueTable.tsx
│ ├── index.css
│ ├── index.tsx
│ ├── model
│ │ └── calm.tsx
│ ├── output.css
│ ├── reportWebVitals.js
│ ├── service
│ │ └── calm-service.tsx
│ └── visualizer
│ │ ├── Visualizer.css
│ │ ├── Visualizer.tsx
│ │ ├── components
│ │ ├── cytoscape-renderer
│ │ │ ├── CytoscapeRenderer.tsx
│ │ │ ├── cytoscape.css
│ │ │ └── cytoscape.d.ts
│ │ ├── drawer
│ │ │ ├── Drawer.test.tsx
│ │ │ └── Drawer.tsx
│ │ ├── menu
│ │ │ ├── Menu.test.tsx
│ │ │ └── Menu.tsx
│ │ ├── sidebar
│ │ │ ├── Sidebar.test.tsx
│ │ │ └── Sidebar.tsx
│ │ └── visualizer-container
│ │ │ ├── VisualizerContainer.test.tsx
│ │ │ └── VisualizerContainer.tsx
│ │ ├── contracts
│ │ └── contracts.ts
│ │ ├── helpers
│ │ ├── set-functions.test.ts
│ │ └── set-functions.ts
│ │ └── services
│ │ ├── layout-correction-service.test.ts
│ │ ├── layout-correction-service.ts
│ │ ├── node-position-service.test.tsx
│ │ └── node-position-service.tsx
├── tsconfig.json
├── vite-env.d.ts
├── vite.config.ts
└── vitest.setup.ts
├── calm-hub
├── .dockerignore
├── .gitignore
├── README.md
├── deploy
│ └── docker-compose.yml
├── k8s
│ ├── calm-hub.yml
│ ├── mongo-config.yml
│ └── mongo.yml
├── keycloak-dev
│ ├── device-code-flow-entraid.sh
│ ├── device-code-flow.sh
│ ├── docker-compose.yml
│ └── imports
│ │ └── realm.json
├── local-dev
│ └── docker-compose.yml
├── mongo
│ └── init-mongo.js
├── nitrite
│ └── init-nitrite.sh
├── pom.xml
└── src
│ ├── integration-test
│ └── java
│ │ └── integration
│ │ ├── EndToEndResource.java
│ │ ├── IntegrationTestProfile.java
│ │ ├── IntegrationTestSecureProfile.java
│ │ ├── KeycloakTestResource.java
│ │ ├── MongoAdrIntegration.java
│ │ ├── MongoArchitectureIntegration.java
│ │ ├── MongoDomainIntegration.java
│ │ ├── MongoFlowIntegration.java
│ │ ├── MongoNamespaceIntegration.java
│ │ ├── MongoPatternIntegration.java
│ │ ├── MongoSchemaIntegration.java
│ │ ├── MongoSetup.java
│ │ ├── MongoStandardIntegration.java
│ │ ├── PermittedScopesIntegration.java
│ │ └── UserAccessGrantsIntegration.java
│ ├── main
│ ├── docker
│ │ ├── Dockerfile.jvm
│ │ └── Dockerfile.multistage
│ ├── java
│ │ └── org
│ │ │ └── finos
│ │ │ └── calm
│ │ │ ├── config
│ │ │ ├── NitriteDBConfig.java
│ │ │ └── StandaloneQualifier.java
│ │ │ ├── domain
│ │ │ ├── Architecture.java
│ │ │ ├── Domain.java
│ │ │ ├── Flow.java
│ │ │ ├── Pattern.java
│ │ │ ├── Standard.java
│ │ │ ├── StandardDetails.java
│ │ │ ├── UserAccess.java
│ │ │ ├── ValueWrapper.java
│ │ │ ├── adr
│ │ │ │ ├── Adr.java
│ │ │ │ ├── AdrMeta.java
│ │ │ │ ├── Decision.java
│ │ │ │ ├── Link.java
│ │ │ │ ├── NewAdrRequest.java
│ │ │ │ ├── Option.java
│ │ │ │ └── Status.java
│ │ │ └── exception
│ │ │ │ ├── AdrNotFoundException.java
│ │ │ │ ├── AdrParseException.java
│ │ │ │ ├── AdrPersistenceException.java
│ │ │ │ ├── AdrRevisionNotFoundException.java
│ │ │ │ ├── ArchitectureNotFoundException.java
│ │ │ │ ├── ArchitectureVersionExistsException.java
│ │ │ │ ├── ArchitectureVersionNotFoundException.java
│ │ │ │ ├── DomainAlreadyExistsException.java
│ │ │ │ ├── FlowNotFoundException.java
│ │ │ │ ├── FlowVersionExistsException.java
│ │ │ │ ├── FlowVersionNotFoundException.java
│ │ │ │ ├── NamespaceNotFoundException.java
│ │ │ │ ├── PatternNotFoundException.java
│ │ │ │ ├── PatternVersionExistsException.java
│ │ │ │ ├── PatternVersionNotFoundException.java
│ │ │ │ ├── StandardNotFoundException.java
│ │ │ │ ├── StandardVersionExistsException.java
│ │ │ │ ├── StandardVersionNotFoundException.java
│ │ │ │ └── UserAccessNotFoundException.java
│ │ │ ├── resources
│ │ │ ├── AdrResource.java
│ │ │ ├── ArchitectureResource.java
│ │ │ ├── CalmResourceErrorResponses.java
│ │ │ ├── CoreSchemaResource.java
│ │ │ ├── DomainSchemaResource.java
│ │ │ ├── FlowResource.java
│ │ │ ├── NamespaceResource.java
│ │ │ ├── PatternResource.java
│ │ │ ├── ResourceValidationConstants.java
│ │ │ ├── StandardResource.java
│ │ │ └── UserAccessResource.java
│ │ │ ├── security
│ │ │ ├── AccessControlFilter.java
│ │ │ ├── CalmHubScopes.java
│ │ │ ├── PermittedScopes.java
│ │ │ ├── UserAccessValidator.java
│ │ │ └── UserRequestAttributes.java
│ │ │ └── store
│ │ │ ├── AdrStore.java
│ │ │ ├── ArchitectureStore.java
│ │ │ ├── CoreSchemaStore.java
│ │ │ ├── DomainStore.java
│ │ │ ├── FlowStore.java
│ │ │ ├── NamespaceStore.java
│ │ │ ├── PatternStore.java
│ │ │ ├── StandardStore.java
│ │ │ ├── UserAccessStore.java
│ │ │ ├── mongo
│ │ │ ├── MongoAdrStore.java
│ │ │ ├── MongoArchitectureStore.java
│ │ │ ├── MongoCoreSchemaStore.java
│ │ │ ├── MongoCounterStore.java
│ │ │ ├── MongoDomainStore.java
│ │ │ ├── MongoFlowStore.java
│ │ │ ├── MongoNamespaceStore.java
│ │ │ ├── MongoPatternStore.java
│ │ │ ├── MongoStandardStore.java
│ │ │ └── MongoUserAccessStore.java
│ │ │ ├── nitrite
│ │ │ ├── NitriteAdrStore.java
│ │ │ ├── NitriteArchitectureStore.java
│ │ │ ├── NitriteCoreSchemaStore.java
│ │ │ ├── NitriteCounterStore.java
│ │ │ ├── NitriteDomainStore.java
│ │ │ ├── NitriteFlowStore.java
│ │ │ ├── NitriteNamespaceStore.java
│ │ │ ├── NitritePatternStore.java
│ │ │ ├── NitriteStandardStore.java
│ │ │ └── NitriteUserAccessStore.java
│ │ │ └── producer
│ │ │ ├── AdrStoreProducer.java
│ │ │ ├── ArchitectureStoreProducer.java
│ │ │ ├── CoreSchemaStoreProducer.java
│ │ │ ├── DomainStoreProducer.java
│ │ │ ├── FlowStoreProducer.java
│ │ │ ├── NamespaceStoreProducer.java
│ │ │ ├── PatternStoreProducer.java
│ │ │ ├── StandardStoreProducer.java
│ │ │ └── UserAccessStoreProducer.java
│ └── resources
│ │ ├── application-secure.properties
│ │ └── application.properties
│ └── test
│ ├── java
│ └── org
│ │ └── finos
│ │ └── calm
│ │ ├── config
│ │ └── NitriteDBConfigTest.java
│ │ ├── domain
│ │ ├── TestPattern.java
│ │ ├── TestUserAccessShould.java
│ │ └── adr
│ │ │ ├── TestDecisionShould.java
│ │ │ ├── TestLinkShould.java
│ │ │ ├── TestNewAdrRequestShould.java
│ │ │ └── TestOptionShould.java
│ │ ├── resources
│ │ ├── AllowPutProfile.java
│ │ ├── TestAdrResourceShould.java
│ │ ├── TestArchitectureResourcePutEnabledShould.java
│ │ ├── TestArchitectureResourceShould.java
│ │ ├── TestCalmErrorResponsesShould.java
│ │ ├── TestCoreSchemaResourceShould.java
│ │ ├── TestDomainSchemaResourceShould.java
│ │ ├── TestFlowResourcePutEnabledShould.java
│ │ ├── TestFlowResourceShould.java
│ │ ├── TestNamespaceResourceShould.java
│ │ ├── TestPatternResourcePutEnabledShould.java
│ │ ├── TestPatternResourceShould.java
│ │ ├── TestStandardResourceShould.java
│ │ └── TestUserAccessResourceShould.java
│ │ ├── security
│ │ ├── TestAccessControlFilterShould.java
│ │ ├── TestCalmHubScopesShould.java
│ │ └── TestUserAccessValidatorShould.java
│ │ └── store
│ │ ├── mongo
│ │ ├── TestMongoAdrStoreShould.java
│ │ ├── TestMongoArchitectureStoreShould.java
│ │ ├── TestMongoCoreSchemaStoreShould.java
│ │ ├── TestMongoCounterStoreShould.java
│ │ ├── TestMongoDomainStoreShould.java
│ │ ├── TestMongoFlowStoreShould.java
│ │ ├── TestMongoNamespaceStoreShould.java
│ │ ├── TestMongoPatternStoreShould.java
│ │ ├── TestMongoStandardStoreShould.java
│ │ └── TestMongoUserAccessStoreShould.java
│ │ ├── nitrite
│ │ ├── TestNitriteAdrStoreShould.java
│ │ ├── TestNitriteArchitectureStoreShould.java
│ │ ├── TestNitriteCoreSchemaStoreShould.java
│ │ ├── TestNitriteCounterStoreShould.java
│ │ ├── TestNitriteDomainStoreShould.java
│ │ ├── TestNitriteFlowStoreShould.java
│ │ ├── TestNitriteNamespaceStoreShould.java
│ │ ├── TestNitritePatternStoreShould.java
│ │ ├── TestNitriteStandardStoreShould.java
│ │ └── TestNitriteUserAccessStoreShould.java
│ │ └── producer
│ │ ├── TestAdrStoreProducerShould.java
│ │ ├── TestArchitectureStoreProducerShould.java
│ │ ├── TestCoreSchemaStoreProducerShould.java
│ │ ├── TestDomainStoreProducerShould.java
│ │ ├── TestFlowStoreProducerShould.java
│ │ ├── TestNamespaceStoreProducerShould.java
│ │ ├── TestPatternStoreProducerShould.java
│ │ ├── TestStandardStoreProducerShould.java
│ │ └── TestUserAccessStoreProducerShould.java
│ └── resources
│ ├── application.properties
│ └── secure-profile
│ └── realm.json
├── calm
├── README.md
├── control-example
│ ├── one-node-wonder.json
│ ├── pre-prod-review-configuration.json
│ ├── pre-prod-review-evidence.json
│ └── pre-prod-review-specification.json
├── controls
│ └── README.md
├── domains-example
│ ├── pattern
│ │ ├── instantiation.json
│ │ └── secure-application-pattern.json
│ └── security
│ │ ├── cluster-ingress-https.json
│ │ ├── cluster-internal-mtls.json
│ │ ├── cluster-micro-segmentation.json
│ │ └── schema
│ │ ├── micro-segmentation.json
│ │ └── permitted-connection.json
├── draft
│ ├── 1083
│ │ ├── README.md
│ │ ├── meta
│ │ │ ├── calm.json
│ │ │ ├── core.json
│ │ │ └── interface.json
│ │ └── prototype
│ │ │ ├── example-architecture.json
│ │ │ └── interfaces
│ │ │ ├── grpc-service.json
│ │ │ └── kafka-topic.json
│ ├── 1177
│ │ ├── README.md
│ │ ├── meta
│ │ │ └── core.json
│ │ └── prototype
│ │ │ ├── authentication-as-control.json
│ │ │ ├── authentication-control-config.json
│ │ │ └── authentication-control-requirement.json
│ ├── 1224
│ │ ├── README.md
│ │ ├── meta
│ │ │ └── core.json
│ │ └── prototype
│ │ │ └── api-gateway.json
│ ├── 1232
│ │ └── meta
│ │ │ └── core.json
│ ├── 1233
│ │ ├── README.md
│ │ ├── meta
│ │ │ └── control.json
│ │ └── prototype
│ │ │ ├── access-control-requirement.json
│ │ │ ├── data-encryption-requirement.json
│ │ │ ├── encryption-config.json
│ │ │ ├── example-inline-config.json
│ │ │ ├── example-mixed-config.json
│ │ │ ├── example-url-config.json
│ │ │ └── rbac-config.json
│ ├── 2024-02
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ └── core.json
│ ├── 2024-03
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ └── core.json
│ ├── 2024-04
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ ├── core.json
│ │ │ └── interface.json
│ ├── 2024-08
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ ├── control-requirement.json
│ │ │ ├── control.json
│ │ │ ├── core.json
│ │ │ ├── evidence.json
│ │ │ └── interface.json
│ ├── 2024-09
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ ├── control-requirement.json
│ │ │ ├── control.json
│ │ │ ├── core.json
│ │ │ ├── evidence.json
│ │ │ └── interface.json
│ ├── 2024-10
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ ├── control-requirement.json
│ │ │ ├── control.json
│ │ │ ├── core.json
│ │ │ ├── evidence.json
│ │ │ ├── flow.json
│ │ │ ├── interface.json
│ │ │ └── units.json
│ ├── 2024-12
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ ├── control-requirement.json
│ │ │ ├── control.json
│ │ │ ├── core.json
│ │ │ ├── evidence.json
│ │ │ ├── flow.json
│ │ │ ├── interface.json
│ │ │ └── units.json
│ ├── 2025-01
│ │ └── meta
│ │ │ ├── calm.json
│ │ │ ├── control-requirement.json
│ │ │ ├── control.json
│ │ │ ├── core.json
│ │ │ ├── evidence.json
│ │ │ ├── flow.json
│ │ │ ├── interface.json
│ │ │ └── units.json
│ └── 2025-03
│ │ ├── meta
│ │ ├── calm.json
│ │ ├── control-requirement.json
│ │ ├── control.json
│ │ ├── core.json
│ │ ├── evidence.json
│ │ ├── flow.json
│ │ ├── interface.json
│ │ └── units.json
│ │ ├── prototype
│ │ ├── anyof
│ │ │ ├── both-options.architecture.json
│ │ │ ├── neither-option.architecture.json
│ │ │ └── options-prototype.pattern.json
│ │ ├── multiple-choices
│ │ │ ├── architecture.json
│ │ │ └── options-prototype.pattern.json
│ │ ├── oneof
│ │ │ ├── application-a.architecture.json
│ │ │ ├── application-b.architecture.json
│ │ │ └── options-prototype.pattern.json
│ │ └── throughput-control-prototype.json
│ │ └── samples
│ │ └── traderx
│ │ └── control-requirement
│ │ ├── README.md
│ │ ├── business_logic_and_process_control
│ │ └── business-logic-enforcement-control-requirement.json
│ │ ├── compliance_and_governance
│ │ ├── access-review-control-requirements.json
│ │ ├── approval-workflow-control-requirement.json
│ │ ├── change-management-control-requirement.json
│ │ ├── regulatory-compliance-control-requirement.json
│ │ └── review-adjustments-control-requirement.json
│ │ ├── data_integrity_and_retention
│ │ ├── data-consistency-requirement.json
│ │ ├── data-integrity-control-requirement.json
│ │ ├── data-retention-control-requirement.json
│ │ └── schema-validation-control-requirement.json
│ │ ├── monitoring_and_observability
│ │ ├── alerting-control-requirement.json
│ │ ├── db-monitoring-control-requirement.json
│ │ ├── health-check-requirement.json
│ │ ├── logging-control-requirement.json
│ │ ├── monitoring-control-requirement.json
│ │ └── tracing-control-requirement.json
│ │ ├── performance_and_scalability
│ │ ├── latency-control-requirement.json
│ │ ├── resource-utilization-control-requirement.json
│ │ ├── scalability-control-requirement.json
│ │ ├── throughput-control-requirement.json
│ │ └── timeout-handling-control-requirement.json
│ │ ├── resilience_and_risk_management
│ │ ├── availability-control-requirement.json
│ │ ├── disaster-recovery-control-requirement.json
│ │ ├── error-handling-control-requirement.json
│ │ ├── escalation-path-control-requirement.json
│ │ ├── failover-redundancy-control-requirement.json
│ │ ├── incident-response-control-requirement.json
│ │ └── risk-management-control-requirement.json
│ │ └── security_and_access_control
│ │ ├── api-rate-limiting-control-requirement.json
│ │ ├── audit-logging-control-requirement.json
│ │ ├── authentication-control-requirement.json
│ │ ├── authorization-control-requirement.json
│ │ ├── data-encryption-control-requirement.json
│ │ └── secrets-management-control-requirement.json
├── interfaces
│ └── README.md
├── pattern
│ └── api-gateway.json
├── pom.xml
├── release
│ └── 1.0-rc1
│ │ ├── RELEASE_NOTES.md
│ │ ├── meta
│ │ ├── calm.json
│ │ ├── control-requirement.json
│ │ ├── control.json
│ │ ├── core.json
│ │ ├── evidence.json
│ │ ├── flow.json
│ │ ├── interface.json
│ │ └── units.json
│ │ └── prototype
│ │ ├── access-control-requirement.json
│ │ ├── adr-example.json
│ │ ├── anyof
│ │ ├── both-options.architecture.json
│ │ ├── neither-option.architecture.json
│ │ └── options-prototype.pattern.json
│ │ ├── authentication-as-control.json
│ │ ├── authentication-control-config.json
│ │ ├── authentication-control-requirement.json
│ │ ├── custom-interface-example.json
│ │ ├── custom-node-type-example.json
│ │ ├── data-encryption-requirement.json
│ │ ├── example-inline-config.json
│ │ ├── example-mixed-config.json
│ │ ├── interfaces
│ │ ├── grpc-service.json
│ │ └── kafka-topic.json
│ │ ├── multiple-choices
│ │ ├── architecture.json
│ │ └── options-prototype.pattern.json
│ │ ├── oneof
│ │ ├── application-a.architecture.json
│ │ ├── application-b.architecture.json
│ │ └── options-prototype.pattern.json
│ │ ├── rbac-config.json
│ │ └── throughput-control-prototype.json
├── samples
│ ├── 2024-10
│ │ └── traderx
│ │ │ ├── README.md
│ │ │ ├── controls
│ │ │ └── flow-sla-control-requirement.json
│ │ │ ├── flows
│ │ │ ├── add-update-account
│ │ │ │ ├── add-update-account-control-configuration.json
│ │ │ │ └── add-update-account.json
│ │ │ ├── bootstrapping-position-blotter
│ │ │ │ └── bootstrapping-position-blotter.json
│ │ │ ├── load-list-of-accounts
│ │ │ │ └── load-list-of-accounts.json
│ │ │ ├── submit-trade-ticket
│ │ │ │ ├── submit-trade-ticket-control-configuration.json
│ │ │ │ └── submit-trade-ticket.json
│ │ │ └── trade-processing
│ │ │ │ ├── trade-processing-control-configuration.json
│ │ │ │ ├── trade-processing-new-trade.json
│ │ │ │ └── trade-processing-update-trade.json
│ │ │ ├── traderx.json
│ │ │ └── traderx.yaml
│ ├── 2024-12
│ │ └── traderx
│ │ │ ├── README.md
│ │ │ ├── controls
│ │ │ └── flow-sla-control-requirement.json
│ │ │ ├── flows
│ │ │ ├── add-update-account
│ │ │ │ ├── add-update-account-control-configuration.json
│ │ │ │ └── add-update-account.json
│ │ │ ├── load-list-of-accounts
│ │ │ │ └── load-list-of-accounts.json
│ │ │ ├── load-positions
│ │ │ │ └── load-positions.json
│ │ │ ├── submit-trade-ticket
│ │ │ │ ├── submit-trade-ticket-control-configuration.json
│ │ │ │ └── submit-trade-ticket.json
│ │ │ └── trade-processing
│ │ │ │ ├── trade-processing-control-configuration.json
│ │ │ │ ├── trade-processing-new-trade.json
│ │ │ │ └── trade-processing-update-trade.json
│ │ │ └── traderx.json
│ ├── api-gateway-architecture.json
│ ├── traderx
│ │ └── traderx.layout.json
│ └── visualization.png
└── workshop
│ ├── README.md
│ ├── architecture
│ ├── conference-secure-signup-amended.arch.json
│ └── conference-signup.arch.json
│ ├── cached
│ └── cluster_start.sh
│ ├── conference-secure-signup.pattern.json
│ ├── conference-signup.pattern.json
│ ├── controls
│ ├── micro-segmentation.config.json
│ ├── micro-segmentation.requirement.json
│ ├── permitted-connection-http.config.json
│ ├── permitted-connection-jdbc.config.json
│ └── permitted-connection.requirement.json
│ ├── directory.json
│ ├── insecure-example
│ ├── cluster
│ │ └── cluster_start.sh
│ └── kubernetes
│ │ ├── application-deployment.yaml
│ │ ├── application-service.yaml
│ │ ├── database-deployment.yaml
│ │ ├── database-service.yaml
│ │ ├── kustomization.yaml
│ │ └── namespace.yaml
│ ├── secure-infra-template-bundle
│ ├── application-deployment.yaml
│ ├── application-service.yaml
│ ├── calico-global-deny.yaml
│ ├── cluster_start.hbs
│ ├── database-deployment.yaml
│ ├── database-service.yaml
│ ├── index.json
│ ├── infrastructure-transformer.js
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ ├── permit-app-from-db.yaml
│ ├── permit-app-to-db.yaml
│ └── permit-lb-to-app.yaml
│ └── walkthrough.sh
├── cli
├── .gitignore
├── DEVELOPER_GUIDE.md
├── README.md
├── eslint.config.mjs
├── package.json
├── pom.xml
├── src
│ ├── cli-config.spec.ts
│ ├── cli-config.ts
│ ├── cli.e2e.spec.ts
│ ├── cli.spec.ts
│ ├── cli.ts
│ ├── command-helpers
│ │ ├── calmhub-input.spec.ts
│ │ ├── calmhub-input.ts
│ │ ├── file-input.spec.ts
│ │ ├── file-input.ts
│ │ ├── generate-options.spec.ts
│ │ ├── generate-options.ts
│ │ ├── template.spec.ts
│ │ ├── template.ts
│ │ ├── validate.spec.ts
│ │ └── validate.ts
│ ├── index.ts
│ └── server
│ │ ├── cli-server.ts
│ │ └── routes
│ │ ├── health-route.spec.ts
│ │ ├── health-route.ts
│ │ ├── routes.spec.ts
│ │ ├── routes.ts
│ │ ├── validation-route.spec.ts
│ │ └── validation-route.ts
├── test_fixtures
│ ├── generate_output.json
│ ├── template
│ │ ├── expected-output
│ │ │ └── cli-e2e-output.html
│ │ ├── model
│ │ │ ├── document-system.json
│ │ │ ├── flows
│ │ │ │ └── flow-document-upload.json
│ │ │ └── url-to-file-directory.json
│ │ └── template-bundles
│ │ │ └── doc-system
│ │ │ ├── basic-transformer.js
│ │ │ ├── index.json
│ │ │ └── main.html
│ ├── validate_architecture_only_output.json
│ ├── validate_output.json
│ ├── validate_output_junit.xml
│ ├── validate_output_pretty.txt
│ └── validation_route
│ │ ├── invalid_api_gateway_instantiation_missing_schema_key.json
│ │ ├── invalid_api_gateway_instantiation_schema_points_to_missing_schema.json
│ │ └── valid_instantiation.json
├── tsconfig.build.json
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
└── watch.mjs
├── docs
├── .gitignore
├── DEVELOPER_GUIDE.md
├── README.md
├── babel.config.js
├── calm
│ └── intro.md
├── community
│ └── intro.md
├── docs
│ ├── core-concepts
│ │ ├── controls.md
│ │ ├── index.md
│ │ ├── interfaces.md
│ │ ├── metadata.md
│ │ ├── nodes.md
│ │ └── relationships.md
│ ├── index.md
│ ├── introduction
│ │ ├── index.md
│ │ ├── key-features.md
│ │ ├── what-is-calm.md
│ │ └── why-use-calm.md
│ └── working-with-calm
│ │ ├── generate.md
│ │ ├── index.md
│ │ ├── installation.md
│ │ ├── using-the-cli.md
│ │ └── validate.md
├── docusaurus.config.js
├── package.json
├── pom.xml
├── sidebars.js
├── src
│ ├── components
│ │ └── HomepageFeatures
│ │ │ ├── index.js
│ │ │ └── styles.module.css
│ ├── css
│ │ └── custom.css
│ └── pages
│ │ ├── index.js.old
│ │ ├── index.module.css
│ │ └── markdown-page.md
├── static
│ ├── .nojekyll
│ └── img
│ │ ├── favicon.ico
│ │ ├── logo.png
│ │ └── logo.svg
└── talks
│ └── index.md
├── mvnw
├── mvnw.cmd
├── package-lock.json
├── package.json
├── pom.xml
├── prettier.config.js
├── renovate.json
├── shared
├── README.md
├── eslint.config.mjs
├── package.json
├── pom.xml
├── scripts
│ └── copy-templates.mjs
├── spectral-examples
│ └── bad-rest-api.json
├── src
│ ├── commands
│ │ ├── generate
│ │ │ ├── components
│ │ │ │ ├── instantiate.spec.ts
│ │ │ │ ├── instantiate.ts
│ │ │ │ ├── options.spec.ts
│ │ │ │ ├── options.ts
│ │ │ │ ├── property.spec.ts
│ │ │ │ └── property.ts
│ │ │ ├── generate.e2e.spec.ts
│ │ │ ├── generate.spec.ts
│ │ │ └── generate.ts
│ │ └── validate
│ │ │ ├── output-formats
│ │ │ ├── junit-output.spec.ts
│ │ │ ├── junit-output.ts
│ │ │ ├── pretty-output.spec.ts
│ │ │ └── pretty-output.ts
│ │ │ ├── spectral.result.ts
│ │ │ ├── validate.spec.ts
│ │ │ ├── validate.ts
│ │ │ └── validation.output.ts
│ ├── consts.ts
│ ├── docify
│ │ ├── docifier.e2e.spec.ts
│ │ ├── docifier.spec.ts
│ │ ├── docifier.ts
│ │ ├── graphing
│ │ │ ├── c4.spec.ts
│ │ │ ├── c4.ts
│ │ │ ├── relationship-graph.spec.ts
│ │ │ └── relationship-graph.ts
│ │ └── template-bundles
│ │ │ └── docusaurus
│ │ │ ├── c4-container.hbs
│ │ │ ├── control-requirement.hbs
│ │ │ ├── controls.hbs
│ │ │ ├── custom.css
│ │ │ ├── docusaurus-transformer.ts
│ │ │ ├── docusaurus.config.js
│ │ │ ├── flow-sequence.hbs
│ │ │ ├── flow.mdx.hbs
│ │ │ ├── index.json
│ │ │ ├── index.md.hbs
│ │ │ ├── json-doc.mdx.hbs
│ │ │ ├── node.mdx.hbs
│ │ │ ├── package.json
│ │ │ ├── relationships.hbs
│ │ │ ├── remark-replace-links.js
│ │ │ ├── row-template.html
│ │ │ ├── sidebar.js.hbs
│ │ │ └── table-template.html
│ ├── document-loader
│ │ ├── calmhub-document-loader.spec.ts
│ │ ├── calmhub-document-loader.ts
│ │ ├── document-loader.spec.ts
│ │ ├── document-loader.ts
│ │ ├── file-system-document-loader.spec.ts
│ │ └── file-system-document-loader.ts
│ ├── index.ts
│ ├── logger.ts
│ ├── model
│ │ ├── control-requirement.spec.ts
│ │ ├── control-requirement.ts
│ │ ├── control.spec.ts
│ │ ├── control.ts
│ │ ├── core.spec.ts
│ │ ├── core.ts
│ │ ├── flow.spec.ts
│ │ ├── flow.ts
│ │ ├── interface.spec.ts
│ │ ├── interface.ts
│ │ ├── metadata.spec.ts
│ │ ├── metadata.ts
│ │ ├── node.spec.ts
│ │ ├── node.ts
│ │ ├── relationship.spec.ts
│ │ └── relationship.ts
│ ├── parser
│ │ ├── parser.e2e.spec.ts
│ │ └── parser.ts
│ ├── resolver
│ │ ├── calm-reference-resolver.spec.ts
│ │ └── calm-reference-resolver.ts
│ ├── schema-directory.spec.ts
│ ├── schema-directory.ts
│ ├── spectral
│ │ ├── examples
│ │ │ └── bad-rest-api.json
│ │ ├── functions
│ │ │ ├── architecture
│ │ │ │ ├── ids-are-unique.ts
│ │ │ │ ├── interface-id-exists-on-node.ts
│ │ │ │ ├── interface-id-exists.ts
│ │ │ │ ├── node-has-relationship.ts
│ │ │ │ └── node-id-exists.ts
│ │ │ ├── helper-functions.ts
│ │ │ └── pattern
│ │ │ │ ├── ids-are-unique.ts
│ │ │ │ ├── interface-id-exists-on-node.ts
│ │ │ │ ├── interface-id-exists.ts
│ │ │ │ ├── is-defined-in-oneof-or-anyof.ts
│ │ │ │ ├── node-has-relationship.ts
│ │ │ │ └── node-id-exists.ts
│ │ ├── rules-architecture.ts
│ │ └── rules-pattern.ts
│ ├── template
│ │ ├── template-bundle-file-loader.spec.ts
│ │ ├── template-bundle-file-loader.ts
│ │ ├── template-calm-file-dereferencer.e2e.spec.ts
│ │ ├── template-calm-file-dereferencer.spec.ts
│ │ ├── template-calm-file-dereferencer.ts
│ │ ├── template-default-transfomer.spec.ts
│ │ ├── template-default-transformer.ts
│ │ ├── template-engine.spec.ts
│ │ ├── template-engine.ts
│ │ ├── template-processor.e2e.spec.ts
│ │ ├── template-processor.spec.ts
│ │ ├── template-processor.ts
│ │ └── types.ts
│ ├── test
│ │ ├── mocks
│ │ │ ├── handlers.ts
│ │ │ └── server.ts
│ │ └── setup-msw.ts
│ ├── types.ts
│ ├── types
│ │ ├── control-requirement-types.ts
│ │ ├── control-types.ts
│ │ ├── core-types.ts
│ │ ├── flow-types.ts
│ │ ├── interface-types.ts
│ │ ├── metadata-types.ts
│ │ └── units-types.ts
│ ├── util.spec.ts
│ └── util.ts
├── test_fixtures
│ ├── additional-props.json
│ ├── api-gateway-implementation-that-does-not-match-schema.json
│ ├── api-gateway-implementation-that-does-not-pass-the-spectral-validation.json
│ ├── api-gateway-implementation.json
│ ├── api-gateway-self-reference.json
│ ├── api-gateway-with-no-relationships.json
│ ├── api-gateway.json
│ ├── bad-schema
│ │ └── bad-json-schema.json
│ ├── calm.json
│ ├── calm
│ │ ├── calm.json
│ │ ├── core.json
│ │ └── file-to-ignore.txt
│ ├── command
│ │ └── generate
│ │ │ └── expected-output
│ │ │ ├── conference-secure-signup.arch.json
│ │ │ └── conference-signup.arch.json
│ ├── core.json
│ ├── markdown.md
│ ├── schema-directory
│ │ ├── missing-inner-ref.json
│ │ ├── recursive.json
│ │ ├── references.json
│ │ └── relative-ref.json
│ └── template
│ │ ├── bundles
│ │ ├── bad-transformer
│ │ │ ├── bad-transformer.ts
│ │ │ ├── index.json
│ │ │ └── main.hbs
│ │ ├── default-transformer
│ │ │ ├── index.json
│ │ │ └── main.hbs
│ │ ├── dereferencing-transformer
│ │ │ ├── deref-transformer.ts
│ │ │ ├── index.json
│ │ │ └── main.hbs
│ │ ├── failing-transformer
│ │ │ ├── failing-transformer.ts
│ │ │ ├── index.json
│ │ │ └── main.hbs
│ │ ├── infrastructure-transformer
│ │ │ ├── application-deployment.yaml
│ │ │ ├── application-service.yaml
│ │ │ ├── calico-global-deny.yaml
│ │ │ ├── cluster_start.hbs
│ │ │ ├── database-deployment.yaml
│ │ │ ├── database-service.yaml
│ │ │ ├── index.json
│ │ │ ├── infrastructure-transformer.ts
│ │ │ ├── kustomization.yaml
│ │ │ ├── namespace.yaml
│ │ │ ├── permit-app-from-db.yaml
│ │ │ ├── permit-app-to-db.yaml
│ │ │ └── permit-lb-to-app.yaml
│ │ ├── js-transformer
│ │ │ ├── index.json
│ │ │ ├── main.hbs
│ │ │ └── transformer.js
│ │ ├── missing-transformer
│ │ │ ├── index.json
│ │ │ └── main.hbs
│ │ ├── repeated
│ │ │ ├── index.json
│ │ │ ├── main.hbs
│ │ │ └── repeated-transformer.ts
│ │ ├── single-file
│ │ │ ├── index.json
│ │ │ ├── main.hbs
│ │ │ └── simple-transformer.ts
│ │ └── with-partials
│ │ │ ├── footer.hbs
│ │ │ ├── header.hbs
│ │ │ ├── index.json
│ │ │ ├── main.hbs
│ │ │ └── with-partials-transformer.ts
│ │ ├── data
│ │ ├── conference-secure-signup.amended.arch.json
│ │ ├── controls
│ │ │ ├── architect.configuration.json
│ │ │ ├── business-owner.configuration.json
│ │ │ ├── owner-responsibility.requirement.json
│ │ │ └── system-owner.configuration.json
│ │ ├── document-system-with-controls.json
│ │ ├── document-system.json
│ │ ├── flow-document-upload.json
│ │ └── simple-nodes.json
│ │ └── expected-output
│ │ ├── deref-output.html
│ │ ├── doc-system-one-pager.md
│ │ ├── js-transformer.txt
│ │ ├── with-partials.txt
│ │ └── workshop
│ │ └── infrastructure
│ │ ├── cluster
│ │ ├── calico-global-deny.yaml
│ │ └── cluster_start.sh
│ │ └── kubernetes
│ │ ├── application-deployment.yaml
│ │ ├── application-service.yaml
│ │ ├── database-deployment.yaml
│ │ ├── database-service.yaml
│ │ ├── kustomization.yaml
│ │ ├── namespace.yaml
│ │ ├── permit-app-from-db.yaml
│ │ ├── permit-app-to-db.yaml
│ │ └── permit-lb-to-app.yaml
├── tsconfig.build.json
├── tsconfig.json
├── tsup.config.ts
└── vitest.config.ts
├── template-bundles
└── control
│ ├── control-requirement.hbs
│ ├── control-transformer.ts
│ └── index.json
├── tsconfig.base.json
└── vitest-globals.d.ts
/.devcontainer/devcontainer.json:
--------------------------------------------------------------------------------
1 | {
2 | "image": "mcr.microsoft.com/devcontainers/universal:3",
3 | "features": {
4 | "ghcr.io/devcontainers-contrib/features/maven-sdkman:2": {
5 | "version": "latest",
6 | "jdkVersion": "latest",
7 | "jdkDistro": "open"
8 | },
9 | "ghcr.io/devcontainers-contrib/features/mvnd-sdkman:2": {
10 | "version": "latest",
11 | "jdkVersion": "latest",
12 | "jdkDistro": "open"
13 | }
14 | },
15 | "containerEnv": {
16 | "JAVA_HOME": "/usr/local/sdkman/candidates/java/current"
17 | },
18 | "postCreateCommand": "echo 'export JAVA_HOME=/usr/local/sdkman/candidates/java/current' >> ~/.bashrc",
19 | "hostRequirements": {
20 | "cpus": 4,
21 | "memory": "16gb"
22 | },
23 | "customizations": {
24 | "vscode": {
25 | "extensions": [
26 | "vscjava.vscode-java-pack"
27 | ]
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.flox/.gitignore:
--------------------------------------------------------------------------------
1 | run/
2 | cache/
3 | lib/
4 | log/
5 |
--------------------------------------------------------------------------------
/.flox/env.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "calm",
3 | "version": 1
4 | }
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.mov filter=lfs diff=lfs merge=lfs -text
2 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @finos/architecture-as-code-maintainers
2 |
3 | /calm/ @finos/calm-schema-governance
4 |
5 | /calm-hub/ @jpgough-ms @rocketstack-matt @grahampacker-ms @Thels
6 |
7 | /cli/ @aidanm3341 @lbulanti-ms @willosborne @grahampacker-ms @jpgough-ms @rocketstack-matt @Thels @LeighFinegold
8 |
9 | /calm-visualizer/ @oliviajanejohns @aidanm3341 @jpgough-ms @rocketstack-matt
10 |
11 | /shared/ @aidanm3341 @lbulanti-ms @willosborne @grahampacker-ms @jpgough-ms @rocketstack-matt @Thels @LeighFinegold
12 |
13 | # Ownership for dependency-related files at the root level
14 | /package.json @finos/architecture-as-code-maintainers
15 | /package-lock.json @finos/architecture-as-code-maintainers
16 | /pom.xml @finos/architecture-as-code-maintainers
17 |
18 | # Ownership for dependency-related files across all subdirectories
19 | **/package.json @finos/architecture-as-code-maintainers
20 | **/package-lock.json @finos/architecture-as-code-maintainers
21 | **/pom.xml @finos/architecture-as-code-maintainers
22 |
--------------------------------------------------------------------------------
/.github/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct for architecture-as-code
2 |
3 | Please see the [Community Code of Conduct](https://www.finos.org/code-of-conduct).
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🐛 Bug Report
3 | about: If something isn't working as expected 🤔
4 |
5 | ---
6 |
7 | ## Bug Report
8 |
9 | ### Steps to Reproduce:
10 | 1. ...step 1 description...
11 | 2. ...step 2 description...
12 | 3. ...step 3 description...
13 |
14 | ### Expected Result:
15 | ...description of what you expected to see...
16 |
17 | ### Actual Result:
18 | ...what actually happened, including full exceptions (please include the entire stack trace, including "caused by" entries), log entries, screen shots etc. where appropriate...
19 |
20 | ### Environment:
21 | ...version and build of the project, OS and runtime versions, virtualised environment (if any), etc. ...
22 |
23 | ### Additional Context:
24 | ...add any other context about the problem here. If applicable, add screenshots to help explain...
25 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/Support_question.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: 🤗 Support Question
3 | about: If you have a question about configuration, usage, etc. 💬
4 |
5 | ---
6 |
7 | ## Support Question
8 |
9 | ...ask your question here.
10 |
11 | ...be sure to search existing issues since someone might have already asked something similar.
12 |
--------------------------------------------------------------------------------
/.github/labeler.yml:
--------------------------------------------------------------------------------
1 | cli:
2 | - "cli/**"
3 | shared:
4 | - "shared/**"
5 | docs:
6 | - "docs/**"
7 | calm-hub:
8 | - "calm-hub/**"
9 | calm:
10 | - "calm/**"
11 | calm-hub-ui:
12 | - "calm-hub-ui/**"
13 | config:
14 | - "pom.xml"
15 | - "**/package.json"
16 | - "**/package-lock.json"
17 |
--------------------------------------------------------------------------------
/.github/maven-cve-ignore-list.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | .*quarkus-run\.jar
6 | 10.0
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.github/workflows/build-calm-hub-coverage.yml:
--------------------------------------------------------------------------------
1 | name: Build Calm Hub For Unit Test Coverage
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - "main"
7 | push:
8 | branches:
9 | - "main"
10 |
11 | jobs:
12 | build:
13 | name: Build Calm Hub
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | # Step 1: Checkout PR Branch
18 | - name: Checkout PR Branch
19 | uses: actions/checkout@v4
20 |
21 | # Step 2: Set up JDK
22 | - name: Set up JDK
23 | uses: actions/setup-java@v4
24 | with:
25 | distribution: 'temurin'
26 | java-version: '21'
27 |
28 | # Step 3: Cache Maven Dependencies
29 | - name: Cache Maven Dependencies
30 | uses: actions/cache@v4
31 | with:
32 | path: ~/.m2
33 | key: ${{ runner.os }}-m2-${{ hashFiles('calm-hub/pom.xml') }}
34 | restore-keys: |
35 | ${{ runner.os }}-m2-
36 |
37 | # Step 4: Build and Test
38 | - name: Build and Test
39 | working-directory: calm-hub
40 | run: mvn clean verify
41 |
--------------------------------------------------------------------------------
/.github/workflows/build-calm-hub-ui.yml:
--------------------------------------------------------------------------------
1 | name: Build CALM Hub UI
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - "main"
7 | push:
8 | branches:
9 | - "main"
10 |
11 | jobs:
12 | shared:
13 | name: Build, Test, and Lint Shared Module
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Checkout PR Branch
18 | uses: actions/checkout@v4
19 |
20 | - name: Setup Node.js
21 | uses: actions/setup-node@v4
22 | with:
23 | node-version: v22
24 |
25 | - name: Install workspace
26 | run: npm ci
27 |
28 | - name: Lint Shared Module
29 | run: npm run lint --workspace=calm-hub-ui
30 |
31 | - name: Build workspace
32 | run: npm run build --workspace=calm-hub-ui
33 |
34 | - name: Run tests for Shared
35 | run: npm run test --workspace=calm-hub-ui
36 |
--------------------------------------------------------------------------------
/.github/workflows/build-cli.yml:
--------------------------------------------------------------------------------
1 | name: Build CLI
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - "main"
7 | push:
8 | branches:
9 | - "main"
10 |
11 | jobs:
12 | cli:
13 | name: Build, Test, and Lint CLI Module
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Checkout PR Branch
18 | uses: actions/checkout@v4
19 |
20 | - name: Setup Node.js
21 | uses: actions/setup-node@v4
22 | with:
23 | node-version: v22
24 |
25 | - name: Install workspace
26 | run: npm ci
27 |
28 | - name: Lint CLI Module
29 | run: npm run lint --workspace=cli
30 |
31 | - name: Build workspace
32 | run: npm run build:cli
33 |
34 | - name: Run tests with coverage for CLI
35 | run: npm run test --workspace=cli
36 |
--------------------------------------------------------------------------------
/.github/workflows/build-docs.yml:
--------------------------------------------------------------------------------
1 | name: Build Docs
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - "main"
7 | push:
8 | branches:
9 | - "main"
10 |
11 | jobs:
12 | docs:
13 | name: Build Docs Module
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Checkout PR Branch
18 | uses: actions/checkout@v4
19 |
20 | - name: Setup Node.js
21 | uses: actions/setup-node@v4
22 | with:
23 | node-version: v22
24 | cache: npm
25 | cache-dependency-path: package-lock.json
26 |
27 | - name: Install workspace
28 | run: npm ci
29 |
30 | - name: Build Docs
31 | run: npm run build:docs
32 |
--------------------------------------------------------------------------------
/.github/workflows/build-shared.yml:
--------------------------------------------------------------------------------
1 | name: Build Shared
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - "main"
7 | push:
8 | branches:
9 | - "main"
10 |
11 | jobs:
12 | shared:
13 | name: Build, Test, and Lint Shared Module
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Checkout PR Branch
18 | uses: actions/checkout@v4
19 |
20 | - name: Setup Node.js
21 | uses: actions/setup-node@v4
22 | with:
23 | node-version: v22
24 |
25 | - name: Install workspace
26 | run: npm ci
27 |
28 | - name: Lint Shared Module
29 | run: npm run lint --workspace=shared
30 |
31 | - name: Build workspace
32 | run: npm run build --workspace=shared
33 |
34 | - name: Run tests with coverage for Shared
35 | run: npm run test --workspace=shared
--------------------------------------------------------------------------------
/.github/workflows/license-scanning-node.yml:
--------------------------------------------------------------------------------
1 | name: License Scanning for Node.js
2 |
3 | on:
4 | schedule:
5 | - cron: '0 8,18 * * 1-5'
6 | push:
7 | paths:
8 | - '**/package-json.lock'
9 | - '**/package.json'
10 | - '.github/workflows/license-scanning-node.yml'
11 |
12 | jobs:
13 | scan:
14 | runs-on: ubuntu-latest
15 | strategy:
16 | matrix:
17 | node-version: ['22.x']
18 | module-folder: ['cli', 'docs', 'shared']
19 | steps:
20 | - uses: actions/checkout@v4
21 | - name: Use Node.js ${{ matrix.node-version }}
22 | uses: actions/setup-node@v4
23 | with:
24 | node-version: ${{ matrix.node-version }}
25 | - run: npm install --omit=dev
26 | working-directory: ${{ matrix.module-folder }}
27 | - run: npm install -g node-license-validator
28 | working-directory: ${{ matrix.module-folder }}
29 | - run: node-license-validator . --allow-licenses Apache-2.0 MIT BSD-2-Clause BSD BSD-3-Clause Unlicense ISC
30 | working-directory: ${{ matrix.module-folder }}
31 |
--------------------------------------------------------------------------------
/.github/workflows/pr-labelling.yml:
--------------------------------------------------------------------------------
1 | name: PR Labeler
2 |
3 | on:
4 | pull_request_target:
5 | types: [opened, synchronize]
6 |
7 | jobs:
8 | label:
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - name: Checkout repository
13 | uses: actions/checkout@v4
14 |
15 | - name: Label PR based on changes
16 | uses: actions/labeler@v4
17 | with:
18 | repo-token: "${{ secrets.GITHUB_TOKEN }}"
--------------------------------------------------------------------------------
/.github/workflows/publish-cli-to-npm.yml:
--------------------------------------------------------------------------------
1 | name: Publish CLI to NPM
2 |
3 | on:
4 | release:
5 | types: [published]
6 |
7 | jobs:
8 | publish-cli:
9 | runs-on: ubuntu-latest
10 | steps:
11 |
12 | # Checkout the code
13 | - name: Checkout code
14 | uses: actions/checkout@v4
15 |
16 | # Set up Node.js
17 | - name: Setup Node.js
18 | uses: actions/setup-node@v4
19 | with:
20 | node-version: v22
21 | registry-url: "https://registry.npmjs.org"
22 |
23 | # Install the workspace
24 | - name: Install workspace
25 | run: npm ci
26 |
27 | # Build the entire workspace
28 | - name: Build workspace
29 | run: npm run build
30 |
31 | # Publish the CLI module
32 | - name: Publish CLI module
33 | run: npm publish --workspace cli
34 | env:
35 | NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
36 |
--------------------------------------------------------------------------------
/.github/workflows/s3-docs-sync.yml:
--------------------------------------------------------------------------------
1 | name: Sync Docs to S3
2 |
3 | on:
4 | workflow_dispatch: {}
5 | push:
6 | branches: ["main"]
7 | paths: ["docs/**"]
8 |
9 | jobs:
10 | sync-to-s3:
11 | runs-on: ubuntu-latest
12 | defaults:
13 | run:
14 | working-directory: docs
15 |
16 | steps:
17 | - name: Checkout repository
18 | uses: actions/checkout@v4
19 |
20 | - uses: actions/setup-node@v4
21 | with:
22 | node-version: 22
23 | cache: npm
24 | cache-dependency-path: package-lock.json
25 | - name: Install dependencies
26 | run: npm ci
27 | - name: Build website
28 | run: npm run build
29 |
30 | - name: Configure AWS credentials
31 | uses: aws-actions/configure-aws-credentials@v4
32 | with:
33 | aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY }}
34 | aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_ACCESS_KEY }}
35 | aws-region: us-east-1
36 | - name: Sync docs to S3
37 | run: |
38 | aws s3 sync build s3://calm.finos.org/ --delete --include "*" --exclude "draft/*" --exclude "samples/*" --exclude "video/*"
39 |
--------------------------------------------------------------------------------
/.github/workflows/s3-sync.yml:
--------------------------------------------------------------------------------
1 | name: Sync CALM to S3
2 |
3 | on:
4 | workflow_dispatch: {}
5 | push:
6 | branches:
7 | - main
8 | paths:
9 | - 'calm/draft/**'
10 | - 'calm/samples/**'
11 |
12 | jobs:
13 | sync-to-s3:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - name: Checkout repository
18 | uses: actions/checkout@v4
19 | - name: Configure AWS credentials
20 | uses: aws-actions/configure-aws-credentials@v4
21 | with:
22 | aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY }}
23 | aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_ACCESS_KEY }}
24 | aws-region: us-east-1
25 | - name: Sync calm/draft folder to S3
26 | run: |
27 | aws s3 sync calm/draft s3://${{ vars.AWS_S3_BUCKET }}/draft --delete
28 | - name: Sync calm/samples folder to S3
29 | run: |
30 | aws s3 sync calm/samples s3://${{ vars.AWS_S3_BUCKET }}/samples --delete
31 |
--------------------------------------------------------------------------------
/.github/workflows/s3-video-sync.yml:
--------------------------------------------------------------------------------
1 | name: Sync Videos to S3
2 |
3 | on:
4 | workflow_dispatch: {}
5 | push:
6 | branches:
7 | - main
8 | paths:
9 | - 'video'
10 |
11 | jobs:
12 | sync-to-s3:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - name: Checkout repository
17 | uses: actions/checkout@v4
18 | - name: Configure AWS credentials
19 | uses: aws-actions/configure-aws-credentials@v4
20 | with:
21 | aws-access-key-id: ${{ secrets.AWS_S3_ACCESS_KEY }}
22 | aws-secret-access-key: ${{ secrets.AWS_S3_SECRET_ACCESS_KEY }}
23 | aws-region: us-east-1
24 | - name: Sync video folder to S3
25 | run: |
26 | aws s3 sync video s3://${{ vars.AWS_S3_BUCKET }}/video
27 |
--------------------------------------------------------------------------------
/.github/workflows/semgrep-ci.yml:
--------------------------------------------------------------------------------
1 | name: Semgrep
2 | on:
3 | workflow_dispatch: {}
4 | pull_request: {}
5 | push:
6 | branches:
7 | - main
8 | paths:
9 | - .github/workflows/semgrep-ci.yml
10 | schedule:
11 | # random HH:MM to avoid a load spike on GitHub Actions at 00:00
12 | - cron: '09 15 * * *'
13 | jobs:
14 | semgrep:
15 | name: semgrep/ci
16 | runs-on: ubuntu-24.04
17 | env:
18 | SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
19 | container:
20 | image: semgrep/semgrep
21 | if: (github.actor != 'dependabot[bot]')
22 | steps:
23 | - uses: actions/checkout@v4
24 | - run: semgrep ci
25 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
3 | # Docusaurus generated folders
4 | website/translated_docs/
5 | website/build/
6 | website/i18n/
7 |
8 | # Yarn build
9 | website/node_modules/
10 |
11 | # Generated docs
12 | docs/contributing.md
13 |
14 | # We use YARN
15 | website/package-lock.json
16 | /.idea/
17 |
18 | **/.vscode/
19 |
20 | node_modules/
21 | **/dist/
22 | **/.vscode-test/
23 | **/out/
24 | **/dependency-check-report/
25 |
26 | **/tsconfig.tsbuildinfo
27 |
28 | !/.mvn/wrapper/maven-wrapper.jar
29 |
30 | coverage/
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | # Licensed to the Apache Software Foundation (ASF) under one
2 | # or more contributor license agreements. See the NOTICE file
3 | # distributed with this work for additional information
4 | # regarding copyright ownership. The ASF licenses this file
5 | # to you under the Apache License, Version 2.0 (the
6 | # "License"); you may not use this file except in compliance
7 | # with the License. You may obtain a copy of the License at
8 | #
9 | # http://www.apache.org/licenses/LICENSE-2.0
10 | #
11 | # Unless required by applicable law or agreed to in writing,
12 | # software distributed under the License is distributed on an
13 | # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 | # KIND, either express or implied. See the License for the
15 | # specific language governing permissions and limitations
16 | # under the License.
17 | wrapperVersion=3.3.2
18 | distributionType=only-script
19 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.9/apache-maven-3.9.9-bin.zip
20 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "testing.openTesting": "neverOpen",
3 | "jest.outputConfig": {
4 | "revealOn": "run",
5 | "revealWithFocus": "none",
6 | "clearOnRun": "none"
7 | },
8 | "editor.formatOnSave": true,
9 | "editor.codeActionsOnSave": {
10 | "source.fixAll.eslint": "explicit"
11 | },
12 | "java.compile.nullAnalysis.mode": "automatic",
13 | "java.configuration.updateBuildConfiguration": "automatic",
14 | "editor.defaultFormatter": "esbenp.prettier-vscode",
15 | "editor.formatOnPaste": false,
16 | "testing.automaticallyOpenTestResults": "neverOpen"
17 | }
18 |
--------------------------------------------------------------------------------
/LICENSE.spdx:
--------------------------------------------------------------------------------
1 | SPDXVersion: SPDX-2.0
2 | DataLicense: CC0-1.0
3 | Creator: FINOS
4 | PackageName: architecture-as-code
5 | PackageOriginator: FINOS
6 | PackageHomePage: https://github.com/finos/architecture-as-code
7 | PackageLicenseDeclared: Apache-2.0
8 |
--------------------------------------------------------------------------------
/NOTICE:
--------------------------------------------------------------------------------
1 | architecture-as-code - FINOS
2 | Copyright - 2023 FINOS info@finos.org
3 |
4 | This product includes software developed at the Fintech Open Source Foundation (https://www.finos.org/).
5 |
6 |
--------------------------------------------------------------------------------
/brand/2025_CALM_Logo.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/2025_CALM_Logo.pdf
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal.eps
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal.jpg
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal.png
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal_BLK.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal_BLK.eps
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal_BLK.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal_BLK.jpg
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal_BLK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal_BLK.png
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal_WHT.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal_WHT.eps
--------------------------------------------------------------------------------
/brand/Horizontal/2025_CALM_Horizontal_WHT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Horizontal/2025_CALM_Horizontal_WHT.png
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon.eps
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon.jpg
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon.png
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon_BLK.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon_BLK.eps
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon_BLK.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon_BLK.jpg
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon_BLK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon_BLK.png
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon_WHT.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon_WHT.eps
--------------------------------------------------------------------------------
/brand/Icon/2025_CALM_Icon_WHT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Icon/2025_CALM_Icon_WHT.png
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked.eps
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked.jpg
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked.png
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked_BLK.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked_BLK.eps
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked_BLK.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked_BLK.jpg
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked_BLK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked_BLK.png
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked_WHT.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked_WHT.eps
--------------------------------------------------------------------------------
/brand/Stacked/2025_CALM_Stacked_WHT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Stacked/2025_CALM_Stacked_WHT.png
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark.eps
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark.jpg
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark.png
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark_BLK.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark_BLK.eps
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark_BLK.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark_BLK.jpg
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark_BLK.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark_BLK.png
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark_WHT.eps:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark_WHT.eps
--------------------------------------------------------------------------------
/brand/Wordmark/2025_CALM_Wordmark_WHT.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/brand/Wordmark/2025_CALM_Wordmark_WHT.png
--------------------------------------------------------------------------------
/calm-hub-ui/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 | /public/brand
14 |
15 | # misc
16 | .DS_Store
17 | .env.local
18 | .env.development.local
19 | .env.test.local
20 | .env.production.local
21 |
22 | npm-debug.log*
23 | yarn-debug.log*
24 | yarn-error.log*
25 |
--------------------------------------------------------------------------------
/calm-hub-ui/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 4,
4 | "semi": true,
5 | "singleQuote": true,
6 | "bracketSpacing": true,
7 | "endOfLine": "auto",
8 | "printWidth": 100
9 | }
10 |
--------------------------------------------------------------------------------
/calm-hub-ui/eslint.config.js:
--------------------------------------------------------------------------------
1 | import js from '@eslint/js';
2 | import globals from 'globals';
3 | import reactHooks from 'eslint-plugin-react-hooks';
4 | import reactRefresh from 'eslint-plugin-react-refresh';
5 | import tseslint from 'typescript-eslint';
6 |
7 | export default tseslint.config(
8 | { ignores: ['dist'] },
9 | {
10 | extends: [js.configs.recommended, ...tseslint.configs.recommended],
11 | files: ['**/*.{ts,tsx}'],
12 | languageOptions: {
13 | ecmaVersion: 2020,
14 | globals: globals.browser,
15 | },
16 | plugins: {
17 | 'react-hooks': reactHooks,
18 | 'react-refresh': reactRefresh,
19 | },
20 | rules: {
21 | ...reactHooks.configs.recommended.rules,
22 | 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
23 | },
24 | }
25 | );
26 |
--------------------------------------------------------------------------------
/calm-hub-ui/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CALM
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/calm-hub-ui/postcss.config.cjs:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {},
3 | };
4 |
--------------------------------------------------------------------------------
/calm-hub-ui/prettier.config.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @see https://prettier.io/docs/en/configuration.html
3 | * @type {import("prettier").Config}
4 | */
5 | const config = {
6 | trailingComma: 'es5',
7 | tabWidth: 4,
8 | semi: true,
9 | singleQuote: true,
10 | };
11 |
12 | module.exports = config;
13 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/App.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/calm-hub-ui/src/App.css
--------------------------------------------------------------------------------
/calm-hub-ui/src/App.tsx:
--------------------------------------------------------------------------------
1 | import { HashRouter as Router, Route, Routes } from 'react-router-dom';
2 | import Hub from './hub/Hub.js';
3 | import Visualizer from './visualizer/Visualizer.js';
4 |
5 | function App() {
6 | return (
7 |
8 |
9 | } />
10 | } />
11 |
12 |
13 | );
14 | }
15 |
16 | export default App;
17 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/components/navbar/Navbar.css:
--------------------------------------------------------------------------------
1 | .logo {
2 | max-width: unset;
3 | height: inherit;
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/hub/components/value-table/ValueTable.tsx:
--------------------------------------------------------------------------------
1 | interface ValueTableProps {
2 | header: string;
3 | values: string[];
4 | callback: (value: string) => void;
5 | currentValue: string | undefined;
6 | }
7 |
8 | export function ValueTable({ header, values, callback, currentValue }: ValueTableProps) {
9 | return (
10 |
11 |
12 | {header}
13 |
14 |
15 |
16 | {values.map((value) => {
17 | let styles = 'h-fit p-5 hover:bg-gray-50';
18 |
19 | if (currentValue === value) {
20 | styles = styles + ' bg-[#eee]';
21 | }
22 |
23 | return (
24 |
callback(value)}>
25 | {value}
26 |
27 | );
28 | })}
29 |
30 |
31 | );
32 | }
33 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/index.css:
--------------------------------------------------------------------------------
1 | @import 'tailwindcss';
2 | @plugin "daisyui" {
3 | themes: light --default;
4 | }
5 |
6 | [data-theme='light'] {
7 | --color-primary: #000063;
8 | --color-accent: #007dff;
9 | }
10 |
11 | #root {
12 | height: 100vh;
13 | }
14 |
15 | body {
16 | margin: 0;
17 | font-family:
18 | -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell',
19 | 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
20 | -webkit-font-smoothing: antialiased;
21 | -moz-osx-font-smoothing: grayscale;
22 | }
23 |
24 | code {
25 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace;
26 | }
27 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import ProtectedRoute from './ProtectedRoute.js';
4 | import './index.css';
5 | import { authService } from './authService.js';
6 | import App from './App.js';
7 |
8 | const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement);
9 |
10 | const LogoutButton: React.FC = () => {
11 | const handleLogout = async () => {
12 | await authService.logout();
13 | };
14 |
15 | return (
16 |
19 | );
20 | };
21 |
22 | const isHttps = window.location.protocol === 'https:';
23 |
24 | root.render(
25 |
26 | {isHttps ? (
27 |
28 |
29 |
30 |
31 | ) : (
32 |
33 | )}
34 |
35 | );
36 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/model/calm.tsx:
--------------------------------------------------------------------------------
1 | export type Namespace = string;
2 | export type PatternID = string;
3 | export type Pattern = string;
4 | export type Architecture = string;
5 | export type ArchitectureID = string;
6 | export type FlowID = string;
7 | export type Flow = string;
8 | export type Version = string;
9 | export type CalmType = 'Architectures' | 'Patterns' | 'Flows';
10 |
11 | export type Data = {
12 | id: string;
13 | version: string;
14 | name: Namespace;
15 | calmType: CalmType;
16 | data: Pattern | Architecture | Flow | undefined;
17 | };
18 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/output.css:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/calm-hub-ui/src/output.css
--------------------------------------------------------------------------------
/calm-hub-ui/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = (onPerfEntry) => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/visualizer/Visualizer.css:
--------------------------------------------------------------------------------
1 | .node {
2 | padding: 2rem;
3 | border: 2px black solid;
4 | position: absolute;
5 | }
6 |
7 | .container {
8 | position: relative;
9 | display: flex;
10 | justify-content: center;
11 | }
12 |
13 | .z-1 {
14 | z-index: 1;
15 | }
16 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/visualizer/components/cytoscape-renderer/cytoscape.css:
--------------------------------------------------------------------------------
1 | .node {
2 | border: 1px solid;
3 | text-align: center;
4 | width: 200px;
5 | font-family: Arial;
6 | padding: 5px 10px 5px 10px;
7 | background-color: white;
8 | }
9 |
10 | .selected-node {
11 | background-color: #cce1f9;
12 | }
13 |
14 | :focus {
15 | border: 1px solid;
16 | border-color: blue;
17 | }
18 |
19 | .graph-title {
20 | z-index: 1;
21 | padding: var(--navbar-padding, 0.5rem);
22 | }
23 |
24 | .element {
25 | display: flex;
26 | flex-direction: column;
27 | align-items: center;
28 | margin-left: -100px;
29 | }
30 |
31 | .title {
32 | font-weight: bold;
33 | color: black;
34 | }
35 |
36 | .type {
37 | margin-top: 10px;
38 | color: grey;
39 | }
40 |
41 | .description {
42 | margin-top: 10px;
43 | color: black;
44 | }
45 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/visualizer/components/cytoscape-renderer/cytoscape.d.ts:
--------------------------------------------------------------------------------
1 | declare module 'cytoscape-node-html-label';
2 | declare module 'cytoscape-cose-bilkent';
3 | declare module 'cytoscape-expand-collapse';
4 | declare module 'cytoscape-node-edge-html-label';
5 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/visualizer/components/drawer/Drawer.test.tsx:
--------------------------------------------------------------------------------
1 | import { describe, expect, it } from 'vitest';
2 | import { render, screen } from '@testing-library/react';
3 | import { Drawer } from './Drawer.js';
4 |
5 | describe('Drawer', () => {
6 | it('should render Drawer', () => {
7 | render(
8 |
14 | );
15 | expect(screen.getByText('No file selected')).toBeInTheDocument();
16 | });
17 |
18 | it('should render Drawer', () => {
19 | render(
20 |
26 | );
27 | expect(screen.getByText('No file selected')).toBeInTheDocument();
28 | expect(screen.getByRole('checkbox', { name: 'drawer-toggle' })).not.toBeChecked();
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/visualizer/helpers/set-functions.ts:
--------------------------------------------------------------------------------
1 | // Required because sometimes the set API of Typescript is not supported.
2 |
3 | /**
4 | * @param set1
5 | * @param set2
6 | * @returns union of set1 and set2.
7 | */
8 | export function union(set1: Set, set2: Set): Set {
9 | return new Set([...set1, ...set2]);
10 | }
11 |
12 | /**
13 | *
14 | * @param set1
15 | * @param set2
16 | * @returns intersection between set1 and set2.
17 | */
18 | export function intersection(set1: Set, set2: Set): Set {
19 | return new Set([...set1].filter((item) => set2.has(item)));
20 | }
21 |
22 | /**
23 | *
24 | * @param set1
25 | * @param set2
26 | * @returns set1 - set2 i.e. elements in set1 that are not in set2.
27 | */
28 | export function difference(set1: Set, set2: Set): Set {
29 | return new Set([...set1].filter((item) => !set2.has(item)));
30 | }
31 |
--------------------------------------------------------------------------------
/calm-hub-ui/src/visualizer/services/node-position-service.tsx:
--------------------------------------------------------------------------------
1 | export interface StoredNodePosition {
2 | id: string;
3 | position: { x: number; y: number };
4 | }
5 |
6 | export function saveNodePositions(title: string, positions: StoredNodePosition[]) {
7 | try {
8 | localStorage.setItem(title, JSON.stringify(positions));
9 | } catch (err) {
10 | console.error('Failed to save node positions:', err);
11 | }
12 | }
13 |
14 | export function loadStoredNodePositions(title: string): StoredNodePosition[] | null {
15 | try {
16 | const data = localStorage.getItem(title);
17 | return data ? JSON.parse(data) : null;
18 | } catch (err) {
19 | console.error('Failed to load node positions:', err);
20 | return null;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/calm-hub-ui/vite-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/calm-hub-ui/vite.config.ts:
--------------------------------------------------------------------------------
1 | ///
2 | import { defineConfig } from 'vitest/config';
3 | import react from '@vitejs/plugin-react';
4 | import tailwindcss from '@tailwindcss/vite';
5 |
6 | // https://vitejs.dev/config/
7 | export default defineConfig({
8 | plugins: [react(), tailwindcss()],
9 | test: {
10 | globals: true,
11 | environment: 'jsdom',
12 | environmentMatchGlobs: [['./src/**/*.tsx', 'jsdom']],
13 | setupFiles: ['./vitest.setup.ts'],
14 | },
15 | build: {
16 | outDir: 'build',
17 | },
18 | server: {
19 | proxy: {
20 | '/calm': 'http://localhost:8080',
21 | },
22 | },
23 | });
24 |
--------------------------------------------------------------------------------
/calm-hub-ui/vitest.setup.ts:
--------------------------------------------------------------------------------
1 | import '@testing-library/jest-dom/vitest';
2 | import { afterEach } from 'vitest';
3 | import { cleanup } from '@testing-library/react';
4 |
5 | // runs a clean after each test case (e.g. clearing jsdom)
6 | afterEach(() => {
7 | cleanup();
8 | });
9 |
--------------------------------------------------------------------------------
/calm-hub/.dockerignore:
--------------------------------------------------------------------------------
1 | # Ignore everything
2 | *
3 |
4 | # Allow the Maven Wrapper and build files
5 | !pom.xml
6 | !.mvn/
7 | !mvnw
8 | !src
9 |
10 | # Allow the target directory for the final build
11 | !target/*-runner
12 | !target/*-runner.jar
13 | !target/lib/*
14 | !target/quarkus-app/*
15 |
--------------------------------------------------------------------------------
/calm-hub/deploy/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mongodb:
3 | image: mongo:latest
4 | container_name: calm_mongodb
5 | ports:
6 | - "27017:27017"
7 | volumes:
8 | - ../mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
9 | networks:
10 | - calm-net
11 | calmhub:
12 | image: finos/calm-hub:latest
13 | container_name: calm-hub
14 | ports:
15 | - "8080:8080"
16 | environment:
17 | - JAVA_OPTS=-Dquarkus.mongodb.connection-string=mongodb://mongodb:27017
18 | networks:
19 | - calm-net
20 | networks:
21 | calm-net:
22 | driver: bridge
23 |
--------------------------------------------------------------------------------
/calm-hub/k8s/calm-hub.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: calmhub
5 | labels:
6 | app: calmhub
7 | spec:
8 | replicas: 1
9 | selector:
10 | matchLabels:
11 | app: calmhub
12 | template:
13 | metadata:
14 | labels:
15 | app: calmhub
16 | spec:
17 | containers:
18 | - name: calmhub
19 | image: finos/calm-hub:latest
20 | ports:
21 | - containerPort: 8080
22 |
23 | ---
24 | apiVersion: v1
25 | kind: Service
26 | metadata:
27 | name: calmhub
28 | labels:
29 | app: calmhub
30 | spec:
31 | type: LoadBalancer
32 | ports:
33 | - port: 80
34 | targetPort: 8080
35 | selector:
36 | app: calmhub
37 |
--------------------------------------------------------------------------------
/calm-hub/k8s/mongo.yml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: mongodb
5 | labels:
6 | app: mongodb
7 | spec:
8 | replicas: 1
9 | selector:
10 | matchLabels:
11 | app: mongodb
12 | template:
13 | metadata:
14 | labels:
15 | app: mongodb
16 | spec:
17 | containers:
18 | - name: mongodb
19 | image: mongo:latest
20 | ports:
21 | - containerPort: 27017
22 | volumeMounts:
23 | - name: init-mongo-script
24 | mountPath: /docker-entrypoint-initdb.d/init-mongo.js
25 | subPath: init-mongo.js
26 | volumes:
27 | - name: init-mongo-script
28 | configMap:
29 | name: mongo-init-config
30 |
31 | ---
32 | apiVersion: v1
33 | kind: Service
34 | metadata:
35 | name: mongodb
36 | labels:
37 | app: mongodb
38 | spec:
39 | ports:
40 | - port: 27017
41 | targetPort: 27017
42 | selector:
43 | app: mongodb
44 |
--------------------------------------------------------------------------------
/calm-hub/keycloak-dev/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | keycloak:
3 | image: quay.io/keycloak/keycloak:26.2
4 | container_name: keycloak
5 | ports:
6 | - "9443:8443"
7 | environment:
8 | KC_BOOTSTRAP_ADMIN_USERNAME: admin
9 | KC_BOOTSTRAP_ADMIN_PASSWORD: ${KC_BOOTSTRAP_ADMIN_PASSWORD}
10 | KC_HTTPS_PORT: 8443
11 | KC_HTTPS_CERTIFICATE_FILE: /opt/keycloak/certs/cert.pem
12 | KC_HTTPS_CERTIFICATE_KEY_FILE: /opt/keycloak/certs/key.pem
13 | volumes:
14 | - ./imports:/opt/keycloak/data/import
15 | - ./certs:/opt/keycloak/certs
16 | command: start-dev --import-realm
17 | restart: unless-stopped
--------------------------------------------------------------------------------
/calm-hub/local-dev/docker-compose.yml:
--------------------------------------------------------------------------------
1 | services:
2 | mongodb:
3 | image: mongo:latest
4 | container_name: calm_mongodb
5 | ports:
6 | - "27017:27017"
7 | volumes:
8 | - ../mongo/init-mongo.js:/docker-entrypoint-initdb.d/init-mongo.js:ro
9 | networks:
10 | - calm-net
11 | networks:
12 | calm-net:
13 | driver: bridge
--------------------------------------------------------------------------------
/calm-hub/src/integration-test/java/integration/EndToEndResource.java:
--------------------------------------------------------------------------------
1 | package integration;
2 |
3 | import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import org.testcontainers.containers.MongoDBContainer;
7 |
8 | import java.util.Map;
9 |
10 | public class EndToEndResource implements QuarkusTestResourceLifecycleManager {
11 |
12 | private MongoDBContainer mongoDBContainer;
13 |
14 | private static final Logger logger = LoggerFactory.getLogger(EndToEndResource.class);
15 |
16 | @Override
17 | public Map start() {
18 | if(mongoDBContainer == null) {
19 | mongoDBContainer = new MongoDBContainer("mongo:4.4.3");
20 | }
21 |
22 | logger.info("Starting MongoDB container");
23 | mongoDBContainer.start();
24 | return Map.of(
25 | "quarkus.mongodb.connection-string", mongoDBContainer.getReplicaSetUrl()
26 | );
27 | }
28 |
29 | @Override
30 | public void stop() {
31 | mongoDBContainer.stop();
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/calm-hub/src/integration-test/java/integration/IntegrationTestProfile.java:
--------------------------------------------------------------------------------
1 | package integration;
2 |
3 | import io.quarkus.test.common.QuarkusTestResource;
4 | import io.quarkus.test.junit.QuarkusTestProfile;
5 |
6 | import java.util.Set;
7 |
8 | @QuarkusTestResource(EndToEndResource.class)
9 | public class IntegrationTestProfile implements QuarkusTestProfile {
10 |
11 | @Override
12 | public Set> getEnabledAlternatives() {
13 | // Optionally, return specific classes you want enabled only for this profile
14 | return Set.of();
15 | }
16 |
17 | @Override
18 | public String getConfigProfile() {
19 | // Optional: specify a custom profile name if needed
20 | return "integration-test";
21 | }
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/config/StandaloneQualifier.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.config;
2 |
3 | import jakarta.inject.Qualifier;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 | import java.lang.annotation.ElementType;
8 |
9 | /**
10 | * Qualifier for standalone mode database instances.
11 | * Used to inject the NitriteDB instance in standalone mode.
12 | */
13 | @Qualifier
14 | @Retention(RetentionPolicy.RUNTIME)
15 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
16 | public @interface StandaloneQualifier {
17 | }
18 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/Domain.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain;
2 |
3 | /**
4 | * Represents a domain in the CALM system.
5 | * A domain is a logical grouping of controls and shared control schemas
6 | */
7 | public class Domain {
8 |
9 | /**
10 | * Constructor to create a Domain with a specified name.
11 | *
12 | * @param name the name of the domain
13 | */
14 | public Domain(String name) {
15 | this.name = name;
16 | }
17 |
18 | /**
19 | * Default constructor for Domain.
20 | * This constructor is used for deserialization purposes.
21 | */
22 | public Domain() {
23 |
24 | }
25 |
26 | private String name;
27 |
28 | public String getName() {
29 | return name;
30 | }
31 |
32 | public void setName(String name) {
33 | this.name = name;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/Standard.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain;
2 |
3 | import java.util.Objects;
4 |
5 | public class Standard extends StandardDetails {
6 | private String standardJson;
7 |
8 | public Standard(String name, String description, String standardJson, Integer id, String version) {
9 | super(name, description, id, version);
10 | this.standardJson = standardJson;
11 | }
12 |
13 | public Standard() {
14 | // Default constructor
15 | }
16 |
17 | public String getStandardJson() {
18 | return standardJson;
19 | }
20 |
21 | public void setStandardJson(String standardJson) {
22 | this.standardJson = standardJson;
23 | }
24 |
25 | @Override
26 | public boolean equals(Object o) {
27 | if (o == null || getClass() != o.getClass()) return false;
28 | if (!super.equals(o)) return false;
29 | Standard standard1 = (Standard) o;
30 | return Objects.equals(standardJson, standard1.standardJson);
31 | }
32 |
33 | @Override
34 | public int hashCode() {
35 | return Objects.hash(super.hashCode(), standardJson);
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/ValueWrapper.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * Wrapper class for a list of values, this is used to wrap a list of values and provide the option to paginate results later
7 | *
8 | * @param the type of the values
9 | */
10 | public class ValueWrapper {
11 | private List values;
12 |
13 | public ValueWrapper(List values) {
14 | this.values = values;
15 | }
16 |
17 | public List getValues() {
18 | return values;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/adr/Status.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.adr;
2 |
3 | public enum Status {
4 | draft,
5 | proposed,
6 | accepted,
7 | superseded,
8 | rejected,
9 | deprecated
10 | }
11 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/AdrNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the specified ADR is not found.
5 | */
6 | public class AdrNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/AdrParseException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class AdrParseException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/AdrPersistenceException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class AdrPersistenceException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/AdrRevisionNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the specified ADR revision is not found.
5 | */
6 | public class AdrRevisionNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/ArchitectureNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the specified architecture is not found.
5 | */
6 | public class ArchitectureNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/ArchitectureVersionExistsException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when an architecture version already exists.
5 | */
6 | public class ArchitectureVersionExistsException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/ArchitectureVersionNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the specified architecture version is not found.
5 | */
6 | public class ArchitectureVersionNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/DomainAlreadyExistsException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class DomainAlreadyExistsException extends Exception {
4 | public DomainAlreadyExistsException(String message) {
5 | super(message);
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/FlowNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class FlowNotFoundException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/FlowVersionExistsException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class FlowVersionExistsException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/FlowVersionNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class FlowVersionNotFoundException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/NamespaceNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the specified namespace is not found.
5 | */
6 | public class NamespaceNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/PatternNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the specified pattern is not found.
5 | */
6 | public class PatternNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/PatternVersionExistsException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when a pattern version already exists.
5 | */
6 | public class PatternVersionExistsException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/PatternVersionNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the specified pattern version is not found.
5 | */
6 | public class PatternVersionNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/StandardNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class StandardNotFoundException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/StandardVersionExistsException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class StandardVersionExistsException extends Exception {
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/StandardVersionNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | public class StandardVersionNotFoundException extends Exception{
4 | }
5 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/domain/exception/UserAccessNotFoundException.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.domain.exception;
2 |
3 | /**
4 | * Exception thrown when the user access details are not found.
5 | */
6 | public class UserAccessNotFoundException extends Exception {
7 | }
8 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/resources/CalmResourceErrorResponses.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.resources;
2 |
3 | import jakarta.ws.rs.core.Response;
4 |
5 | public class CalmResourceErrorResponses {
6 | public static Response invalidNamespaceResponse(String namespace) {
7 | return Response.status(Response.Status.NOT_FOUND).entity("Invalid namespace provided: " + namespace).build();
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/resources/ResourceValidationConstants.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.resources;
2 |
3 | import org.owasp.html.HtmlPolicyBuilder;
4 | import org.owasp.html.PolicyFactory;
5 |
6 | public class ResourceValidationConstants {
7 | public static final String NAMESPACE_REGEX = "^[A-Za-z0-9-]+$";
8 | public static final String NAMESPACE_MESSAGE = "namespace must match pattern '^[A-Za-z0-9-]+$'";
9 | public static final String VERSION_REGEX = "^(0|[1-9][0-9]*)[-.]?(0|[1-9][0-9]*)[-.]?(0|[1-9][0-9]*)$";
10 | public static final String VERSION_MESSAGE = "version must match pattern '^(0|[1-9][0-9]*)[-.]?(0|[1-9][0-9]*)[-.]?(0|[1-9][0-9]*)$'";
11 | public static final PolicyFactory STRICT_SANITIZATION_POLICY = new HtmlPolicyBuilder().toFactory();
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/security/PermittedScopes.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.security;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | /**
9 | * Custom annotation to define required scopes for a REST endpoint.
10 | */
11 | @Target({ ElementType.METHOD, ElementType.TYPE })
12 | @Retention(RetentionPolicy.RUNTIME)
13 | public @interface PermittedScopes {
14 | String[] value();
15 | }
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/security/UserRequestAttributes.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.security;
2 |
3 | public record UserRequestAttributes(String requestMethod, String username, String path, String namespace) {
4 |
5 | }
6 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/store/CoreSchemaStore.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.store;
2 |
3 | import java.util.List;
4 | import java.util.Map;
5 |
6 | public interface CoreSchemaStore {
7 | List getVersions();
8 | Map getSchemasForVersion(String version);
9 | void createSchemaVersion(String version, Map schemas);
10 | }
11 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/store/DomainStore.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.store;
2 |
3 | import org.finos.calm.domain.Domain;
4 | import org.finos.calm.domain.exception.DomainAlreadyExistsException;
5 |
6 | import java.util.List;
7 |
8 | /**
9 | * Interface for managing domains in the CALM system.
10 | * Provides methods to retrieve and create domains.
11 | */
12 | public interface DomainStore {
13 | /**
14 | * Retrieves a list of all domains in the system.
15 | *
16 | * @return a list of domain names
17 | */
18 | List getDomains();
19 |
20 | /**
21 | * Creates a new domain with the specified name.
22 | *
23 | * @param name the name of the domain to create
24 | * @return the created Domain object
25 | * @throws DomainAlreadyExistsException if a domain with the same name already exists
26 | */
27 | Domain createDomain(String name) throws DomainAlreadyExistsException;
28 | }
29 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/store/FlowStore.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.store;
2 |
3 | import org.finos.calm.domain.*;
4 | import org.finos.calm.domain.exception.NamespaceNotFoundException;
5 | import org.finos.calm.domain.exception.FlowNotFoundException;
6 | import org.finos.calm.domain.exception.FlowVersionExistsException;
7 | import org.finos.calm.domain.exception.FlowVersionNotFoundException;
8 |
9 | import java.util.List;
10 |
11 | public interface FlowStore {
12 | List getFlowsForNamespace(String namespace) throws NamespaceNotFoundException;
13 | Flow createFlowForNamespace(Flow flow) throws NamespaceNotFoundException;
14 | List getFlowVersions(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException;
15 | String getFlowForVersion(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException, FlowVersionNotFoundException;
16 | Flow createFlowForVersion(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException, FlowVersionExistsException;
17 | Flow updateFlowForVersion(Flow flow) throws NamespaceNotFoundException, FlowNotFoundException;
18 | }
19 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/store/NamespaceStore.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.store;
2 |
3 | import java.util.List;
4 |
5 | public interface NamespaceStore {
6 | List getNamespaces();
7 | boolean namespaceExists(String namespace);
8 | void createNamespace(String namespace);
9 | }
10 |
--------------------------------------------------------------------------------
/calm-hub/src/main/java/org/finos/calm/store/StandardStore.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.store;
2 |
3 | import org.finos.calm.domain.Standard;
4 | import org.finos.calm.domain.StandardDetails;
5 | import org.finos.calm.domain.exception.NamespaceNotFoundException;
6 | import org.finos.calm.domain.exception.StandardNotFoundException;
7 | import org.finos.calm.domain.exception.StandardVersionExistsException;
8 | import org.finos.calm.domain.exception.StandardVersionNotFoundException;
9 |
10 | import java.util.List;
11 |
12 | public interface StandardStore {
13 | List getStandardsForNamespace(String namespace) throws NamespaceNotFoundException;
14 | Standard createStandardForNamespace(Standard standard) throws NamespaceNotFoundException;
15 | List getStandardVersions(StandardDetails standard) throws NamespaceNotFoundException, StandardNotFoundException;
16 | String getStandardForVersion(StandardDetails standardDetails) throws NamespaceNotFoundException, StandardNotFoundException, StandardVersionNotFoundException;
17 | Standard createStandardForVersion(Standard standard) throws NamespaceNotFoundException, StandardNotFoundException, StandardVersionExistsException;
18 | }
19 |
--------------------------------------------------------------------------------
/calm-hub/src/main/resources/application-secure.properties:
--------------------------------------------------------------------------------
1 | quarkus.http.ssl-port=8443
2 | quarkus.http.insecure-requests=disabled
3 | quarkus.http.ssl.certificate.key-files=key.pem
4 | quarkus.http.ssl.certificate.key-store-file-type=PEM
5 | quarkus.http.ssl.certificate.files=cert.pem
6 |
7 | quarkus.http.auth.permission.secured.paths=/calm/*
8 | quarkus.http.auth.permission.secured.policy=authenticated
9 |
10 | #calm-hub has to configure with truststore to validate the IdP's server certs.
11 | quarkus.oidc.tls.verification=none
12 | quarkus.oidc.auth-server-url=https://localhost:9443/realms/calm-hub-realm
13 | quarkus.oidc.client-id=calm-hub-producer-app
14 | quarkus.oidc.token.audience=calm-hub-producer-app
15 | quarkus.oidc.tenant-enabled=true
--------------------------------------------------------------------------------
/calm-hub/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | quarkus.swagger-ui.always-include=true
2 | quarkus.smallrye-openapi.info-title=Calm Hub
3 | #If using in quarkus dev mode can be 'mongo' or 'standalone'
4 | calm.database.mode=mongo
5 | # Standalone mode configuration
6 | calm.standalone.data-directory=${user.home}/.calm-hub/data
7 | calm.standalone.database-name=calmSchemas
8 | calm.standalone.username=admin
9 | calm.standalone.password=admin
10 | calm.standalone.init-script-path=mongo/init-mongo.js
11 | quarkus.mongodb.connection-string = mongodb://localhost:27017
12 | quarkus.mongodb.database = calmSchemas
13 |
14 | #Disable creating the keycloak container for default profile.
15 | quarkus.oidc.enabled=true
16 | quarkus.keycloak.devservices.enabled=false
17 | quarkus.oidc.tenant-enabled=false
18 |
19 | #quarkus.http.port=8081
--------------------------------------------------------------------------------
/calm-hub/src/test/java/org/finos/calm/resources/AllowPutProfile.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.resources;
2 |
3 | import io.quarkus.test.junit.QuarkusTestProfile;
4 |
5 | import java.util.Map;
6 |
7 | public class AllowPutProfile implements QuarkusTestProfile {
8 | @Override
9 | public Map getConfigOverrides() {
10 | return Map.of(
11 | "allow.put.operations", "true"
12 | );
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/calm-hub/src/test/java/org/finos/calm/resources/TestCalmErrorResponsesShould.java:
--------------------------------------------------------------------------------
1 | package org.finos.calm.resources;
2 |
3 | import jakarta.ws.rs.core.Response;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import static org.hamcrest.MatcherAssert.assertThat;
7 | import static org.hamcrest.Matchers.equalTo;
8 |
9 | public class TestCalmErrorResponsesShould {
10 |
11 | @Test
12 | void create_an_invalid_namespace_response() {
13 | try (Response response = CalmResourceErrorResponses.invalidNamespaceResponse("finos")) {
14 | assertThat(response.getStatus(), equalTo(404));
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/calm-hub/src/test/resources/application.properties:
--------------------------------------------------------------------------------
1 | # Test configuration
2 | quarkus.arc.remove-unused-beans=false
3 | quarkus.test.native-image-profile=test
4 | quarkus.test.continuous-testing=enabled
5 | quarkus.test.flat-class-path=true
6 |
7 | # Database configuration for tests
8 | quarkus.mongodb.connection-string=mongodb://localhost:27017
9 | quarkus.mongodb.database=test
10 | quarkus.mongodb.devservices.enabled=true
11 |
12 | # Standalone mode configuration
13 | calm.database.mode=mongo
14 | calm.standalone.data-directory=target/test-data
15 | calm.standalone.database-name=calmSchemasTest
16 | calm.standalone.username=admin
17 | calm.standalone.password=admin
18 | calm.standalone.init-script-path=src/test/resources/init-mongo.js
19 |
--------------------------------------------------------------------------------
/calm/control-example/one-node-wonder.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-08/meta/calm.json",
3 | "title": "Demonstration of domain and controls",
4 | "nodes": [
5 | {
6 | "unique-id": "example-system",
7 | "node-type": "system",
8 | "name": "Example System",
9 | "description": "Example System",
10 | "controls": {
11 | "cbom": {
12 | "description": "Control requirements for delivering patterns",
13 | "requirements": [
14 | {
15 | "control-requirement": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/control-example/pre-prod-review-specification.json",
16 | "control-config": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/control-example/pre-prod-review-configuration.json"
17 | }
18 | ]
19 | }
20 | }
21 | }
22 | ],
23 | "relationships": [],
24 | "metadata": []
25 | }
--------------------------------------------------------------------------------
/calm/control-example/pre-prod-review-configuration.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/control-example/control-specification.json",
3 | "title": "Evidence of pre-production review",
4 | "control-id": "ci-arch-001",
5 | "name": "Architecture review pre-production",
6 | "scope-text": "All workloads going to production",
7 | "scope-rego": "input.metadata.target-deployment.environment == Production",
8 | "description": "As part of the SDLC requirements, each workload going to production is subject to an architecture review"
9 | }
--------------------------------------------------------------------------------
/calm/control-example/pre-prod-review-evidence.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-08/meta/evidence.json",
3 | "evidence": {
4 | "unique-id": "pre-prod-review-evidence",
5 | "control-configuration-url": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/control-example/pre-prod-review-configuration.json",
6 | "evidence-paths": [
7 | "https://evidence.com/12345"
8 | ]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/calm/control-example/pre-prod-review-specification.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/control-example/control-specification.json",
4 | "title": "Example Production Control Specification",
5 | "type": "object",
6 | "allOf": [
7 | {
8 | "$ref": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-08/meta/control-requirement.json"
9 | }
10 | ],
11 | "properties": {
12 | "control-id": {
13 | "const": "ci-arch-001"
14 | },
15 | "name": {
16 | "const": "Architecture review pre-production"
17 | },
18 | "description": {
19 | "const": "As part of the SDLC requirements, each workload going to production is subject to an architecture review"
20 | },
21 | "scope-text": {
22 | "const": "All workloads going to production"
23 | },
24 | "scope-rego": {
25 | "const": "input.metadata.target-deployment.environment == Production"
26 | }
27 | },
28 | "required": [
29 | "scope-text",
30 | "scope-rego",
31 | "control-id",
32 | "name",
33 | "description"
34 | ]
35 | }
--------------------------------------------------------------------------------
/calm/domains-example/security/cluster-ingress-https.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/domains-example/security/schema/permitted-connection.json",
3 | "control-id": "security-002",
4 | "name": "Permitted Connection",
5 | "description": "Permits a connection on a relationship specified in the architecture",
6 | "protocol": "HTTPS"
7 | }
--------------------------------------------------------------------------------
/calm/domains-example/security/cluster-internal-mtls.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/domains-example/security/schema/permitted-connection.json",
3 | "control-id": "security-002",
4 | "name": "Permitted Connection",
5 | "description": "Permits a connection on a relationship specified in the architecture",
6 | "protocol": "mTLS"
7 | }
--------------------------------------------------------------------------------
/calm/domains-example/security/cluster-micro-segmentation.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/domains-example/security/schema/micro-segmentation.json",
3 | "control-id": "security-001",
4 | "name": "Micro-segmentation of Kubernetes Cluster",
5 | "description": "Micro-segmentation is in place to prevent lateral movement outside of permitted flows",
6 | "permit-ingress": true,
7 | "permit-egress": false
8 | }
--------------------------------------------------------------------------------
/calm/domains-example/security/schema/micro-segmentation.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/domains-example/security/schema/micro-segmentation.json",
4 | "title": "Micro-segmentation in place",
5 | "type": "object",
6 | "allOf": [
7 | {
8 | "$ref": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-08/meta/control-requirement.json"
9 | }
10 | ],
11 | "properties": {
12 | "control-id": {
13 | "const": "security-001"
14 | },
15 | "name": {
16 | "const": "Micro-segmentation of Kubernetes Cluster"
17 | },
18 | "description": {
19 | "const": "Micro-segmentation is in place to prevent lateral movement outside of permitted flows"
20 | },
21 | "permit-ingress": {
22 | "type": "boolean"
23 | },
24 | "permit-egress": {
25 | "type": "boolean"
26 | }
27 | },
28 | "required": [
29 | "control-id",
30 | "name",
31 | "description",
32 | "permit-ingress",
33 | "permit-egress"
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/calm/draft/1083/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/1083/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://calm.finos.org/draft/1083/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://calm.finos.org/draft/1083/meta/core.json"}
20 | ]
21 | }
--------------------------------------------------------------------------------
/calm/draft/1083/prototype/interfaces/kafka-topic.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/1083/interfaces/kafka-topic",
4 | "title": "Kafka Topic Interface",
5 | "type": "object",
6 | "properties": {
7 | "topic": {
8 | "type": "string",
9 | "description": "The name of the Kafka topic"
10 | },
11 | "host": {
12 | "type": "string",
13 | "format": "hostname",
14 | "description": "The Kafka broker hostname or IP"
15 | },
16 | "port": {
17 | "type": "integer",
18 | "description": "The port on which the Kafka broker is exposed",
19 | "minimum": 1,
20 | "maximum": 65535
21 | }
22 | },
23 | "required": ["topic", "host", "port"]
24 | }
--------------------------------------------------------------------------------
/calm/draft/1177/prototype/authentication-control-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$id": "https://calm.finos.org/draft/1177/prototype/authentication-control-config.json",
3 | "auth-method": "OAuth2",
4 | "token-expiry": {
5 | "unit": "hours",
6 | "value": 1
7 | },
8 | "mfa-required": false,
9 | "token-revocation": true,
10 | "additional-details": {
11 | "grant-type": "client_credentials",
12 | "token-endpoint": "https://auth.example.com/token"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/calm/draft/1233/prototype/encryption-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "encryption-algorithm": "AES-256",
3 | "key-rotation-period": "90-days",
4 | "data-at-rest": true,
5 | "data-in-transit": true
6 | }
7 |
--------------------------------------------------------------------------------
/calm/draft/1233/prototype/example-inline-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "controls": {
3 | "data-security": {
4 | "description": "Data security controls for the system",
5 | "requirements": [
6 | {
7 | "control-requirement-url": "https://calm.finos.org/draft/1233/prototype/data-encryption-requirement.json",
8 | "control-config": {
9 | "encryption-algorithm": "AES-256",
10 | "key-rotation-period": "90-days",
11 | "data-at-rest": true,
12 | "data-in-transit": true
13 | }
14 | },
15 | {
16 | "control-requirement-url": "https://calm.finos.org/draft/1233/prototype/access-control-requirement.json",
17 | "control-config-url": "https://calm.finos.org/draft/1233/prototype/rbac-config.json"
18 | }
19 | ]
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/calm/draft/1233/prototype/example-url-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "controls": {
3 | "data-security": {
4 | "description": "Data security controls for the system",
5 | "requirements": [
6 | {
7 | "control-requirement-url": "https://calm.finos.org/draft/1233/prototype/data-encryption-requirement.json",
8 | "control-config-url": "https://calm.finos.org/draft/1233/prototype/encryption-config.json"
9 | },
10 | {
11 | "control-requirement-url": "https://calm.finos.org/draft/1233/prototype/access-control-requirement.json",
12 | "control-config-url": "https://calm.finos.org/draft/1233/prototype/rbac-config.json"
13 | }
14 | ]
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/calm/draft/1233/prototype/rbac-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "access-model": "RBAC",
3 | "multi-factor-authentication": true,
4 | "session-timeout": 30,
5 | "password-policy": {
6 | "minimum-length": 12,
7 | "require-special-chars": true,
8 | "require-numbers": true,
9 | "require-mixed-case": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/calm/draft/2024-02/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-02/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-02/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-02/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2024-03/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-03/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-03/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-03/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2024-04/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-04/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-04/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-04/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2024-08/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-08/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-08/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://raw.githubusercontent.com/finos/architecture-as-code/main/calm/draft/2024-08/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2024-09/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/2024-09/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://calm.finos.org/draft/2024-09/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://calm.finos.org/draft/2024-09/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2024-10/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/2024-10/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://calm.finos.org/draft/2024-10/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://calm.finos.org/draft/2024-10/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2024-12/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/2024-12/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://calm.finos.org/draft/2024-12/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://calm.finos.org/draft/2024-12/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2025-01/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/2025-01/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://calm.finos.org/draft/2025-01/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://calm.finos.org/draft/2025-01/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2025-03/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/2025-03/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://calm.finos.org/draft/2025-03/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://calm.finos.org/draft/2025-03/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/draft/2025-03/prototype/anyof/neither-option.architecture.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://calm.finos.org/draft/2025-03/prototype/anyof/both-options-prototype.pattern.json",
3 | "$id": "https://calm.finos.org/draft/2025-03/prototype/anyof/neither-option.architecture.json",
4 | "title": "Application without Database Pattern Example",
5 | "nodes": [
6 | {
7 | "unique-id": "application",
8 | "name": "Application",
9 | "description": "An application that optionally connects to one or more DBs",
10 | "node-type": "service"
11 | }
12 | ],
13 | "relationships": [
14 | {
15 | "unique-id": "connection-options",
16 | "description": "Which databases does your application connect to?",
17 | "relationship-type": {
18 | "options": []
19 | }
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/calm/draft/2025-03/prototype/throughput-control-prototype.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/traderx/control-requirement/throughput",
4 | "title": "Throughput Requirement",
5 | "type": "object",
6 | "allOf": [
7 | {
8 | "$ref": "https://calm.finos.org/draft/2025-03/meta/control-requirement.json"
9 | }
10 | ],
11 | "properties": {
12 | "expected-message-rate": {
13 | "$ref": "https://calm.finos.org/draft/2025-03/meta/units.json#/defs/rate-unit",
14 | "description": "Define the expected message rate that the flow should handle (e.g., 1000 per second)."
15 | }
16 | },
17 | "required": [
18 | "expected-message-rate"
19 | ]
20 | }
--------------------------------------------------------------------------------
/calm/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 |
7 | org.finos.architecture-as-code
8 | parent
9 | 1.0.0-SNAPSHOT
10 |
11 |
12 | calm
13 | pom
14 |
15 | Placeholder module for CALM
16 |
17 |
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/meta/calm.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/release/1.0-rc1/meta/calm.json",
4 |
5 | "$vocabulary": {
6 | "https://json-schema.org/draft/2020-12/vocab/core": true,
7 | "https://json-schema.org/draft/2020-12/vocab/applicator": true,
8 | "https://json-schema.org/draft/2020-12/vocab/validation": true,
9 | "https://json-schema.org/draft/2020-12/vocab/meta-data": true,
10 | "https://json-schema.org/draft/2020-12/vocab/format-annotation": true,
11 | "https://json-schema.org/draft/2020-12/vocab/content": true,
12 | "https://calm.finos.org/release/1.0-rc1/meta/core.json": true
13 | },
14 | "$dynamicAnchor": "meta",
15 |
16 | "title": "Common Architecture Language Model (CALM) Schema",
17 | "allOf": [
18 | {"$ref": "https://json-schema.org/draft/2020-12/schema"},
19 | {"$ref": "https://calm.finos.org/release/1.0-rc1/meta/core.json"}
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/prototype/anyof/neither-option.architecture.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://calm.finos.org/release/1.0-rc1/prototype/anyof/both-options-prototype.pattern.json",
3 | "$id": "https://calm.finos.org/release/1.0-rc1/prototype/anyof/neither-option.architecture.json",
4 | "title": "Application without Database Pattern Example",
5 | "nodes": [
6 | {
7 | "unique-id": "application",
8 | "name": "Application",
9 | "description": "An application that optionally connects to one or more DBs",
10 | "node-type": "service"
11 | }
12 | ],
13 | "relationships": [
14 | {
15 | "unique-id": "connection-options",
16 | "description": "Which databases does your application connect to?",
17 | "relationship-type": {
18 | "options": []
19 | }
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/prototype/authentication-control-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$id": "https://calm.finos.org/draft/1177/prototype/authentication-control-config.json",
3 | "auth-method": "OAuth2",
4 | "token-expiry": {
5 | "unit": "hours",
6 | "value": 1
7 | },
8 | "mfa-required": false,
9 | "token-revocation": true,
10 | "additional-details": {
11 | "grant-type": "client_credentials",
12 | "token-endpoint": "https://auth.example.com/token"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/prototype/custom-node-type-example.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://calm.finos.org/release/1.0-rc1/meta/calm.json",
3 | "nodes": [
4 | {
5 | "unique-id": "standard-node",
6 | "node-type": "service",
7 | "name": "Standard Service",
8 | "description": "This node uses a standard node type from the enum"
9 | },
10 | {
11 | "unique-id": "custom-node",
12 | "node-type": "microservice",
13 | "name": "Custom Microservice",
14 | "description": "This node uses a custom node type that is not in the standard enum"
15 | },
16 | {
17 | "unique-id": "custom-node-2",
18 | "node-type": "gateway",
19 | "name": "API Gateway",
20 | "description": "Another example of a custom node type"
21 | }
22 | ],
23 | "relationships": [
24 | {
25 | "unique-id": "rel-1",
26 | "relationship-type": {
27 | "connects": {
28 | "source": {
29 | "node": "custom-node"
30 | },
31 | "destination": {
32 | "node": "standard-node"
33 | }
34 | }
35 | }
36 | }
37 | ]
38 | }
39 |
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/prototype/example-inline-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "controls": {
3 | "data-security": {
4 | "description": "Data security controls for the system",
5 | "requirements": [
6 | {
7 | "control-requirement-url": "https://calm.finos.org/release/1.0-rc1/prototype/data-encryption-requirement.json",
8 | "control-config": {
9 | "encryption-algorithm": "AES-256",
10 | "key-rotation-period": "90-days",
11 | "data-at-rest": true,
12 | "data-in-transit": true
13 | }
14 | },
15 | {
16 | "control-requirement-url": "https://calm.finos.org/release/1.0-rc1/prototype/access-control-requirement.json",
17 | "control-config-url": "https://calm.finos.org/release/1.0-rc1/prototype/rbac-config.json"
18 | }
19 | ]
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/prototype/interfaces/kafka-topic.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/draft/1083/interfaces/kafka-topic",
4 | "title": "Kafka Topic Interface",
5 | "type": "object",
6 | "properties": {
7 | "topic": {
8 | "type": "string",
9 | "description": "The name of the Kafka topic"
10 | },
11 | "host": {
12 | "type": "string",
13 | "format": "hostname",
14 | "description": "The Kafka broker hostname or IP"
15 | },
16 | "port": {
17 | "type": "integer",
18 | "description": "The port on which the Kafka broker is exposed",
19 | "minimum": 1,
20 | "maximum": 65535
21 | }
22 | },
23 | "required": ["topic", "host", "port"]
24 | }
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/prototype/rbac-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "access-model": "RBAC",
3 | "multi-factor-authentication": true,
4 | "session-timeout": 30,
5 | "password-policy": {
6 | "minimum-length": 12,
7 | "require-special-chars": true,
8 | "require-numbers": true,
9 | "require-mixed-case": true
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/calm/release/1.0-rc1/prototype/throughput-control-prototype.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/traderx/control-requirement/throughput",
4 | "title": "Throughput Requirement",
5 | "type": "object",
6 | "allOf": [
7 | {
8 | "$ref": "https://calm.finos.org/release/1.0-rc1/meta/control-requirement.json"
9 | }
10 | ],
11 | "properties": {
12 | "expected-message-rate": {
13 | "$ref": "https://calm.finos.org/release/1.0-rc1/meta/units.json#/defs/rate-unit",
14 | "description": "Define the expected message rate that the flow should handle (e.g., 1000 per second)."
15 | }
16 | },
17 | "required": [
18 | "expected-message-rate"
19 | ]
20 | }
--------------------------------------------------------------------------------
/calm/samples/2024-10/traderx/README.md:
--------------------------------------------------------------------------------
1 | ### TraderX Example
2 |
3 | [TraderX](https://github.com/finos/traderX) is a Sample Trading Application, designed to be a distributed reference application in the financial services domain.
4 |
5 | This sample uses the [C4 model](https://github.com/finos/traderX/blob/main/docs/c4/c4-diagram.png) of the TraderX application and shows how to model it using CALM.
6 |
7 | You can see in thus sample how you can use the base CALM vocab is both JSON and YAML documents.
--------------------------------------------------------------------------------
/calm/samples/2024-12/traderx/README.md:
--------------------------------------------------------------------------------
1 | ### TraderX Example
2 |
3 | [TraderX](https://github.com/finos/traderX) is a Sample Trading Application, designed to be a distributed reference application in the financial services domain.
4 |
5 | This sample uses the [C4 model](https://github.com/finos/traderX/blob/main/docs/c4/c4-diagram.png) of the TraderX application and shows how to model it using CALM.
6 |
7 | You can see in thus sample how you can use the base CALM vocab is both JSON and YAML documents.
--------------------------------------------------------------------------------
/calm/samples/visualization.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/finos/architecture-as-code/a54518a8317eb889ea2541210c0297e30e9d880f/calm/samples/visualization.png
--------------------------------------------------------------------------------
/calm/workshop/cached/cluster_start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 |
5 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6 |
7 | KUBERNETES_VERSION=1.30.0
8 |
9 | echo "Starting Minikube..."
10 | minikube start --network-plugin=cni --cni=calico --kubernetes-version=$KUBERNETES_VERSION --cpus=4 --profile secure --wait=none --install-addons=false
11 |
12 | echo "Enabling global Calico default-deny policy..."
13 | kubectl apply --filename "${SCRIPT_DIR}/calico-global-deny.yaml" --namespace kube-system
14 |
--------------------------------------------------------------------------------
/calm/workshop/controls/micro-segmentation.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://calm.finos.org/workshop/controls/micro-segmentation.requirement.json",
3 | "$id": "https://calm.finos.org/workshop/controls/micro-segmentation.config.json",
4 | "control-id": "security-001",
5 | "name": "Micro-segmentation of Kubernetes Cluster",
6 | "description": "Micro-segmentation in place to prevent lateral movement outside of permitted flows",
7 | "permit-ingress": true,
8 | "permit-egress": false
9 | }
--------------------------------------------------------------------------------
/calm/workshop/controls/micro-segmentation.requirement.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json-schema.org/draft/2020-12/schema",
3 | "$id": "https://calm.finos.org/workshop/controls/micro-segmentation.requirement.json",
4 | "title": "Micro-segmentation configured Kubernetes Cluster",
5 | "type": "object",
6 | "allOf": [
7 | {
8 | "$ref": "https://calm.finos.org/release/1.0-rc1/meta/control-requirement.json"
9 | }
10 | ],
11 | "properties": {
12 | "control-id": {
13 | "const": "security-001"
14 | },
15 | "name": {
16 | "const": "Micro-segmentation of Kubernetes Cluster"
17 | },
18 | "description": {
19 | "const": "Micro-segmentation in place to prevent lateral movement outside of permitted flows"
20 | },
21 | "permit-ingress": {
22 | "type": "boolean"
23 | },
24 | "permit-egress": {
25 | "type": "boolean"
26 | }
27 | },
28 | "required": [
29 | "control-id",
30 | "name",
31 | "description",
32 | "permit-ingress",
33 | "permit-egress"
34 | ]
35 | }
--------------------------------------------------------------------------------
/calm/workshop/controls/permitted-connection-http.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://calm.finos.org/workshop/controls/permitted-connection.requirement.json",
3 | "control-id": "security-002",
4 | "name": "Permitted Connection",
5 | "description": "Permits a connection on a relationship specified in the architecture",
6 | "reason": "Required to enable flow between architecture components",
7 | "protocol": "HTTP"
8 | }
--------------------------------------------------------------------------------
/calm/workshop/controls/permitted-connection-jdbc.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://calm.finos.org/workshop/controls/permitted-connection.requirement.json",
3 | "control-id": "security-002",
4 | "name": "Permitted Connection",
5 | "description": "Permits a connection on a relationship specified in the architecture",
6 | "reason": "Permitted to allow the connection between application and database",
7 | "protocol": "JDBC"
8 | }
--------------------------------------------------------------------------------
/calm/workshop/directory.json:
--------------------------------------------------------------------------------
1 | {
2 | "https://calm.finos.org/release/1.0-rc1/meta/control-requirement.json": "../release/1.0-rc1/meta/control-requirement.json",
3 | "https://calm.finos.org/workshop/controls/micro-segmentation.config.json": "controls/micro-segmentation.config.json",
4 | "https://calm.finos.org/workshop/controls/micro-segmentation.requirement.json": "controls/micro-segmentation.requirement.json",
5 | "https://calm.finos.org/workshop/controls/permitted-connection.requirement.json": "controls/permitted-connection.requirement.json",
6 | "https://calm.finos.org/workshop/controls/permitted-connection-http.config.json": "controls/permitted-connection-http.config.json",
7 | "https://calm.finos.org/workshop/controls/permitted-connection-jdbc.config.json": "controls/permitted-connection-jdbc.config.json"
8 | }
9 |
--------------------------------------------------------------------------------
/calm/workshop/insecure-example/cluster/cluster_start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 |
5 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6 |
7 | KUBERNETES_VERSION=1.30.0
8 |
9 | echo "Starting Minikube..."
10 | minikube start --kubernetes-version=$KUBERNETES_VERSION --cpus=4 --profile insecure --wait=none --install-addons=false
11 |
--------------------------------------------------------------------------------
/calm/workshop/insecure-example/kubernetes/application-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: attendees
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: attendees
10 | template:
11 | metadata:
12 | labels:
13 | app: attendees
14 | spec:
15 | containers:
16 | - name: app
17 | image: masteringapi/attendees-quarkus:ws-native-db
18 | imagePullPolicy: IfNotPresent
19 | ports:
20 | - containerPort: 8080
--------------------------------------------------------------------------------
/calm/workshop/insecure-example/kubernetes/application-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: attendees-service
5 | spec:
6 | selector:
7 | app: attendees
8 | type: LoadBalancer
9 | ports:
10 | - protocol: TCP
11 | port: 80
12 | targetPort: 8080
--------------------------------------------------------------------------------
/calm/workshop/insecure-example/kubernetes/database-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: attendees-store
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | db: attendees-store
10 | template:
11 | metadata:
12 | labels:
13 | db: attendees-store
14 | spec:
15 | containers:
16 | - name: db
17 | image: postgres
18 | imagePullPolicy: IfNotPresent
19 | ports:
20 | - containerPort: 5432
21 | env:
22 | - name: POSTGRES_DB
23 | value: conference
24 | - name: POSTGRES_USER
25 | value: calm
26 | - name: POSTGRES_PASSWORD
27 | value: demo
28 | resources:
29 | requests:
30 | memory: "128Mi" # Equivalent to shm_size: 128mb in Docker Compose
--------------------------------------------------------------------------------
/calm/workshop/insecure-example/kubernetes/database-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: db
5 | spec:
6 | selector:
7 | db: attendees-store
8 | ports:
9 | - protocol: TCP
10 | port: 5432
11 | targetPort: 5432
12 | type: ClusterIP
--------------------------------------------------------------------------------
/calm/workshop/insecure-example/kubernetes/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: conference
5 |
6 | resources:
7 | - namespace.yaml
8 | - application-deployment.yaml
9 | - application-service.yaml
10 | - database-deployment.yaml
11 | - database-service.yaml
--------------------------------------------------------------------------------
/calm/workshop/insecure-example/kubernetes/namespace.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Namespace
3 | metadata:
4 | name: conference
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/application-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: {{ appName }}
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | app: {{ appName }}
10 | template:
11 | metadata:
12 | labels:
13 | app: {{ appName }}
14 | spec:
15 | containers:
16 | - name: app
17 | image: {{ applicationImage }}
18 | imagePullPolicy: IfNotPresent
19 | ports:
20 | - containerPort: {{ applicationPort }}
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/application-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: {{ appName }}-service
5 | spec:
6 | selector:
7 | app: {{ appName }}
8 | type: LoadBalancer
9 | ports:
10 | - protocol: TCP
11 | port: {{ lbPort }}
12 | targetPort: {{ applicationPort }}
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/calico-global-deny.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: crd.projectcalico.org/v1
2 | kind: GlobalNetworkPolicy
3 | metadata:
4 | name: deny-app-policy
5 | spec:
6 | namespaceSelector: has(projectcalico.org/name) && projectcalico.org/name not in {"kube-system"}
7 | types:
8 | - Ingress
9 | - Egress
10 | egress:
11 | # allow all namespaces to communicate to DNS pods
12 | - action: Allow
13 | protocol: UDP
14 | destination:
15 | selector: 'k8s-app == "kube-dns"'
16 | ports:
17 | - 53
18 | - action: Allow
19 | protocol: TCP
20 | destination:
21 | selector: 'k8s-app == "kube-dns"'
22 | ports:
23 | - 53
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/cluster_start.hbs:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -euo pipefail
4 |
5 | SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6 |
7 | KUBERNETES_VERSION=1.30.0
8 |
9 | echo "Starting Minikube..."
10 | minikube start --network-plugin=cni --cni=calico --kubernetes-version=$KUBERNETES_VERSION --cpus=4 --profile secure --wait=none --install-addons=false
11 |
12 | {{#if secure}}
13 | echo "Enabling global Calico default-deny policy..."
14 | kubectl apply --filename "${SCRIPT_DIR}/calico-global-deny.yaml" --namespace kube-system
15 | {{/if}}
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/database-deployment.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: apps/v1
2 | kind: Deployment
3 | metadata:
4 | name: {{ databaseName }}
5 | spec:
6 | replicas: 1
7 | selector:
8 | matchLabels:
9 | db: {{ databaseName }}
10 | template:
11 | metadata:
12 | labels:
13 | db: {{ databaseName }}
14 | spec:
15 | containers:
16 | - name: db
17 | image: postgres
18 | imagePullPolicy: IfNotPresent
19 | ports:
20 | - containerPort: {{ databasePort }}
21 | env:
22 | - name: POSTGRES_DB
23 | value: conference
24 | - name: POSTGRES_USER
25 | value: calm
26 | - name: POSTGRES_PASSWORD
27 | value: demo
28 | resources:
29 | requests:
30 | memory: "128Mi" # Equivalent to shm_size: 128mb in Docker Compose
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/database-service.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Service
3 | metadata:
4 | name: db
5 | spec:
6 | selector:
7 | db: {{ databaseName }}
8 | ports:
9 | - protocol: TCP
10 | port: 5432
11 | targetPort: 5432
12 | type: ClusterIP
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/kustomization.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: kustomize.config.k8s.io/v1beta1
2 | kind: Kustomization
3 |
4 | namespace: {{ namespaceName }}
5 |
6 | resources:
7 | - namespace.yaml
8 | - application-deployment.yaml
9 | - application-service.yaml
10 | - database-deployment.yaml
11 | - database-service.yaml
12 | - permit-app-from-db.yaml
13 | - permit-app-to-db.yaml
14 | - permit-lb-to-app.yaml
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/namespace.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | kind: Namespace
3 | metadata:
4 | name: {{ namespaceName }}
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/permit-app-from-db.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.k8s.io/v1
2 | kind: NetworkPolicy
3 | metadata:
4 | name: allow-ingress-to-db-from-app
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | db: {{ databaseName }}
9 | ingress:
10 | - from:
11 | - podSelector:
12 | matchLabels:
13 | app: {{ appName }}
14 | policyTypes:
15 | - Ingress
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/permit-app-to-db.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.k8s.io/v1
2 | kind: NetworkPolicy
3 | metadata:
4 | name: allow-egress-from-app-to-db
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | app: {{ appName }}
9 | egress:
10 | - to:
11 | - podSelector:
12 | matchLabels:
13 | db: {{ databaseName }}
14 | policyTypes:
15 | - Egress
--------------------------------------------------------------------------------
/calm/workshop/secure-infra-template-bundle/permit-lb-to-app.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: networking.k8s.io/v1
2 | kind: NetworkPolicy
3 | metadata:
4 | name: allow-external-ingress-to-app
5 | spec:
6 | podSelector:
7 | matchLabels:
8 | app: {{ appName }}
9 | ingress:
10 | - {}
11 | policyTypes:
12 | - Ingress
--------------------------------------------------------------------------------
/cli/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 | pnpm-debug.log*
8 | lerna-debug.log*
9 |
10 | node_modules
11 | dist
12 | dist-ssr
13 | *.local
14 |
15 | # Editor directories and files
16 | .vscode/*
17 | !.vscode/extensions.json
18 | .idea
19 | .DS_Store
20 | *.suo
21 | *.ntvs*
22 | *.njsproj
23 | *.sln
24 | *.sw?
25 |
--------------------------------------------------------------------------------
/cli/pom.xml:
--------------------------------------------------------------------------------
1 |
4 | 4.0.0
5 |
6 |
7 | org.finos.architecture-as-code
8 | parent
9 | 1.0.0-SNAPSHOT
10 |
11 |
12 | cli
13 | pom
14 |
15 | Placeholder module for CLI
16 |
17 |
--------------------------------------------------------------------------------
/cli/src/cli-config.ts:
--------------------------------------------------------------------------------
1 | import { initLogger } from '@finos/calm-shared';
2 | import { readFile } from 'fs/promises';
3 | import { homedir } from 'os';
4 | import { join } from 'path';
5 |
6 | export interface CLIConfig {
7 | calmHubUrl?: string
8 | }
9 |
10 | function getUserConfigLocation(): string {
11 | const homeDir = homedir();
12 | return join(homeDir, '.calm.json');
13 | }
14 |
15 | export async function loadCliConfig(): Promise {
16 | const logger = initLogger(false, 'calm-cli');
17 |
18 | const configFilePath = getUserConfigLocation();
19 | try {
20 | const config = await readFile(configFilePath, 'utf8');
21 | const parsed = JSON.parse(config) as CLIConfig;
22 | logger.debug('Parsed user config: ' + config);
23 | return parsed;
24 | }
25 | catch (err) {
26 | if (err.code === 'ENOENT') {
27 | logger.debug('No config file found at ' + configFilePath);
28 | return null;
29 | }
30 | logger.error('Unexpected error loading user config: ', err);
31 | return null;
32 | }
33 | }
--------------------------------------------------------------------------------
/cli/src/command-helpers/calmhub-input.ts:
--------------------------------------------------------------------------------
1 | import { initLogger } from '@finos/calm-shared';
2 | import { DocumentLoader } from '@finos/calm-shared/dist/document-loader/document-loader';
3 |
4 | export async function loadPatternFromCalmHub(patternId: string, docLoader: DocumentLoader, debug: boolean): Promise