Git Product home page Git Product logo

slavavedernikov / c4interflow Goto Github PK

View Code? Open in Web Editor NEW
14.0 1.0 3.0 81.45 MB

Architecture as Code (AaC) framework that generates diagrams and lets you analyse Application Architecture. Inspired by C4 Model

Home Page: https://www.c4interflow.com

License: MIT License

C# 100.00%
application-architecture architecture-as-code architecture-as-code-dsl architecture-as-code-toolchain architecture-as-code-tools architecture-diagrams-generation business-process-as-code c4-model plantuml-diagrams

c4interflow's People

Contributors

slavavedernikov avatar

Stargazers

 avatar  avatar

Watchers

 avatar

c4interflow's Issues

Make sure all diagrams have consistent and complete titles

Context

At the moment diagrams of different Scopes have different Title structures e.g.

Diagrams of Software System/Container/Component Interface Scopes have the following Title structure:
<Software System> [- <Container>] [- <Component>] - <Interface> - <Level of Details> level

Diagrams of Software System/Container/Component Scopes have the following Title structure:
<Type> - <Level of Details> level

Requirement

The diagrams titles must be constructed as follows:
Diagrams of Software System/Container/Component Interface Scopes must have the following Title structure:
<Software System> [- <Container>] [- <Component>] - <Interface> - <Type> - <Level of Details> level

Diagrams of Software System/Container/Component Scopes must have the following Title structure:
[<Software System>] [<Container>] [<Component>] - <Type> - <Level of Details> level

Diagrams of Software Systems Scope must have the following Title structure:
All Software Systems - <Type> - <Level of Details> level

Add support for writing Debug, Information, Warning and Error log level messages to a Console and to a local log file

Context

At the moment Information and Error messages are written to Console with Console.WriteLine method.

Requirement

It would be better if the user was able to add CLI Command Options to control the logging e.g.

Option
-lo, --log-out - Default console. Multiple values allowed.
Possible values
console
file

Option
-ll, --log-level - Default info
Possible values
debug
info
warning
error

Initial implementation can replace all Console.WriteLine invocations inside catch block as logs as error level, and all other Console.WriteLine invocations as logs at info level.

Introduce a new type of diagram - C4 Sequence (c4-sequence)

Context

At the moment there is support for native PlantUML Sequence (sequence) diagrams, which look like this
Component Sequence

This is not visually consistent with the rest of the diagrams, which use the default C4-PlantUML colour scheme.

Requirement

Introduce a new diagram Type - c4-sequnce, which would use C4-PlantUML Sequence extension. It renders more consistently with the rest of the C4 diagrams. See example below.
C4-Sequence example

Here is the source for the above diagram

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Sequence.puml

title Basket Api - Grpc - Basket Service - Update Basket - COMPONENT level

System(C4InterFlow.SoftwareSystems.ExternalSystem, "External")

System_Boundary(dotnet.eShop.Architecture.SoftwareSystems.BasketApi, "Basket Api")
    Container_Boundary(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc, "Grpc")
        Component(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Basket Service")
    Boundary_End()

    Container_Boundary(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data, "Data")
        Component(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, "Redis Basket Repository")
        Component(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisDatabase, "Redis Database")
    Boundary_End()
Boundary_End()

Rel(C4InterFlow.SoftwareSystems.ExternalSystem, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Update Basket")
group Update Basket
alt string.IsNullOrEmpty(userId)
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Throw Not Authenticated")
end
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Map To Customer Basket")
group Map To Customer Basket
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Retun (response)")
end
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, "Update Basket Async")
group Update Basket Async
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisDatabase, "String Set Async")
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, "Get Basket Key")
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, "Get Basket Async")
group Get Basket Async
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisDatabase, "String Get Lease Async")
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, "Get Basket Key")
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository, "Retun (JsonSerializer.Deserialize)")
end
end
alt response is null
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Throw Basket Does Not Exist")
end
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Map To Customer Basket Response")
group Map To Customer Basket Response
Rel(dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService, "Retun (response)")
end
end

SHOW_LEGEND()
@enduml

Add support for relative Interface Paths (Aliases) in Use Flows of YAML AaC

