Skip to content

lisegmbh/fluxflow

FluxFlow

Code-First Workflow Engine for Modern Applications

Maven Central License Build Status Kotlin Java Spring Boot


📚 Table of Contents


🎯 What is FluxFlow?

FluxFlow is a lightweight, developer-friendly workflow engine that transforms how you build and manage business processes. Instead of wrestling with XML configurations or visual designers, you define workflows directly in your Java or Kotlin code – making them testable, maintainable, and type-safe.

💡 The FluxFlow Philosophy

Your code IS your workflow.
Transform your Java/Kotlin classes into powerful workflow steps, where properties become state and methods define transitions.

Unlike traditional BPMN engines that scatter logic across multiple artifacts, FluxFlow consolidates everything in your domain code. This means:

  • No XML hell – Pure code-based workflows
  • Type safety – Compile-time verification of your workflows
  • Easy testing – Unit test your business logic naturally
  • Version control friendly – Track changes like any other code
  • IDE support – Full autocomplete, refactoring, and debugging

🚀 Why Choose FluxFlow?

Traditional BPMN FluxFlow
🔴 XML configuration files 🟢 Pure Java/Kotlin code
🔴 Separated business logic 🟢 Unified codebase
🔴 Hard to test 🟢 Easy unit testing
🔴 Designer dependency 🟢 IDE-native development
🔴 Runtime errors 🟢 Compile-time safety
🔴 Complex debugging 🟢 Standard debugging tools

✨ Key Features

🏗️ Code-First Architecture
  • Step Classes: Your POJOs become workflow steps
  • State Management: Properties hold step-specific data
  • Action Methods: Methods define transitions and business logic
  • Type Safety: Compile-time verification of workflow structure
🔄 Workflow Components
  • Workflow Data: Shared information across the entire workflow
  • Step Data: Step-specific state that can be queried and updated
  • Step Actions: Transitions and business logic execution
  • Jobs: Scheduled automatic execution (powered by Quartz)
  • Validation: Built-in Jakarta Bean Validation support
🌱 Spring Boot Integration
  • Dependency Injection: Full Spring context support
  • Auto-Configuration: Zero-configuration setup
  • Persistence: Automatic workflow state management
  • Testing: Comprehensive test utilities
  • Monitoring: Built-in metrics and health checks
🧪 Testing & Quality
  • Unit Testing: Test workflow logic like any other code
  • Mocking Support: Easy step and action mocking
  • Test Utilities: Specialized testing framework
  • Coverage: Full code coverage for workflows

🔥 Quick Example

Transform this pizza ordering process into executable code:

1. Add FluxFlow to your project:

Gradle (Kotlin DSL)
dependencies {
    implementation("de.lise.fluxflow:springboot:0.2.0")
    implementation("de.lise.fluxflow:mongo:0.2.0") // For MongoDB persistence
}
Gradle (Groovy)
dependencies {
    implementation 'de.lise.fluxflow:springboot:0.2.0'
    implementation 'de.lise.fluxflow:mongo:0.2.0' // For MongoDB persistence
}
Maven
<dependency>
    <groupId>de.lise.fluxflow</groupId>
    <artifactId>springboot</artifactId>
    <version>0.2.0</version>
</dependency>
<dependency>
    <groupId>de.lise.fluxflow</groupId>
    <artifactId>mongo</artifactId>
    <version>0.2.0</version>
</dependency>

2. Define your workflow steps:

// 1️⃣ Add Pizza to Cart Step
@Step
class AddPizzaToCartStep(
    @Data 
    @NotEmpty(message = "Cart cannot be empty. Please add at least one pizza before checkout.")
    var pizzas: MutableList<Pizza> = mutableListOf()
) {
    @Action(beforeExecutionValidation = ValidationBehavior.AllowInvalid)
    fun addPizza(pizza: Pizza): AddPizzaToCartStep {
        // Add the pizza to cart
        pizzas.add(pizza)
        // Return to same step for more pizzas
        return AddPizzaToCartStep(pizzas)
    }
    
    @Action
    fun toCheckout(): CheckoutStep {
        // Calculate total and proceed to checkout with current pizzas
        val total = pizzas.sumOf { it.price }
        return CheckoutStep(pizzas, total)
    }
}

