Skip to content

feat: adopt @cap-js/data-privacy plugin v1.x (DPI /dpp/* endpoints) #977

Description

@jung-thomas

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 aspectsdb/-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

  • File issue on github.com/cap-js/data-privacy citing 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.
  • Wait for plugin 1.x GA with fix for (a) and either (b) a supported opt-out annotation for aggregate views, or documented workaround.

What "done" looks like

The remaining checklist from #960:

  1. Install @cap-js/data-privacy@^1.x — clean cds build --production on our schema.
  2. 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
  3. Add xs-security scopesPersonalDataManagerUser, DataRetentionManagerUser (both xs-security.json and .deploy/xs-security.json — dual-file drift is guarded by test/unit/xs-security-authorities.test.js).
  4. Add approuter routes/dpp/information and /dpp/retention scoped to Admin (or DPI service technical user when wiring against a real BTP DPI instance).
  5. Verify boot with no [data-privacy] warnings (or with a documented-and-accepted subset).
  6. Smoke test for /dpp/* endpoints on the deployed approuter.
  7. 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

Metadata

Metadata

Assignees

Labels

BlockedWaiting on someone or something elseenhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions