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>
475 lines
14 KiB
TypeScript
475 lines
14 KiB
TypeScript
'use client'
|
|
|
|
import { useContext, useMemo, useCallback } from 'react'
|
|
import { ComplianceContext, type ComplianceContextValue } from './provider'
|
|
import type {
|
|
SDKState,
|
|
SDKAction,
|
|
Control,
|
|
Evidence,
|
|
Risk,
|
|
Requirement,
|
|
Obligation,
|
|
TOM,
|
|
ProcessingActivity,
|
|
ConsentPurpose,
|
|
} from '@breakpilot/compliance-sdk-types'
|
|
|
|
// =============================================================================
|
|
// MAIN HOOK
|
|
// =============================================================================
|
|
|
|
export function useCompliance(): ComplianceContextValue {
|
|
const context = useContext(ComplianceContext)
|
|
if (!context) {
|
|
throw new Error('useCompliance must be used within ComplianceProvider')
|
|
}
|
|
return context
|
|
}
|
|
|
|
// =============================================================================
|
|
// STATE HOOK
|
|
// =============================================================================
|
|
|
|
export function useComplianceState(): SDKState {
|
|
const { state } = useCompliance()
|
|
return state
|
|
}
|
|
|
|
export function useComplianceDispatch(): React.Dispatch<SDKAction> {
|
|
const { dispatch } = useCompliance()
|
|
return dispatch
|
|
}
|
|
|
|
// =============================================================================
|
|
// DSGVO HOOKS
|
|
// =============================================================================
|
|
|
|
export function useDSGVO() {
|
|
const { dsgvo, state } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
// DSR
|
|
dsrRequests: state.dsrRequests,
|
|
dsrConfig: state.dsrConfig,
|
|
submitDSR: dsgvo.submitDSR.bind(dsgvo),
|
|
|
|
// Consent
|
|
consents: state.consents,
|
|
hasConsent: dsgvo.hasConsent.bind(dsgvo),
|
|
getConsentsByUserId: dsgvo.getConsentsByUserId.bind(dsgvo),
|
|
|
|
// VVT
|
|
processingActivities: state.vvt,
|
|
getProcessingActivityById: dsgvo.getProcessingActivityById.bind(dsgvo),
|
|
|
|
// DSFA
|
|
dsfa: state.dsfa,
|
|
isDSFARequired: dsgvo.isDSFARequired.bind(dsgvo),
|
|
|
|
// TOMs
|
|
toms: state.toms,
|
|
getTOMsByCategory: dsgvo.getTOMsByCategory.bind(dsgvo),
|
|
getTOMScore: dsgvo.getTOMScore.bind(dsgvo),
|
|
|
|
// Retention
|
|
retentionPolicies: state.retentionPolicies,
|
|
getUpcomingDeletions: dsgvo.getUpcomingDeletions.bind(dsgvo),
|
|
|
|
// Cookie Banner
|
|
cookieBanner: state.cookieBanner,
|
|
generateCookieBannerCode: dsgvo.generateCookieBannerCode.bind(dsgvo),
|
|
}),
|
|
[dsgvo, state]
|
|
)
|
|
}
|
|
|
|
export function useConsent(userId: string) {
|
|
const { dsgvo, state } = useCompliance()
|
|
|
|
return useMemo(() => {
|
|
const userConsents = state.consents.filter(c => c.userId === userId)
|
|
|
|
return {
|
|
consents: userConsents,
|
|
hasConsent: (purpose: ConsentPurpose) => dsgvo.hasConsent(userId, purpose),
|
|
hasAnalyticsConsent: dsgvo.hasConsent(userId, 'ANALYTICS'),
|
|
hasMarketingConsent: dsgvo.hasConsent(userId, 'MARKETING'),
|
|
hasFunctionalConsent: dsgvo.hasConsent(userId, 'FUNCTIONAL'),
|
|
}
|
|
}, [dsgvo, state.consents, userId])
|
|
}
|
|
|
|
export function useDSR() {
|
|
const { dsgvo, state, dispatch } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
requests: state.dsrRequests,
|
|
config: state.dsrConfig,
|
|
submitRequest: dsgvo.submitDSR.bind(dsgvo),
|
|
pendingRequests: state.dsrRequests.filter(r => r.status !== 'COMPLETED' && r.status !== 'REJECTED'),
|
|
overdueRequests: state.dsrRequests.filter(r => {
|
|
if (r.status === 'COMPLETED' || r.status === 'REJECTED') return false
|
|
return new Date(r.dueDate) < new Date()
|
|
}),
|
|
}),
|
|
[dsgvo, state.dsrRequests, state.dsrConfig]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// COMPLIANCE HOOKS
|
|
// =============================================================================
|
|
|
|
export function useComplianceModule() {
|
|
const { compliance, state } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
// Controls
|
|
controls: state.controls,
|
|
getControlById: compliance.getControlById.bind(compliance),
|
|
getControlsByDomain: compliance.getControlsByDomain.bind(compliance),
|
|
getControlsByStatus: compliance.getControlsByStatus.bind(compliance),
|
|
controlComplianceRate: compliance.getControlComplianceRate(),
|
|
|
|
// Evidence
|
|
evidence: state.evidence,
|
|
getEvidenceByControlId: compliance.getEvidenceByControlId.bind(compliance),
|
|
expiringEvidence: compliance.getExpiringEvidence(),
|
|
|
|
// Requirements
|
|
requirements: state.requirements,
|
|
getRequirementsByRegulation: compliance.getRequirementsByRegulation.bind(compliance),
|
|
requirementComplianceRate: compliance.getRequirementComplianceRate(),
|
|
|
|
// Obligations
|
|
obligations: state.obligations,
|
|
upcomingObligations: compliance.getUpcomingObligations(),
|
|
overdueObligations: compliance.getOverdueObligations(),
|
|
|
|
// AI Act
|
|
aiActClassification: state.aiActClassification,
|
|
aiActRiskCategory: compliance.getAIActRiskCategory(),
|
|
isHighRiskAI: compliance.isHighRiskAI(),
|
|
|
|
// Score
|
|
complianceScore: compliance.calculateComplianceScore(),
|
|
|
|
// Risks
|
|
risks: state.risks,
|
|
criticalRisks: compliance.getCriticalRisks(),
|
|
averageRiskScore: compliance.getAverageRiskScore(),
|
|
}),
|
|
[compliance, state]
|
|
)
|
|
}
|
|
|
|
export function useControls() {
|
|
const { compliance, state, dispatch } = useCompliance()
|
|
|
|
const addControl = useCallback(
|
|
(control: Control) => {
|
|
dispatch({ type: 'ADD_CONTROL', payload: control })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
const updateControl = useCallback(
|
|
(id: string, data: Partial<Control>) => {
|
|
dispatch({ type: 'UPDATE_CONTROL', payload: { id, data } })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
return useMemo(
|
|
() => ({
|
|
controls: state.controls,
|
|
addControl,
|
|
updateControl,
|
|
getById: compliance.getControlById.bind(compliance),
|
|
getByDomain: compliance.getControlsByDomain.bind(compliance),
|
|
getByStatus: compliance.getControlsByStatus.bind(compliance),
|
|
implementedCount: state.controls.filter(c => c.implementationStatus === 'IMPLEMENTED').length,
|
|
totalCount: state.controls.length,
|
|
complianceRate: compliance.getControlComplianceRate(),
|
|
}),
|
|
[state.controls, compliance, addControl, updateControl]
|
|
)
|
|
}
|
|
|
|
export function useEvidence() {
|
|
const { compliance, state, dispatch } = useCompliance()
|
|
|
|
const addEvidence = useCallback(
|
|
(evidence: Evidence) => {
|
|
dispatch({ type: 'ADD_EVIDENCE', payload: evidence })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
const updateEvidence = useCallback(
|
|
(id: string, data: Partial<Evidence>) => {
|
|
dispatch({ type: 'UPDATE_EVIDENCE', payload: { id, data } })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
const deleteEvidence = useCallback(
|
|
(id: string) => {
|
|
dispatch({ type: 'DELETE_EVIDENCE', payload: id })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
return useMemo(
|
|
() => ({
|
|
evidence: state.evidence,
|
|
addEvidence,
|
|
updateEvidence,
|
|
deleteEvidence,
|
|
getByControlId: compliance.getEvidenceByControlId.bind(compliance),
|
|
expiringEvidence: compliance.getExpiringEvidence(),
|
|
activeCount: state.evidence.filter(e => e.status === 'ACTIVE').length,
|
|
totalCount: state.evidence.length,
|
|
}),
|
|
[state.evidence, compliance, addEvidence, updateEvidence, deleteEvidence]
|
|
)
|
|
}
|
|
|
|
export function useRisks() {
|
|
const { compliance, state, dispatch } = useCompliance()
|
|
|
|
const addRisk = useCallback(
|
|
(risk: Risk) => {
|
|
dispatch({ type: 'ADD_RISK', payload: risk })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
const updateRisk = useCallback(
|
|
(id: string, data: Partial<Risk>) => {
|
|
dispatch({ type: 'UPDATE_RISK', payload: { id, data } })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
const deleteRisk = useCallback(
|
|
(id: string) => {
|
|
dispatch({ type: 'DELETE_RISK', payload: id })
|
|
},
|
|
[dispatch]
|
|
)
|
|
|
|
return useMemo(
|
|
() => ({
|
|
risks: state.risks,
|
|
addRisk,
|
|
updateRisk,
|
|
deleteRisk,
|
|
criticalRisks: compliance.getCriticalRisks(),
|
|
getByStatus: compliance.getRisksByStatus.bind(compliance),
|
|
getBySeverity: compliance.getRisksBySeverity.bind(compliance),
|
|
averageScore: compliance.getAverageRiskScore(),
|
|
}),
|
|
[state.risks, compliance, addRisk, updateRisk, deleteRisk]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// RAG HOOKS
|
|
// =============================================================================
|
|
|
|
export function useRAG() {
|
|
const { rag } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
search: rag.search.bind(rag),
|
|
searchByRegulation: rag.searchByRegulation.bind(rag),
|
|
searchByArticle: rag.searchByArticle.bind(rag),
|
|
ask: rag.ask.bind(rag),
|
|
askAboutRegulation: rag.askAboutRegulation.bind(rag),
|
|
explainArticle: rag.explainArticle.bind(rag),
|
|
checkCompliance: rag.checkCompliance.bind(rag),
|
|
getQuickAnswer: rag.getQuickAnswer.bind(rag),
|
|
findRelevantArticles: rag.findRelevantArticles.bind(rag),
|
|
availableRegulations: rag.getAvailableRegulations(),
|
|
chatHistory: rag.getChatHistory(),
|
|
clearChatHistory: rag.clearChatHistory.bind(rag),
|
|
startNewSession: rag.startNewSession.bind(rag),
|
|
}),
|
|
[rag]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// SECURITY HOOKS
|
|
// =============================================================================
|
|
|
|
export function useSecurity() {
|
|
const { security, state } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
// SBOM
|
|
sbom: state.sbom,
|
|
components: security.getComponents(),
|
|
vulnerableComponents: security.getVulnerableComponents(),
|
|
licenseSummary: security.getLicenseSummary(),
|
|
|
|
// Issues
|
|
issues: state.securityIssues,
|
|
openIssues: security.getOpenIssues(),
|
|
criticalIssues: security.getCriticalIssues(),
|
|
getIssuesBySeverity: security.getIssuesBySeverity.bind(security),
|
|
getIssuesByTool: security.getIssuesByTool.bind(security),
|
|
|
|
// Backlog
|
|
backlog: state.securityBacklog,
|
|
overdueBacklogItems: security.getOverdueBacklogItems(),
|
|
|
|
// Scanning
|
|
startScan: security.startScan.bind(security),
|
|
getScanResult: security.getScanResult.bind(security),
|
|
lastScanResult: security.getLastScanResult(),
|
|
|
|
// Summary
|
|
summary: security.getSecuritySummary(),
|
|
securityScore: security.getSecurityScore(),
|
|
availableTools: security.getAvailableTools(),
|
|
}),
|
|
[security, state]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// NAVIGATION HOOKS
|
|
// =============================================================================
|
|
|
|
export function useSDKNavigation() {
|
|
const {
|
|
currentStep,
|
|
goToStep,
|
|
goToNextStep,
|
|
goToPreviousStep,
|
|
canGoNext,
|
|
canGoPrevious,
|
|
completionPercentage,
|
|
phase1Completion,
|
|
phase2Completion,
|
|
state,
|
|
} = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
currentStep,
|
|
currentPhase: state.currentPhase,
|
|
completedSteps: state.completedSteps,
|
|
goToStep,
|
|
goToNextStep,
|
|
goToPreviousStep,
|
|
canGoNext,
|
|
canGoPrevious,
|
|
completionPercentage,
|
|
phase1Completion,
|
|
phase2Completion,
|
|
}),
|
|
[
|
|
currentStep,
|
|
state.currentPhase,
|
|
state.completedSteps,
|
|
goToStep,
|
|
goToNextStep,
|
|
goToPreviousStep,
|
|
canGoNext,
|
|
canGoPrevious,
|
|
completionPercentage,
|
|
phase1Completion,
|
|
phase2Completion,
|
|
]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// SYNC HOOKS
|
|
// =============================================================================
|
|
|
|
export function useSync() {
|
|
const { syncState, forceSyncToServer, isOnline, saveState, loadState } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
status: syncState.status,
|
|
lastSyncedAt: syncState.lastSyncedAt,
|
|
pendingChanges: syncState.pendingChanges,
|
|
error: syncState.error,
|
|
isOnline,
|
|
isSyncing: syncState.status === 'syncing',
|
|
hasConflict: syncState.status === 'conflict',
|
|
forceSyncToServer,
|
|
saveState,
|
|
loadState,
|
|
}),
|
|
[syncState, isOnline, forceSyncToServer, saveState, loadState]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// CHECKPOINT HOOKS
|
|
// =============================================================================
|
|
|
|
export function useCheckpoints() {
|
|
const { validateCheckpoint, overrideCheckpoint, getCheckpointStatus, state } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
checkpoints: state.checkpoints,
|
|
validateCheckpoint,
|
|
overrideCheckpoint,
|
|
getCheckpointStatus,
|
|
passedCheckpoints: Object.values(state.checkpoints).filter(c => c.passed).length,
|
|
totalCheckpoints: Object.keys(state.checkpoints).length,
|
|
}),
|
|
[state.checkpoints, validateCheckpoint, overrideCheckpoint, getCheckpointStatus]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// EXPORT HOOKS
|
|
// =============================================================================
|
|
|
|
export function useExport() {
|
|
const { exportState } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
exportJSON: () => exportState('json'),
|
|
exportPDF: () => exportState('pdf'),
|
|
exportZIP: () => exportState('zip'),
|
|
exportState,
|
|
}),
|
|
[exportState]
|
|
)
|
|
}
|
|
|
|
// =============================================================================
|
|
// COMMAND BAR HOOK
|
|
// =============================================================================
|
|
|
|
export function useCommandBar() {
|
|
const { isCommandBarOpen, setCommandBarOpen } = useCompliance()
|
|
|
|
return useMemo(
|
|
() => ({
|
|
isOpen: isCommandBarOpen,
|
|
open: () => setCommandBarOpen(true),
|
|
close: () => setCommandBarOpen(false),
|
|
toggle: () => setCommandBarOpen(!isCommandBarOpen),
|
|
}),
|
|
[isCommandBarOpen, setCommandBarOpen]
|
|
)
|
|
}
|