Skip to content

feat: support multiple start annotations on one entity#69

Merged
tilwbr merged 29 commits intomainfrom
multipleAnnotations
Apr 1, 2026
Merged

feat: support multiple start annotations on one entity#69
tilwbr merged 29 commits intomainfrom
multipleAnnotations

Conversation

@tilwbr
Copy link
Copy Markdown
Contributor

@tilwbr tilwbr commented Mar 31, 2026

Have you...

  • Added relevant entry to the change log?

Copy link
Copy Markdown
Contributor

@hyperspace-insights hyperspace-insights bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR introduces well-structured support for multiple @bpm.process.start annotations via CDS qualifiers, with good test coverage for the main scenarios. A few substantive issues were flagged: the return type of prefetchStartDataForDelete is incorrect (declared as EntityRow | void but actually returns a DeleteProcessObject-shaped record), the businessKey CSN value extraction in findStartAnnotations uses a loose cast that could silently yield undefined, and there is no collision guard when two annotations share the same qualifier key during prefetch. Please address these before merging.

PR Bot Information

Version: 1.19.9 | 📖 Documentation | 🚨 Create Incident | 💬 Feedback

  • File Content Strategy: Full file content
  • LLM: anthropic--claude-4.6-sonnet
  • Correlation ID: 78336e20-2ce7-11f1-935f-c289eaab9b21
  • Event Trigger: pull_request.opened

@tilwbr tilwbr marked this pull request as ready for review March 31, 2026 11:39
@tilwbr tilwbr requested a review from a team as a code owner March 31, 2026 11:39
@hyperspace-insights
Copy link
Copy Markdown
Contributor

Summary

The following content is AI-generated and provides a summary of the pull request:


Support Multiple @bpm.process.start Annotations on One Entity Using Qualifiers

New Feature

✨ Added support for defining multiple @bpm.process.start annotations on the same CDS entity by using CDS qualifiers (e.g., @bpm.process.start #two). Each qualified annotation is validated and handled independently, allowing an entity to trigger multiple process starts for different events, conditions, or process definitions.

Changes

  • lib/constants.ts: Refactored annotation constants — removed hardcoded per-annotation keys and replaced them with composable suffix constants (SUFFIX_ID, SUFFIX_ON, SUFFIX_IF, SUFFIX_CASCADE, SUFFIX_INPUTS). Derived full-path keys are now generated from the base + suffix, keeping the file DRY.

  • lib/shared/annotations-helper.ts (new): Introduced helper functions getAnnotationPrefixes and findStartAnnotations to scan entity keys and resolve all matching @bpm.process.start annotation prefixes (including qualified ones), returning a list of StartAnnotationDescriptor objects.

  • lib/types/cds-plugin.d.ts: Added the StartAnnotationDescriptor interface (with qualifier, id, on, conditionExpr, inputs, businessKey). Updated EntityEventCache to replace the hasStart: boolean flag with startAnnotations: StartAnnotationDescriptor[].

  • lib/handlers/annotationCache.ts: Updated to use findStartAnnotations instead of reading a single PROCESS_START_ON/PROCESS_START_ID. The cache now stores a filtered list of StartAnnotationDescriptor objects per event.

  • lib/handlers/annotationHandlers.ts: Updated the before DELETE and after handlers to iterate over all startAnnotations in the cache, dispatching handleProcessStart for each annotation in parallel.

  • lib/handlers/processStart.ts: Refactored handleProcessStart to accept a StartAnnotationDescriptor parameter. Replaced addDeletedEntityToRequestStart/addDeletedEntityToRequestStartBusinessKey with a single prefetchStartDataForDelete function that pre-fetches data for all start annotations, storing results in Map<qualifier, EntityRow> entries.

  • lib/handlers/onDeleteUtils.ts: Changed Start and StartBusinessKey fields in DeleteProcessObject from Results to Map<string, Results> to support per-qualifier pre-fetched data. Added getPrefetchedDataForDelete and exported buildWhereDeleteExpression.

  • lib/build/plugin.ts: Updated validateStartAnnotations to iterate over all annotation prefixes returned by getAnnotationPrefixes, validating each qualified start annotation independently.

  • lib/build/validations.ts / lib/build/validation-utils.ts: Updated validateRequiredStartAnnotations, validateIdAnnotation, validateInputTypes, and getParsedInputEntries to accept dynamic annotation key parameters instead of hardcoded constants, enabling per-qualifier validation.

  • tests/bookshop/srv/annotation-service.cds: Added test entities for multiple start annotation scenarios: both on CREATE, on different events (CREATE + UPDATE), both on DELETE, and with a conditional qualified annotation.

  • tests/integration/annotations/multipleStartAnnotations.test.ts (new): Integration tests covering all multiple-start scenarios.

  • tests/integration/build-validation/qualifiedAnnotations.test.ts (new): Build validation tests for qualified annotations, including valid/invalid combinations and per-qualifier error isolation.

  • CHANGELOG.md: Added entry for the new feature.


  • 🔄 Regenerate and Update Summary
  • ✏️ Insert as PR Description (deletes this comment)
  • 🗑️ Delete comment
PR Bot Information

Version: 1.19.9 | 📖 Documentation | 🚨 Create Incident | 💬 Feedback

  • LLM: anthropic--claude-4.6-sonnet
  • Correlation ID: 3737b250-2cf6-11f1-98e1-f572856b8f5a
  • Event Trigger: pull_request.ready_for_review
  • File Content Strategy: Full file content
  • Summary Prompt: Default Prompt
  • Output Template: Default Template

💌 Have ideas or want to contribute? Create an issue and share your thoughts with us!
📑 Check out the documentation for more information.
📬 Subscribe to the Hyperspace PR Bot DL to get the latest announcements and pilot features!

Made with ❤️ by Hyperspace.

Copy link
Copy Markdown
Contributor

@hyperspace-insights hyperspace-insights bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR introduces well-structured support for multiple @bpm.process.start qualifiers, but there are several correctness concerns: a duplicate-qualifier race condition in prefetchStartDataForDelete that silently overwrites entity data, a failure-isolation gap in Promise.all when dispatching multiple start annotations (one rejection aborts the rest), and a silent no-op path on DELETE when the where clause resolves to nothing for all annotations. The shared businessKey being broadcast to all qualifiers also warrants explicit documentation to avoid future confusion.

PR Bot Information

Version: 1.19.9 | 📖 Documentation | 🚨 Create Incident | 💬 Feedback

  • Event Trigger: pull_request.ready_for_review
  • File Content Strategy: Full file content
  • LLM: anthropic--claude-4.6-sonnet
  • Correlation ID: 3737b250-2cf6-11f1-98e1-f572856b8f5a

@tilwbr tilwbr requested a review from Kronprinz03 March 31, 2026 13:32
@tilwbr tilwbr requested a review from SirSimon04 March 31, 2026 13:47
@tilwbr tilwbr requested a review from Kronprinz03 March 31, 2026 14:11
Copy link
Copy Markdown
Contributor

@Kronprinz03 Kronprinz03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay now i am finished with reviewing

Copy link
Copy Markdown
Contributor

@SirSimon04 SirSimon04 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from my side for the tests okay, refer to yannis comments for impl

Copy link
Copy Markdown
Contributor

@Kronprinz03 Kronprinz03 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@tilwbr tilwbr merged commit f1b36c7 into main Apr 1, 2026
12 checks passed
@tilwbr tilwbr deleted the multipleAnnotations branch April 1, 2026 07:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants