Skip to content

fix: Propagate subject type - #588

Merged
daogrady merged 11 commits into
mainfrom
fix/req.subject-type-CQL
Aug 20, 2026
Merged

fix: Propagate subject type#588
daogrady merged 11 commits into
mainfrom
fix/req.subject-type-CQL

Conversation

@daogrady

@daogrady daogrady commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #590

Fix: Propagate Subject Type Through Bound Action Handlers

Bug Fix

🐛 Fixes the propagation of the entity subject type in bound action handlers. Previously, req.subject in bound action handlers was untyped, preventing type-safe usage with CQL operations like SELECT, UPDATE, and DELETE. This change carries the entity type information through the subject property, enabling full type inference when using req.subject in database queries.

Changes

  • apis/ql.d.ts: Introduced ClassInstance and EntityClassFromInstance<T> utility types to derive an entity class type from an instance. Added typed overloads for SELECT.one.from, SELECT.from, DELETE.from, and UPDATE.entity that accept a class instance (subject) and return properly typed results.
  • apis/services.d.ts: Updated ActionRequest<P, S> to explicitly omit and re-declare the subject property so it is properly typed as S (the bound action's instance type) rather than being inherited as any.
  • test/typescript/apis/project/cds-services.ts: Updated the bound action handler test to async and added assertions verifying that SELECT.one.from, SELECT.from, DELETE.from, and UPDATE correctly infer the entity type when called with req.subject.
  • test/typescript/apis/project/dummy.ts: Added declare static readonly kind: 'entity' to the Foo class to satisfy the EntityClassFromInstance constraint, and minor formatting fix.
  • CHANGELOG.md: Documented the new behavior — bound action handlers now keep req.subject typed as the bound action's instance type, and subject-based query overloads now derive the entity class from the passed subject to preserve typed query results.
  • 🔄 Regenerate and Update Summary
PR Bot Information

Version: 1.29.33

  • File Content Strategy: Full file content
  • LLM: anthropic--claude-4.6-sonnet
  • Summary Prompt: Default Prompt
  • Event Trigger: pull_request.edited
  • Output Template: Default Template
  • Correlation ID: 5e4a13a0-9c91-11f1-8ebb-e301069f6ab9

@hyperspace-pr-bot hyperspace-pr-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The PR introduces TypedRef<T> as a branded wrapper around cqn_ref to propagate the entity type through bound action handlers into CQL query builders (SELECT, DELETE, UPDATE). The core idea is sound, but the brand field being optional (__entity?: T) means it is not a true discriminant — any plain cqn_ref satisfies TypedRef<T>, and the four new overloads are all ordered before their cqn_ref fallbacks, causing plain refs to silently match the typed overload and infer T = unknown instead of falling through to _TODO.

PR Bot Information

Version: 1.29.33

  • LLM: anthropic--claude-4.6-sonnet
  • Event Trigger: pull_request.opened
  • Correlation ID: 2ecc3300-9bbb-11f1-98c4-113ca607fd21
  • File Content Strategy: Full file content

Comment thread apis/ql.d.ts Outdated
Comment thread apis/ql.d.ts Outdated
Comment thread apis/ql.d.ts Outdated
Comment thread apis/ql.d.ts Outdated
@daogrady
daogrady marked this pull request as ready for review August 20, 2026 12:23
@daogrady
daogrady requested a review from chgeo August 20, 2026 12:23
@hyperspace-pr-bot

Copy link
Copy Markdown
Contributor

Summary

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


Fix: Propagate Subject Type Through Bound Action Handlers

Bug Fix

🐛 Fixes the propagation of the entity subject type in bound action handlers. Previously, req.subject was untyped in bound action handlers, preventing type-safe usage with CQL operations like SELECT, UPDATE, and DELETE. This change ensures full type inference when using req.subject in database queries.

Changes

  • apis/ql.d.ts: Introduced ClassInstance and EntityClassFromInstance<T> utility types to derive an entity class type from an instance. Added typed overloads for SELECT.one.from, SELECT.from, DELETE.from, and UPDATE.entity that accept a subject instance and return properly typed results.
  • apis/services.d.ts: Updated ActionRequest<P, S> to explicitly omit and re-declare the subject property, ensuring it is typed as S (the bound action's instance type) rather than being inherited as any.
  • test/typescript/apis/project/cds-services.ts: Updated the bound action handler test to async and added assertions verifying that SELECT.one.from, SELECT.from, DELETE.from, and UPDATE correctly infer the entity type when called with req.subject.
  • test/typescript/apis/project/dummy.ts: Added declare static readonly kind: 'entity' to the Foo class to satisfy the EntityClassFromInstance constraint, plus a minor formatting fix.
  • CHANGELOG.md: Documented that bound action handlers now keep req.subject typed as the bound action's instance type, and subject-based query overloads now derive the entity class from the passed subject to preserve typed query results.

GitHub Issues

  • #590: [FEATURE] Improvements on the type safety when working with bound actions / functions (e.g. req.subject)

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

Version: 1.29.33

@hyperspace-pr-bot hyperspace-pr-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The PR introduces utility types to propagate the subject type through bound action handlers and adds typed overloads for CQL operations. The implementation has several overload-ordering issues (already flagged) and a dead-code branch in EntityClassFromInstance where the else arm is unreachable because every TypeScript object structurally satisfies { constructor: infer C }. Additionally, the new NonConstructable<T> overload for UPDATE.entity is positioned before the cqn_ref explicit fallback, meaning a bare cqn_ref value could match the new overload and return a wrongly-typed UPDATE<cqn_ref> instead of UPDATE<StaticAny>. Please address the open comments before merging.

PR Bot Information

Version: 1.29.33

  • Event Trigger: pull_request.ready_for_review
  • File Content Strategy: Full file content
  • Correlation ID: eb4a1d90-9c91-11f1-9859-adb332e327e6
  • LLM: anthropic--claude-4.6-sonnet

Comment thread apis/ql.d.ts
Comment thread apis/ql.d.ts

@chgeo chgeo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good :)

@daogrady
daogrady merged commit 2754bb5 into main Aug 20, 2026
19 of 20 checks passed
@daogrady
daogrady deleted the fix/req.subject-type-CQL branch August 20, 2026 13:34
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.

[FEATURE] Improvements on the type safety when working with bound actions / functions (e.g. req.subject)

2 participants