Initial commit: breakpilot-compliance - Compliance SDK Platform

Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Boenisch
2026-02-11 23:47:28 +01:00
commit 4435e7ea0a
734 changed files with 251369 additions and 0 deletions

View File

@@ -0,0 +1,509 @@
/**
* Angular Integration fuer @breakpilot/consent-sdk
*
* @example
* ```typescript
* // app.module.ts
* import { ConsentModule } from '@breakpilot/consent-sdk/angular';
*
* @NgModule({
* imports: [
* ConsentModule.forRoot({
* apiEndpoint: 'https://consent.example.com/api/v1',
* siteId: 'site_abc123',
* }),
* ],
* })
* export class AppModule {}
* ```
*/
// =============================================================================
// NOTE: Angular SDK Structure
// =============================================================================
//
// Angular hat ein komplexeres Build-System (ngc, ng-packagr).
// Diese Datei definiert die Schnittstelle - fuer Production muss ein
// separates Angular Library Package erstellt werden:
//
// ng generate library @breakpilot/consent-sdk-angular
//
// Die folgende Implementation ist fuer direkten Import vorgesehen.
// =============================================================================
import { ConsentManager } from '../core/ConsentManager';
import type {
ConsentConfig,
ConsentState,
ConsentCategory,
ConsentCategories,
} from '../types';
// =============================================================================
// Angular Service Interface
// =============================================================================
/**
* ConsentService Interface fuer Angular DI
*
* @example
* ```typescript
* @Component({...})
* export class MyComponent {
* constructor(private consent: ConsentService) {
* if (this.consent.hasConsent('analytics')) {
* // Analytics laden
* }
* }
* }
* ```
*/
export interface IConsentService {
/** Initialisiert? */
readonly isInitialized: boolean;
/** Laedt noch? */
readonly isLoading: boolean;
/** Banner sichtbar? */
readonly isBannerVisible: boolean;
/** Aktueller Consent-Zustand */
readonly consent: ConsentState | null;
/** Muss Consent eingeholt werden? */
readonly needsConsent: boolean;
/** Prueft Consent fuer Kategorie */
hasConsent(category: ConsentCategory): boolean;
/** Alle akzeptieren */
acceptAll(): Promise<void>;
/** Alle ablehnen */
rejectAll(): Promise<void>;
/** Auswahl speichern */
saveSelection(categories: Partial<ConsentCategories>): Promise<void>;
/** Banner anzeigen */
showBanner(): void;
/** Banner ausblenden */
hideBanner(): void;
/** Einstellungen oeffnen */
showSettings(): void;
}
// =============================================================================
// ConsentService Implementation
// =============================================================================
/**
* ConsentService - Angular Service Wrapper
*
* Diese Klasse kann als Angular Service registriert werden:
*
* @example
* ```typescript
* // consent.service.ts
* import { Injectable } from '@angular/core';
* import { ConsentServiceBase } from '@breakpilot/consent-sdk/angular';
*
* @Injectable({ providedIn: 'root' })
* export class ConsentService extends ConsentServiceBase {
* constructor() {
* super({
* apiEndpoint: environment.consentApiEndpoint,
* siteId: environment.siteId,
* });
* }
* }
* ```
*/
export class ConsentServiceBase implements IConsentService {
private manager: ConsentManager;
private _consent: ConsentState | null = null;
private _isInitialized = false;
private _isLoading = true;
private _isBannerVisible = false;
// Callbacks fuer Angular Change Detection
private changeCallbacks: Array<(consent: ConsentState) => void> = [];
private bannerShowCallbacks: Array<() => void> = [];
private bannerHideCallbacks: Array<() => void> = [];
constructor(config: ConsentConfig) {
this.manager = new ConsentManager(config);
this.setupEventListeners();
this.initialize();
}
// ---------------------------------------------------------------------------
// Getters
// ---------------------------------------------------------------------------
get isInitialized(): boolean {
return this._isInitialized;
}
get isLoading(): boolean {
return this._isLoading;
}
get isBannerVisible(): boolean {
return this._isBannerVisible;
}
get consent(): ConsentState | null {
return this._consent;
}
get needsConsent(): boolean {
return this.manager.needsConsent();
}
// ---------------------------------------------------------------------------
// Methods
// ---------------------------------------------------------------------------
hasConsent(category: ConsentCategory): boolean {
return this.manager.hasConsent(category);
}
async acceptAll(): Promise<void> {
await this.manager.acceptAll();
}
async rejectAll(): Promise<void> {
await this.manager.rejectAll();
}
async saveSelection(categories: Partial<ConsentCategories>): Promise<void> {
await this.manager.setConsent(categories);
this.manager.hideBanner();
}
showBanner(): void {
this.manager.showBanner();
}
hideBanner(): void {
this.manager.hideBanner();
}
showSettings(): void {
this.manager.showSettings();
}
// ---------------------------------------------------------------------------
// Change Detection Support
// ---------------------------------------------------------------------------
/**
* Registriert Callback fuer Consent-Aenderungen
* (fuer Angular Change Detection)
*/
onConsentChange(callback: (consent: ConsentState) => void): () => void {
this.changeCallbacks.push(callback);
return () => {
const index = this.changeCallbacks.indexOf(callback);
if (index > -1) {
this.changeCallbacks.splice(index, 1);
}
};
}
/**
* Registriert Callback wenn Banner angezeigt wird
*/
onBannerShow(callback: () => void): () => void {
this.bannerShowCallbacks.push(callback);
return () => {
const index = this.bannerShowCallbacks.indexOf(callback);
if (index > -1) {
this.bannerShowCallbacks.splice(index, 1);
}
};
}
/**
* Registriert Callback wenn Banner ausgeblendet wird
*/
onBannerHide(callback: () => void): () => void {
this.bannerHideCallbacks.push(callback);
return () => {
const index = this.bannerHideCallbacks.indexOf(callback);
if (index > -1) {
this.bannerHideCallbacks.splice(index, 1);
}
};
}
// ---------------------------------------------------------------------------
// Internal
// ---------------------------------------------------------------------------
private setupEventListeners(): void {
this.manager.on('change', (consent) => {
this._consent = consent;
this.changeCallbacks.forEach((cb) => cb(consent));
});
this.manager.on('banner_show', () => {
this._isBannerVisible = true;
this.bannerShowCallbacks.forEach((cb) => cb());
});
this.manager.on('banner_hide', () => {
this._isBannerVisible = false;
this.bannerHideCallbacks.forEach((cb) => cb());
});
}
private async initialize(): Promise<void> {
try {
await this.manager.init();
this._consent = this.manager.getConsent();
this._isInitialized = true;
this._isBannerVisible = this.manager.isBannerVisible();
} catch (error) {
console.error('Failed to initialize ConsentManager:', error);
} finally {
this._isLoading = false;
}
}
}
// =============================================================================
// Angular Module Configuration
// =============================================================================
/**
* Konfiguration fuer ConsentModule.forRoot()
*/
export interface ConsentModuleConfig extends ConsentConfig {}
/**
* Token fuer Dependency Injection
* Verwendung mit Angular @Inject():
*
* @example
* ```typescript
* constructor(@Inject(CONSENT_CONFIG) private config: ConsentConfig) {}
* ```
*/
export const CONSENT_CONFIG = 'CONSENT_CONFIG';
export const CONSENT_SERVICE = 'CONSENT_SERVICE';
// =============================================================================
// Factory Functions fuer Angular DI
// =============================================================================
/**
* Factory fuer ConsentService
*
* @example
* ```typescript
* // app.module.ts
* providers: [
* { provide: CONSENT_CONFIG, useValue: { apiEndpoint: '...', siteId: '...' } },
* { provide: CONSENT_SERVICE, useFactory: consentServiceFactory, deps: [CONSENT_CONFIG] },
* ]
* ```
*/
export function consentServiceFactory(config: ConsentConfig): ConsentServiceBase {
return new ConsentServiceBase(config);
}
// =============================================================================
// Angular Module Definition (Template)
// =============================================================================
/**
* ConsentModule - Angular Module
*
* Dies ist eine Template-Definition. Fuer echte Angular-Nutzung
* muss ein separates Angular Library Package erstellt werden.
*
* @example
* ```typescript
* // In einem Angular Library Package:
* @NgModule({
* declarations: [ConsentBannerComponent, ConsentGateDirective],
* exports: [ConsentBannerComponent, ConsentGateDirective],
* })
* export class ConsentModule {
* static forRoot(config: ConsentModuleConfig): ModuleWithProviders<ConsentModule> {
* return {
* ngModule: ConsentModule,
* providers: [
* { provide: CONSENT_CONFIG, useValue: config },
* { provide: CONSENT_SERVICE, useFactory: consentServiceFactory, deps: [CONSENT_CONFIG] },
* ],
* };
* }
* }
* ```
*/
export const ConsentModuleDefinition = {
/**
* Providers fuer Root-Module
*/
forRoot: (config: ConsentModuleConfig) => ({
provide: CONSENT_CONFIG,
useValue: config,
}),
};
// =============================================================================
// Component Templates (fuer Angular Library)
// =============================================================================
/**
* ConsentBannerComponent Template
*
* Fuer Angular Library Implementation:
*
* @example
* ```typescript
* @Component({
* selector: 'bp-consent-banner',
* template: CONSENT_BANNER_TEMPLATE,
* styles: [CONSENT_BANNER_STYLES],
* })
* export class ConsentBannerComponent {
* constructor(public consent: ConsentService) {}
* }
* ```
*/
export const CONSENT_BANNER_TEMPLATE = `
<div
*ngIf="consent.isBannerVisible"
class="bp-consent-banner"
role="dialog"
aria-modal="true"
aria-label="Cookie-Einstellungen"
>
<div class="bp-consent-banner-content">
<h2>Datenschutzeinstellungen</h2>
<p>
Wir nutzen Cookies und ähnliche Technologien, um Ihnen ein optimales
Nutzererlebnis zu bieten.
</p>
<div class="bp-consent-banner-actions">
<button
type="button"
class="bp-consent-btn bp-consent-btn-reject"
(click)="consent.rejectAll()"
>
Alle ablehnen
</button>
<button
type="button"
class="bp-consent-btn bp-consent-btn-settings"
(click)="consent.showSettings()"
>
Einstellungen
</button>
<button
type="button"
class="bp-consent-btn bp-consent-btn-accept"
(click)="consent.acceptAll()"
>
Alle akzeptieren
</button>
</div>
</div>
</div>
`;
/**
* ConsentGateDirective Template
*
* @example
* ```typescript
* @Directive({
* selector: '[bpConsentGate]',
* })
* export class ConsentGateDirective implements OnInit, OnDestroy {
* @Input('bpConsentGate') category!: ConsentCategory;
*
* private unsubscribe?: () => void;
*
* constructor(
* private templateRef: TemplateRef<any>,
* private viewContainer: ViewContainerRef,
* private consent: ConsentService
* ) {}
*
* ngOnInit() {
* this.updateView();
* this.unsubscribe = this.consent.onConsentChange(() => this.updateView());
* }
*
* ngOnDestroy() {
* this.unsubscribe?.();
* }
*
* private updateView() {
* if (this.consent.hasConsent(this.category)) {
* this.viewContainer.createEmbeddedView(this.templateRef);
* } else {
* this.viewContainer.clear();
* }
* }
* }
* ```
*/
export const CONSENT_GATE_USAGE = `
<!-- Verwendung in Templates -->
<div *bpConsentGate="'analytics'">
<analytics-component></analytics-component>
</div>
<!-- Mit else Template -->
<ng-container *bpConsentGate="'marketing'; else placeholder">
<marketing-component></marketing-component>
</ng-container>
<ng-template #placeholder>
<p>Bitte akzeptieren Sie Marketing-Cookies.</p>
</ng-template>
`;
// =============================================================================
// RxJS Observable Wrapper (Optional)
// =============================================================================
/**
* RxJS Observable Wrapper fuer ConsentService
*
* Fuer Projekte die RxJS bevorzugen:
*
* @example
* ```typescript
* import { BehaviorSubject, Observable } from 'rxjs';
*
* export class ConsentServiceRx extends ConsentServiceBase {
* private consentSubject = new BehaviorSubject<ConsentState | null>(null);
* private bannerVisibleSubject = new BehaviorSubject<boolean>(false);
*
* consent$ = this.consentSubject.asObservable();
* isBannerVisible$ = this.bannerVisibleSubject.asObservable();
*
* constructor(config: ConsentConfig) {
* super(config);
* this.onConsentChange((c) => this.consentSubject.next(c));
* this.onBannerShow(() => this.bannerVisibleSubject.next(true));
* this.onBannerHide(() => this.bannerVisibleSubject.next(false));
* }
* }
* ```
*/
// =============================================================================
// Exports
// =============================================================================
export type { ConsentConfig, ConsentState, ConsentCategory, ConsentCategories };