Skip to content

Support flow-first modelling before logical architecture #1875

@rocketstack-matt

Description

@rocketstack-matt

Summary

Enable users to capture business flows independently of the logical architecture, allowing a "flow-first" modelling approach where business processes are defined before the technical architecture is designed around them.

Problem Statement

Currently, CALM flows are tightly coupled to the logical architecture:

"transitions": [
  {
    "relationship-unique-id": "node-1-to-node-2",  // Must reference existing relationship
    "sequence-number": 1,
    "description": "User authenticates"
  }
]

This requires:

  1. The logical architecture (nodes and relationships) to exist first
  2. Each transition to reference a relationship-unique-id that must be valid

The limitation: Some users want to model existing business flows before designing the architecture. They want to:

  • Document current business processes
  • Identify actors and interactions at a business level
  • Use these flows to inform and drive the logical architecture design

Proposed Solution

Extend the flow schema to support abstract transitions that don't require architecture references, while maintaining backward compatibility with architecture-linked flows.

Option A: Dual Transition Types

Introduce an alternative transition type for flow-first modelling:

{
  "defs": {
    "abstract-transition": {
      "type": "object",
      "properties": {
        "sequence-number": { "type": "integer" },
        "description": { "type": "string" },
        "source-actor": { "type": "string", "description": "Business actor or system initiating the step" },
        "destination-actor": { "type": "string", "description": "Business actor or system receiving the interaction" },
        "interaction-type": { "type": "string", "description": "Type of interaction (e.g., request, response, event)" }
      },
      "required": ["sequence-number", "description", "source-actor", "destination-actor"]
    },
    "transition": {
      "oneOf": [
        { "$ref": "#/defs/architecture-transition" },
        { "$ref": "#/defs/abstract-transition" }
      ]
    }
  }
}

Option B: Optional Architecture Binding

Make relationship-unique-id optional and add actor fields:

{
  "transition": {
    "properties": {
      "relationship-unique-id": { "type": "string" },
      "source-actor": { "type": "string" },
      "destination-actor": { "type": "string" },
      "sequence-number": { "type": "integer" },
      "description": { "type": "string" }
    },
    "oneOf": [
      { "required": ["relationship-unique-id", "sequence-number", "description"] },
      { "required": ["source-actor", "destination-actor", "sequence-number", "description"] }
    ]
  }
}

Option C: Separate Flow Types

Introduce a flow-type discriminator:

{
  "flow": {
    "properties": {
      "flow-type": { 
        "enum": ["business", "technical"],
        "default": "technical"
      }
    }
  }
}

Where business flows use abstract actors and technical flows require architecture references.

Example: Flow-First Modelling

Step 1: Capture Business Flow (no architecture yet)

{
  "flows": [
    {
      "unique-id": "user-login-flow",
      "name": "User Login",
      "description": "End-to-end user authentication process",
      "flow-type": "business",
      "transitions": [
        {
          "sequence-number": 1,
          "source-actor": "End User",
          "destination-actor": "Web Application",
          "description": "User submits credentials"
        },
        {
          "sequence-number": 2,
          "source-actor": "Web Application",
          "destination-actor": "Identity Provider",
          "description": "Credentials validated"
        },
        {
          "sequence-number": 3,
          "source-actor": "Identity Provider",
          "destination-actor": "Web Application",
          "description": "Auth token returned"
        }
      ]
    }
  ]
}

Step 2: Design Architecture Informed by Flow

The architect uses the business flow to design nodes and relationships.

Step 3: Bind Flow to Architecture (optional)

Later, the flow can be linked to the architecture:

{
  "transitions": [
    {
      "sequence-number": 1,
      "source-actor": "End User",
      "destination-actor": "Web Application",
      "relationship-unique-id": "user-to-webapp",  // Now linked
      "description": "User submits credentials"
    }
  ]
}

Benefits

  • Business-driven architecture: Capture requirements before committing to technical design
  • Stakeholder collaboration: Business analysts can contribute flows without understanding technical architecture
  • Traceability: Clear lineage from business process to technical implementation
  • Incremental refinement: Start abstract, add technical detail over time
  • Backward compatible: Existing architecture-linked flows continue to work

Considerations

  1. Validation: How should CLI validate abstract vs bound flows?
  2. Visualisation: How should flow diagrams render actors vs nodes?
  3. Actor-to-node mapping: Should there be explicit mapping from actors to nodes?
  4. Migration path: Tooling to help convert abstract flows to architecture-bound flows

Affected Components

  • Shared (shared/) - Schema changes
  • CLI (cli/) - Validation logic
  • CALM Widgets (calm-widgets/) - Flow visualisation
  • VS Code Extension (calm-plugins/vscode/)
  • Documentation (docs/)

Related

  • Current flow schema: calm/release/1.1/meta/flow.json

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions