Skip to content

Commit 24d73a4

Browse files
authored
Added annotations for changelog_disable_assoc (#89)
1 parent 99d3f3f commit 24d73a4

File tree

2 files changed

+23
-44
lines changed

2 files changed

+23
-44
lines changed

README.md

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@ The `@cap-js/change-tracking` package is a [CDS plugin](https://cap.cloud.sap/do
1010

1111
<img width="1300" alt="change-history-loading" src="_assets/change-history.gif">
1212

13-
14-
1513
### Table of Contents
1614

1715
- [Change Tracking Plugin for SAP Cloud Application Programming Model (CAP)](#change-tracking-plugin-for-sap-cloud-application-programming-model-cap)
18-
- [Table of Contents](#table-of-contents)
16+
- [Table of Contents](#table-of-contents)
1917
- [Preliminaries](#preliminaries)
2018
- [Setup](#setup)
2119
- [Annotations](#annotations)
@@ -27,6 +25,8 @@ The `@cap-js/change-tracking` package is a [CDS plugin](https://cap.cloud.sap/do
2725
- [Customizations](#customizations)
2826
- [Altered table view](#altered-table-view)
2927
- [Disable lazy loading](#disable-lazy-loading)
28+
- [Disable UI Facet generation](#disable-ui-facet-generation)
29+
- [Disable Association to Changes Generation](#disable-association-to-changes-generation)
3030
- [Modelling Samples](#modelling-samples)
3131
- [Specify Object ID](#specify-object-id)
3232
- [Tracing Changes](#tracing-changes)
@@ -35,8 +35,6 @@ The `@cap-js/change-tracking` package is a [CDS plugin](https://cap.cloud.sap/do
3535
- [Code of Conduct](#code-of-conduct)
3636
- [Licensing](#licensing)
3737

38-
39-
4038
## Preliminaries
4139

4240
In this guide, we use the [Incidents Management reference sample app](https://github.com/cap-js/incidents-app) as the base to add change tracking to. Clone the repository and apply the step-by-step instructions:
@@ -59,8 +57,6 @@ npm i
5957
cds w samples/change-tracking
6058
```
6159

62-
63-
6460
## Setup
6561

6662
To enable change tracking, simply add this self-configuring plugin package to your project:
@@ -69,8 +65,6 @@ To enable change tracking, simply add this self-configuring plugin package to yo
6965
npm add @cap-js/change-tracking
7066
```
7167

72-
73-
7468
## Annotations
7569

7670
> [!WARNING]
@@ -96,7 +90,6 @@ The minimal annotation we require for change tracking is `@changelog` on element
9690

9791
Additional identifiers or labels can be added to obtain more *human-readable* change records as described below.
9892

99-
10093
### Human-readable Types and Fields
10194

10295
By default the implementation looks up *Object Type* names or *Field* namesfrom respective `@title` or `@Common.Label` annotations, and applies i18n lookups. If no such annotations are given, the technical names of the respective CDS definitions are displayed.
@@ -115,7 +108,6 @@ We get a human-readable display for *Object Type*:
115108

116109
<img width="1300" alt="change-history-type-hr" src="_assets/changes-type-hr-wbox.png">
117110

118-
119111
### Human-readable IDs
120112

121113
The changelog annotations for *Object ID* are defined at entity level.
@@ -127,18 +119,19 @@ For example, having a `@changelog` annotation without any additional identifiers
127119
```cds
128120
annotate ProcessorService.Conversations {
129121
```
122+
130123
<img width="1300" alt="change-history-id" src="_assets/changes-id-wbox.png">
131124

132125
However, this is not advisable as we cannot easily distinguish between changes. It is more appropriate to annotate as follows:
133126

134127
```cds
135128
annotate ProcessorService.Conversations with @changelog: [author, timestamp] {
136129
```
130+
137131
<img width="1300" alt="change-history-id-hr" src="_assets/changes-id-hr-wbox.png">
138132

139133
Expanding the changelog annotation by additional identifiers `[author, timestamp]`, we can now better identify the `message` change events by their respective author and timestamp.
140134

141-
142135
### Human-readable Values
143136

144137
The changelog annotations for *New Value* and *Old Value* are defined at element level.
@@ -148,28 +141,29 @@ They are already human-readable by default, unless the `@changelog` definition c
148141
For example, having a `@changelog` annotation without any additional identifiers, changes to incident customer would show up as UUIDs:
149142

150143
```cds
151-
customer @changelog;
144+
customer @changelog;
152145
```
153146

154147
<img width="1300" alt="change-history-value" src="_assets/changes-value-wbox.png">
155148

156149
Hence, here it is essential to add a unique identifier to obtain human-readable value columns:
157150

158151
```cds
159-
customer @changelog: [customer.name];
152+
customer @changelog: [customer.name];
160153
```
161154

162155
<img width="1300" alt="change-history-value-hr" src="_assets/changes-value-hr-wbox.png">
163156

164-
165157
## Test-drive locally
166158

167159
With the steps above, we have successfully set up change tracking for our reference application. Let's see that in action.
168160

169161
1. **Start the server**:
170-
```sh
171-
cds watch
172-
```
162+
163+
```sh
164+
cds watch
165+
```
166+
173167
2. **Make a change** on your change-tracked elements. This change will automatically be persisted in the database table (`sap.changelog.ChangeLog`) and made available in a pre-defined view, namely the [Change History view](#change-history-view) for your convenience.
174168

175169
## Change History View
@@ -222,15 +216,20 @@ annotate sap.changelog.aspect @(UI.Facets: [{
222216
Target: 'changes/@UI.PresentationVariant',
223217
![@UI.PartOfPreview]
224218
}]);
225-
226219
```
227220

228221
The system now uses the SAPUI5 default setting `![@UI.PartOfPreview]: true`, such that the table will always shown when navigating to that respective Object page.
229222

230-
### Disable UI Facet completely
223+
### Disable UI Facet generation
231224

232225
If you do not want the UI facet added to a specific UI, you can annotate the service entity with `@changelog.disable_facet`. This will disable the automatic addition of the UI faced to this specific entity, but also all views or further projections up the chain.
233226

227+
### Disable Association to Changes Generation
228+
229+
For some scenarios, e.g. when doing `UNION` and the `@changelog` annotion is still propageted, the automatic addition of the association to `changes` does not make sense. You can use `@changelog.disable_assoc`for this to be disabled on entity level.
230+
231+
> [!IMPORTANT]
232+
> This will also supress the addition of the UI facet, since the change-view is not available as target entity anymore.
234233
235234
## Modelling Samples
236235

@@ -253,7 +252,6 @@ entity Incidents : cuid, managed {
253252
status : Association to Status default 'N';
254253
...
255254
}
256-
257255
```
258256

259257
Add the following `@changelog` annotations in `srv/change-tracking.cds`
@@ -262,7 +260,6 @@ Add the following `@changelog` annotations in `srv/change-tracking.cds`
262260
annotate ProcessorService.Incidents with @changelog: [customer.name, urgency.code, status.criticality] {
263261
title @changelog;
264262
}
265-
266263
```
267264

268265
![AssociationID](_assets/AssociationID.png)
@@ -285,7 +282,6 @@ entity Customers : cuid, managed {
285282
phone : PhoneNumber; // customized type
286283
...
287284
}
288-
289285
```
290286

291287
Add the following `@changelog` annotations in `srv/change-tracking.cds`
@@ -294,7 +290,6 @@ Add the following `@changelog` annotations in `srv/change-tracking.cds`
294290
annotate ProcessorService.Incidents with @changelog: [customer.email, customer.phone] {
295291
title @changelog;
296292
}
297-
298293
```
299294

300295
![CustomTypeID](_assets/CustomTypeID.png)
@@ -315,7 +310,6 @@ entity Customers : cuid, managed {
315310
addresses : Association to Addresses;
316311
...
317312
}
318-
319313
```
320314

321315
Add the following `@changelog` annotations in `srv/change-tracking.cds`
@@ -324,7 +318,6 @@ Add the following `@changelog` annotations in `srv/change-tracking.cds`
324318
annotate ProcessorService.Incidents with @changelog: [customer.addresses.city, customer.addresses.postCode] {
325319
title @changelog;
326320
}
327-
328321
```
329322

330323
![ChainedAssociationID](_assets/ChainedAssociationID.png)
@@ -351,7 +344,6 @@ aspect Conversation: managed, cuid {
351344
...
352345
message : String;
353346
}
354-
355347
```
356348

357349
Add the following `@changelog` annotations in `srv/change-tracking.cds`
@@ -360,7 +352,6 @@ Add the following `@changelog` annotations in `srv/change-tracking.cds`
360352
annotate ProcessorService.Incidents with @changelog: [title] {
361353
conversation @changelog: [conversation.message];
362354
}
363-
364355
```
365356

366357
![CompositionChange](_assets/CompositionChange.png)
@@ -382,7 +373,6 @@ entity Customers : cuid, managed {
382373
email : EMailAddress;
383374
...
384375
}
385-
386376
```
387377

388378
Add the following `@changelog` annotations in `srv/change-tracking.cds`
@@ -391,7 +381,6 @@ Add the following `@changelog` annotations in `srv/change-tracking.cds`
391381
annotate ProcessorService.Incidents with @changelog: [title] {
392382
customer @changelog: [customer.email];
393383
}
394-
395384
```
396385

397386
![AssociationChange](_assets/AssociationChange.png)
@@ -409,7 +398,6 @@ entity Incidents : cuid, managed {
409398
status : StatusType default 'N';
410399
...
411400
}
412-
413401
```
414402

415403
Add the following `@changelog` annotations in `srv/change-tracking.cds`
@@ -418,7 +406,6 @@ Add the following `@changelog` annotations in `srv/change-tracking.cds`
418406
annotate ProcessorService.Incidents with @changelog: [title] {
419407
status @changelog: [status.code];
420408
}
421-
422409
```
423410

424411
![CustomTypeChange](_assets/CustomTypeChange.png)
@@ -440,7 +427,6 @@ entity Customers : cuid, managed {
440427
addresses : Association to Addresses;
441428
...
442429
}
443-
444430
```
445431

446432
Add the following `@changelog` annotations in `srv/change-tracking.cds`
@@ -449,7 +435,6 @@ Add the following `@changelog` annotations in `srv/change-tracking.cds`
449435
annotate ProcessorService.Incidents with @changelog: [title] {
450436
customer @changelog: [customer.addresses.city, customer.addresses.streetAddress];
451437
}
452-
453438
```
454439

455440
![ChainedAssociationChange](_assets/ChainedAssociationChange.png)
@@ -468,7 +453,6 @@ entity Payables : cuid {
468453
cryptoAmount : Decimal;
469454
fiatAmount : Decimal;
470455
};
471-
472456
```
473457

474458
`Payment.cds`:
@@ -479,7 +463,6 @@ entity Payments : cuid {
479463
@changelog
480464
name : String;
481465
};
482-
483466
```
484467

485468
Union entity in `BusinessTransaction.cds`:
@@ -504,7 +487,6 @@ union all
504487
on changes.objectID = ID AND changes.entity = 'payables.Payables'
505488
}
506489
);
507-
508490
```
509491

510492
![UnionChange.png](_assets/UnionChange.png)
@@ -520,7 +502,6 @@ entity Customers : cuid, managed {
520502
...
521503
incidents : Association to many Incidents on incidents.customer = $self;
522504
}
523-
524505
```
525506

526507
The reason is that: the relationship: `Association to many` is only for modelling purpose and there is no concrete field in database table. In the above sample, there is no column for incidents in the table Customers, but there is a navigation property of incidents in Customers OData entity metadata.
@@ -535,7 +516,6 @@ entity AggregatedBusinessTransactionData @(cds.autoexpose) : cuid {
535516
and FootprintInventory.FootprintInventoryScope.ID = FootprintInventoryScope.ID;
536517
...
537518
}
538-
539519
```
540520

541521
The reason is that: When deploying to relational databases, Associations are mapped to foreign keys. Yet, when mapped to non-relational databases they're just references. More details could be found in [Prefer Managed Associations](https://cap.cloud.sap/docs/guides/domain-models#managed-associations). In the above sample, there is no column for FootprintInventory in the table AggregatedBusinessTransactionData, but there is a navigation property FootprintInventoryof in OData entity metadata.
@@ -549,22 +529,19 @@ this.on("UpdateActivationStatus", async (req) =>
549529
.where({ ID: paymentAgreement.ID })
550530
.set({ ActivationStatus_code: ActivationCodes.ACTIVE });
551531
);
552-
553532
```
554533

555534
The reason is that: Application level services are by design the only place where business logic is enforced. This by extension means, that it also is the only point where e.g. change-tracking would be enabled. The underlying method used to do change tracking is `req.diff` which is responsible to read the necessary before-image from the database, and this method is not available on DB level.
556535

557-
558536
## Contributing
559537

560538
This project is open to feature requests/suggestions, bug reports etc. via [GitHub issues](https://github.com/cap-js/change-tracking/issues). Contribution and feedback are encouraged and always welcome. For more information about how to contribute, the project structure, as well as additional contribution information, see our [Contribution Guidelines](CONTRIBUTING.md).
561539

562-
563540
## Code of Conduct
564541

565542
We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone. By participating in this project, you agree to abide by its [Code of Conduct](CODE_OF_CONDUCT.md) at all times.
566543

567-
568544
## Licensing
569545

570546
Copyright 2023 SAP SE or an SAP affiliate company and contributors. Please see our [LICENSE](LICENSE) for copyright and license information. Detailed information including third-party components and their licensing/copyright information is available [via the REUSE tool](https://api.reuse.software/info/github.com/cap-js/change-tracking).
547+

cds-plugin.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ cds.on('loaded', m => {
5151
})})
5252
const assoc = { ...changes, on }
5353
const query = entity.projection || entity.query?.SELECT
54+
if(!entity['@changelog.disable_assoc'])
55+
{
5456
if (query) {
5557
(query.columns ??= ['*']).push({ as: 'changes', cast: assoc })
5658
} else {
@@ -60,7 +62,7 @@ cds.on('loaded', m => {
6062
// Add UI.Facet for Change History List
6163
if(!entity['@changelog.disable_facet'])
6264
entity['@UI.Facets']?.push(facet)
63-
65+
}
6466
// The changehistory list should be refreshed after the custom action is triggered
6567
if (entity.actions) {
6668

0 commit comments

Comments
 (0)