Context

At the moment Use Flows in YAML AaC Interface definitions require full paths (aliases) to other Interfaces e.g.

dotnet:
  eShop:
    Architecture:
      SoftwareSystems:
        BasketApi:
          Containers:
            Grpc:
              Components:
                BasketService:
                  Interfaces:
                    UpdateBasket:
                      Label: Update Basket
                      IsPrivate: false
                      Flow:
                        Flows:
                        - Type: If
                          Expression: string.IsNullOrEmpty(userId)
                          Flows:
                          - Type: Use
                            Expression: dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService.Interfaces.ThrowNotAuthenticated
                        - Type: Use
                          Expression: dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService.Interfaces.MapToCustomerBasket
                        - Type: Use
                          Expression: dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Data.Components.RedisBasketRepository.Interfaces.UpdateBasketAsync
                        - Type: If
                          Expression: response is null
                          Flows:
                          - Type: Use
                            Expression: dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService.Interfaces.ThrowBasketDoesNotExist
                        - Type: Use
                          Expression: dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService.Interfaces.MapToCustomerBasketResponse

Requirement

It would be more convenient and less verbose if it was possible to use relative Interface paths (aliases) when the interface being used in the Flow is in the same Software System, Container or Component. The above example then would look as follows:

dotnet:
  eShop:
    Architecture:
      SoftwareSystems:
        BasketApi:
          Containers:
            Grpc:
              Components:
                BasketService:
                  Interfaces:
                    UpdateBasket:
                      Label: Update Basket
                      IsPrivate: false
                      Flow:
                        Flows:
                        - Type: If
                          Expression: string.IsNullOrEmpty(userId)
                          Flows:
                          - Type: Use
                            Expression: Interfaces.ThrowNotAuthenticated
                        - Type: Use
                          Expression: Interfaces.MapToCustomerBasket
                        - Type: Use
                          Expression: Containers.Data.Components.RedisBasketRepository.Interfaces.UpdateBasketAsync
                        - Type: If
                          Expression: response is null
                          Flows:
                          - Type: Use
                            Expression: Interfaces.ThrowBasketDoesNotExist
                        - Type: Use
                          Expression: Interfaces.MapToCustomerBasketResponse

The Structure Resolver would then infer the full paths (aliases) based on the relative Paths (Aliases) and the position of the current Structure in the node hierarchy.

Extend the implementation of Entity concept

Context

At the moment there is a little bit of support for Entity in the framework (see C4InterFlow.Structures.Entity).

  • There is support for Composition via ComposedOfMany and ComposedOfOne properties and Inheritance via Extends property.
  • Entity can be associated with Container by being added under Entities object.
  • Entity can also be associated with Interface by being added as its Input and/or Output

Requirement

  • Allow Entity to be added to Namespace under 'Entities' object
  • Allow Entity to be added to SoftwareSystem under 'Entities' object
  • Add 'Realises' property to 'Entity' so that lower level 'Entity' (e.g. at Container level ) can be associated with a higher level Entity (e.g. as Namespace level)

Add a concept of Business Capability

Context

Many organisations are using Business Capability Model for strategic planning. When it comes to technical execution of a plan, it's not always clear which Software Systems will be affected.

Requirement

  • Add a concept of a hierarchical Business Capability Model
  • Interfaces can then relate to Capability Model nodes via a "Realises" property
  • It should be possible then to query Interfaces by Capability Node(s)
    • The output of such queries can be used as input to draw-diagrams command to produce the technology view of a Capability

Resources:
How to Do Capability Mapping Like a Pro

Add support for recursive descent JSON Path syntax

Context

At the moment, when using structure aliases, only the full path would work e.g.
dotnet.eShop.Architecture.SoftwareSystems.BasketApi.Containers.Grpc.Components.BasketService

Requirement

Add support for .. recursive descent JSON Path syntax, so that the paths can be shortened e.g.
It would be possible to use a shorter path ..BasketApi.Containers.Grpc.Components.BasketService.Interfaces.*

