Skip to content

Latest commit

 

History

History
133 lines (96 loc) · 6.24 KB

File metadata and controls

133 lines (96 loc) · 6.24 KB

Agent Instructions

This file provides guidance to AI coding agents when working with code in this repository.

Project Overview

bpmn-to-code is a Gradle and Maven plugin that generates type-safe API definitions from BPMN process models. The project consists of:

  • bpmn-to-code-core: Core logic for parsing BPMN files and generating API code (Kotlin)
  • bpmn-to-code-gradle: Gradle plugin wrapper
  • bpmn-to-code-maven: Maven plugin wrapper
  • bpmn-to-code-web: Web plugin wrapper
  • bpmn-to-code-testing: Arch-Unit like feature that allows us to test bpmnModels for specific rules

Architecture

The core follows hexagonal architecture with clear separation of concerns:

Domain Layer (bpmn-to-code-core/src/main/kotlin/io/miragon/bpmn/domain/)

  • BpmnModel.kt, BpmnFile.kt, BpmnModelApi.kt: Core domain entities
  • shared/: Common types like OutputLanguage, ProcessEngine, ServiceTaskDefinition
  • ProcessModel.mergeByProcessId(...): merges BPMN models sharing a process id into variants

Application Layer (bpmn-to-code-core/src/main/kotlin/io/miragon/bpmn/application/)

  • port/inbound/GenerateProcessApiUseCase.kt: Main use case interface
  • port/outbound/: Adapter interfaces for external dependencies
  • service/GenerateProcessApiService.kt: Use case implementation

Adapter Layer (bpmn-to-code-core/src/main/kotlin/io/miragon/bpmn/adapter/)

  • inbound/CreateProcessApiPlugin.kt: Entry point for plugins
  • outbound/codegen/: Code generation adapters with Java/Kotlin builders
  • outbound/engine/: BPMN parsing adapters for Camunda 7 and Zeebe
  • outbound/filesystem/BpmnFileLoader.kt: File system operations

Common Commands

One-time setup

Install Lefthook and register the git hooks (runs coverage check before push):

brew install lefthook  # or see docs/development/contributing.md for other platforms
lefthook install

Build and Test

# Build entire project
./gradlew build

# Run tests for specific module
./gradlew :bpmn-to-code-core:test

# Run all tests
./gradlew test

Code Generation Testing

# Test Gradle plugin
./gradlew :bpmn-to-code-gradle:test

# Test Maven plugin
./gradlew :bpmn-to-code-maven:test

Code Quality (ktlint + detekt)

Kotlin quality is enforced by ktlint (formatting/imports) and detekt (semantic/structural). Both are wired into check/build and gate CI + the pre-push hook.

./gradlew lintKotlin    # ktlint check
./gradlew formatKotlin  # ktlint auto-fix
./gradlew detektMain detektTest  # detekt (with type resolution)

Lines target 120 chars: anything that fits on one line within that limit stays on one line (ktlint wraps longer lines but never joins shorter ones, so collapse them by hand). No baseline and no silent suppressions — fix findings or add a scoped exception in the relevant config. ktlint config lives in .editorconfig, detekt config in config/detekt/detekt.yml.

Plugin Development

The plugins generate code from BPMN files. Key configuration parameters:

  • filePattern: BPMN file location pattern
  • outputFolderPath: Where to generate code
  • packagePath: Generated code package
  • outputLanguage: KOTLIN, JAVA, or CSHARP (C# inlines its runtime types per file)
  • processEngine: CAMUNDA_7 or ZEEBE

Testing Strategy

Tests are organized by layer:

  • Unit tests for domain services and builders
  • Integration tests for adapters and extractors
  • Test resources include sample BPMN files and expected API outputs
  • Shared BPMN test models live in shared/bpmn/{c7,zeebe,operaton}/ (MiraVelo domain) and follow the modeling guideline in docs/contributing/best-practices.md

The project uses JUnit 5, AssertJ, and MockK for testing. Use testBpmnModel() or the in-memory mirrors of the shared models like testBikeLeasingModel() to programmatically construct test models instead of parsing BPMN files or hand-building domain objects.

Best Practices

Test-Driven Development

Follow TDD when planning and implementing changes: update the domain model first (if applicable), then write/update tests to express the expected behavior (RED phase), then implement the production code to make them pass (GREEN phase).

Verify After Each Task

After completing each discrete task (e.g., a phase in a plan, a refactor step, a bug fix), run a Gradle build on the affected modules to confirm compilation and tests still pass. Use targeted module builds (e.g., ./gradlew :bpmn-to-code-core:test) rather than a full project build when only specific modules were changed.

Always Consider Testing Impact

When making code changes, always think about the testing implications:

  • Write new tests for new functionality or behavior changes
  • Update existing tests when modifying expected outputs or behavior
  • Run affected tests to verify changes work correctly before committing
  • Update test fixtures (like expected output files) when generation logic changes

Example: When modifying code generators (e.g., KotlinApiBuilder), remember to:

  1. Update the corresponding expected output files in src/test/resources/
  2. Run the specific test suite to verify the changes
  3. Check if other builders or tests are affected

GitHub

  • Use the gh CLI for GitHub operations.
  • Keep commit messages and PR descriptions short. Focus on what changed and why.
  • For issues: write a summary, current state, and desired state. Give a high-level overview of technical impact (breaking or not). Focus on behavior, not implementation details.

Personality

You are a knowledgeable colleague, not someone who passively takes orders. If something proposed doesn't look right, suggest corrections, ask critical questions, and push back where needed. Challenge ideas that could benefit from further improvement or iterative refinement rather than just accepting them at face value.

AI Skills

Reusable skill definitions live in .claude/skills/. New skills should be created under .claude/skills/<skill-name>/SKILL.md. See docs/development/ai-skills.md for details.