// 2️⃣ Checkout Step
@Step
class CheckoutStep(
    @Data val pizzas: List<Pizza>,
    @Data val total: BigDecimal
) {
    @Data var deliveryAddress: String = ""
    @Data var paymentMethod: String = ""
    
    @Action
    fun submitOrder(): Continuation<OrderConfirmation> {
        // Process order with pre-calculated total
        val confirmation = OrderConfirmation(
            orderId = UUID.randomUUID().toString(),
            pizzas = pizzas,
            total = total,
            deliveryAddress = deliveryAddress
        )
        
        // Workflow completes successfully
        return Continuation.end(confirmation)
    }
}

data class Pizza(val name: String, val price: BigDecimal)
data class OrderConfirmation(
    val orderId: String,
    val pizzas: List<Pizza>,
    val total: BigDecimal,
    val deliveryAddress: String
)

3. Test your workflow logic:

class PizzaOrderWorkflowTest {
    
    @Test
    fun `addPizza should add pizza to cart and return to same step`() {
        // Arrange
        val initialStep = AddPizzaToCartStep()
        val pizza = Pizza("Margherita", BigDecimal("12.99"))
        
        // Act
        val result = initialStep.addPizza(pizza)
        
        // Assert
        assertThat(result.pizzas).hasSize(1)
        assertThat(result.pizzas[0]).isEqualTo(pizza)
        assertThat(result).isInstanceOf(AddPizzaToCartStep::class.java)
    }
    
    @Test
    fun `toCheckout should transition to checkout step with current pizzas`() {
        // Arrange
        val pizzas = mutableListOf(
            Pizza("Margherita", BigDecimal("12.99")),
            Pizza("Pepperoni", BigDecimal("14.99"))
        )
        val step = AddPizzaToCartStep(pizzas)
        
        // Act
        val result = step.toCheckout()
        
        // Assert
        assertThat(result).isInstanceOf(CheckoutStep::class.java)
        assertThat(result.pizzas).hasSize(2)
        assertThat(result.total).isEqualTo(BigDecimal("27.98"))
    }
    
    @Test
    fun `submitOrder should create confirmation with pre-calculated total`() {
        // Arrange
        val pizzas = listOf(
            Pizza("Margherita", BigDecimal("12.99")),
            Pizza("Pepperoni", BigDecimal("14.99"))
        )
        val checkoutStep = CheckoutStep(pizzas, BigDecimal("27.98")).apply {
            deliveryAddress = "123 Main St"
            paymentMethod = "Credit Card"
        }
        
        // Act
        val result = checkoutStep.submitOrder()
        
        // Assert
        assertThat(result.isCompleted).isTrue()
        val confirmation = result.completionData as OrderConfirmation
        assertThat(confirmation.pizzas).isEqualTo(pizzas)
        assertThat(confirmation.total).isEqualTo(BigDecimal("27.98"))
        assertThat(confirmation.deliveryAddress).isEqualTo("123 Main St")
        assertThat(confirmation.orderId).isNotBlank()
    }
}

That's it! You now have a fully functional pizza ordering workflow with:

  • ✅ Type-safe state management
  • ✅ Decision logic with looping
  • ✅ Built-in validation rules
  • ✅ Comprehensive unit tests
  • ✅ Automatic persistence (with Spring Boot)

📊 Workflow Visualization

Sample Workflow Process

Pizza ordering workflow: Add Pizza (addPizza/toCheckout actions) → Checkout → Submit

💡 Example Use Cases

FluxFlow is well-suited for various business scenarios:

🏢 Enterprise Applications

  • Employee onboarding/offboarding
  • Approval processes
  • Document workflows
  • Compliance procedures

💰 Financial Processing

  • Loan application processing
  • KYC/AML workflows
  • Trade settlement
  • Risk assessment flows

🛒 E-Commerce Applications

  • Order fulfillment
  • Return processing
  • Inventory management
  • Customer service tickets

🏥 Healthcare Systems

  • Patient intake processes
  • Medical record workflows
  • Insurance claim processing
  • Treatment approval flows

⚡ Quick Start

1️⃣ Add FluxFlow to your project

Gradle (Kotlin DSL)
dependencies {
    implementation("de.lise.fluxflow:springboot:0.2.0")
    implementation("de.lise.fluxflow:mongo:0.2.0") // For MongoDB persistence
}
Gradle (Groovy)
dependencies {
    implementation 'de.lise.fluxflow:springboot:0.2.0'
    implementation 'de.lise.fluxflow:mongo:0.2.0' // For MongoDB persistence
}
Maven
<dependency>
    <groupId>de.lise.fluxflow</groupId>
    <artifactId>springboot</artifactId>
    <version>0.2.0</version>
</dependency>
<dependency>
    <groupId>de.lise.fluxflow</groupId>
    <artifactId>mongo</artifactId>
    <version>0.2.0</version>
</dependency>

2️⃣ Create your first workflow step

// Java Example - Pizza Ordering Step
@Step
public class AddPizzaToCartStep {
    @Data 
    @NotEmpty(message = "Cart cannot be empty. Please add at least one pizza before checkout.")
    private List<Pizza> pizzas = new ArrayList<>();
    
    @Action(beforeExecutionValidation = ValidationBehavior.AllowInvalid)
    public AddPizzaToCartStep addPizza(Pizza pizza) {
        // Add pizza to cart
        pizzas.add(pizza);
        return new AddPizzaToCartStep(pizzas);
    }
    
    @Action 
    public CheckoutStep toCheckout() {
        // Calculate total and proceed to checkout
        BigDecimal total = pizzas.stream()
            .map(Pizza::getPrice)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
        return new CheckoutStep(pizzas, total);
    }
}

3️⃣ Configure Spring Boot

@SpringBootApplication
@EnableFluxFlow
class MyApplication

fun main(args: Array<String>) {
    runApplication<MyApplication>(*args)
}

4️⃣ Start your workflow

@RestController
class PizzaOrderController(
    private val workflowEngine: WorkflowEngine
) {
    @PostMapping("/pizza-orders")
    fun startPizzaOrder(): String {
        val workflow = workflowEngine.start(AddPizzaToCartStep())
        return workflow.id
    }
}

🏗️ Architecture Overview

FluxFlow follows a simple, layered architecture:

  • 🔧 Your Application Code: Define workflow steps as regular Java/Kotlin classes
  • ⚙️ FluxFlow Engine: Manages workflow execution, state transitions, and persistence
  • 💾 Persistence Layer: Stores workflow state (MongoDB, in-memory, or custom implementations)
  • 📅 Scheduling: Optional Quartz integration for time-based workflow actions
  • 🌱 Spring Integration: Auto-configuration and dependency injection support

📋 Core Concepts

Concept Description Example
🔄 Workflow A complete business process Pizza ordering process
📦 Step Individual stage in workflow "Add Pizza to Cart" step
💾 Step Data State specific to a step Pizza list, customer ID
⚡ Action Transition between steps addPizza() method
🗄️ Workflow Data Shared data across all steps Customer info, order ID
⏰ Jobs Scheduled automatic actions Send reminder after 30min

🔗 Resources & Links

Resource Link
📖 Documentation docs.fluxflow.cloud
🚀 Getting Started Quick Start Guide
📦 Maven Central Browse Packages
📝 Changelog Release Notes
🤝 Contributing Contribution Guide
🔒 Security Security Policy

❓ Frequently Asked Questions

How does FluxFlow compare to traditional BPMN engines?

FluxFlow takes a code-first approach rather than model-first. Instead of designing workflows in visual tools and then implementing the logic separately, you write your workflows directly in Java/Kotlin. This eliminates the gap between design and implementation, makes testing easier, and leverages your existing development tools.

Can I use FluxFlow without Spring Boot?

Yes! While FluxFlow has excellent Spring Boot integration, the core engine is framework-agnostic. You can use it with other frameworks or in standalone applications by manually configuring the workflow engine components.

What persistence options are available?

FluxFlow supports multiple persistence backends including MongoDB and in-memory storage for testing. The persistence layer is pluggable, so you can implement custom storage backends if needed.

How do I handle long-running workflows?

FluxFlow automatically persists workflow state between steps. Long-running workflows can be paused and resumed, and the engine handles scheduling of future actions through integration with Quartz Scheduler.

Is FluxFlow production-ready?

Yes! FluxFlow is actively used in production environments. It includes comprehensive monitoring, metrics, error handling, and has been battle-tested in enterprise applications.

🚧 Compatibility

Component Version Support
Java 17+ ✅ Full Support
Kotlin 2.0+ ✅ Full Support
Spring Boot 3.0+ ✅ Full Support
Jakarta EE 9+ ✅ Full Support

🤝 Community & Support

Found a bug? Report it
Have a question? Start a discussion
Want to contribute? Read our guide


🌟 If FluxFlow helps your project, please consider giving us a star!

⭐ Star on GitHub | 🐦 Follow on Twitter

👥 Contributors

We're grateful to these wonderful people who have contributed to FluxFlow:

In Memory:

  • Jagadish Singh - We deeply appreciate his valuable contributions to both FluxFlow and our team

Built with ❤️ by Lise GmbH

FluxFlow is open source software licensed under the Apache License 2.0

About

A flexible workflow engine that helps to create and orchestrate business processes as domain code.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages