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:
@@ -0,0 +1,258 @@
|
||||
/**
|
||||
* Controls composable for compliance controls management
|
||||
*/
|
||||
|
||||
import { computed, type ComputedRef, type Ref, ref } from 'vue'
|
||||
import { useComplianceStore } from '../plugin'
|
||||
import type {
|
||||
Control,
|
||||
Evidence,
|
||||
Risk,
|
||||
ControlDomain,
|
||||
ImplementationStatus,
|
||||
EvidenceType,
|
||||
RiskLikelihood,
|
||||
RiskImpact,
|
||||
} from '@breakpilot/compliance-sdk-types'
|
||||
|
||||
export interface UseControlsReturn {
|
||||
// Controls
|
||||
controls: ComputedRef<Control[]>
|
||||
controlsByDomain: ComputedRef<Record<ControlDomain, Control[]>>
|
||||
implementedControls: ComputedRef<Control[]>
|
||||
pendingControls: ComputedRef<Control[]>
|
||||
getControl: (id: string) => Control | undefined
|
||||
addControl: (control: Omit<Control, 'id' | 'createdAt' | 'updatedAt'>) => void
|
||||
updateControl: (id: string, updates: Partial<Control>) => void
|
||||
deleteControl: (id: string) => void
|
||||
setControlStatus: (id: string, status: ImplementationStatus) => void
|
||||
|
||||
// Evidence
|
||||
evidence: ComputedRef<Evidence[]>
|
||||
validEvidence: ComputedRef<Evidence[]>
|
||||
expiredEvidence: ComputedRef<Evidence[]>
|
||||
getEvidenceForControl: (controlId: string) => Evidence[]
|
||||
addEvidence: (evidence: Omit<Evidence, 'id' | 'uploadedAt'>) => void
|
||||
updateEvidence: (id: string, updates: Partial<Evidence>) => void
|
||||
deleteEvidence: (id: string) => void
|
||||
|
||||
// Risks
|
||||
risks: ComputedRef<Risk[]>
|
||||
criticalRisks: ComputedRef<Risk[]>
|
||||
unmitigatedRisks: ComputedRef<Risk[]>
|
||||
getRisksForControl: (controlId: string) => Risk[]
|
||||
addRisk: (risk: Omit<Risk, 'id' | 'createdAt' | 'updatedAt'>) => void
|
||||
updateRisk: (id: string, updates: Partial<Risk>) => void
|
||||
deleteRisk: (id: string) => void
|
||||
assessRisk: (id: string, likelihood: RiskLikelihood, impact: RiskImpact) => void
|
||||
|
||||
// Compliance Score
|
||||
complianceScore: ComputedRef<number>
|
||||
scoreByDomain: ComputedRef<Record<ControlDomain, number>>
|
||||
}
|
||||
|
||||
export function useControls(): UseControlsReturn {
|
||||
const store = useComplianceStore()
|
||||
const { state, dispatch, compliance } = store
|
||||
|
||||
// Controls
|
||||
const controls = computed(() => state.controls)
|
||||
|
||||
const controlsByDomain = computed(() => {
|
||||
const domains: ControlDomain[] = [
|
||||
'ACCESS_CONTROL',
|
||||
'DATA_PROTECTION',
|
||||
'NETWORK_SECURITY',
|
||||
'INCIDENT_RESPONSE',
|
||||
'BUSINESS_CONTINUITY',
|
||||
'COMPLIANCE',
|
||||
'RISK_MANAGEMENT',
|
||||
'ASSET_MANAGEMENT',
|
||||
'HUMAN_RESOURCES',
|
||||
]
|
||||
|
||||
return domains.reduce(
|
||||
(acc, domain) => {
|
||||
acc[domain] = state.controls.filter(c => c.domain === domain)
|
||||
return acc
|
||||
},
|
||||
{} as Record<ControlDomain, Control[]>
|
||||
)
|
||||
})
|
||||
|
||||
const implementedControls = computed(() =>
|
||||
state.controls.filter(c => c.implementationStatus === 'IMPLEMENTED')
|
||||
)
|
||||
|
||||
const pendingControls = computed(() =>
|
||||
state.controls.filter(c => c.implementationStatus === 'NOT_IMPLEMENTED')
|
||||
)
|
||||
|
||||
const getControl = (id: string): Control | undefined => {
|
||||
return state.controls.find(c => c.id === id)
|
||||
}
|
||||
|
||||
const addControl = (control: Omit<Control, 'id' | 'createdAt' | 'updatedAt'>): void => {
|
||||
dispatch({ type: 'ADD_CONTROL', payload: control })
|
||||
}
|
||||
|
||||
const updateControl = (id: string, updates: Partial<Control>): void => {
|
||||
dispatch({ type: 'UPDATE_CONTROL', payload: { id, updates } })
|
||||
}
|
||||
|
||||
const deleteControl = (id: string): void => {
|
||||
dispatch({ type: 'DELETE_CONTROL', payload: id })
|
||||
}
|
||||
|
||||
const setControlStatus = (id: string, status: ImplementationStatus): void => {
|
||||
dispatch({
|
||||
type: 'UPDATE_CONTROL',
|
||||
payload: { id, updates: { implementationStatus: status } },
|
||||
})
|
||||
}
|
||||
|
||||
// Evidence
|
||||
const evidence = computed(() => state.evidence)
|
||||
|
||||
const validEvidence = computed(() => {
|
||||
const now = new Date()
|
||||
return state.evidence.filter(e => !e.validUntil || new Date(e.validUntil) > now)
|
||||
})
|
||||
|
||||
const expiredEvidence = computed(() => {
|
||||
const now = new Date()
|
||||
return state.evidence.filter(e => e.validUntil && new Date(e.validUntil) <= now)
|
||||
})
|
||||
|
||||
const getEvidenceForControl = (controlId: string): Evidence[] => {
|
||||
return state.evidence.filter(e => e.controlIds.includes(controlId))
|
||||
}
|
||||
|
||||
const addEvidence = (ev: Omit<Evidence, 'id' | 'uploadedAt'>): void => {
|
||||
dispatch({ type: 'ADD_EVIDENCE', payload: ev })
|
||||
}
|
||||
|
||||
const updateEvidence = (id: string, updates: Partial<Evidence>): void => {
|
||||
dispatch({ type: 'UPDATE_EVIDENCE', payload: { id, updates } })
|
||||
}
|
||||
|
||||
const deleteEvidence = (id: string): void => {
|
||||
dispatch({ type: 'DELETE_EVIDENCE', payload: id })
|
||||
}
|
||||
|
||||
// Risks
|
||||
const risks = computed(() => state.risks)
|
||||
|
||||
const criticalRisks = computed(() => compliance.getCriticalRisks())
|
||||
|
||||
const unmitigatedRisks = computed(() =>
|
||||
state.risks.filter(r => r.status === 'IDENTIFIED' || r.status === 'ANALYZED')
|
||||
)
|
||||
|
||||
const getRisksForControl = (controlId: string): Risk[] => {
|
||||
return state.risks.filter(r => r.controlIds?.includes(controlId))
|
||||
}
|
||||
|
||||
const addRisk = (risk: Omit<Risk, 'id' | 'createdAt' | 'updatedAt'>): void => {
|
||||
dispatch({ type: 'ADD_RISK', payload: risk })
|
||||
}
|
||||
|
||||
const updateRisk = (id: string, updates: Partial<Risk>): void => {
|
||||
dispatch({ type: 'UPDATE_RISK', payload: { id, updates } })
|
||||
}
|
||||
|
||||
const deleteRisk = (id: string): void => {
|
||||
dispatch({ type: 'DELETE_RISK', payload: id })
|
||||
}
|
||||
|
||||
const assessRisk = (id: string, likelihood: RiskLikelihood, impact: RiskImpact): void => {
|
||||
const severity = likelihood * impact
|
||||
let severityLevel: Risk['severity']
|
||||
|
||||
if (severity >= 20) severityLevel = 'CRITICAL'
|
||||
else if (severity >= 12) severityLevel = 'HIGH'
|
||||
else if (severity >= 6) severityLevel = 'MEDIUM'
|
||||
else severityLevel = 'LOW'
|
||||
|
||||
dispatch({
|
||||
type: 'UPDATE_RISK',
|
||||
payload: {
|
||||
id,
|
||||
updates: {
|
||||
likelihood,
|
||||
impact,
|
||||
severity: severityLevel,
|
||||
status: 'ANALYZED',
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Compliance Score
|
||||
const complianceScore = computed(() => {
|
||||
const score = compliance.calculateComplianceScore()
|
||||
return score.overall
|
||||
})
|
||||
|
||||
const scoreByDomain = computed(() => {
|
||||
const domains: ControlDomain[] = [
|
||||
'ACCESS_CONTROL',
|
||||
'DATA_PROTECTION',
|
||||
'NETWORK_SECURITY',
|
||||
'INCIDENT_RESPONSE',
|
||||
'BUSINESS_CONTINUITY',
|
||||
'COMPLIANCE',
|
||||
'RISK_MANAGEMENT',
|
||||
'ASSET_MANAGEMENT',
|
||||
'HUMAN_RESOURCES',
|
||||
]
|
||||
|
||||
return domains.reduce(
|
||||
(acc, domain) => {
|
||||
const domainControls = state.controls.filter(c => c.domain === domain)
|
||||
if (domainControls.length === 0) {
|
||||
acc[domain] = 0
|
||||
return acc
|
||||
}
|
||||
|
||||
const implemented = domainControls.filter(c => c.implementationStatus === 'IMPLEMENTED')
|
||||
const partial = domainControls.filter(c => c.implementationStatus === 'PARTIAL')
|
||||
|
||||
acc[domain] = Math.round(
|
||||
((implemented.length + partial.length * 0.5) / domainControls.length) * 100
|
||||
)
|
||||
return acc
|
||||
},
|
||||
{} as Record<ControlDomain, number>
|
||||
)
|
||||
})
|
||||
|
||||
return {
|
||||
controls,
|
||||
controlsByDomain,
|
||||
implementedControls,
|
||||
pendingControls,
|
||||
getControl,
|
||||
addControl,
|
||||
updateControl,
|
||||
deleteControl,
|
||||
setControlStatus,
|
||||
evidence,
|
||||
validEvidence,
|
||||
expiredEvidence,
|
||||
getEvidenceForControl,
|
||||
addEvidence,
|
||||
updateEvidence,
|
||||
deleteEvidence,
|
||||
risks,
|
||||
criticalRisks,
|
||||
unmitigatedRisks,
|
||||
getRisksForControl,
|
||||
addRisk,
|
||||
updateRisk,
|
||||
deleteRisk,
|
||||
assessRisk,
|
||||
complianceScore,
|
||||
scoreByDomain,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user