Skip to content

compliance-profiles-demo

Same app code, three tenants, three regulatory profiles — no if (region) branches in your domain handlers.

How a multi-tenant platform uses compliance-profiles to deliver different regulatory behaviour per tenant:

TenantProfileSupervisory authorityLanguagesTenant-destroy grace
A (DACH)eu-dsgvoBlnBDI Berlinde / en30 days
B (Switzerland)swiss-dsgEDÖB Bernde / fr / it / en30 days
C (DACH-HR)de-hr-dsgvo-hgbState DPAde60 days (HR override)

Plus tenant B with an override (gracePeriod: { days: 90 }) extending user-rights grace without losing other profile fields — deep-merge on the base profile; atomic paths replace, the rest inherits from swiss-dsg (which itself extends eu-dsgvo).

The sample imports one feature:

import { createComplianceProfilesFeature } from "@cosmicdrift/kumiko-bundled-features/compliance-profiles";
export const features = [createComplianceProfilesFeature()];

The feature exposes compliance.forTenant — other features (user-data-rights, data-retention, tenant lifecycle) resolve the effective profile via this API instead of hard-coding region rules.

  1. Operator assigns a profile to each tenant (eu-dsgvo, swiss-dsg, …).
  2. Tenant B adds a partial override (longer grace) — merged atomically.
  3. compliance.forTenant(tenantId) returns resolved fields (languages, supervisory authority, grace periods, retention presets).
  4. Downstream features read the resolver — forget grace, retention policy, and audit obligations follow the profile without app-level branching.
Terminal window
# From kumiko-framework repo root:
bun test samples/recipes/compliance-profiles-demo/src/__tests__/feature.integration.test.ts

Five full-stack tests via setupTestStack + real HTTP — profile assignment, override merge, and cross-tenant isolation.

This recipe has no standalone server bootstrap — tests are self-contained. To try interactively, mount complianceProfilesDemoFeatures in your own runDevApp config.


The feature entry point — embedded straight from the source file, so the code here is exactly what runs. Multi-file samples keep their remaining files next to it on GitHub (link below):

// Compliance-Profiles Demo
//
// Same App-Code, two different tenants, two different DSGVO-Profile —
// das ist die Sales-Story von Compliance-Profiles. Tenant-Admin waehlt
// einmal beim Onboarding, danach laufen alle User-Rights-Grace-Periods,
// Notification-Sprachen, Breach-Disclosure-Pflichten und Audit-Log-
// Retentions automatisch profil-spezifisch.
//
// Demo-Szenario:
// Tenant A (DACH-Customer) → eu-dsgvo
// - 30d Grace-Period fuer Forget
// - DE/EN-Notifications
// - Aufsicht: BlnBDI Berlin
//
// Tenant B (Swiss-Customer) → swiss-dsg
// - 30d Grace-Period (geerbt aus eu-dsgvo via extends)
// - DE/FR/IT/EN-Notifications
// - Aufsicht: EDÖB Bern
//
// Beide Tenants laufen auf derselben App-Instance. Das compliance-
// profiles-Feature haelt den Profile-State pro Tenant; jedes consumer-
// Feature ruft `compliance.forTenant` (Sprint 2+) und sieht das
// effektive Profile fuer den aktuellen Tenant.
import { createComplianceProfilesFeature } from "@cosmicdrift/kumiko-bundled-features/compliance-profiles";
export const complianceProfilesDemoFeatures = [createComplianceProfilesFeature()];

📄 On GitHub: samples/recipes/compliance-profiles-demo/src/feature.ts