diff --git a/docs/src/process-development/api-v2/dsf/index.md b/docs/src/process-development/api-v2/dsf/index.md index 63d6f9d6f..6467f4bf8 100644 --- a/docs/src/process-development/api-v2/dsf/index.md +++ b/docs/src/process-development/api-v2/dsf/index.md @@ -18,4 +18,5 @@ icon: creative - [Read Access Tag](read-access-tag.md) - [Requester and Recipient](requester-and-recipient.md) - [Spring Framework Integration](spring-framework-integration.md) +- [Understanding the Process Authorization Extension](./understanding-the-process-authorization-extension.md) - [Versions, Placeholders and URLs](versions-placeholders-urls.md) \ No newline at end of file diff --git a/docs/src/process-development/api-v2/dsf/requester-and-recipient.md b/docs/src/process-development/api-v2/dsf/requester-and-recipient.md index 59c318994..8a0c8e397 100644 --- a/docs/src/process-development/api-v2/dsf/requester-and-recipient.md +++ b/docs/src/process-development/api-v2/dsf/requester-and-recipient.md @@ -251,4 +251,4 @@ The `recipeint` element uses one of the following Codings: ## Related Topics -[ActivityDefinition](../fhir/activitydefinition.md) +[ActivityDefinition](../fhir/activitydefinition.md), [Understanding the Process Authorization Extension](./understanding-the-process-authorization-extension.md) diff --git a/docs/src/process-development/api-v2/dsf/understanding-the-process-authorization-extension.md b/docs/src/process-development/api-v2/dsf/understanding-the-process-authorization-extension.md new file mode 100644 index 000000000..de9aa4b02 --- /dev/null +++ b/docs/src/process-development/api-v2/dsf/understanding-the-process-authorization-extension.md @@ -0,0 +1,95 @@ +--- +title: Understanding the Process Authorization Extension +icon: creative +--- + +The authorization rules live inside a `` block in the `ActivityDefinition`. Before you make changes, read through the annotated structure below so you know exactly what each line does and where to make your edits later. + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +When you need to restrict access to a **specific organization** or a **specific OIDC role**, add a nested `` inside `` to narrow the rule further: + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +> **Reading tip:** Think of the outer `` as the *category* of the rule (e.g. "a local client with a specific role") and the inner `` as the *precise value* within that category (e.g. "the role `DSF_ADMIN`"). You always need both together. + +## Related Topics +[ActivityDefinition](../fhir/activitydefinition.md), [Creating ActivityDefinitions](../guides/creating-activity-definitions.md), [Requester and Recipient Examples](./requester-and-recipient.md) \ No newline at end of file diff --git a/docs/src/process-development/api-v2/guides/creating-activity-definitions.md b/docs/src/process-development/api-v2/guides/creating-activity-definitions.md index daf122fae..3f46074b8 100644 --- a/docs/src/process-development/api-v2/guides/creating-activity-definitions.md +++ b/docs/src/process-development/api-v2/guides/creating-activity-definitions.md @@ -757,4 +757,4 @@ All other elements can technically be omitted. Still, the following elements are ## Related Topics -[ActivityDefinition](../fhir/activitydefinition.md), [Creating CodeSystems for DSF Processes](creating-codesystems-for-dsf-processes.md), [Creating ValueSets for DSF Processes](creating-valuesets-for-dsf-processes.md), [Task](../fhir/task.md) +[ActivityDefinition](../fhir/activitydefinition.md), [Creating CodeSystems for DSF Processes](creating-codesystems-for-dsf-processes.md), [Creating ValueSets for DSF Processes](creating-valuesets-for-dsf-processes.md), [Requester and Recipient Examples](../dsf/requester-and-recipient.md), [Task](../fhir/task.md), [Understanding the Process Authorization Extension](../dsf/understanding-the-process-authorization-extension.md) diff --git a/docs/src/process-development/api-v2/guides/user-tasks-in-the-dsf.md b/docs/src/process-development/api-v2/guides/user-tasks-in-the-dsf.md index e763a90b0..84190190c 100644 --- a/docs/src/process-development/api-v2/guides/user-tasks-in-the-dsf.md +++ b/docs/src/process-development/api-v2/guides/user-tasks-in-the-dsf.md @@ -21,7 +21,7 @@ Below is a template for a [Questionnaire](https://www.hl7.org/fhir/R4/questionna ```xml - + diff --git a/docs/src/process-development/linter-tool/validation.md b/docs/src/process-development/linter-tool/validation.md index e578a5cf2..26b48cd4f 100644 --- a/docs/src/process-development/linter-tool/validation.md +++ b/docs/src/process-development/linter-tool/validation.md @@ -112,6 +112,28 @@ The linter performs comprehensive validation on BPMN 2.0 process definitions usi - The process engine only deploys and executes processes marked as executable - Non-executable processes are typically used for documentation or as templates +##### Process Version Tag Validation + +- **Requirement**: + - Process must define `camunda:versionTag` + - Expected placeholder value in DSF process plugins: `#{version}` + - Error: `BPMN_PROCESS_VERSION_TAG_MISSING_OR_EMPTY` (missing, empty/blank, or literal `"null"`) + - Warning: `BPMN_PROCESS_VERSION_TAG_NO_PLACEHOLDER` (present but without `#{version}`) + - Success: `SUCCESS` when `camunda:versionTag` contains `#{version}` + +- **Valid Example**: + - ✅ `` + +- **Error Examples**: + - ❌ `` (missing `camunda:versionTag`) + - ❌ `` (empty value) + - ❌ `` (literal `null`) + +- **Warning Examples**: + - ⚠️ `` + - ⚠️ `` + + #### Task Validation ##### Service Tasks @@ -638,9 +660,51 @@ Task resources are validated against the DSF Task base profile (`http://dsf.dev/ - Error: `FHIR_TASK_INPUT_SLICE_COUNT_BELOW_SLICE_MIN` - Error: `FHIR_TASK_INPUT_SLICE_COUNT_EXCEEDS_SLICE_MAX` -- **Terminology Validation**: - - Code/system combinations validated against DSF CodeSystems - - Error: `FHIR_TASK_UNKNOWN_CODE` + - **Terminology Validation**: + - Generic coding validation (outside `Task.input.type.coding`) checks code/system pairs against known DSF CodeSystems + - Error: `FHIR_TASK_UNKNOWN_CODE` + +- **Task.input.type.coding Terminology Validation (binding-driven)**: + - Validation for `Task.input.type.coding` is performed in three strict, ordered checks: + 1. **Known CodeSystem check**: + - `Task.input.type.coding.system` must be a known CodeSystem URI + - Error: `FHIR_TASK_INPUT_CODING_SYSTEM_UNKNOWN` + - If this check fails, subsequent checks for that input are skipped + 2. **Binding context check**: + - The system must be allowed by the slice-specific binding context from the referenced `StructureDefinition` + - Resolution order: + - `fixedUri` on `Task.input:sliceName.type.coding.system` (exact match required) + - `binding.valueSet` on `Task.input:sliceName.type` (fallback: `...type.coding`) and membership in `ValueSet.compose.include.system` + - Error: `FHIR_TASK_INPUT_CODING_SYSTEM_NOT_IN_VALUE_SET` + - If this check fails, code validation for that input is skipped + 3. **Code-in-system check**: + - `Task.input.type.coding.code` must exist in the specified CodeSystem + - Error: `FHIR_TASK_INPUT_CODING_CODE_UNKNOWN_FOR_SYSTEM` + +- **Binding Resolution Notes**: + - ValueSet checks are strict and context-aware; no permissive fallback to unrelated ValueSets is used + - If a slice declares `binding.valueSet` but the ValueSet is not loaded into the cache, validation fails explicitly with: + `FHIR_TASK_INPUT_CODING_SYSTEM_NOT_IN_VALUE_SET` + - If no resolvable binding context exists for a slice (`fixedUri` and `binding.valueSet` both missing), validation fails explicitly with: + `FHIR_TASK_INPUT_CODING_SYSTEM_NOT_IN_VALUE_SET` + - Inputs already failing structural checks (`FHIR_TASK_INPUT_REQUIRED_CODING_SYSTEM_AND_CODING_CODE`) are not re-reported by terminology checks + +- **Task.input Fixed Constraint Validation (`fixedUri` / `fixedCode`)**: + - Validates actual `Task.input.type.coding.system` and `Task.input.type.coding.code` pairs against fixed constraints declared in the referenced `StructureDefinition` slices + - Validation direction is **Task → StructureDefinition** (actual instance values are checked against allowed fixed pairs) + - **System mismatch for existing code**: + - If a Task input code exists in SD constraints, but with a different system + - Error: `FHIR_TASK_INPUT_FIXED_URI_MISMATCH` + - **Code mismatch for existing system**: + - If a Task input system exists in SD constraints, but with a different code + - Error: `FHIR_TASK_INPUT_FIXED_CODE_MISMATCH` + - **Pair not allowed by SD constraints**: + - If a non-BPMN Task input `(system, code)` pair is not defined by any SD `fixedUri/fixedCode` constraint + - Error: `FHIR_TASK_INPUT_PAIR_NOT_ALLOWED_BY_SD` + - **Validation Behavior**: + - Check runs only when profile can be resolved and fixed constraints are extractable from the referenced `StructureDefinition` + - BPMN message inputs (`http://dsf.dev/fhir/CodeSystem/bpmn-message`) are excluded from this specific pair-not-allowed check because they are validated in dedicated Task input rules + #### StructureDefinition Resources @@ -702,6 +766,24 @@ According to FHIR profiling specification §5.1.0.14: - No individual slice's maximum cardinality may exceed base element's maximum - Error: `STRUCTURE_DEFINITION_SLICE_MAX_TOO_HIGH` +##### Binding and Fixed Coding Validation +- **`binding.valueSet` Reference Validation**: + - Checks whether `binding.valueSet` URLs in differential elements can be resolved to a known ValueSet in project resources + - For unresolved references with `strength="required"`: + - Warning: `STRUCTURE_DEFINITION_BINDING_VALUESET_UNRESOLVED` + - For unresolved references with non-required strengths (`extensible`, `preferred`, `example`): + - Info: `STRUCTURE_DEFINITION_BINDING_VALUESET_UNRESOLVED_NON_REQUIRED` + - Success: `SUCCESS` when the referenced ValueSet is resolvable +- **`fixedUri` / `fixedCode` Validation Against CodeSystems**: + - For differential elements using `fixedUri` on `*.system`, verifies that the referenced CodeSystem exists in project terminology cache + - If referenced CodeSystem is unknown: + - Info: `STRUCTURE_DEFINITION_FIXED_URI_CODESYSTEM_NOT_FOUND` + - Note: `fixedCode` validation is skipped for this path when CodeSystem is unknown + - If `fixedCode` is present and the CodeSystem is known, verifies that the code exists in that CodeSystem + - Error: `STRUCTURE_DEFINITION_FIXED_CODE_NOT_IN_CODESYSTEM` + - Success: `SUCCESS` when `fixedUri` resolves (and `fixedCode`, if present, is valid) + + #### ValueSet Resources ValueSet resources are validated against the DSF ValueSet base profile. @@ -1023,6 +1105,59 @@ ValueSet resources are validated against the DSF ValueSet base profile. - `dsf-bpe/dsf-bpe-process-api-v2/src/main/java/dev/dsf/bpe/v2/ProcessPluginDefinition.java` - The `getResourceVersion()` method extracts the resource version from the plugin version +#### Spring Configuration Registration + +In the DSF runtime, the Camunda engine does not instantiate Java delegate or +listener classes directly. Spring creates those instances via `@Bean` methods +declared in `@Configuration` classes. For those beans to be available to the +BPE at runtime, the corresponding `@Configuration` classes must be explicitly +returned by `ProcessPluginDefinition#getSpringConfigurations()`. Forgetting +to add a `@Bean` for a BPMN-referenced class typically surfaces as a +`BeanCreationException` or `ClassNotFoundException` only at deployment time. + +- **Every BPMN-referenced class must be provided as a `@Bean`**: + - The linter collects every `camunda:class` reference used by + `serviceTask`, `sendTask`, `messageEventDefinition`, + `camunda:executionListener` and `camunda:taskListener` elements in the + plugin's BPMN files (List 1). + - The linter calls `getSpringConfigurations()` to get the registered + `@Configuration` classes and inspects the return types of their + `@Bean` methods (List 2). + - For every class in List 1, the linter checks whether it is provided + as a `@Bean` (exact type or supertype) in any `@Configuration` from + List 2. + - If a BPMN-referenced class has **no matching `@Bean`** in any + registered configuration, this is reported as an error. + - Error: `PLUGIN_DEFINITION_SPRING_CONFIGURATION_MISSING` + - Success: `SUCCESS` when all BPMN delegate/listener references are + covered by a `@Bean` in a registered `@Configuration`, or when no + BPMN delegate/listener references exist. + +- **Code Example**: + ```java + @Override + public List> getSpringConfigurations() { + return List.of(DataSharingConfig.class, DataSharingVariablesConfig.class); + } + ``` + ```java + @Configuration + public class DataSharingConfig { + + // Every class referenced via camunda:class in the BPMN must have + // a corresponding @Bean here (or in another registered @Configuration). + @Bean + public SelectDicTargets selectDicTargets() { + return new SelectDicTargets(api); + } + + @Bean + public SelectDmsTarget selectDmsTarget() { + return new SelectDmsTarget(api); + } + } + ``` + #### Leftover Resource Detection The linter performs project-level analysis to identify unreferenced resources: