This file provides guidance to AI coding agents when working with code in this repository.
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
The core follows hexagonal architecture with clear separation of concerns:
BpmnModel.kt,BpmnFile.kt,BpmnModelApi.kt: Core domain entitiesshared/: Common types likeOutputLanguage,ProcessEngine,ServiceTaskDefinitionProcessModel.mergeByProcessId(...): merges BPMN models sharing a process id into variants
port/inbound/GenerateProcessApiUseCase.kt: Main use case interfaceport/outbound/: Adapter interfaces for external dependenciesservice/GenerateProcessApiService.kt: Use case implementation
inbound/CreateProcessApiPlugin.kt: Entry point for pluginsoutbound/codegen/: Code generation adapters with Java/Kotlin buildersoutbound/engine/: BPMN parsing adapters for Camunda 7 and Zeebeoutbound/filesystem/BpmnFileLoader.kt: File system operations
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 entire project
./gradlew build
# Run tests for specific module
./gradlew :bpmn-to-code-core:test
# Run all tests
./gradlew test# Test Gradle plugin
./gradlew :bpmn-to-code-gradle:test
# Test Maven plugin
./gradlew :bpmn-to-code-maven:testKotlin 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.
The plugins generate code from BPMN files. Key configuration parameters:
filePattern: BPMN file location patternoutputFolderPath: Where to generate codepackagePath: Generated code packageoutputLanguage: KOTLIN, JAVA, or CSHARP (C# inlines its runtime types per file)processEngine: CAMUNDA_7 or ZEEBE
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 indocs/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.
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).
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.
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:
- Update the corresponding expected output files in
src/test/resources/ - Run the specific test suite to verify the changes
- Check if other builders or tests are affected
- Use the
ghCLI 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.
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.
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.