Context
Follow-up to #960. The annotation-cleanup portion of that issue shipped in #976 (merged 2026-07-04), but @cap-js/data-privacy plugin adoption itself was deferred because the current beta (@cap-js/data-privacy@0.6.2) crashes cds build --production on our schema.
Why the beta plugin can't ship today
Two crash paths in @cap-js/data-privacy@0.6.2 (both hit the MTA build, not cds serve/cds watch):
- (a) Per-task build missing plugin aspects —
db/-task builds don't include the plugin's own sap.ilm.blocking / sap.ilm.destruction aspects. exposeEntity.js:26 unconditionally derefs m.definitions['sap.ilm.blocking'].elements → TypeError.
- (b) Aggregate views drop DataSubjectID FK — plugin auto-exposes aggregate views atop
DataSubjectDetails entities and expects the FK to survive GROUP BY. Our AnalyticsBranchTopPick/AnalyticsBranchPerformance (over BranchDecisions) and CompletionAnalytics/TutorialCompletionStats/ActiveLearnersDaily (over TaskRecords) drop the FK by design → plugin refuses to build.
Runtime works fine — the crash is limited to the MTA build path, which is a shipping blocker.
Prerequisite: upstream bug
What "done" looks like
The remaining checklist from #960:
- Install
@cap-js/data-privacy@^1.x — clean cds build --production on our schema.
- Add
@ILM retention rules to at least the 3 baseline entities so /dpp/retention returns useful content:
TaskRecords — bounded by user lifetime
AuthorAiRequests — audit-trail retention window
AnalyticsQueryHistory — already has a 90-day cleanup cron via cleanupChangeLog
- Add xs-security scopes —
PersonalDataManagerUser, DataRetentionManagerUser (both xs-security.json and .deploy/xs-security.json — dual-file drift is guarded by test/unit/xs-security-authorities.test.js).
- Add approuter routes —
/dpp/information and /dpp/retention scoped to Admin (or DPI service technical user when wiring against a real BTP DPI instance).
- Verify boot with no
[data-privacy] warnings (or with a documented-and-accepted subset).
- Smoke test for
/dpp/* endpoints on the deployed approuter.
- Zero regression on unit + hybrid tests.
Reused blueprints
The plan for #960 already blueprinted Tasks 7–9 for this follow-up:
Existing @personaldata surface (already landed in #976)
The schema is DPI-ready — annotations are in place:
DataSubjectDetails + cascade: 'delete': Users and its 4 compositions (PrizeRecords, AccomplishmentRecords, DeveloperEnvironmentTabs, DeveloperEnvironmentLinks), plus 3 audit entities (CodeCheckSubmissions, ValidateAnswerSubmissions, AuthorAiRequests)
Other + DataSubjectRole: 'Developer': AnalyticsQueryHistory, AnalyticsSavedQuery, BranchDecisions
- Note:
BranchDecisions intentionally stayed Other because its aggregate views broke plugin (b) — that shape holds even in a no-plugin world; may need revisiting depending on how the plugin 1.x aggregate-view story lands.
Scope guardrails
- Not in scope: wiring against a real BTP Data Privacy Integration instance (separate ops task — needs a DPI service instance in the subaccount).
- Not in scope: user-facing consent flows or takeout endpoints.
/dpp/* are consumed by the DPI service, not end users.
References
Context
Follow-up to #960. The annotation-cleanup portion of that issue shipped in #976 (merged 2026-07-04), but
@cap-js/data-privacyplugin adoption itself was deferred because the current beta (@cap-js/data-privacy@0.6.2) crashescds build --productionon our schema.Why the beta plugin can't ship today
Two crash paths in
@cap-js/data-privacy@0.6.2(both hit the MTA build, notcds serve/cds watch):db/-task builds don't include the plugin's ownsap.ilm.blocking/sap.ilm.destructionaspects.exposeEntity.js:26unconditionally derefsm.definitions['sap.ilm.blocking'].elements→ TypeError.DataSubjectDetailsentities and expects the FK to survive GROUP BY. OurAnalyticsBranchTopPick/AnalyticsBranchPerformance(overBranchDecisions) andCompletionAnalytics/TutorialCompletionStats/ActiveLearnersDaily(overTaskRecords) drop the FK by design → plugin refuses to build.Runtime works fine — the crash is limited to the MTA build path, which is a shipping blocker.
Prerequisite: upstream bug
github.com/cap-js/data-privacyciting both crash paths and our schema pattern (per-task build + aggregate views over DataSubjectDetails). — filed as cap-js/data-privacy#41 on 2026-07-04.What "done" looks like
The remaining checklist from #960:
@cap-js/data-privacy@^1.x— cleancds build --productionon our schema.@ILMretention rules to at least the 3 baseline entities so/dpp/retentionreturns useful content:TaskRecords— bounded by user lifetimeAuthorAiRequests— audit-trail retention windowAnalyticsQueryHistory— already has a 90-day cleanup cron viacleanupChangeLogPersonalDataManagerUser,DataRetentionManagerUser(bothxs-security.jsonand.deploy/xs-security.json— dual-file drift is guarded bytest/unit/xs-security-authorities.test.js)./dpp/informationand/dpp/retentionscoped toAdmin(or DPI service technical user when wiring against a real BTP DPI instance).[data-privacy]warnings (or with a documented-and-accepted subset)./dpp/*endpoints on the deployed approuter.Reused blueprints
The plan for #960 already blueprinted Tasks 7–9 for this follow-up:
docs/superpowers/plans/2026-07-04-960-data-privacy-plugin.md— Tasks 7 (xs-security scopes), 8 (approuter routes), 9 (smoke test) carried forward.docs/superpowers/specs/2026-07-04-960-data-privacy-plugin-design.md— see "Scope revision — 2026-07-04" section for the deferral rationale.Existing @personaldata surface (already landed in #976)
The schema is DPI-ready — annotations are in place:
DataSubjectDetails + cascade: 'delete':Usersand its 4 compositions (PrizeRecords,AccomplishmentRecords,DeveloperEnvironmentTabs,DeveloperEnvironmentLinks), plus 3 audit entities (CodeCheckSubmissions,ValidateAnswerSubmissions,AuthorAiRequests)Other + DataSubjectRole: 'Developer':AnalyticsQueryHistory,AnalyticsSavedQuery,BranchDecisionsBranchDecisionsintentionally stayedOtherbecause its aggregate views broke plugin (b) — that shape holds even in a no-plugin world; may need revisiting depending on how the plugin 1.x aggregate-view story lands.Scope guardrails
/dpp/*are consumed by the DPI service, not end users.References