Instead of using full path dotnet.eShop.Architecture.SoftwareSystems.*.Containers.Grpc.Components.*.Interfaces.*
It would be possible to use a shorter path ...Grpc.Components.*.Interfaces.*

Add support for viewing Diagrams in GitHub Pages

Context

At the moment there is no out-of-the-box way of publishing Diagrams to any documentation platforms.

It is possible to build CI/CD pipelines to publish Diagrams in commonly supported formats (e.g. .png, .md) to multiple platforms, however.

Requirement

Provide the out-of-the-box support for publishing Diagrams to GitHub Pages.

Below is the outline of a possible solution:

  • Add a new Command e.g. publish-diagrams
    • Add a new Option -d-ps, --diagrams-publisher-strategy
  • Write a GitHubPages Diagrams Publisher Strategy e.g. GitHubPagesDiagramsPublisherStrategy in C4InterFlow.Automation.Publishers namespace
    • It should support the following parameters:
      • output-dir e.g. --params output-dir="Diagrams"
      • site-source e.g. --params site-source="C4InterFlow.Automation\Publishers\GitHubPages\Source"
        • This parameter should be optional, and should default to C4InterFlow.Automation\Publishers\GitHubPages\Source
    • It should have the following logic:
      • Generate sitemap.json file that would have a "sitemap" for the directory passed as a value for output-dir parameter (see example below)
        • Foreach location in the directory tree populate types, levelsOfDetails and formats arrays based on the files in it e.g.
          • Given that a location has the following files in it
            • Component - C4 Static.png
            • Component - C4 Static.puml
            • Component - C4 Static.svg
            • Component - C4.png
            • Component - C4.puml
            • Component - C4.svg
            • Container - C4 Static.png
            • Container - C4 Static.puml
            • Container - C4 Static.svg
            • Container - C4.png
            • Container - C4.puml
            • Container - C4.svg
          • Then types array will be set to ["C4", "C4 Static"]
          • And levelsOfDetails array will be set to ["Component", "Container"]
          • And formats array will be set to ["png", "puml", "svg"]
        • Save sitemap.json file in a location provided in output-dir parameter
      • Copy all files/directories from a location provided in site-source parameter to a location provided in output-dir parameter
  • Write the site source in JavaScript and save it in C4InterFlow.Automation\Publishers\GitHubPages\Source directory
    • The site should have a single page e.g. index.html (See UI mockup below)
      • It should ideally rely on vanilla/plain JavaScript only (i.e. no other JS packages used) for simplicity
      • It should load sitemap.json and render a Tree View
      • On load, it should select the first top-level Tree View node that corresponds to the first element of the top-level urlset array.
      • On Tree View node selection
        • If the object that corresponds to the selected Tree View node has types, levelsOfDetails and formats arrays, enable the corresponding radio-buttons in the UI. Any radio-buttons that don't have a corresponding value in types, levelsOfDetails and formats arrays should be disabled.
          • Set radio-button selections based on the last remembered User's selection, if present (see below)
            • If the last remembered User's selection is not present, select the first enabled radio-button option from each set
        • If the object that corresponds to the selected Tree View node doesn't have types, levelsOfDetails and formats arrays
          • Disable all radio-buttons in the UI
          • Render a list of links based on the current object's urlset array (if present)
      • On radio-button selection, load the corresponding diagram file from the URL constructed with {location}\{levelOfDetails} - {type}.{format} template
        • e.g. Software Systems/Basket Api/Containers/Grpc/Components/Basket Service/Interfaces/Update Basket/Component - C4 Static.svg

JSON Sitemap example

