Port extensibility customization guide to XTravels and add CDS-Oyster documentation and reference - #2917
Port extensibility customization guide to XTravels and add CDS-Oyster documentation and reference#2917nkaputnik wants to merge 17 commits into
Conversation
Port the extensibility customization guide from the Orders/bookshop sample to XTravels: model-only extension (x_priority + x_CostCenter), multi-repo workspace setup, local multitenancy, and tenant subscription. Regenerate all four screenshots against a running XTravels tenant: - base Travels list - extension project readme - Fiori preview with Priority and Cost Center columns - deployed tenant UI with Priority and Cost Center columns Remove the superseded Orders screenshots.
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
- Add Preferred Project Layout, Ship a Pre-Filled Base Model, and Make It Browsable subsections so a cloned template runs with npm install + cds watch. - Add Seed External & Federated Data (@capire/common, S4 customers, flights): explain the minified base model, trim sap.common-Currencies.csv to code;symbol;name;descr, and don't seed Languages/Regions (no target table). - Split reference wiring into its own section (Provide Reference Logic for Local Runs); renumber Extension Guides/Deploy accordingly. - Purge comments from JSON code blocks; use VitePress line-highlight instead. - Regenerate xtravels-deployed-ext and xtravels-ext-readme screenshots.
Extract the @sap/cds-oyster code-extension sandbox reference material into a dedicated Code Extension Reference page (code-extension.md), mirroring the multitenancy index.md/mtxs.md how+reference split. business-logic.md and business-logic-advanced.md keep their walkthroughs and best practices, with moved blocks replaced by short orientation stubs linking into the reference. Also applies a house-style pass across all three pages (pre-defined, -ize spelling, bare ## Introduction headings, no & in headings) and adds the new page to _menu.md.
…ox debugging business-logic.md: - Document the generated JSDoc handler stub and how it drives code completion - Note the mocked sandbox is debuggable in-process (cds watch --debug) business-logic-advanced.md: - Reframe before-CREATE around the verified declarative-vs-handler boundary: @mandatory/@assert.range/@assert.notNull/@readonly work in extensions only on added, defaulted fields; provider fields and @Assert:(case ...) constraints are rejected at push. Keep only the cross-record checks (customer lookup, budget). - Replace the hand-rolled TravelLog audit trio with a pointer to @cap-js/change-tracking and a single after-CREATE emit('TravelCreated') example - Swap TravelLog for CustomerPolicies + a TravelCreated event in the opened surface code-extension.md: - Add a Debugging in the mocked sandbox section and a troubleshooting row
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Co-authored-by: hyperspace-pr-bot[bot] <209611008+hyperspace-pr-bot[bot]@users.noreply.github.com>
Control PanelHi, I'm an AI-powered Review Bot that helps you with summarizing and reviewing pull requests.
|
SummaryThe following content is AI-generated and provides a summary of the pull request: Update Extensibility Guides for XTravels and Code ExtensionsDocumentation📚 Ports the extensibility customization walkthrough from the Orders sample to XTravels and expands the extensibility documentation with new code-extension guidance. Changes
PR Bot InformationVersion:
|
There was a problem hiding this comment.
I found a few substantive documentation issues that could mislead readers about CAP handler transaction timing and one template layout mismatch around db/data. The rest of the PR reads as a coherent port to XTravels with clear structure and useful examples.
PR Bot Information
Version: 1.31.64
- LLM:
gpt-5.5 - File Content Strategy: Full file content
- Event Trigger:
issue_comment.edited - Review Focus Files:
- Correlation ID:
f0a55c10-bcd9-11f1-8252-55e0b9ef2f35
…layout after handlers run inside the request transaction (pre-commit), not post-commit: a reject rolls back both the write and the handler's own changes. Verified via a purpose-built test in cds-oyster under both the mocked and wasm engines. Also show db/data in the template layout, which the walkthrough creates for the shipped code list.
There was a problem hiding this comment.
I posted a few targeted comments where the new docs could mislead readers about supported handler events or local test setup. The earlier transaction-boundary and template-layout comments appear to have been addressed, so I did not repeat them.
PR Bot Information
Version: 1.31.64
- LLM:
gpt-5.5 - Correlation ID:
288c5390-bcdf-11f1-92bb-b6b30f554ebc - Event Trigger:
issue_comment.edited - Review Focus Files:
- File Content Strategy: Full file content
|
|
||
| ## CRUD Event Handler Scope {#crud} | ||
|
|
||
| Beyond the action and event handlers used for [pre-defined extension points](business-logic), opening an entity enables **before** and **after** handlers on its CRUD events (Create, Read, Update, Delete, Upsert). The full event scope (signatures, transaction semantics, and the `req.data` / `req.subject` / `req.results` each handler sees) is in [Code Extension Reference › Event Scope](code-extension#events). The handler-file convention and sandbox API are unchanged from [Part 1](code-extension#files). |
There was a problem hiding this comment.
Clarity: This sentence implies before-READ handlers are supported
The reference page only lists before handlers for Create, Update, Upsert, and Delete, while Read is only listed for after. Readers may create before-READ.js handlers that do not match the documented sandbox surface.
Consider splitting the before and after scopes explicitly.
| Beyond the action and event handlers used for [pre-defined extension points](business-logic), opening an entity enables **before** and **after** handlers on its CRUD events (Create, Read, Update, Delete, Upsert). The full event scope (signatures, transaction semantics, and the `req.data` / `req.subject` / `req.results` each handler sees) is in [Code Extension Reference › Event Scope](code-extension#events). The handler-file convention and sandbox API are unchanged from [Part 1](code-extension#files). | |
| Beyond the action and event handlers used for [pre-defined extension points](business-logic), opening an entity enables **before** handlers on Create, Update, Upsert, and Delete, plus **after** handlers on Read, Create, Update, Upsert, and Delete. The full event scope (signatures, transaction semantics, and the `req.data` / `req.subject` / `req.results` each handler sees) is in [Code Extension Reference › Event Scope](code-extension#events). The handler-file convention and sandbox API are unchanged from [Part 1](code-extension#files). |
Double-check suggestion before committing. Edit this comment for amendments.
Please provide feedback on the review comment by checking the appropriate box:
- 🌟 Awesome comment, a human might have missed that.
- ✅ Helpful comment
- 🤷 Neutral
- ❌ This comment is not helpful
| ├─ on-<action>.js # unbound action or event | ||
| └─ <EntityName>/ | ||
| ├─ before-<CUD>.js # before a Create/Update/Delete | ||
| ├─ after-READ.js # after a Read | ||
| └─ on-<action>.js # bound action or event |
There was a problem hiding this comment.
Clarity: Handler layout omits supported CRUD events
The event table below includes before Upsert and after Create, Update, Delete, and Upsert, but this tree only documents before-<CUD>.js and after-READ.js. Readers may not know how to name supported files such as after-CREATE.js.
Consider making the file pattern match the documented event scope.
| ├─ on-<action>.js # unbound action or event | |
| └─ <EntityName>/ | |
| ├─ before-<CUD>.js # before a Create/Update/Delete | |
| ├─ after-READ.js # after a Read | |
| └─ on-<action>.js # bound action or event | |
| ├─ on-<action>.js # unbound action or event | |
| └─ <EntityName>/ | |
| ├─ before-<CUD|UPSERT>.js # before a Create/Update/Delete/Upsert | |
| ├─ after-<CRUD|UPSERT>.js # after a Create/Read/Update/Delete/Upsert | |
| └─ on-<action>.js # bound action or event |
Double-check suggestion before committing. Edit this comment for amendments.
Please provide feedback on the review comment by checking the appropriate box:
- 🌟 Awesome comment, a human might have missed that.
- ✅ Helpful comment
- 🤷 Neutral
- ❌ This comment is not helpful
| Because the mocked sandbox runs your handler **in-process**, you can debug it like ordinary code. Start with `cds watch --debug` (or `--inspect-brk` to break on the first line), then set breakpoints straight in your handler file to step through and inspect `req`, `req.data`, and `this.entities`. The production `wasm` sandbox runs isolated, so breakpoints don't bind there — see [Debugging in the mocked sandbox](code-extension#debugging) for the full story. | ||
|
|
||
| ::: tip Reproduce provider wiring locally | ||
| `cds pull` delivers the base *model*, not the provider's handler code, so the `before(submitForReview)` call that triggers your handler isn't present in a standalone run. Re-provide just that wiring in a read-only _srv/server.js_, exactly as described for [reference logic](customization#reference-wiring). On a real tenant this wiring is already there. |
There was a problem hiding this comment.
Clarity: The referenced local wiring does not trigger submitForReview
The customization#reference-wiring example is model-only and stubs existing UI actions; it does not reconnect to TravelExtensionService or register the before(submitForReview) call needed for this code-extension test. Readers following it exactly will still have a handler that never fires locally.
Consider telling readers to adapt the reference pattern with the provider wiring shown earlier.
| `cds pull` delivers the base *model*, not the provider's handler code, so the `before(submitForReview)` call that triggers your handler isn't present in a standalone run. Re-provide just that wiring in a read-only _srv/server.js_, exactly as described for [reference logic](customization#reference-wiring). On a real tenant this wiring is already there. | |
| `cds pull` delivers the base *model*, not the provider's handler code, so the `before(submitForReview)` call that triggers your handler isn't present in a standalone run. Add a local-only _srv/server.js_ that reconnects to `TravelExtensionService` and registers the same `before(submitForReview)` handler shown in [Call the Extension Point](#wire); use the [reference logic](customization#reference-wiring) section only as the pattern for local wiring. On a real tenant this wiring is already there. |
Double-check suggestion before committing. Edit this comment for amendments.
Please provide feedback on the review comment by checking the appropriate box:
- 🌟 Awesome comment, a human might have missed that.
- ✅ Helpful comment
- 🤷 Neutral
- ❌ This comment is not helpful
| cds add ext-handler --filter validateReview | ||
| ``` | ||
|
|
||
| This writes _srv/TravelExtensionService/on-validateReview.js_ with a leading `#` in its name, marking it an **inactive** stub. Remove the `#` to activate it. |
There was a problem hiding this comment.
Clarity: The generated inactive filename is shown without the leading #
The sentence says the file has a leading #, but the path shown is the active filename. This can make readers look for or rename the wrong file.
Consider showing the inactive filename explicitly.
| This writes _srv/TravelExtensionService/on-validateReview.js_ with a leading `#` in its name, marking it an **inactive** stub. Remove the `#` to activate it. | |
| This writes _srv/TravelExtensionService/#on-validateReview.js_, marking it an **inactive** stub. Remove the `#` to activate it. |
Double-check suggestion before committing. Edit this comment for amendments.
Please provide feedback on the review comment by checking the appropriate box:
- 🌟 Awesome comment, a human might have missed that.
- ✅ Helpful comment
- 🤷 Neutral
- ❌ This comment is not helpful
Port Extensibility Guides to XTravels
Documentation
📚 Updates the extensibility documentation to use the XTravels sample throughout and adds new code extensibility guides for sandboxed business logic extensions. The model customization walkthrough now focuses on extending
sap.capire.travels.Travelswithx_priorityandx_CostCenter, including local setup, tenant activation, test data guidance, and refreshed UI verification screenshots.Changes
guides/extensibility/customization.md: Reworked the customization guide from Orders/bookshop examples to XTravels, including multi-repo workspace setup, MTX sidecar subscription flow, extension template layout, local reference wiring, model-only extension examples, local vs shipped data guidance, and XTravels-specific UI annotations.guides/extensibility/business-logic.md: Added a new guide for pre-defined business logic extension points using@sap/cds-oyster, covering provider setup, tenant handler implementation, local/wasm testing, push flow, and best practices.guides/extensibility/business-logic-advanced.md: Added advanced guidance for opening regular services to controlled code extensions, including CRUD handlers, after-READ enrichment, cross-record validation, pagination, and safety recommendations.guides/extensibility/code-extension.md: Added a sandbox reference covering engines, configuration, handler file layout, sandbox API, event scope, query constraints, forbidden constructs, quarantine behavior, and troubleshooting.guides/extensibility/_menu.md: Added navigation entries for the new business logic and code extension documentation pages.guides/extensibility/assets/*: Replaced superseded Orders screenshots with new XTravels screenshots for the base Travels list, extension template README, Fiori preview, and deployed tenant UI.Images and Links
PR Bot Information
Version:
1.31.64264dc780-bcda-11f1-810b-d179ffdc6203issue_comment.edited