{
  "urlset": [
    {
      "label": "Software Systems",
      "loc": "Software Systems",
      "urlset": [
        {
          "label": "Basket Api",
          "loc": "Software Systems/Basket Api",
          "urlset": [
            {
              "label": "Containers",
              "loc": "Software Systems/Basket Api/Containers",
              "urlset": [
                {
                  "label": "Grpc",
                  "loc": "Software Systems/Basket Api/Containers/Grpc",
                  "urlset": [
                    {
                      "label": "Components",
                      "loc": "Software Systems/Basket Api/Containers/Grpc/Components",
                      "urlset": [
                        {
                          "label": "Basket Service",
                          "loc": "Software Systems/Basket Api/Containers/Grpc/Components/Basket Service",
                          "urlset": [
                            {
                              "label": "Interfaces",
                              "loc": "Software Systems/Basket Api/Containers/Grpc/Components/Basket Service/Interfaces",
                              "urlset": [
                                {
                                  "label": "Delete Basket",
                                  "loc": "Software Systems/Basket Api/Containers/Grpc/Components/Basket Service/Delete Basket",
                                  "types": [
                                    "C4",
                                    "C4 Static",
                                    "Sequence"
                                  ],
                                  "levelsOfDetails": [
                                    "Component"
                                  ],
                                  "formats": [
                                    "puml",
                                    "png",
                                    "svg"
                                  ]
                                },
                                {
                                  "label": "Get Basket",
                                  "loc": "Software Systems/Basket Api/Containers/Grpc/Components/Basket Service/Get Basket",
                                  "types": [
                                    "C4",
                                    "C4 Static",
                                    "Sequence"
                                  ],
                                  "levelsOfDetails": [
                                    "Component"
                                  ],
                                  "formats": [
                                    "puml",
                                    "png",
                                    "svg"
                                  ]
                                },
                                {
                                  "label": "Update Basket",
                                  "loc": "Software Systems/Basket Api/Containers/Grpc/Components/Basket Service/Update Basket",
                                  "types": [
                                    "C4",
                                    "C4 Static",
                                    "Sequence"
                                  ],
                                  "levelsOfDetails": [
                                    "Component"
                                  ],
                                  "formats": [
                                    "puml",
                                    "png",
                                    "svg"
                                  ]
                                }
                              ]
                            }
                          ],
                          "types": [
                            "C4",
                            "C4 Static"
                          ],
                          "levelsOfDetails": [
                            "Component"
                          ],
                          "formats": [
                            "puml",
                            "png",
                            "svg"
                          ]
                        }
                      ]
                    }
                  ],
                  "types": [
                    "C4",
                    "C4 Static"
                  ],
                  "levelsOfDetails": [
                    "Context",
                    "Container",
                    "Component"
                  ],
                  "formats": [
                    "puml",
                    "png",
                    "svg"
                  ]
                }
              ]
            }
          ],
          "types": [
            "C4",
            "C4 Static"
          ],
          "levelsOfDetails": [
            "Context",
            "Container",
            "Component"
          ],
          "formats": [
            "puml",
            "png",
            "svg"
          ]
        },
        {
          "label": "Catalog Api",
          "loc": "Software Systems/Catalog Api",
          "types": [
            "C4",
            "C4 Static"
          ],
          "levelsOfDetails": [
            "Context",
            "Container",
            "Component"
          ],
          "formats": [
            "puml",
            "png",
            "svg"
          ]
        }
      ],
      "types": [
        "C4",
        "C4 Static"
      ],
      "levelsOfDetails": [
        "Context",
        "Container"
      ],
      "formats": [
        "puml",
        "png",
        "svg"
      ]
    }
  ]
}

UI mockup

Diagrams viewer UI mockup

Add support for shortcuts for known Read Strategies

Context

C4InterFlow supports two AaC Read Strategies:
C4InterFlow.Automation.Readers.CSharpAaCReaderStrategy,C4InterFlow.Automation
C4InterFlow.Automation.Readers.YamlAaCReaderStrategy,C4InterFlow.Automation

When using CLI commands that use AaC Read Strategy e.g. draw-diagrams, query-use-flows etc., the full names of these AaC Read Strategies need to be provided as a value for aac-reader-strategy Option e.g.
--aac-reader-strategy C4InterFlow.Automation.Readers.YamlAaCReaderStrategy,C4InterFlow.Automation

Requirement

It would be more convenient if CSharp shortcut could be used for C4InterFlow.Automation.Readers.CSharpAaCReaderStrategy,C4InterFlow.Automation, and Yaml for C4InterFlow.Automation.Readers.YamlAaCReaderStrategy,C4InterFlow.Automation.

Then the command option for YAML AaC, for example, would look like follows --aac-reader-strategy Yaml, which is a lot more concise.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.