@tantainnovative/ndpr-toolkit 1.0.9 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/README.md +295 -124
  2. package/dist/breach-BpSBPrdk.d.mts +185 -0
  3. package/dist/breach-BpSBPrdk.d.ts +185 -0
  4. package/dist/breach-D5zJYNph.d.mts +17 -0
  5. package/dist/breach-D7NgrdMX.d.ts +17 -0
  6. package/dist/breach.d.mts +275 -0
  7. package/dist/breach.d.ts +275 -0
  8. package/dist/breach.js +2 -0
  9. package/dist/breach.js.map +1 -0
  10. package/dist/breach.mjs +2 -0
  11. package/dist/breach.mjs.map +1 -0
  12. package/dist/chunk-2SYNHRP6.mjs +2 -0
  13. package/dist/chunk-2SYNHRP6.mjs.map +1 -0
  14. package/dist/chunk-2XHD22J7.mjs +7 -0
  15. package/dist/chunk-2XHD22J7.mjs.map +1 -0
  16. package/dist/chunk-4A354HL3.js +2 -0
  17. package/dist/chunk-4A354HL3.js.map +1 -0
  18. package/dist/chunk-4DKT6IB6.js +94 -0
  19. package/dist/chunk-4DKT6IB6.js.map +1 -0
  20. package/dist/chunk-5ZBO2UPH.js +2 -0
  21. package/dist/chunk-5ZBO2UPH.js.map +1 -0
  22. package/dist/chunk-6JFTAYXV.mjs +2 -0
  23. package/dist/chunk-6JFTAYXV.mjs.map +1 -0
  24. package/dist/chunk-6JVYYLS7.js +2 -0
  25. package/dist/chunk-6JVYYLS7.js.map +1 -0
  26. package/dist/chunk-6SGG6WPA.mjs +2 -0
  27. package/dist/chunk-6SGG6WPA.mjs.map +1 -0
  28. package/dist/chunk-AQEGDEQM.js +7 -0
  29. package/dist/chunk-AQEGDEQM.js.map +1 -0
  30. package/dist/chunk-C2IJWCZQ.mjs +2 -0
  31. package/dist/chunk-C2IJWCZQ.mjs.map +1 -0
  32. package/dist/chunk-CMZTI7SG.js +2 -0
  33. package/dist/chunk-CMZTI7SG.js.map +1 -0
  34. package/dist/chunk-DB3JH4DS.mjs +2 -0
  35. package/dist/chunk-DB3JH4DS.mjs.map +1 -0
  36. package/dist/chunk-EWOZKYLY.mjs +2 -0
  37. package/dist/chunk-EWOZKYLY.mjs.map +1 -0
  38. package/dist/chunk-FFW7RUAG.mjs +94 -0
  39. package/dist/chunk-FFW7RUAG.mjs.map +1 -0
  40. package/dist/chunk-FK3CSFLJ.js +2 -0
  41. package/dist/chunk-FK3CSFLJ.js.map +1 -0
  42. package/dist/chunk-GIV2OHE6.mjs +2 -0
  43. package/dist/chunk-GIV2OHE6.mjs.map +1 -0
  44. package/dist/chunk-GMLNWS2N.mjs +2 -0
  45. package/dist/chunk-GMLNWS2N.mjs.map +1 -0
  46. package/dist/chunk-IQF726GS.js +2 -0
  47. package/dist/chunk-IQF726GS.js.map +1 -0
  48. package/dist/chunk-IWUUVRLJ.js +2 -0
  49. package/dist/chunk-IWUUVRLJ.js.map +1 -0
  50. package/dist/chunk-JUN6YPLL.mjs +72 -0
  51. package/dist/chunk-JUN6YPLL.mjs.map +1 -0
  52. package/dist/chunk-L3FKTBGV.js +72 -0
  53. package/dist/chunk-L3FKTBGV.js.map +1 -0
  54. package/dist/chunk-L52PDW6O.mjs +2 -0
  55. package/dist/chunk-L52PDW6O.mjs.map +1 -0
  56. package/dist/chunk-LI6WJ3LZ.js +2 -0
  57. package/dist/chunk-LI6WJ3LZ.js.map +1 -0
  58. package/dist/chunk-LXRXDTPI.js +2 -0
  59. package/dist/chunk-LXRXDTPI.js.map +1 -0
  60. package/dist/chunk-MQFZHA2D.js +2 -0
  61. package/dist/chunk-MQFZHA2D.js.map +1 -0
  62. package/dist/chunk-OITITR6K.mjs +2 -0
  63. package/dist/chunk-OITITR6K.mjs.map +1 -0
  64. package/dist/chunk-PDJGTQMY.mjs +2 -0
  65. package/dist/chunk-PDJGTQMY.mjs.map +1 -0
  66. package/dist/chunk-PGSA2O5P.mjs +2 -0
  67. package/dist/chunk-PGSA2O5P.mjs.map +1 -0
  68. package/dist/chunk-PM7CMTMB.js +4 -0
  69. package/dist/chunk-PM7CMTMB.js.map +1 -0
  70. package/dist/chunk-PYEX7DFR.mjs +4 -0
  71. package/dist/chunk-PYEX7DFR.mjs.map +1 -0
  72. package/dist/chunk-QKK5S54L.mjs +2 -0
  73. package/dist/chunk-QKK5S54L.mjs.map +1 -0
  74. package/dist/chunk-RB26MIRI.js +2 -0
  75. package/dist/chunk-RB26MIRI.js.map +1 -0
  76. package/dist/chunk-RGYK4VAY.mjs +2 -0
  77. package/dist/chunk-RGYK4VAY.mjs.map +1 -0
  78. package/dist/chunk-RHWW5FDP.js +16 -0
  79. package/dist/chunk-RHWW5FDP.js.map +1 -0
  80. package/dist/chunk-RYZEIDNR.js +2 -0
  81. package/dist/chunk-RYZEIDNR.js.map +1 -0
  82. package/dist/chunk-SLNMKGQ2.mjs +2 -0
  83. package/dist/chunk-SLNMKGQ2.mjs.map +1 -0
  84. package/dist/chunk-SSGJREE3.js +2 -0
  85. package/dist/chunk-SSGJREE3.js.map +1 -0
  86. package/dist/chunk-SWF3YVE5.js +4 -0
  87. package/dist/chunk-SWF3YVE5.js.map +1 -0
  88. package/dist/chunk-T44JQT2O.mjs +2 -0
  89. package/dist/chunk-T44JQT2O.mjs.map +1 -0
  90. package/dist/chunk-TDDAYVKK.js +2 -0
  91. package/dist/chunk-TDDAYVKK.js.map +1 -0
  92. package/dist/chunk-TXBZPCGF.mjs +2 -0
  93. package/dist/chunk-TXBZPCGF.mjs.map +1 -0
  94. package/dist/chunk-U2CGMEWB.js +2 -0
  95. package/dist/chunk-U2CGMEWB.js.map +1 -0
  96. package/dist/chunk-UUWVBENC.js +2 -0
  97. package/dist/chunk-UUWVBENC.js.map +1 -0
  98. package/dist/chunk-UYP64PV7.mjs +4 -0
  99. package/dist/chunk-UYP64PV7.mjs.map +1 -0
  100. package/dist/chunk-VMJBW3EF.mjs +2 -0
  101. package/dist/chunk-VMJBW3EF.mjs.map +1 -0
  102. package/dist/chunk-WW3X3ELF.js +2 -0
  103. package/dist/chunk-WW3X3ELF.js.map +1 -0
  104. package/dist/chunk-WWT2ZSNU.mjs +2 -0
  105. package/dist/chunk-WWT2ZSNU.mjs.map +1 -0
  106. package/dist/chunk-XMKA6GVK.mjs +16 -0
  107. package/dist/chunk-XMKA6GVK.mjs.map +1 -0
  108. package/dist/chunk-Y34DQYS7.js +2 -0
  109. package/dist/chunk-Y34DQYS7.js.map +1 -0
  110. package/dist/chunk-ZU73VG3X.js +2 -0
  111. package/dist/chunk-ZU73VG3X.js.map +1 -0
  112. package/dist/consent-CmVzqZUk.d.mts +99 -0
  113. package/dist/consent-CmVzqZUk.d.ts +99 -0
  114. package/dist/consent-DCc5zjXI.d.mts +24 -0
  115. package/dist/consent-DLWb5ota.d.ts +24 -0
  116. package/dist/consent.d.mts +197 -0
  117. package/dist/consent.d.ts +197 -0
  118. package/dist/consent.js +2 -0
  119. package/dist/consent.js.map +1 -0
  120. package/dist/consent.mjs +2 -0
  121. package/dist/consent.mjs.map +1 -0
  122. package/dist/core.d.mts +14 -0
  123. package/dist/core.d.ts +14 -0
  124. package/dist/core.js +2 -0
  125. package/dist/core.js.map +1 -0
  126. package/dist/core.mjs +2 -0
  127. package/dist/core.mjs.map +1 -0
  128. package/dist/cross-border-BrIy1ieh.d.mts +192 -0
  129. package/dist/cross-border-BrIy1ieh.d.ts +192 -0
  130. package/dist/cross-border.d.mts +58 -0
  131. package/dist/cross-border.d.ts +58 -0
  132. package/dist/cross-border.js +2 -0
  133. package/dist/cross-border.js.map +1 -0
  134. package/dist/cross-border.mjs +2 -0
  135. package/dist/cross-border.mjs.map +1 -0
  136. package/dist/dpia-B9ZZJG5a.d.mts +15 -0
  137. package/dist/dpia-fdtTd2DI.d.ts +15 -0
  138. package/dist/dpia-vWfE_9bO.d.mts +137 -0
  139. package/dist/dpia-vWfE_9bO.d.ts +137 -0
  140. package/dist/dpia.d.mts +179 -0
  141. package/dist/dpia.d.ts +179 -0
  142. package/dist/dpia.js +2 -0
  143. package/dist/dpia.js.map +1 -0
  144. package/dist/dpia.mjs +2 -0
  145. package/dist/dpia.mjs.map +1 -0
  146. package/dist/dsr-jq5NUEdz.d.ts +14 -0
  147. package/dist/dsr-pQzQ3H1O.d.mts +128 -0
  148. package/dist/dsr-pQzQ3H1O.d.ts +128 -0
  149. package/dist/dsr-whPkiI0_.d.mts +14 -0
  150. package/dist/dsr.d.mts +192 -0
  151. package/dist/dsr.d.ts +192 -0
  152. package/dist/dsr.js +2 -0
  153. package/dist/dsr.js.map +1 -0
  154. package/dist/dsr.mjs +2 -0
  155. package/dist/dsr.mjs.map +1 -0
  156. package/dist/hooks.d.mts +17 -0
  157. package/dist/hooks.d.ts +17 -0
  158. package/dist/hooks.js +2 -0
  159. package/dist/hooks.js.map +1 -0
  160. package/dist/hooks.mjs +2 -0
  161. package/dist/hooks.mjs.map +1 -0
  162. package/dist/index.d.mts +31 -448
  163. package/dist/index.d.ts +31 -448
  164. package/dist/index.js +1 -190
  165. package/dist/index.js.map +1 -1
  166. package/dist/index.mjs +1 -190
  167. package/dist/index.mjs.map +1 -1
  168. package/dist/lawful-basis-CWtvDG1x.d.mts +112 -0
  169. package/dist/lawful-basis-CWtvDG1x.d.ts +112 -0
  170. package/dist/lawful-basis-D-oXFizg.d.mts +57 -0
  171. package/dist/lawful-basis-v04AhbK2.d.ts +57 -0
  172. package/dist/lawful-basis.d.mts +55 -0
  173. package/dist/lawful-basis.d.ts +55 -0
  174. package/dist/lawful-basis.js +2 -0
  175. package/dist/lawful-basis.js.map +1 -0
  176. package/dist/lawful-basis.mjs +2 -0
  177. package/dist/lawful-basis.mjs.map +1 -0
  178. package/dist/policy.d.mts +195 -0
  179. package/dist/policy.d.ts +195 -0
  180. package/dist/policy.js +2 -0
  181. package/dist/policy.js.map +1 -0
  182. package/dist/policy.mjs +2 -0
  183. package/dist/policy.mjs.map +1 -0
  184. package/dist/privacy-9FcJceMr.d.mts +15 -0
  185. package/dist/privacy-BXz7O2ej.d.ts +15 -0
  186. package/dist/privacy-Ca6te9Ir.d.mts +138 -0
  187. package/dist/privacy-Ca6te9Ir.d.ts +138 -0
  188. package/dist/ropa-BebGfqKQ.d.ts +200 -0
  189. package/dist/ropa-Rb4dsFSz.d.mts +200 -0
  190. package/dist/ropa.d.mts +45 -0
  191. package/dist/ropa.d.ts +45 -0
  192. package/dist/ropa.js +2 -0
  193. package/dist/ropa.js.map +1 -0
  194. package/dist/ropa.mjs +2 -0
  195. package/dist/ropa.mjs.map +1 -0
  196. package/dist/unstyled.d.mts +4 -4
  197. package/dist/unstyled.d.ts +4 -4
  198. package/dist/unstyled.js +1 -1
  199. package/dist/unstyled.js.map +1 -1
  200. package/dist/unstyled.mjs +1 -1
  201. package/dist/unstyled.mjs.map +1 -1
  202. package/dist/useBreach-DRKnexsk.d.mts +99 -0
  203. package/dist/useBreach-DuT0N0K1.d.ts +99 -0
  204. package/dist/useConsent-D0pAfTlb.d.ts +65 -0
  205. package/dist/useConsent-DOt2Njst.d.mts +65 -0
  206. package/dist/useCrossBorderTransfer-D4FQYfFt.d.ts +66 -0
  207. package/dist/useCrossBorderTransfer-TVnY8_UX.d.mts +66 -0
  208. package/dist/useDPIA-DFDHBLSa.d.ts +94 -0
  209. package/dist/useDPIA-FqPofFaV.d.mts +94 -0
  210. package/dist/useDSR-DAqqOBXb.d.ts +74 -0
  211. package/dist/useDSR-OXM5Q9rf.d.mts +74 -0
  212. package/dist/useLawfulBasis-DNQ8YszQ.d.mts +68 -0
  213. package/dist/useLawfulBasis-RILM_xsx.d.ts +68 -0
  214. package/dist/usePrivacyPolicy-CfySfBLS.d.ts +89 -0
  215. package/dist/usePrivacyPolicy-Dit2sFuV.d.mts +89 -0
  216. package/dist/useROPA-Bcs6cRdi.d.ts +64 -0
  217. package/dist/useROPA-nmcSiUYv.d.mts +64 -0
  218. package/package.json +162 -35
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/dpia.ts"],"names":["assessDPIARisk","dpiaResult","riskCounts","highestRiskScore","unmitigatedHighRisks","risk","overallRiskLevel","requiresConsultation","canProceed","recommendations"],"mappings":"aAOO,SAASA,CAAAA,CAAeC,CAAAA,CAK7B,CAEA,IAAMC,EAAa,CACjB,GAAA,CAAK,CAAA,CACL,MAAA,CAAQ,CAAA,CACR,IAAA,CAAM,CAAA,CACN,QAAA,CAAU,CACZ,CAAA,CAGIC,CAAAA,CAAmB,CAAA,CAGjBC,CAAAA,CAAmC,EAAC,CAG1CH,CAAAA,CAAW,KAAA,CAAM,QAAQI,CAAAA,EAAQ,CAE/BH,CAAAA,CAAWG,CAAAA,CAAK,KAAK,CAAA,EAAA,CAGjBA,CAAAA,CAAK,KAAA,CAAQF,IACfA,CAAAA,CAAmBE,CAAAA,CAAK,KAAA,CAAA,CAAA,CAIrBA,CAAAA,CAAK,KAAA,GAAU,MAAA,EAAUA,CAAAA,CAAK,KAAA,GAAU,aAAe,CAACA,CAAAA,CAAK,SAAA,EAChED,CAAAA,CAAqB,IAAA,CAAKC,CAAI,EAElC,CAAC,EAGD,IAAIC,CAAAA,CAEAJ,CAAAA,CAAW,QAAA,CAAW,CAAA,CACxBI,CAAAA,CAAmB,UAAA,CACVJ,CAAAA,CAAW,KAAO,CAAA,EAAMA,CAAAA,CAAW,IAAA,CAAO,CAAA,EAAKA,CAAAA,CAAW,MAAA,CAAS,CAAA,CAC5EI,CAAAA,CAAmB,OACVJ,CAAAA,CAAW,IAAA,CAAO,CAAA,EAAKA,CAAAA,CAAW,MAAA,CAAS,CAAA,CACpDI,CAAAA,CAAmB,QAAA,CAEnBA,EAAmB,KAAA,CAKrB,IAAMC,CAAAA,CAAuBD,CAAAA,GAAqB,MAAA,EAAUA,CAAAA,GAAqB,UAAA,CAI3EE,CAAAA,CAAaJ,EAAqB,MAAA,GAAW,CAAA,CAG7CK,CAAAA,CAA4B,EAAC,CAEnC,OAAIL,CAAAA,CAAqB,MAAA,CAAS,GAChCK,CAAAA,CAAgB,IAAA,CACd,CAAA,8DAAA,EACEL,CAAAA,CAAqB,GAAA,CAAIC,CAAAA,EAAQA,CAAAA,CAAK,WAAW,EAAE,IAAA,CAAK,IAAI,CAC9D,CAAA,CACF,CAAA,CAGEE,CAAAA,EACFE,CAAAA,CAAgB,IAAA,CACd,6IACF,CAAA,CAGEP,CAAAA,CAAW,MAAA,CAAS,CAAA,EACtBO,CAAAA,CAAgB,IAAA,CACd,8EACF,CAAA,CAGEH,IAAqB,KAAA,CACvBG,CAAAA,CAAgB,IAAA,CACd,wGACF,CAAA,CAEAA,CAAAA,CAAgB,IAAA,CACd,uFACF,EAGK,CACL,gBAAA,CAAAH,CAAAA,CACA,oBAAA,CAAAC,CAAAA,CACA,UAAA,CAAAC,CAAAA,CACA,eAAA,CAAAC,CACF,CACF","file":"chunk-SSGJREE3.js","sourcesContent":["import { DPIAResult, DPIARisk } from '../types/dpia';\n\n/**\n * Assesses the risk level of a DPIA based on the identified risks\n * @param dpiaResult The DPIA result containing risks to assess\n * @returns Assessment result with overall risk level and recommendations\n */\nexport function assessDPIARisk(dpiaResult: DPIAResult): {\n overallRiskLevel: 'low' | 'medium' | 'high' | 'critical';\n requiresConsultation: boolean;\n canProceed: boolean;\n recommendations: string[];\n} {\n // Count risks by level\n const riskCounts = {\n low: 0,\n medium: 0,\n high: 0,\n critical: 0\n };\n \n // Calculate the highest risk score\n let highestRiskScore = 0;\n \n // Track unmitigated high/critical risks\n const unmitigatedHighRisks: DPIARisk[] = [];\n \n // Analyze each risk\n dpiaResult.risks.forEach(risk => {\n // Count by level\n riskCounts[risk.level]++;\n \n // Track highest score\n if (risk.score > highestRiskScore) {\n highestRiskScore = risk.score;\n }\n \n // Track unmitigated high/critical risks\n if ((risk.level === 'high' || risk.level === 'critical') && !risk.mitigated) {\n unmitigatedHighRisks.push(risk);\n }\n });\n \n // Determine overall risk level\n let overallRiskLevel: 'low' | 'medium' | 'high' | 'critical';\n \n if (riskCounts.critical > 0) {\n overallRiskLevel = 'critical';\n } else if (riskCounts.high > 2 || (riskCounts.high > 0 && riskCounts.medium > 3)) {\n overallRiskLevel = 'high';\n } else if (riskCounts.high > 0 || riskCounts.medium > 1) {\n overallRiskLevel = 'medium';\n } else {\n overallRiskLevel = 'low';\n }\n \n // Determine if NDPC consultation is required\n // Under NDPA Section 39, prior consultation with the NDPC is required when residual risk is high\n const requiresConsultation = overallRiskLevel === 'high' || overallRiskLevel === 'critical';\n \n // Determine if processing can proceed\n // Processing can proceed if all high/critical risks are mitigated\n const canProceed = unmitigatedHighRisks.length === 0;\n \n // Generate recommendations\n const recommendations: string[] = [];\n \n if (unmitigatedHighRisks.length > 0) {\n recommendations.push(\n `Mitigate the following high/critical risks before proceeding: ${\n unmitigatedHighRisks.map(risk => risk.description).join(', ')\n }`\n );\n }\n \n if (requiresConsultation) {\n recommendations.push(\n 'Consult with the NDPC (Nigeria Data Protection Commission) before proceeding with this processing activity, as required by NDPA Section 39.'\n );\n }\n \n if (riskCounts.medium > 0) {\n recommendations.push(\n 'Implement additional safeguards to reduce medium-level risks where possible.'\n );\n }\n \n if (overallRiskLevel !== 'low') {\n recommendations.push(\n 'Schedule a review of this DPIA in 6 months to reassess risks and effectiveness of mitigation measures.'\n );\n } else {\n recommendations.push(\n 'Schedule a review of this DPIA in 12 months as part of regular compliance activities.'\n );\n }\n \n return {\n overallRiskLevel,\n requiresConsultation,\n canProceed,\n recommendations\n };\n}\n"]}
@@ -0,0 +1,4 @@
1
+ 'use strict';var l=["consent","contract","legal_obligation","vital_interests","public_interest","legitimate_interests"];function h(e){let s=[];return (!e.id||e.id.trim()==="")&&s.push("Record ID is required."),(!e.name||e.name.trim()==="")&&s.push("Processing activity name is required."),(!e.description||e.description.trim()==="")&&s.push("Processing description is required."),e.controllerDetails?((!e.controllerDetails.name||e.controllerDetails.name.trim()==="")&&s.push("Controller name is required."),(!e.controllerDetails.contact||e.controllerDetails.contact.trim()==="")&&s.push("Controller contact is required."),(!e.controllerDetails.address||e.controllerDetails.address.trim()==="")&&s.push("Controller address is required.")):s.push("Controller details are required."),(!e.lawfulBasis||!l.includes(e.lawfulBasis))&&s.push("A valid lawful basis must be specified (NDPA Section 25)."),(!e.lawfulBasisJustification||e.lawfulBasisJustification.trim()==="")&&s.push("Lawful basis justification is required to demonstrate compliance."),(!e.purposes||e.purposes.length===0)&&s.push("At least one processing purpose must be specified."),(!e.dataCategories||e.dataCategories.length===0)&&s.push("At least one data category must be specified."),(!e.dataSubjectCategories||e.dataSubjectCategories.length===0)&&s.push("At least one data subject category must be specified."),(!e.recipients||e.recipients.length===0)&&s.push("At least one recipient or category of recipients must be specified."),(!e.retentionPeriod||e.retentionPeriod.trim()==="")&&s.push("Retention period must be specified."),(!e.securityMeasures||e.securityMeasures.length===0)&&s.push("At least one security measure must be documented."),e.dataSource||s.push("Data source must be specified."),e.dataSource==="third_party"&&(!e.thirdPartySourceDetails||e.thirdPartySourceDetails.trim()==="")&&s.push('Third-party source details are required when data source is "third_party".'),e.automatedDecisionMaking&&(!e.automatedDecisionMakingDetails||e.automatedDecisionMakingDetails.trim()==="")&&s.push("Automated decision-making details are required when automated decision-making is involved."),e.dpiaRequired&&(!e.dpiaReference||e.dpiaReference.trim()==="")&&s.push("DPIA reference is required when DPIA is marked as required."),{valid:s.length===0,errors:s}}function D(e){let s=l.reduce((a,u)=>(a[u]=0,a),{}),o=0,t=0,i=0,n=0,r=0,p=[],d={},m=Date.now();for(let a of e.records)a.lawfulBasis&&l.includes(a.lawfulBasis)&&s[a.lawfulBasis]++,a.status==="active"&&o++,a.sensitiveDataCategories&&a.sensitiveDataCategories.length>0&&t++,a.crossBorderTransfers&&a.crossBorderTransfers.length>0&&i++,a.dpiaRequired&&n++,a.automatedDecisionMaking&&r++,a.nextReviewDate&&a.nextReviewDate<=m&&p.push(a),a.department&&(d[a.department]=(d[a.department]||0)+1);let g=Object.entries(d).map(([a,u])=>({department:a,count:u})).sort((a,u)=>u.count-a.count).slice(0,10);return {totalRecords:e.records.length,activeRecords:o,byLawfulBasis:s,sensitiveDataRecords:t,crossBorderRecords:i,dpiaRequiredRecords:n,automatedDecisionRecords:r,recordsDueForReview:p,topDepartments:g,lastUpdated:e.lastUpdated}}function f(e){return e.includes(",")||e.includes('"')||e.includes(`
2
+ `)||e.includes("\r")?`"${e.replace(/"/g,'""')}"`:e}function c(e){return e?new Date(e).toISOString():""}function R(e){let s=["ID","Name","Description","Controller Name","Controller Contact","Lawful Basis","Lawful Basis Justification","Purposes","Data Categories","Sensitive Data Categories","Data Subject Categories","Recipients","Cross-Border Transfers","Retention Period","Security Measures","Data Source","DPIA Required","DPIA Reference","Automated Decision-Making","Status","Department","Systems Used","Created At","Updated At","Last Reviewed At","Next Review Date"],o=e.records.map(i=>{let n=i.crossBorderTransfers?i.crossBorderTransfers.map(r=>`${r.destinationCountry} (${r.transferMechanism}: ${r.safeguards})`).join("; "):"";return [i.id,i.name,i.description,i.controllerDetails.name,i.controllerDetails.contact,i.lawfulBasis,i.lawfulBasisJustification,i.purposes.join("; "),i.dataCategories.join("; "),(i.sensitiveDataCategories||[]).join("; "),i.dataSubjectCategories.join("; "),i.recipients.join("; "),n,i.retentionPeriod,i.securityMeasures.join("; "),i.dataSource,i.dpiaRequired?"Yes":"No",i.dpiaReference||"",i.automatedDecisionMaking?"Yes":"No",i.status,i.department||"",(i.systemsUsed||[]).join("; "),c(i.createdAt),c(i.updatedAt),c(i.lastReviewedAt),c(i.nextReviewDate)].map(r=>f(String(r)))});return [s.map(i=>f(i)).join(","),...o.map(i=>i.join(","))].join(`
3
+ `)}function w(e){let s=[],o=Date.now();for(let t of e.records){let i=[];if((!t.lawfulBasisJustification||t.lawfulBasisJustification.trim()==="")&&i.push("Missing lawful basis justification (NDPA Section 25 requires documented justification)."),(!t.retentionPeriod||t.retentionPeriod.trim()==="")&&i.push("Missing retention period (data must not be kept longer than necessary)."),(!t.securityMeasures||t.securityMeasures.length===0)&&i.push("No security measures documented (NDPA requires appropriate technical and organizational measures)."),t.nextReviewDate&&t.nextReviewDate<=o){let n=Math.ceil((o-t.nextReviewDate)/864e5);i.push(`Review is overdue by ${n} day${n!==1?"s":""}.`);}if(t.dpiaRequired&&(!t.dpiaReference||t.dpiaReference.trim()==="")&&i.push("DPIA is required but no reference to a completed DPIA was provided."),t.automatedDecisionMaking&&(!t.automatedDecisionMakingDetails||t.automatedDecisionMakingDetails.trim()==="")&&i.push("Automated decision-making is flagged but no details are documented."),t.crossBorderTransfers)for(let n of t.crossBorderTransfers)(!n.safeguards||n.safeguards.trim()==="")&&i.push(`Cross-border transfer to ${n.destinationCountry} is missing safeguard documentation.`),(!n.transferMechanism||n.transferMechanism.trim()==="")&&i.push(`Cross-border transfer to ${n.destinationCountry} is missing transfer mechanism.`);t.dataSource==="third_party"&&(!t.thirdPartySourceDetails||t.thirdPartySourceDetails.trim()==="")&&i.push('Data source is "third_party" but no source details are provided.'),(!t.purposes||t.purposes.length===0)&&i.push("No processing purposes specified."),(!t.recipients||t.recipients.length===0)&&i.push("No recipients or categories of recipients specified."),i.length>0&&s.push({recordId:t.id,recordName:t.name,gaps:i});}return s}exports.a=h;exports.b=D;exports.c=R;exports.d=w;//# sourceMappingURL=chunk-SWF3YVE5.js.map
4
+ //# sourceMappingURL=chunk-SWF3YVE5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/ropa.ts"],"names":["ALL_LAWFUL_BASES","validateProcessingRecord","record","errors","generateROPASummary","ropa","byLawfulBasis","acc","basis","activeRecords","sensitiveDataRecords","crossBorderRecords","dpiaRequiredRecords","automatedDecisionRecords","recordsDueForReview","departmentCounts","now","topDepartments","department","count","b","escapeCSVField","value","formatTimestamp","timestamp","exportROPAToCSV","headers","rows","crossBorderSummary","t","field","h","row","identifyComplianceGaps","gaps","recordGaps","overdueBy","transfer"],"mappings":"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","file":"chunk-SWF3YVE5.js","sourcesContent":["import type { LawfulBasis } from '../types/lawful-basis';\nimport type {\n ProcessingRecord,\n RecordOfProcessingActivities,\n ROPASummary,\n} from '../types/ropa';\n\n/**\n * Compliance gap found in a processing record\n */\nexport interface ROPAComplianceGap {\n recordId: string;\n recordName: string;\n gaps: string[];\n}\n\n/**\n * Validation result for a processing record\n */\nexport interface ROPAValidationResult {\n valid: boolean;\n errors: string[];\n}\n\nconst ALL_LAWFUL_BASES: LawfulBasis[] = [\n 'consent',\n 'contract',\n 'legal_obligation',\n 'vital_interests',\n 'public_interest',\n 'legitimate_interests',\n];\n\n/**\n * Validates a processing record to ensure all required fields are present\n * and properly filled per NDPA 2023 requirements.\n *\n * @param record - The processing record to validate\n * @returns Validation result with any errors found\n */\nexport function validateProcessingRecord(\n record: ProcessingRecord\n): ROPAValidationResult {\n const errors: string[] = [];\n\n if (!record.id || record.id.trim() === '') {\n errors.push('Record ID is required.');\n }\n\n if (!record.name || record.name.trim() === '') {\n errors.push('Processing activity name is required.');\n }\n\n if (!record.description || record.description.trim() === '') {\n errors.push('Processing description is required.');\n }\n\n if (!record.controllerDetails) {\n errors.push('Controller details are required.');\n } else {\n if (!record.controllerDetails.name || record.controllerDetails.name.trim() === '') {\n errors.push('Controller name is required.');\n }\n if (!record.controllerDetails.contact || record.controllerDetails.contact.trim() === '') {\n errors.push('Controller contact is required.');\n }\n if (!record.controllerDetails.address || record.controllerDetails.address.trim() === '') {\n errors.push('Controller address is required.');\n }\n }\n\n if (!record.lawfulBasis || !ALL_LAWFUL_BASES.includes(record.lawfulBasis)) {\n errors.push('A valid lawful basis must be specified (NDPA Section 25).');\n }\n\n if (!record.lawfulBasisJustification || record.lawfulBasisJustification.trim() === '') {\n errors.push('Lawful basis justification is required to demonstrate compliance.');\n }\n\n if (!record.purposes || record.purposes.length === 0) {\n errors.push('At least one processing purpose must be specified.');\n }\n\n if (!record.dataCategories || record.dataCategories.length === 0) {\n errors.push('At least one data category must be specified.');\n }\n\n if (!record.dataSubjectCategories || record.dataSubjectCategories.length === 0) {\n errors.push('At least one data subject category must be specified.');\n }\n\n if (!record.recipients || record.recipients.length === 0) {\n errors.push('At least one recipient or category of recipients must be specified.');\n }\n\n if (!record.retentionPeriod || record.retentionPeriod.trim() === '') {\n errors.push('Retention period must be specified.');\n }\n\n if (!record.securityMeasures || record.securityMeasures.length === 0) {\n errors.push('At least one security measure must be documented.');\n }\n\n if (!record.dataSource) {\n errors.push('Data source must be specified.');\n }\n\n if (\n record.dataSource === 'third_party' &&\n (!record.thirdPartySourceDetails || record.thirdPartySourceDetails.trim() === '')\n ) {\n errors.push('Third-party source details are required when data source is \"third_party\".');\n }\n\n if (\n record.automatedDecisionMaking &&\n (!record.automatedDecisionMakingDetails || record.automatedDecisionMakingDetails.trim() === '')\n ) {\n errors.push(\n 'Automated decision-making details are required when automated decision-making is involved.'\n );\n }\n\n if (\n record.dpiaRequired &&\n (!record.dpiaReference || record.dpiaReference.trim() === '')\n ) {\n errors.push('DPIA reference is required when DPIA is marked as required.');\n }\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Generates a summary of the Record of Processing Activities.\n * Provides statistics and identifies records that are due for review.\n *\n * @param ropa - The full Record of Processing Activities\n * @returns Summary statistics for the ROPA\n */\nexport function generateROPASummary(\n ropa: RecordOfProcessingActivities\n): ROPASummary {\n const byLawfulBasis = ALL_LAWFUL_BASES.reduce(\n (acc, basis) => {\n acc[basis] = 0;\n return acc;\n },\n {} as Record<LawfulBasis, number>\n );\n\n let activeRecords = 0;\n let sensitiveDataRecords = 0;\n let crossBorderRecords = 0;\n let dpiaRequiredRecords = 0;\n let automatedDecisionRecords = 0;\n const recordsDueForReview: ProcessingRecord[] = [];\n const departmentCounts: Record<string, number> = {};\n\n const now = Date.now();\n\n for (const record of ropa.records) {\n // Count by lawful basis\n if (record.lawfulBasis && ALL_LAWFUL_BASES.includes(record.lawfulBasis)) {\n byLawfulBasis[record.lawfulBasis]++;\n }\n\n // Count active records\n if (record.status === 'active') {\n activeRecords++;\n }\n\n // Count sensitive data records\n if (\n record.sensitiveDataCategories &&\n record.sensitiveDataCategories.length > 0\n ) {\n sensitiveDataRecords++;\n }\n\n // Count cross-border transfer records\n if (record.crossBorderTransfers && record.crossBorderTransfers.length > 0) {\n crossBorderRecords++;\n }\n\n // Count DPIA-required records\n if (record.dpiaRequired) {\n dpiaRequiredRecords++;\n }\n\n // Count automated decision-making records\n if (record.automatedDecisionMaking) {\n automatedDecisionRecords++;\n }\n\n // Identify records due for review\n if (record.nextReviewDate && record.nextReviewDate <= now) {\n recordsDueForReview.push(record);\n }\n\n // Track department counts\n if (record.department) {\n departmentCounts[record.department] =\n (departmentCounts[record.department] || 0) + 1;\n }\n }\n\n // Sort departments by count and take the top ones\n const topDepartments = Object.entries(departmentCounts)\n .map(([department, count]) => ({ department, count }))\n .sort((a, b) => b.count - a.count)\n .slice(0, 10);\n\n return {\n totalRecords: ropa.records.length,\n activeRecords,\n byLawfulBasis,\n sensitiveDataRecords,\n crossBorderRecords,\n dpiaRequiredRecords,\n automatedDecisionRecords,\n recordsDueForReview,\n topDepartments,\n lastUpdated: ropa.lastUpdated,\n };\n}\n\n/**\n * Escapes a string value for safe inclusion in CSV output\n */\nfunction escapeCSVField(value: string): string {\n if (\n value.includes(',') ||\n value.includes('\"') ||\n value.includes('\\n') ||\n value.includes('\\r')\n ) {\n return `\"${value.replace(/\"/g, '\"\"')}\"`;\n }\n return value;\n}\n\n/**\n * Formats a timestamp as an ISO date string for CSV export\n */\nfunction formatTimestamp(timestamp: number | undefined): string {\n if (!timestamp) return '';\n return new Date(timestamp).toISOString();\n}\n\n/**\n * Exports the Record of Processing Activities to a CSV string.\n * The CSV includes all key fields from each processing record.\n *\n * @param ropa - The full Record of Processing Activities\n * @returns CSV-formatted string\n */\nexport function exportROPAToCSV(ropa: RecordOfProcessingActivities): string {\n const headers = [\n 'ID',\n 'Name',\n 'Description',\n 'Controller Name',\n 'Controller Contact',\n 'Lawful Basis',\n 'Lawful Basis Justification',\n 'Purposes',\n 'Data Categories',\n 'Sensitive Data Categories',\n 'Data Subject Categories',\n 'Recipients',\n 'Cross-Border Transfers',\n 'Retention Period',\n 'Security Measures',\n 'Data Source',\n 'DPIA Required',\n 'DPIA Reference',\n 'Automated Decision-Making',\n 'Status',\n 'Department',\n 'Systems Used',\n 'Created At',\n 'Updated At',\n 'Last Reviewed At',\n 'Next Review Date',\n ];\n\n const rows = ropa.records.map((record) => {\n const crossBorderSummary = record.crossBorderTransfers\n ? record.crossBorderTransfers\n .map(\n (t) =>\n `${t.destinationCountry} (${t.transferMechanism}: ${t.safeguards})`\n )\n .join('; ')\n : '';\n\n return [\n record.id,\n record.name,\n record.description,\n record.controllerDetails.name,\n record.controllerDetails.contact,\n record.lawfulBasis,\n record.lawfulBasisJustification,\n record.purposes.join('; '),\n record.dataCategories.join('; '),\n (record.sensitiveDataCategories || []).join('; '),\n record.dataSubjectCategories.join('; '),\n record.recipients.join('; '),\n crossBorderSummary,\n record.retentionPeriod,\n record.securityMeasures.join('; '),\n record.dataSource,\n record.dpiaRequired ? 'Yes' : 'No',\n record.dpiaReference || '',\n record.automatedDecisionMaking ? 'Yes' : 'No',\n record.status,\n record.department || '',\n (record.systemsUsed || []).join('; '),\n formatTimestamp(record.createdAt),\n formatTimestamp(record.updatedAt),\n formatTimestamp(record.lastReviewedAt),\n formatTimestamp(record.nextReviewDate),\n ].map((field) => escapeCSVField(String(field)));\n });\n\n const csvLines = [\n headers.map((h) => escapeCSVField(h)).join(','),\n ...rows.map((row) => row.join(',')),\n ];\n\n return csvLines.join('\\n');\n}\n\n/**\n * Identifies compliance gaps in the Record of Processing Activities.\n * Finds records that are missing required information per NDPA 2023.\n *\n * @param ropa - The full Record of Processing Activities\n * @returns Array of compliance gaps grouped by record\n */\nexport function identifyComplianceGaps(\n ropa: RecordOfProcessingActivities\n): ROPAComplianceGap[] {\n const gaps: ROPAComplianceGap[] = [];\n const now = Date.now();\n\n for (const record of ropa.records) {\n const recordGaps: string[] = [];\n\n // Check lawful basis justification\n if (\n !record.lawfulBasisJustification ||\n record.lawfulBasisJustification.trim() === ''\n ) {\n recordGaps.push(\n 'Missing lawful basis justification (NDPA Section 25 requires documented justification).'\n );\n }\n\n // Check retention period\n if (!record.retentionPeriod || record.retentionPeriod.trim() === '') {\n recordGaps.push(\n 'Missing retention period (data must not be kept longer than necessary).'\n );\n }\n\n // Check security measures\n if (!record.securityMeasures || record.securityMeasures.length === 0) {\n recordGaps.push(\n 'No security measures documented (NDPA requires appropriate technical and organizational measures).'\n );\n }\n\n // Check for overdue review\n if (record.nextReviewDate && record.nextReviewDate <= now) {\n const overdueBy = Math.ceil(\n (now - record.nextReviewDate) / (24 * 60 * 60 * 1000)\n );\n recordGaps.push(\n `Review is overdue by ${overdueBy} day${overdueBy !== 1 ? 's' : ''}.`\n );\n }\n\n // Check DPIA reference when required\n if (\n record.dpiaRequired &&\n (!record.dpiaReference || record.dpiaReference.trim() === '')\n ) {\n recordGaps.push(\n 'DPIA is required but no reference to a completed DPIA was provided.'\n );\n }\n\n // Check automated decision-making documentation\n if (\n record.automatedDecisionMaking &&\n (!record.automatedDecisionMakingDetails ||\n record.automatedDecisionMakingDetails.trim() === '')\n ) {\n recordGaps.push(\n 'Automated decision-making is flagged but no details are documented.'\n );\n }\n\n // Check cross-border transfer safeguards\n if (record.crossBorderTransfers) {\n for (const transfer of record.crossBorderTransfers) {\n if (!transfer.safeguards || transfer.safeguards.trim() === '') {\n recordGaps.push(\n `Cross-border transfer to ${transfer.destinationCountry} is missing safeguard documentation.`\n );\n }\n if (\n !transfer.transferMechanism ||\n transfer.transferMechanism.trim() === ''\n ) {\n recordGaps.push(\n `Cross-border transfer to ${transfer.destinationCountry} is missing transfer mechanism.`\n );\n }\n }\n }\n\n // Check third-party source details\n if (\n record.dataSource === 'third_party' &&\n (!record.thirdPartySourceDetails ||\n record.thirdPartySourceDetails.trim() === '')\n ) {\n recordGaps.push(\n 'Data source is \"third_party\" but no source details are provided.'\n );\n }\n\n // Check missing purposes\n if (!record.purposes || record.purposes.length === 0) {\n recordGaps.push('No processing purposes specified.');\n }\n\n // Check missing recipients\n if (!record.recipients || record.recipients.length === 0) {\n recordGaps.push('No recipients or categories of recipients specified.');\n }\n\n if (recordGaps.length > 0) {\n gaps.push({\n recordId: record.id,\n recordName: record.name,\n gaps: recordGaps,\n });\n }\n }\n\n return gaps;\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import {b as b$1,c,d}from'./chunk-PYEX7DFR.mjs';import {b,a}from'./chunk-WWT2ZSNU.mjs';import {useState,useCallback}from'react';function w({initialData:R,onRecordAdd:n,onRecordUpdate:c$1,onRecordArchive:d$1}){let[s,p]=useState(R),O=useCallback(e=>{p(t=>b(a({},t),{records:[...t.records,e],lastUpdated:Date.now()})),n==null||n(e);},[n]),l=useCallback((e,t)=>{p(o=>b(a({},o),{records:o.records.map(g=>g.id===e?b(a(a({},g),t),{updatedAt:Date.now()}):g),lastUpdated:Date.now()})),c$1==null||c$1(e,t);},[c$1]),f=useCallback(e=>{p(t=>b(a({},t),{records:t.records.map(o=>o.id===e?b(a({},o),{status:"archived",updatedAt:Date.now()}):o),lastUpdated:Date.now()})),d$1==null||d$1(e);},[d$1]),A=useCallback(e=>s.records.find(t=>t.id===e),[s.records]),y=useCallback(()=>b$1(s),[s]),C=useCallback(()=>c(s),[s]),S=useCallback(()=>d(s),[s]);return {ropa:s,addRecord:O,updateRecord:l,archiveRecord:f,getRecord:A,getSummary:y,exportCSV:C,getComplianceGaps:S}}export{w as a};//# sourceMappingURL=chunk-T44JQT2O.mjs.map
2
+ //# sourceMappingURL=chunk-T44JQT2O.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/hooks/useROPA.ts"],"names":["useROPA","initialData","onRecordAdd","onRecordUpdate","onRecordArchive","ropa","setROPA","useState","addRecord","useCallback","record","prev","__spreadProps","__spreadValues","updateRecord","id","updates","archiveRecord","getRecord","getSummary","generateROPASummary","exportCSV","exportROPAToCSV","getComplianceGaps","identifyComplianceGaps"],"mappings":"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","file":"chunk-T44JQT2O.mjs","sourcesContent":["import { useState, useCallback, useMemo } from 'react';\nimport type {\n ProcessingRecord,\n RecordOfProcessingActivities,\n ROPASummary,\n} from '../types/ropa';\nimport {\n generateROPASummary,\n exportROPAToCSV,\n identifyComplianceGaps,\n type ROPAComplianceGap,\n} from '../utils/ropa';\n\nexport interface UseROPAOptions {\n /**\n * Initial ROPA state\n */\n initialData: RecordOfProcessingActivities;\n\n /**\n * Callback when a record is added\n */\n onRecordAdd?: (record: ProcessingRecord) => void;\n\n /**\n * Callback when a record is updated\n */\n onRecordUpdate?: (id: string, updates: Partial<ProcessingRecord>) => void;\n\n /**\n * Callback when a record is archived\n */\n onRecordArchive?: (id: string) => void;\n}\n\nexport interface UseROPAReturn {\n /**\n * Current state of the Record of Processing Activities\n */\n ropa: RecordOfProcessingActivities;\n\n /**\n * Add a new processing record\n */\n addRecord: (record: ProcessingRecord) => void;\n\n /**\n * Update an existing processing record\n */\n updateRecord: (id: string, updates: Partial<ProcessingRecord>) => void;\n\n /**\n * Archive a processing record by setting its status to 'archived'\n */\n archiveRecord: (id: string) => void;\n\n /**\n * Get a single processing record by ID\n */\n getRecord: (id: string) => ProcessingRecord | undefined;\n\n /**\n * Get a summary of the ROPA including statistics\n */\n getSummary: () => ROPASummary;\n\n /**\n * Export the ROPA as a CSV string\n */\n exportCSV: () => string;\n\n /**\n * Identify compliance gaps across all records\n */\n getComplianceGaps: () => ROPAComplianceGap[];\n}\n\n/**\n * Hook for managing a Record of Processing Activities (ROPA)\n * in compliance with NDPA 2023 requirements.\n *\n * Provides state management and utility functions for maintaining\n * a comprehensive register of all data processing activities.\n */\nexport function useROPA({\n initialData,\n onRecordAdd,\n onRecordUpdate,\n onRecordArchive,\n}: UseROPAOptions): UseROPAReturn {\n const [ropa, setROPA] = useState<RecordOfProcessingActivities>(initialData);\n\n const addRecord = useCallback(\n (record: ProcessingRecord) => {\n setROPA((prev) => ({\n ...prev,\n records: [...prev.records, record],\n lastUpdated: Date.now(),\n }));\n onRecordAdd?.(record);\n },\n [onRecordAdd]\n );\n\n const updateRecord = useCallback(\n (id: string, updates: Partial<ProcessingRecord>) => {\n setROPA((prev) => ({\n ...prev,\n records: prev.records.map((record) =>\n record.id === id\n ? { ...record, ...updates, updatedAt: Date.now() }\n : record\n ),\n lastUpdated: Date.now(),\n }));\n onRecordUpdate?.(id, updates);\n },\n [onRecordUpdate]\n );\n\n const archiveRecord = useCallback(\n (id: string) => {\n setROPA((prev) => ({\n ...prev,\n records: prev.records.map((record) =>\n record.id === id\n ? { ...record, status: 'archived' as const, updatedAt: Date.now() }\n : record\n ),\n lastUpdated: Date.now(),\n }));\n onRecordArchive?.(id);\n },\n [onRecordArchive]\n );\n\n const getRecord = useCallback(\n (id: string): ProcessingRecord | undefined => {\n return ropa.records.find((record) => record.id === id);\n },\n [ropa.records]\n );\n\n const getSummary = useCallback((): ROPASummary => {\n return generateROPASummary(ropa);\n }, [ropa]);\n\n const exportCSV = useCallback((): string => {\n return exportROPAToCSV(ropa);\n }, [ropa]);\n\n const getComplianceGaps = useCallback((): ROPAComplianceGap[] => {\n return identifyComplianceGaps(ropa);\n }, [ropa]);\n\n return {\n ropa,\n addRecord,\n updateRecord,\n archiveRecord,\n getRecord,\n getSummary,\n exportCSV,\n getComplianceGaps,\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';function o(i){let t=[],e=[];return i.id||t.push("Activity ID is required."),(!i.name||i.name.trim()==="")&&t.push("Activity name is required."),(!i.description||i.description.trim()==="")&&t.push("Activity description is required."),i.lawfulBasis||t.push("Lawful basis is required per NDPA Section 25."),(!i.lawfulBasisJustification||i.lawfulBasisJustification.trim()==="")&&t.push("Justification for the lawful basis is required."),(!i.dataCategories||i.dataCategories.length===0)&&t.push("At least one data category must be specified."),(!i.dataSubjectCategories||i.dataSubjectCategories.length===0)&&t.push("At least one data subject category must be specified."),(!i.purposes||i.purposes.length===0)&&t.push("At least one processing purpose must be specified."),(!i.retentionPeriod||i.retentionPeriod.trim()==="")&&t.push("Data retention period is required."),i.lawfulBasis==="legitimate_interests"&&(!i.lawfulBasisJustification||i.lawfulBasisJustification.trim().length<20)&&t.push("Legitimate interests requires a detailed Legitimate Interest Assessment (LIA) justification (NDPA Section 25(1)(f))."),i.involvesSensitiveData&&!i.sensitiveDataCondition&&t.push("Processing sensitive personal data requires specifying a condition under NDPA Section 27."),i.dpoApproval?i.dpoApproval.approved||e.push("Activity has a DPO review but has not been approved."):e.push("Activity has not been approved by the DPO."),i.reviewDate?i.reviewDate<Date.now()&&e.push("Activity is overdue for review."):e.push("No review date has been set. Regular reviews are recommended."),i.retentionJustification||e.push("Consider documenting the justification for the retention period."),i.crossBorderTransfer&&(!i.recipients||i.recipients.length===0)&&e.push("Cross-border transfer is indicated but no recipients are listed. Document the recipients or categories of recipients."),{isValid:t.length===0,errors:t,warnings:e}}function c(i){return {consent:"Consent (NDPA Section 25(1)(a)) - The data subject has given consent to the processing of their personal data for one or more specific purposes.",contract:"Contract (NDPA Section 25(1)(b)) - Processing is necessary for the performance of a contract to which the data subject is a party, or in order to take steps at the request of the data subject prior to entering into a contract.",legal_obligation:"Legal Obligation (NDPA Section 25(1)(c)) - Processing is necessary for compliance with a legal obligation to which the data controller is subject.",vital_interests:"Vital Interests (NDPA Section 25(1)(d)) - Processing is necessary to protect the vital interests of the data subject or another natural person.",public_interest:"Public Interest (NDPA Section 25(1)(e)) - Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the data controller.",legitimate_interests:"Legitimate Interests (NDPA Section 25(1)(f)) - Processing is necessary for the purposes of the legitimate interests pursued by the data controller or a third party, except where such interests are overridden by the interests, rights, or freedoms of the data subject."}[i]}function p(i){let t=[];for(let e of i)e.status!=="archived"&&((!e.dpoApproval||!e.dpoApproval.approved)&&t.push({activityId:e.id,activityName:e.name,type:"missing_approval",severity:"high",description:`Processing activity "${e.name}" has not been approved by the DPO.`}),e.reviewDate&&e.reviewDate<Date.now()&&t.push({activityId:e.id,activityName:e.name,type:"overdue_review",severity:"medium",description:`Processing activity "${e.name}" was due for review on ${new Date(e.reviewDate).toLocaleDateString()}.`}),(!e.lawfulBasisJustification||e.lawfulBasisJustification.trim()==="")&&t.push({activityId:e.id,activityName:e.name,type:"missing_justification",severity:"high",description:`Processing activity "${e.name}" is missing the lawful basis justification.`}),e.lawfulBasis==="legitimate_interests"&&(!e.lawfulBasisJustification||e.lawfulBasisJustification.trim().length<20)&&t.push({activityId:e.id,activityName:e.name,type:"missing_lia",severity:"high",description:`Processing activity "${e.name}" relies on legitimate interests but lacks a detailed Legitimate Interest Assessment (NDPA Section 25(1)(f)).`}),e.involvesSensitiveData&&!e.sensitiveDataCondition&&t.push({activityId:e.id,activityName:e.name,type:"missing_sensitive_condition",severity:"high",description:`Processing activity "${e.name}" involves sensitive data but no condition under NDPA Section 27 has been specified.`}),(!e.retentionPeriod||e.retentionPeriod.trim()==="")&&t.push({activityId:e.id,activityName:e.name,type:"missing_retention",severity:"medium",description:`Processing activity "${e.name}" is missing a documented retention period.`}),(!e.dataCategories||e.dataCategories.length===0)&&t.push({activityId:e.id,activityName:e.name,type:"missing_data_categories",severity:"medium",description:`Processing activity "${e.name}" has no documented data categories.`}),(!e.purposes||e.purposes.length===0)&&t.push({activityId:e.id,activityName:e.name,type:"missing_purposes",severity:"medium",description:`Processing activity "${e.name}" has no documented processing purposes.`}));return t}function u(i){let t={consent:0,contract:0,legal_obligation:0,vital_interests:0,public_interest:0,legitimate_interests:0},e=0,a=0,n=[],r=[];for(let s of i)s.status!=="archived"&&(s.lawfulBasis in t&&t[s.lawfulBasis]++,s.involvesSensitiveData&&e++,s.crossBorderTransfer&&a++,s.reviewDate&&s.reviewDate<Date.now()&&n.push(s),(!s.dpoApproval||!s.dpoApproval.approved)&&r.push(s));return {totalActivities:i.filter(s=>s.status!=="archived").length,byBasis:t,sensitiveDataActivities:e,crossBorderActivities:a,activitiesDueForReview:n,activitiesWithoutApproval:r,lastUpdated:Date.now()}}exports.a=o;exports.b=c;exports.c=p;exports.d=u;//# sourceMappingURL=chunk-TDDAYVKK.js.map
2
+ //# sourceMappingURL=chunk-TDDAYVKK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/lawful-basis.ts"],"names":["validateProcessingActivity","activity","errors","warnings","getLawfulBasisDescription","basis","assessComplianceGaps","activities","gaps","generateLawfulBasisSummary","byBasis","sensitiveDataActivities","crossBorderActivities","activitiesDueForReview","activitiesWithoutApproval","a"],"mappings":"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","file":"chunk-TDDAYVKK.js","sourcesContent":["import {\n LawfulBasis,\n ProcessingActivity,\n LawfulBasisSummary,\n} from '../types/lawful-basis';\n\n/**\n * Validation result for a processing activity\n */\nexport interface LawfulBasisValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Compliance gap identified across processing activities\n */\nexport interface LawfulBasisComplianceGap {\n activityId: string;\n activityName: string;\n type: 'missing_approval' | 'overdue_review' | 'missing_justification' | 'missing_lia' | 'missing_sensitive_condition' | 'missing_retention' | 'missing_data_categories' | 'missing_purposes';\n severity: 'high' | 'medium' | 'low';\n description: string;\n}\n\n/**\n * Validates that all required fields are present on a processing activity\n * and that the lawful basis is properly documented.\n *\n * If lawfulBasis is 'legitimate_interests', ensures a LIA justification exists.\n * If involvesSensitiveData is true, ensures sensitiveDataCondition is set.\n *\n * @param activity The processing activity to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateProcessingActivity(activity: ProcessingActivity): LawfulBasisValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Required fields\n if (!activity.id) {\n errors.push('Activity ID is required.');\n }\n\n if (!activity.name || activity.name.trim() === '') {\n errors.push('Activity name is required.');\n }\n\n if (!activity.description || activity.description.trim() === '') {\n errors.push('Activity description is required.');\n }\n\n if (!activity.lawfulBasis) {\n errors.push('Lawful basis is required per NDPA Section 25.');\n }\n\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n errors.push('Justification for the lawful basis is required.');\n }\n\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n errors.push('At least one data category must be specified.');\n }\n\n if (!activity.dataSubjectCategories || activity.dataSubjectCategories.length === 0) {\n errors.push('At least one data subject category must be specified.');\n }\n\n if (!activity.purposes || activity.purposes.length === 0) {\n errors.push('At least one processing purpose must be specified.');\n }\n\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n errors.push('Data retention period is required.');\n }\n\n // Legitimate interests requires additional justification (LIA)\n if (activity.lawfulBasis === 'legitimate_interests') {\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20) {\n errors.push(\n 'Legitimate interests requires a detailed Legitimate Interest Assessment (LIA) justification (NDPA Section 25(1)(f)).'\n );\n }\n }\n\n // Sensitive data requires a specific condition per NDPA Section 27\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n errors.push(\n 'Processing sensitive personal data requires specifying a condition under NDPA Section 27.'\n );\n }\n\n // Warnings for best practices\n if (!activity.dpoApproval) {\n warnings.push('Activity has not been approved by the DPO.');\n } else if (!activity.dpoApproval.approved) {\n warnings.push('Activity has a DPO review but has not been approved.');\n }\n\n if (!activity.reviewDate) {\n warnings.push('No review date has been set. Regular reviews are recommended.');\n } else if (activity.reviewDate < Date.now()) {\n warnings.push('Activity is overdue for review.');\n }\n\n if (!activity.retentionJustification) {\n warnings.push('Consider documenting the justification for the retention period.');\n }\n\n if (activity.crossBorderTransfer && (!activity.recipients || activity.recipients.length === 0)) {\n warnings.push(\n 'Cross-border transfer is indicated but no recipients are listed. Document the recipients or categories of recipients.'\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Returns a human-readable description of a lawful basis with the relevant\n * NDPA section reference.\n *\n * @param basis The lawful basis to describe\n * @returns Description string including NDPA section reference\n */\nexport function getLawfulBasisDescription(basis: LawfulBasis): string {\n const descriptions: Record<LawfulBasis, string> = {\n consent:\n 'Consent (NDPA Section 25(1)(a)) - The data subject has given consent to the processing of their personal data for one or more specific purposes.',\n contract:\n 'Contract (NDPA Section 25(1)(b)) - Processing is necessary for the performance of a contract to which the data subject is a party, or in order to take steps at the request of the data subject prior to entering into a contract.',\n legal_obligation:\n 'Legal Obligation (NDPA Section 25(1)(c)) - Processing is necessary for compliance with a legal obligation to which the data controller is subject.',\n vital_interests:\n 'Vital Interests (NDPA Section 25(1)(d)) - Processing is necessary to protect the vital interests of the data subject or another natural person.',\n public_interest:\n 'Public Interest (NDPA Section 25(1)(e)) - Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the data controller.',\n legitimate_interests:\n 'Legitimate Interests (NDPA Section 25(1)(f)) - Processing is necessary for the purposes of the legitimate interests pursued by the data controller or a third party, except where such interests are overridden by the interests, rights, or freedoms of the data subject.',\n };\n\n return descriptions[basis];\n}\n\n/**\n * Analyzes all processing activities and returns compliance gaps including\n * missing DPO approval, overdue reviews, undocumented justifications,\n * missing LIA for legitimate interests, and other documentation issues.\n *\n * @param activities Array of processing activities to analyze\n * @returns Array of identified compliance gaps\n */\nexport function assessComplianceGaps(activities: ProcessingActivity[]): LawfulBasisComplianceGap[] {\n const gaps: LawfulBasisComplianceGap[] = [];\n\n for (const activity of activities) {\n // Skip archived activities\n if (activity.status === 'archived') {\n continue;\n }\n\n // Missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_approval',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" has not been approved by the DPO.`,\n });\n }\n\n // Overdue review\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'overdue_review',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" was due for review on ${new Date(activity.reviewDate).toLocaleDateString()}.`,\n });\n }\n\n // Missing justification\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_justification',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" is missing the lawful basis justification.`,\n });\n }\n\n // Missing LIA for legitimate interests\n if (\n activity.lawfulBasis === 'legitimate_interests' &&\n (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20)\n ) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_lia',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" relies on legitimate interests but lacks a detailed Legitimate Interest Assessment (NDPA Section 25(1)(f)).`,\n });\n }\n\n // Missing sensitive data condition\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_sensitive_condition',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" involves sensitive data but no condition under NDPA Section 27 has been specified.`,\n });\n }\n\n // Missing retention period\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_retention',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" is missing a documented retention period.`,\n });\n }\n\n // Missing data categories\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_data_categories',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented data categories.`,\n });\n }\n\n // Missing purposes\n if (!activity.purposes || activity.purposes.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_purposes',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented processing purposes.`,\n });\n }\n }\n\n return gaps;\n}\n\n/**\n * Generates a summary of all lawful basis documentation across processing activities.\n *\n * @param activities Array of processing activities to summarize\n * @returns LawfulBasisSummary with counts, breakdowns, and flagged activities\n */\nexport function generateLawfulBasisSummary(activities: ProcessingActivity[]): LawfulBasisSummary {\n const byBasis: Record<LawfulBasis, number> = {\n consent: 0,\n contract: 0,\n legal_obligation: 0,\n vital_interests: 0,\n public_interest: 0,\n legitimate_interests: 0,\n };\n\n let sensitiveDataActivities = 0;\n let crossBorderActivities = 0;\n const activitiesDueForReview: ProcessingActivity[] = [];\n const activitiesWithoutApproval: ProcessingActivity[] = [];\n\n for (const activity of activities) {\n if (activity.status === 'archived') {\n continue;\n }\n\n // Count by lawful basis\n if (activity.lawfulBasis in byBasis) {\n byBasis[activity.lawfulBasis]++;\n }\n\n // Count sensitive data activities\n if (activity.involvesSensitiveData) {\n sensitiveDataActivities++;\n }\n\n // Count cross-border transfers\n if (activity.crossBorderTransfer) {\n crossBorderActivities++;\n }\n\n // Check for overdue reviews\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n activitiesDueForReview.push(activity);\n }\n\n // Check for missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n activitiesWithoutApproval.push(activity);\n }\n }\n\n return {\n totalActivities: activities.filter(a => a.status !== 'archived').length,\n byBasis,\n sensitiveDataActivities,\n crossBorderActivities,\n activitiesDueForReview,\n activitiesWithoutApproval,\n lastUpdated: Date.now(),\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ function o(i){let t=[],e=[];return i.id||t.push("Activity ID is required."),(!i.name||i.name.trim()==="")&&t.push("Activity name is required."),(!i.description||i.description.trim()==="")&&t.push("Activity description is required."),i.lawfulBasis||t.push("Lawful basis is required per NDPA Section 25."),(!i.lawfulBasisJustification||i.lawfulBasisJustification.trim()==="")&&t.push("Justification for the lawful basis is required."),(!i.dataCategories||i.dataCategories.length===0)&&t.push("At least one data category must be specified."),(!i.dataSubjectCategories||i.dataSubjectCategories.length===0)&&t.push("At least one data subject category must be specified."),(!i.purposes||i.purposes.length===0)&&t.push("At least one processing purpose must be specified."),(!i.retentionPeriod||i.retentionPeriod.trim()==="")&&t.push("Data retention period is required."),i.lawfulBasis==="legitimate_interests"&&(!i.lawfulBasisJustification||i.lawfulBasisJustification.trim().length<20)&&t.push("Legitimate interests requires a detailed Legitimate Interest Assessment (LIA) justification (NDPA Section 25(1)(f))."),i.involvesSensitiveData&&!i.sensitiveDataCondition&&t.push("Processing sensitive personal data requires specifying a condition under NDPA Section 27."),i.dpoApproval?i.dpoApproval.approved||e.push("Activity has a DPO review but has not been approved."):e.push("Activity has not been approved by the DPO."),i.reviewDate?i.reviewDate<Date.now()&&e.push("Activity is overdue for review."):e.push("No review date has been set. Regular reviews are recommended."),i.retentionJustification||e.push("Consider documenting the justification for the retention period."),i.crossBorderTransfer&&(!i.recipients||i.recipients.length===0)&&e.push("Cross-border transfer is indicated but no recipients are listed. Document the recipients or categories of recipients."),{isValid:t.length===0,errors:t,warnings:e}}function c(i){return {consent:"Consent (NDPA Section 25(1)(a)) - The data subject has given consent to the processing of their personal data for one or more specific purposes.",contract:"Contract (NDPA Section 25(1)(b)) - Processing is necessary for the performance of a contract to which the data subject is a party, or in order to take steps at the request of the data subject prior to entering into a contract.",legal_obligation:"Legal Obligation (NDPA Section 25(1)(c)) - Processing is necessary for compliance with a legal obligation to which the data controller is subject.",vital_interests:"Vital Interests (NDPA Section 25(1)(d)) - Processing is necessary to protect the vital interests of the data subject or another natural person.",public_interest:"Public Interest (NDPA Section 25(1)(e)) - Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the data controller.",legitimate_interests:"Legitimate Interests (NDPA Section 25(1)(f)) - Processing is necessary for the purposes of the legitimate interests pursued by the data controller or a third party, except where such interests are overridden by the interests, rights, or freedoms of the data subject."}[i]}function p(i){let t=[];for(let e of i)e.status!=="archived"&&((!e.dpoApproval||!e.dpoApproval.approved)&&t.push({activityId:e.id,activityName:e.name,type:"missing_approval",severity:"high",description:`Processing activity "${e.name}" has not been approved by the DPO.`}),e.reviewDate&&e.reviewDate<Date.now()&&t.push({activityId:e.id,activityName:e.name,type:"overdue_review",severity:"medium",description:`Processing activity "${e.name}" was due for review on ${new Date(e.reviewDate).toLocaleDateString()}.`}),(!e.lawfulBasisJustification||e.lawfulBasisJustification.trim()==="")&&t.push({activityId:e.id,activityName:e.name,type:"missing_justification",severity:"high",description:`Processing activity "${e.name}" is missing the lawful basis justification.`}),e.lawfulBasis==="legitimate_interests"&&(!e.lawfulBasisJustification||e.lawfulBasisJustification.trim().length<20)&&t.push({activityId:e.id,activityName:e.name,type:"missing_lia",severity:"high",description:`Processing activity "${e.name}" relies on legitimate interests but lacks a detailed Legitimate Interest Assessment (NDPA Section 25(1)(f)).`}),e.involvesSensitiveData&&!e.sensitiveDataCondition&&t.push({activityId:e.id,activityName:e.name,type:"missing_sensitive_condition",severity:"high",description:`Processing activity "${e.name}" involves sensitive data but no condition under NDPA Section 27 has been specified.`}),(!e.retentionPeriod||e.retentionPeriod.trim()==="")&&t.push({activityId:e.id,activityName:e.name,type:"missing_retention",severity:"medium",description:`Processing activity "${e.name}" is missing a documented retention period.`}),(!e.dataCategories||e.dataCategories.length===0)&&t.push({activityId:e.id,activityName:e.name,type:"missing_data_categories",severity:"medium",description:`Processing activity "${e.name}" has no documented data categories.`}),(!e.purposes||e.purposes.length===0)&&t.push({activityId:e.id,activityName:e.name,type:"missing_purposes",severity:"medium",description:`Processing activity "${e.name}" has no documented processing purposes.`}));return t}function u(i){let t={consent:0,contract:0,legal_obligation:0,vital_interests:0,public_interest:0,legitimate_interests:0},e=0,a=0,n=[],r=[];for(let s of i)s.status!=="archived"&&(s.lawfulBasis in t&&t[s.lawfulBasis]++,s.involvesSensitiveData&&e++,s.crossBorderTransfer&&a++,s.reviewDate&&s.reviewDate<Date.now()&&n.push(s),(!s.dpoApproval||!s.dpoApproval.approved)&&r.push(s));return {totalActivities:i.filter(s=>s.status!=="archived").length,byBasis:t,sensitiveDataActivities:e,crossBorderActivities:a,activitiesDueForReview:n,activitiesWithoutApproval:r,lastUpdated:Date.now()}}export{o as a,c as b,p as c,u as d};//# sourceMappingURL=chunk-TXBZPCGF.mjs.map
2
+ //# sourceMappingURL=chunk-TXBZPCGF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/utils/lawful-basis.ts"],"names":["validateProcessingActivity","activity","errors","warnings","getLawfulBasisDescription","basis","assessComplianceGaps","activities","gaps","generateLawfulBasisSummary","byBasis","sensitiveDataActivities","crossBorderActivities","activitiesDueForReview","activitiesWithoutApproval","a"],"mappings":"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","file":"chunk-TXBZPCGF.mjs","sourcesContent":["import {\n LawfulBasis,\n ProcessingActivity,\n LawfulBasisSummary,\n} from '../types/lawful-basis';\n\n/**\n * Validation result for a processing activity\n */\nexport interface LawfulBasisValidationResult {\n isValid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n/**\n * Compliance gap identified across processing activities\n */\nexport interface LawfulBasisComplianceGap {\n activityId: string;\n activityName: string;\n type: 'missing_approval' | 'overdue_review' | 'missing_justification' | 'missing_lia' | 'missing_sensitive_condition' | 'missing_retention' | 'missing_data_categories' | 'missing_purposes';\n severity: 'high' | 'medium' | 'low';\n description: string;\n}\n\n/**\n * Validates that all required fields are present on a processing activity\n * and that the lawful basis is properly documented.\n *\n * If lawfulBasis is 'legitimate_interests', ensures a LIA justification exists.\n * If involvesSensitiveData is true, ensures sensitiveDataCondition is set.\n *\n * @param activity The processing activity to validate\n * @returns Validation result with errors and warnings\n */\nexport function validateProcessingActivity(activity: ProcessingActivity): LawfulBasisValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n\n // Required fields\n if (!activity.id) {\n errors.push('Activity ID is required.');\n }\n\n if (!activity.name || activity.name.trim() === '') {\n errors.push('Activity name is required.');\n }\n\n if (!activity.description || activity.description.trim() === '') {\n errors.push('Activity description is required.');\n }\n\n if (!activity.lawfulBasis) {\n errors.push('Lawful basis is required per NDPA Section 25.');\n }\n\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n errors.push('Justification for the lawful basis is required.');\n }\n\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n errors.push('At least one data category must be specified.');\n }\n\n if (!activity.dataSubjectCategories || activity.dataSubjectCategories.length === 0) {\n errors.push('At least one data subject category must be specified.');\n }\n\n if (!activity.purposes || activity.purposes.length === 0) {\n errors.push('At least one processing purpose must be specified.');\n }\n\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n errors.push('Data retention period is required.');\n }\n\n // Legitimate interests requires additional justification (LIA)\n if (activity.lawfulBasis === 'legitimate_interests') {\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20) {\n errors.push(\n 'Legitimate interests requires a detailed Legitimate Interest Assessment (LIA) justification (NDPA Section 25(1)(f)).'\n );\n }\n }\n\n // Sensitive data requires a specific condition per NDPA Section 27\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n errors.push(\n 'Processing sensitive personal data requires specifying a condition under NDPA Section 27.'\n );\n }\n\n // Warnings for best practices\n if (!activity.dpoApproval) {\n warnings.push('Activity has not been approved by the DPO.');\n } else if (!activity.dpoApproval.approved) {\n warnings.push('Activity has a DPO review but has not been approved.');\n }\n\n if (!activity.reviewDate) {\n warnings.push('No review date has been set. Regular reviews are recommended.');\n } else if (activity.reviewDate < Date.now()) {\n warnings.push('Activity is overdue for review.');\n }\n\n if (!activity.retentionJustification) {\n warnings.push('Consider documenting the justification for the retention period.');\n }\n\n if (activity.crossBorderTransfer && (!activity.recipients || activity.recipients.length === 0)) {\n warnings.push(\n 'Cross-border transfer is indicated but no recipients are listed. Document the recipients or categories of recipients.'\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n/**\n * Returns a human-readable description of a lawful basis with the relevant\n * NDPA section reference.\n *\n * @param basis The lawful basis to describe\n * @returns Description string including NDPA section reference\n */\nexport function getLawfulBasisDescription(basis: LawfulBasis): string {\n const descriptions: Record<LawfulBasis, string> = {\n consent:\n 'Consent (NDPA Section 25(1)(a)) - The data subject has given consent to the processing of their personal data for one or more specific purposes.',\n contract:\n 'Contract (NDPA Section 25(1)(b)) - Processing is necessary for the performance of a contract to which the data subject is a party, or in order to take steps at the request of the data subject prior to entering into a contract.',\n legal_obligation:\n 'Legal Obligation (NDPA Section 25(1)(c)) - Processing is necessary for compliance with a legal obligation to which the data controller is subject.',\n vital_interests:\n 'Vital Interests (NDPA Section 25(1)(d)) - Processing is necessary to protect the vital interests of the data subject or another natural person.',\n public_interest:\n 'Public Interest (NDPA Section 25(1)(e)) - Processing is necessary for the performance of a task carried out in the public interest or in the exercise of official authority vested in the data controller.',\n legitimate_interests:\n 'Legitimate Interests (NDPA Section 25(1)(f)) - Processing is necessary for the purposes of the legitimate interests pursued by the data controller or a third party, except where such interests are overridden by the interests, rights, or freedoms of the data subject.',\n };\n\n return descriptions[basis];\n}\n\n/**\n * Analyzes all processing activities and returns compliance gaps including\n * missing DPO approval, overdue reviews, undocumented justifications,\n * missing LIA for legitimate interests, and other documentation issues.\n *\n * @param activities Array of processing activities to analyze\n * @returns Array of identified compliance gaps\n */\nexport function assessComplianceGaps(activities: ProcessingActivity[]): LawfulBasisComplianceGap[] {\n const gaps: LawfulBasisComplianceGap[] = [];\n\n for (const activity of activities) {\n // Skip archived activities\n if (activity.status === 'archived') {\n continue;\n }\n\n // Missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_approval',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" has not been approved by the DPO.`,\n });\n }\n\n // Overdue review\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'overdue_review',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" was due for review on ${new Date(activity.reviewDate).toLocaleDateString()}.`,\n });\n }\n\n // Missing justification\n if (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_justification',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" is missing the lawful basis justification.`,\n });\n }\n\n // Missing LIA for legitimate interests\n if (\n activity.lawfulBasis === 'legitimate_interests' &&\n (!activity.lawfulBasisJustification || activity.lawfulBasisJustification.trim().length < 20)\n ) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_lia',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" relies on legitimate interests but lacks a detailed Legitimate Interest Assessment (NDPA Section 25(1)(f)).`,\n });\n }\n\n // Missing sensitive data condition\n if (activity.involvesSensitiveData && !activity.sensitiveDataCondition) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_sensitive_condition',\n severity: 'high',\n description: `Processing activity \"${activity.name}\" involves sensitive data but no condition under NDPA Section 27 has been specified.`,\n });\n }\n\n // Missing retention period\n if (!activity.retentionPeriod || activity.retentionPeriod.trim() === '') {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_retention',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" is missing a documented retention period.`,\n });\n }\n\n // Missing data categories\n if (!activity.dataCategories || activity.dataCategories.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_data_categories',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented data categories.`,\n });\n }\n\n // Missing purposes\n if (!activity.purposes || activity.purposes.length === 0) {\n gaps.push({\n activityId: activity.id,\n activityName: activity.name,\n type: 'missing_purposes',\n severity: 'medium',\n description: `Processing activity \"${activity.name}\" has no documented processing purposes.`,\n });\n }\n }\n\n return gaps;\n}\n\n/**\n * Generates a summary of all lawful basis documentation across processing activities.\n *\n * @param activities Array of processing activities to summarize\n * @returns LawfulBasisSummary with counts, breakdowns, and flagged activities\n */\nexport function generateLawfulBasisSummary(activities: ProcessingActivity[]): LawfulBasisSummary {\n const byBasis: Record<LawfulBasis, number> = {\n consent: 0,\n contract: 0,\n legal_obligation: 0,\n vital_interests: 0,\n public_interest: 0,\n legitimate_interests: 0,\n };\n\n let sensitiveDataActivities = 0;\n let crossBorderActivities = 0;\n const activitiesDueForReview: ProcessingActivity[] = [];\n const activitiesWithoutApproval: ProcessingActivity[] = [];\n\n for (const activity of activities) {\n if (activity.status === 'archived') {\n continue;\n }\n\n // Count by lawful basis\n if (activity.lawfulBasis in byBasis) {\n byBasis[activity.lawfulBasis]++;\n }\n\n // Count sensitive data activities\n if (activity.involvesSensitiveData) {\n sensitiveDataActivities++;\n }\n\n // Count cross-border transfers\n if (activity.crossBorderTransfer) {\n crossBorderActivities++;\n }\n\n // Check for overdue reviews\n if (activity.reviewDate && activity.reviewDate < Date.now()) {\n activitiesDueForReview.push(activity);\n }\n\n // Check for missing DPO approval\n if (!activity.dpoApproval || !activity.dpoApproval.approved) {\n activitiesWithoutApproval.push(activity);\n }\n }\n\n return {\n totalActivities: activities.filter(a => a.status !== 'archived').length,\n byBasis,\n sensitiveDataActivities,\n crossBorderActivities,\n activitiesDueForReview,\n activitiesWithoutApproval,\n lastUpdated: Date.now(),\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkSSGJREE3_js=require('./chunk-SSGJREE3.js'),chunkMQFZHA2D_js=require('./chunk-MQFZHA2D.js'),react=require('react');function N({sections:d,initialAnswers:Q={},storageKey:f="ndpr_dpia_data",useLocalStorage:m=true,onComplete:I}){let[l,c]=react.useState(0),[i,g]=react.useState(Q);react.useEffect(()=>{if(m&&typeof window!="undefined")try{let r=localStorage.getItem(f);if(r){let{answers:t,sectionIndex:e}=JSON.parse(r);g(t||{}),c(e||0);}}catch(r){console.error("Error loading DPIA data:",r);}},[f,m]),react.useEffect(()=>{if(m&&typeof window!="undefined")try{localStorage.setItem(f,JSON.stringify({answers:i,sectionIndex:l}));}catch(r){console.error("Error saving DPIA data:",r);}},[i,l,f,m]);let p=d[l]||null,E=(r,t)=>{g(e=>chunkMQFZHA2D_js.b(chunkMQFZHA2D_js.a({},e),{[r]:t}));},v=r=>r.showWhen?r.showWhen.every(t=>{let e=i[t.questionId];switch(t.operator){case "equals":return e===t.value;case "contains":return Array.isArray(e)?e.includes(t.value):false;case "greaterThan":return typeof e=="number"?e>t.value:false;case "lessThan":return typeof e=="number"?e<t.value:false;default:return true}}):true,A=()=>p?p.questions.filter(v):[],h=()=>p?A().every(t=>{if(!t.required)return true;let e=i[t.id];return !(e==null||typeof e=="string"&&e.trim()===""||Array.isArray(e)&&e.length===0)}):false,x=()=>{let r={};return p&&A().forEach(e=>{if(!e.required)return;let s=i[e.id];s==null||typeof s=="string"&&s.trim()===""?r[e.id]="This question is required":Array.isArray(s)&&s.length===0&&(r[e.id]="At least one option must be selected");}),r},C=()=>h()&&l<d.length-1?(c(r=>r+1),true):false,L=()=>l>0?(c(r=>r-1),true):false,O=r=>r>=0&&r<d.length?(c(r),true):false,T=()=>d.every((r,t)=>{c(t);let e=h();return c(l),e}),_=()=>{let r=[];return d.forEach(t=>{t.questions.forEach(e=>{let s=i[e.id];if(s!=null&&e.riskLevel)if(["select","radio","checkbox"].includes(e.type)&&e.options)(Array.isArray(s)?s:[s]).forEach(o=>{var w;let a=(w=e.options)==null?void 0:w.find(u=>u.value===o);if(a!=null&&a.riskLevel){let u=a.riskLevel,D=u==="low"?1:u==="medium"?3:5,P=u==="low"?1:u==="medium"?3:5;r.push({id:`risk_${r.length+1}`,description:`${e.text} - ${a.label}`,likelihood:D,impact:P,score:D*P,level:u,mitigated:false,relatedQuestionIds:[e.id]});}});else {let n=e.riskLevel,o=n==="low"?1:n==="medium"?3:5,a=n==="low"?1:n==="medium"?3:5;r.push({id:`risk_${r.length+1}`,description:e.text,likelihood:o,impact:a,score:o*a,level:n,mitigated:false,relatedQuestionIds:[e.id]});}});}),r},$=(r,t,e)=>{let s=_(),n={id:`dpia_${Date.now()}`,title:t,processingDescription:e,startedAt:Date.now(),completedAt:Date.now(),assessor:r,answers:i,risks:s,overallRiskLevel:"low",canProceed:true,conclusion:"",version:"1.0"},o=chunkSSGJREE3_js.a(n);return n.overallRiskLevel=o.overallRiskLevel,n.canProceed=o.canProceed,n.conclusion=o.canProceed?"Based on the assessment, the processing can proceed with appropriate safeguards.":"Based on the assessment, the processing should not proceed without further mitigation measures.",n.recommendations=o.recommendations,I&&I(n),n},U=()=>{g({}),c(0),m&&typeof window!="undefined"&&localStorage.removeItem(f);},V=(()=>{let r=0,t=0;return d.forEach(e=>{e.questions.forEach(s=>{if(s.required&&v(s)){t++;let n=i[s.id];n!=null&&!(typeof n=="string"&&n.trim()==="")&&!(Array.isArray(n)&&n.length===0)&&r++;}});}),t>0?Math.round(r/t*100):0})();return {currentSectionIndex:l,currentSection:p,answers:i,updateAnswer:E,nextSection:C,prevSection:L,goToSection:O,isCurrentSectionValid:h,getCurrentSectionErrors:x,isComplete:T,completeDPIA:$,getVisibleQuestions:A,resetDPIA:U,progress:V}}exports.a=N;//# sourceMappingURL=chunk-U2CGMEWB.js.map
2
+ //# sourceMappingURL=chunk-U2CGMEWB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../packages/ndpr-toolkit/src/hooks/useDPIA.ts"],"names":["useDPIA","sections","initialAnswers","storageKey","useLocalStorage","onComplete","currentSectionIndex","setCurrentSectionIndex","useState","answers","setAnswers","useEffect","savedData","savedAnswers","sectionIndex","error","currentSection","updateAnswer","questionId","value","prevAnswers","__spreadProps","__spreadValues","shouldShowQuestion","question","condition","answer","getVisibleQuestions","isCurrentSectionValid","getCurrentSectionErrors","errors","nextSection","prevIndex","prevSection","goToSection","index","isComplete","section","valid","identifyRisks","risks","selectedOption","_a","option","opt","riskLevel","likelihood","impact","completeDPIA","assessorInfo","title","processingDescription","result","assessment","assessDPIARisk","resetDPIA","progress","answeredQuestions","totalRequiredQuestions"],"mappings":"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","file":"chunk-U2CGMEWB.js","sourcesContent":["import { useState, useEffect } from 'react';\nimport { DPIAQuestion, DPIASection, DPIAResult, DPIARisk } from '../types/dpia';\nimport { assessDPIARisk } from '../utils/dpia';\n\ninterface UseDPIAOptions {\n /**\n * Sections of the DPIA questionnaire\n */\n sections: DPIASection[];\n \n /**\n * Initial answers (if resuming a DPIA)\n */\n initialAnswers?: Record<string, any>;\n \n /**\n * Storage key for DPIA data\n * @default \"ndpr_dpia_data\"\n */\n storageKey?: string;\n \n /**\n * Whether to use local storage to persist DPIA data\n * @default true\n */\n useLocalStorage?: boolean;\n \n /**\n * Callback function called when the DPIA is completed\n */\n onComplete?: (result: DPIAResult) => void;\n}\n\ninterface UseDPIAReturn {\n /**\n * Current section index\n */\n currentSectionIndex: number;\n \n /**\n * Current section\n */\n currentSection: DPIASection | null;\n \n /**\n * All answers\n */\n answers: Record<string, any>;\n \n /**\n * Update an answer\n */\n updateAnswer: (questionId: string, value: any) => void;\n \n /**\n * Go to the next section\n */\n nextSection: () => boolean;\n \n /**\n * Go to the previous section\n */\n prevSection: () => boolean;\n \n /**\n * Go to a specific section\n */\n goToSection: (index: number) => boolean;\n \n /**\n * Check if the current section is valid\n */\n isCurrentSectionValid: () => boolean;\n \n /**\n * Get validation errors for the current section\n */\n getCurrentSectionErrors: () => Record<string, string>;\n \n /**\n * Check if the DPIA is complete\n */\n isComplete: () => boolean;\n \n /**\n * Complete the DPIA and generate a result\n */\n completeDPIA: (assessorInfo: { name: string; role: string; email: string; }, title: string, processingDescription: string) => DPIAResult;\n \n /**\n * Get the visible questions for the current section\n */\n getVisibleQuestions: () => DPIAQuestion[];\n \n /**\n * Reset the DPIA\n */\n resetDPIA: () => void;\n \n /**\n * Progress percentage\n */\n progress: number;\n}\n\n/**\n * Hook for conducting Data Protection Impact Assessments in compliance with the NDPA 2023\n */\nexport function useDPIA({\n sections,\n initialAnswers = {},\n storageKey = \"ndpr_dpia_data\",\n useLocalStorage = true,\n onComplete\n}: UseDPIAOptions): UseDPIAReturn {\n const [currentSectionIndex, setCurrentSectionIndex] = useState<number>(0);\n const [answers, setAnswers] = useState<Record<string, any>>(initialAnswers);\n \n // Load DPIA data from storage on mount\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined') {\n try {\n const savedData = localStorage.getItem(storageKey);\n if (savedData) {\n const { answers: savedAnswers, sectionIndex } = JSON.parse(savedData);\n setAnswers(savedAnswers || {});\n setCurrentSectionIndex(sectionIndex || 0);\n }\n } catch (error) {\n console.error('Error loading DPIA data:', error);\n }\n }\n }, [storageKey, useLocalStorage]);\n \n // Save DPIA data to storage when it changes\n useEffect(() => {\n if (useLocalStorage && typeof window !== 'undefined') {\n try {\n localStorage.setItem(storageKey, JSON.stringify({\n answers,\n sectionIndex: currentSectionIndex\n }));\n } catch (error) {\n console.error('Error saving DPIA data:', error);\n }\n }\n }, [answers, currentSectionIndex, storageKey, useLocalStorage]);\n \n // Get the current section\n const currentSection = sections[currentSectionIndex] || null;\n \n // Update an answer\n const updateAnswer = (questionId: string, value: any) => {\n setAnswers(prevAnswers => ({\n ...prevAnswers,\n [questionId]: value\n }));\n };\n \n // Check if a question should be shown based on its conditions\n const shouldShowQuestion = (question: DPIAQuestion): boolean => {\n if (!question.showWhen) {\n return true;\n }\n \n return question.showWhen.every(condition => {\n const answer = answers[condition.questionId];\n \n switch (condition.operator) {\n case 'equals':\n return answer === condition.value;\n case 'contains':\n return Array.isArray(answer) ? answer.includes(condition.value) : false;\n case 'greaterThan':\n return typeof answer === 'number' ? answer > condition.value : false;\n case 'lessThan':\n return typeof answer === 'number' ? answer < condition.value : false;\n default:\n return true;\n }\n });\n };\n \n // Get the visible questions for the current section\n const getVisibleQuestions = (): DPIAQuestion[] => {\n if (!currentSection) {\n return [];\n }\n \n return currentSection.questions.filter(shouldShowQuestion);\n };\n \n // Check if the current section is valid\n const isCurrentSectionValid = (): boolean => {\n if (!currentSection) {\n return false;\n }\n \n const visibleQuestions = getVisibleQuestions();\n \n return visibleQuestions.every(question => {\n if (!question.required) {\n return true;\n }\n \n const answer = answers[question.id];\n \n if (answer === undefined || answer === null) {\n return false;\n }\n \n if (typeof answer === 'string' && answer.trim() === '') {\n return false;\n }\n \n if (Array.isArray(answer) && answer.length === 0) {\n return false;\n }\n \n return true;\n });\n };\n \n // Get validation errors for the current section\n const getCurrentSectionErrors = (): Record<string, string> => {\n const errors: Record<string, string> = {};\n \n if (!currentSection) {\n return errors;\n }\n \n const visibleQuestions = getVisibleQuestions();\n \n visibleQuestions.forEach(question => {\n if (!question.required) {\n return;\n }\n \n const answer = answers[question.id];\n \n if (answer === undefined || answer === null) {\n errors[question.id] = 'This question is required';\n } else if (typeof answer === 'string' && answer.trim() === '') {\n errors[question.id] = 'This question is required';\n } else if (Array.isArray(answer) && answer.length === 0) {\n errors[question.id] = 'At least one option must be selected';\n }\n });\n \n return errors;\n };\n \n // Go to the next section\n const nextSection = (): boolean => {\n if (!isCurrentSectionValid()) {\n return false;\n }\n \n if (currentSectionIndex < sections.length - 1) {\n setCurrentSectionIndex(prevIndex => prevIndex + 1);\n return true;\n }\n \n return false;\n };\n \n // Go to the previous section\n const prevSection = (): boolean => {\n if (currentSectionIndex > 0) {\n setCurrentSectionIndex(prevIndex => prevIndex - 1);\n return true;\n }\n \n return false;\n };\n \n // Go to a specific section\n const goToSection = (index: number): boolean => {\n if (index >= 0 && index < sections.length) {\n setCurrentSectionIndex(index);\n return true;\n }\n \n return false;\n };\n \n // Check if the DPIA is complete\n const isComplete = (): boolean => {\n return sections.every((section, index) => {\n // Temporarily set the current section to check ifit&apos;s valid\n setCurrentSectionIndex(index);\n const valid = isCurrentSectionValid();\n // Restore the current section\n setCurrentSectionIndex(currentSectionIndex);\n return valid;\n });\n };\n \n // Identify risks based on answers\n const identifyRisks = (): DPIARisk[] => {\n const risks: DPIARisk[] = [];\n \n // Check each question for risk indicators\n sections.forEach(section => {\n section.questions.forEach(question => {\n const answer = answers[question.id];\n \n // Skip if no answer\n if (answer === undefined || answer === null) {\n return;\n }\n \n // Check if the question has a risk level\n if (question.riskLevel) {\n // For select/radio/checkbox questions, check if the selected option has a risk level\n if (['select', 'radio', 'checkbox'].includes(question.type) && question.options) {\n const selectedOptions = Array.isArray(answer) ? answer : [answer];\n \n selectedOptions.forEach(selectedOption => {\n const option = question.options?.find(opt => opt.value === selectedOption);\n \n if (option?.riskLevel) {\n const riskLevel = option.riskLevel;\n const likelihood = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n const impact = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n \n risks.push({\n id: `risk_${risks.length + 1}`,\n description: `${question.text} - ${option.label}`,\n likelihood,\n impact,\n score: likelihood * impact,\n level: riskLevel,\n mitigated: false,\n relatedQuestionIds: [question.id]\n });\n }\n });\n } else {\n // For other question types, use the question's risk level\n const riskLevel = question.riskLevel;\n const likelihood = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n const impact = riskLevel === 'low' ? 1 : riskLevel === 'medium' ? 3 : 5;\n \n risks.push({\n id: `risk_${risks.length + 1}`,\n description: question.text,\n likelihood,\n impact,\n score: likelihood * impact,\n level: riskLevel,\n mitigated: false,\n relatedQuestionIds: [question.id]\n });\n }\n }\n });\n });\n \n return risks;\n };\n \n // Complete the DPIA and generate a result\n const completeDPIA = (\n assessorInfo: { name: string; role: string; email: string; },\n title: string,\n processingDescription: string\n ): DPIAResult => {\n const risks = identifyRisks();\n \n const result: DPIAResult = {\n id: `dpia_${Date.now()}`,\n title,\n processingDescription,\n startedAt: Date.now(),\n completedAt: Date.now(),\n assessor: assessorInfo,\n answers,\n risks,\n overallRiskLevel: 'low',\n canProceed: true,\n conclusion: '',\n version: '1.0'\n };\n \n // Assess the risks\n const assessment = assessDPIARisk(result);\n \n result.overallRiskLevel = assessment.overallRiskLevel;\n result.canProceed = assessment.canProceed;\n result.conclusion = assessment.canProceed\n ? 'Based on the assessment, the processing can proceed with appropriate safeguards.'\n : 'Based on the assessment, the processing should not proceed without further mitigation measures.';\n result.recommendations = assessment.recommendations;\n \n if (onComplete) {\n onComplete(result);\n }\n \n return result;\n };\n \n // Reset the DPIA\n const resetDPIA = () => {\n setAnswers({});\n setCurrentSectionIndex(0);\n \n if (useLocalStorage && typeof window !== 'undefined') {\n localStorage.removeItem(storageKey);\n }\n };\n \n // Calculate progress percentage\n const progress = (() => {\n let answeredQuestions = 0;\n let totalRequiredQuestions = 0;\n \n sections.forEach(section => {\n section.questions.forEach(question => {\n if (question.required && shouldShowQuestion(question)) {\n totalRequiredQuestions++;\n \n const answer = answers[question.id];\n if (\n answer !== undefined && \n answer !== null && \n !(typeof answer === 'string' && answer.trim() === '') &&\n !(Array.isArray(answer) && answer.length === 0)\n ) {\n answeredQuestions++;\n }\n }\n });\n });\n \n return totalRequiredQuestions > 0 \n ? Math.round((answeredQuestions / totalRequiredQuestions) * 100) \n : 0;\n })();\n \n return {\n currentSectionIndex,\n currentSection,\n answers,\n updateAnswer,\n nextSection,\n prevSection,\n goToSection,\n isCurrentSectionValid,\n getCurrentSectionErrors,\n isComplete,\n completeDPIA,\n getVisibleQuestions,\n resetDPIA,\n progress\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkSWF3YVE5_js=require('./chunk-SWF3YVE5.js'),chunkMQFZHA2D_js=require('./chunk-MQFZHA2D.js'),e=require('react');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var e__default=/*#__PURE__*/_interopDefault(e);var P=[{value:"consent",label:"Consent (Section 25(1)(a))"},{value:"contract",label:"Contract (Section 25(1)(b))"},{value:"legal_obligation",label:"Legal Obligation (Section 25(1)(c))"},{value:"vital_interests",label:"Vital Interests (Section 25(1)(d))"},{value:"public_interest",label:"Public Interest (Section 25(1)(e))"},{value:"legitimate_interests",label:"Legitimate Interests (Section 25(1)(f))"}],Q=[{value:"active",label:"Active"},{value:"inactive",label:"Inactive"},{value:"archived",label:"Archived"}],ve=[{value:"data_subject",label:"Directly from Data Subject"},{value:"third_party",label:"Third Party"},{value:"public_source",label:"Public Source"},{value:"other",label:"Other"}];function fe(){let s=Date.now();return {id:`proc_${s}_${Math.random().toString(36).substring(2,11)}`,name:"",description:"",controllerDetails:{name:"",contact:"",address:""},lawfulBasis:"consent",lawfulBasisJustification:"",purposes:[],dataCategories:[],dataSubjectCategories:[],recipients:[],retentionPeriod:"",securityMeasures:[],dataSource:"data_subject",dpiaRequired:false,automatedDecisionMaking:false,status:"active",createdAt:s,updatedAt:s}}function X(s){return s?new Date(s).toLocaleDateString():"N/A"}var he=({ropa:s,onAddRecord:h,onUpdateRecord:k,onArchiveRecord:w,title:Y="Record of Processing Activities (ROPA)",description:Z="Maintain a comprehensive record of all data processing activities as required by the NDPA 2023.",className:R="",buttonClassName:D=""})=>{let[m,c]=e.useState("list"),[f,ee]=e.useState(""),[y,te]=e.useState("all"),[N,re]=e.useState("all"),[a,g]=e.useState(null),[A,x]=e.useState([]),[F,B]=e.useState(""),[I,M]=e.useState(""),[L,j]=e.useState(""),[O,_]=e.useState(""),[E,T]=e.useState(""),[U,$]=e.useState(""),[J,q]=e.useState(""),i=e.useMemo(()=>chunkSWF3YVE5_js.b(s),[s]),b=e.useMemo(()=>chunkSWF3YVE5_js.d(s),[s]),V=e.useMemo(()=>{let r=[...s.records];if(y!=="all"&&(r=r.filter(t=>t.status===y)),N!=="all"&&(r=r.filter(t=>t.lawfulBasis===N)),f){let t=f.toLowerCase();r=r.filter(l=>l.name.toLowerCase().includes(t)||l.description.toLowerCase().includes(t)||l.dataCategories.some(n=>n.toLowerCase().includes(t))||l.department&&l.department.toLowerCase().includes(t));}return r},[s.records,y,N,f]);e.useEffect(()=>{a&&(B(a.purposes.join(", ")),M(a.dataCategories.join(", ")),j((a.sensitiveDataCategories||[]).join(", ")),_(a.dataSubjectCategories.join(", ")),T(a.recipients.join(", ")),$(a.securityMeasures.join(", ")),q((a.systemsUsed||[]).join(", ")));},[a==null?void 0:a.id]);let ae=()=>{let r=fe();r.controllerDetails.name=s.organizationName,r.controllerDetails.contact=s.organizationContact,r.controllerDetails.address=s.organizationAddress,s.ndpcRegistrationNumber&&(r.controllerDetails.registrationNumber=s.ndpcRegistrationNumber),s.dpoDetails&&(r.controllerDetails.dpoContact=s.dpoDetails.email),g(r),x([]),c("form");},se=r=>{g(chunkMQFZHA2D_js.a({},r)),x([]),c("form");},u=r=>r.split(",").map(t=>t.trim()).filter(t=>t.length>0),le=()=>{if(!a)return;let r=chunkMQFZHA2D_js.b(chunkMQFZHA2D_js.a({},a),{purposes:u(F),dataCategories:u(I),sensitiveDataCategories:u(L),dataSubjectCategories:u(O),recipients:u(E),securityMeasures:u(U),systemsUsed:u(J),updatedAt:Date.now()});r.sensitiveDataCategories&&r.sensitiveDataCategories.length===0&&(r.sensitiveDataCategories=void 0),r.systemsUsed&&r.systemsUsed.length===0&&(r.systemsUsed=void 0);let t=chunkSWF3YVE5_js.a(r);if(!t.valid){x(t.errors);return}s.records.find(n=>n.id===r.id)?k==null||k(r.id,r):h==null||h(r),g(null),x([]),c("list");},oe=r=>{w==null||w(r);},de=()=>{let r=chunkSWF3YVE5_js.c(s),t=new Blob([r],{type:"text/csv;charset=utf-8;"}),l=URL.createObjectURL(t),n=document.createElement("a");n.href=l,n.download=`ropa_${s.organizationName.replace(/\s+/g,"_").toLowerCase()}_${new Date().toISOString().slice(0,10)}.csv`,n.click(),setTimeout(()=>URL.revokeObjectURL(l),100);},z=()=>{g(null),x([]),c("list");},o=(r,t)=>{a&&g(l=>l&&chunkMQFZHA2D_js.b(chunkMQFZHA2D_js.a({},l),{[r]:t}));},C=(r,t)=>{a&&g(l=>l&&chunkMQFZHA2D_js.b(chunkMQFZHA2D_js.a({},l),{controllerDetails:chunkMQFZHA2D_js.b(chunkMQFZHA2D_js.a({},l.controllerDetails),{[r]:t})}));},ie=r=>!!r.nextReviewDate&&r.nextReviewDate<=Date.now(),ne=r=>{let t={active:"bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200",inactive:"bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200",archived:"bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300"},l={active:"Active",inactive:"Inactive",archived:"Archived"};return e__default.default.createElement("span",{className:`px-2 py-1 rounded text-xs font-medium ${t[r]}`},l[r])},ue=r=>e__default.default.createElement("span",{className:"px-2 py-1 rounded text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200"},{consent:"Consent",contract:"Contract",legal_obligation:"Legal Obligation",vital_interests:"Vital Interests",public_interest:"Public Interest",legitimate_interests:"Legitimate Interests"}[r]),me=()=>e__default.default.createElement("div",{className:"mb-6 p-4 bg-gray-50 dark:bg-gray-700 rounded-md"},e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("p",{className:"text-sm font-medium text-gray-500 dark:text-gray-400"},"Organization"),e__default.default.createElement("p",{className:"text-sm font-semibold"},s.organizationName)),s.dpoDetails&&e__default.default.createElement("div",null,e__default.default.createElement("p",{className:"text-sm font-medium text-gray-500 dark:text-gray-400"},"Data Protection Officer"),e__default.default.createElement("p",{className:"text-sm font-semibold"},s.dpoDetails.name),e__default.default.createElement("p",{className:"text-xs text-gray-500 dark:text-gray-400"},s.dpoDetails.email)),s.ndpcRegistrationNumber&&e__default.default.createElement("div",null,e__default.default.createElement("p",{className:"text-sm font-medium text-gray-500 dark:text-gray-400"},"NDPC Registration No."),e__default.default.createElement("p",{className:"text-sm font-semibold"},s.ndpcRegistrationNumber))),e__default.default.createElement("div",{className:"mt-2 text-xs text-gray-500 dark:text-gray-400"},"Version ",s.version," | Last Updated: ",X(s.lastUpdated))),ce=()=>e__default.default.createElement("div",{className:"mb-6"},e__default.default.createElement("div",{className:"grid grid-cols-2 md:grid-cols-4 gap-4 mb-4"},e__default.default.createElement("div",{className:"p-4 bg-blue-50 dark:bg-blue-900/20 rounded-md text-center"},e__default.default.createElement("p",{className:"text-2xl font-bold text-blue-700 dark:text-blue-300"},i.totalRecords),e__default.default.createElement("p",{className:"text-xs text-blue-600 dark:text-blue-400"},"Total Records")),e__default.default.createElement("div",{className:"p-4 bg-green-50 dark:bg-green-900/20 rounded-md text-center"},e__default.default.createElement("p",{className:"text-2xl font-bold text-green-700 dark:text-green-300"},i.activeRecords),e__default.default.createElement("p",{className:"text-xs text-green-600 dark:text-green-400"},"Active")),e__default.default.createElement("div",{className:"p-4 bg-purple-50 dark:bg-purple-900/20 rounded-md text-center"},e__default.default.createElement("p",{className:"text-2xl font-bold text-purple-700 dark:text-purple-300"},i.crossBorderRecords),e__default.default.createElement("p",{className:"text-xs text-purple-600 dark:text-purple-400"},"Cross-Border")),e__default.default.createElement("div",{className:"p-4 bg-orange-50 dark:bg-orange-900/20 rounded-md text-center"},e__default.default.createElement("p",{className:"text-2xl font-bold text-orange-700 dark:text-orange-300"},b.length),e__default.default.createElement("p",{className:"text-xs text-orange-600 dark:text-orange-400"},"Records with Gaps"))),e__default.default.createElement("div",{className:"grid grid-cols-2 md:grid-cols-3 gap-4 mb-4"},e__default.default.createElement("div",{className:"p-3 bg-gray-50 dark:bg-gray-700 rounded-md"},e__default.default.createElement("p",{className:"text-sm font-medium mb-2"},"By Lawful Basis"),P.map(r=>e__default.default.createElement("div",{key:r.value,className:"flex justify-between text-xs mb-1"},e__default.default.createElement("span",{className:"text-gray-600 dark:text-gray-400"},r.label.split(" (")[0]),e__default.default.createElement("span",{className:"font-medium"},i.byLawfulBasis[r.value]||0)))),e__default.default.createElement("div",{className:"p-3 bg-gray-50 dark:bg-gray-700 rounded-md"},e__default.default.createElement("p",{className:"text-sm font-medium mb-2"},"Risk Indicators"),e__default.default.createElement("div",{className:"flex justify-between text-xs mb-1"},e__default.default.createElement("span",{className:"text-gray-600 dark:text-gray-400"},"Sensitive Data"),e__default.default.createElement("span",{className:"font-medium"},i.sensitiveDataRecords)),e__default.default.createElement("div",{className:"flex justify-between text-xs mb-1"},e__default.default.createElement("span",{className:"text-gray-600 dark:text-gray-400"},"DPIA Required"),e__default.default.createElement("span",{className:"font-medium"},i.dpiaRequiredRecords)),e__default.default.createElement("div",{className:"flex justify-between text-xs mb-1"},e__default.default.createElement("span",{className:"text-gray-600 dark:text-gray-400"},"Automated Decisions"),e__default.default.createElement("span",{className:"font-medium"},i.automatedDecisionRecords)),e__default.default.createElement("div",{className:"flex justify-between text-xs mb-1"},e__default.default.createElement("span",{className:"text-gray-600 dark:text-gray-400"},"Due for Review"),e__default.default.createElement("span",{className:`font-medium ${i.recordsDueForReview.length>0?"text-red-600 dark:text-red-400":""}`},i.recordsDueForReview.length))),i.topDepartments.length>0&&e__default.default.createElement("div",{className:"p-3 bg-gray-50 dark:bg-gray-700 rounded-md"},e__default.default.createElement("p",{className:"text-sm font-medium mb-2"},"Top Departments"),i.topDepartments.slice(0,5).map(r=>e__default.default.createElement("div",{key:r.department,className:"flex justify-between text-xs mb-1"},e__default.default.createElement("span",{className:"text-gray-600 dark:text-gray-400"},r.department),e__default.default.createElement("span",{className:"font-medium"},r.count))))),b.length>0&&e__default.default.createElement("div",{className:"p-3 bg-red-50 dark:bg-red-900/20 rounded-md"},e__default.default.createElement("p",{className:"text-sm font-medium text-red-800 dark:text-red-200 mb-2"},"Compliance Gaps Detected"),b.slice(0,5).map(r=>e__default.default.createElement("div",{key:r.recordId,className:"mb-2"},e__default.default.createElement("p",{className:"text-xs font-medium text-red-700 dark:text-red-300"},r.recordName),e__default.default.createElement("ul",{className:"list-disc list-inside"},r.gaps.map((t,l)=>e__default.default.createElement("li",{key:l,className:"text-xs text-red-600 dark:text-red-400"},t))))),b.length>5&&e__default.default.createElement("p",{className:"text-xs text-red-600 dark:text-red-400 mt-1"},"...and ",b.length-5," more record(s) with gaps."))),ge=()=>e__default.default.createElement("div",null,e__default.default.createElement("div",{className:"mb-4 grid grid-cols-1 md:grid-cols-4 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"ropaSearch",className:"block text-sm font-medium mb-1"},"Search"),e__default.default.createElement("input",{type:"text",id:"ropaSearch",value:f,onChange:r=>ee(r.target.value),placeholder:"Search records...",className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"ropaStatusFilter",className:"block text-sm font-medium mb-1"},"Status"),e__default.default.createElement("select",{id:"ropaStatusFilter",value:y,onChange:r=>te(r.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"},e__default.default.createElement("option",{value:"all"},"All Statuses"),Q.map(r=>e__default.default.createElement("option",{key:r.value,value:r.value},r.label)))),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"ropaBasisFilter",className:"block text-sm font-medium mb-1"},"Lawful Basis"),e__default.default.createElement("select",{id:"ropaBasisFilter",value:N,onChange:r=>re(r.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"},e__default.default.createElement("option",{value:"all"},"All Bases"),P.map(r=>e__default.default.createElement("option",{key:r.value,value:r.value},r.label.split(" (")[0])))),e__default.default.createElement("div",{className:"flex items-end space-x-2"},e__default.default.createElement("button",{onClick:ae,className:`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 text-sm ${D}`},"Add Record"),e__default.default.createElement("button",{onClick:de,className:`px-4 py-2 bg-gray-600 text-white rounded hover:bg-gray-700 text-sm ${D}`},"Export CSV"))),V.length===0?e__default.default.createElement("p",{className:"text-gray-500 dark:text-gray-400 text-sm text-center py-8"},"No processing records found."):e__default.default.createElement("div",{className:"overflow-x-auto"},e__default.default.createElement("table",{className:"w-full text-sm text-left"},e__default.default.createElement("thead",{className:"text-xs uppercase bg-gray-50 dark:bg-gray-700"},e__default.default.createElement("tr",null,e__default.default.createElement("th",{className:"px-4 py-3"},"Name"),e__default.default.createElement("th",{className:"px-4 py-3"},"Lawful Basis"),e__default.default.createElement("th",{className:"px-4 py-3"},"Data Categories"),e__default.default.createElement("th",{className:"px-4 py-3"},"Status"),e__default.default.createElement("th",{className:"px-4 py-3"},"Last Reviewed"),e__default.default.createElement("th",{className:"px-4 py-3"},"Actions"))),e__default.default.createElement("tbody",null,V.map(r=>{let t=ie(r),l=b.some(n=>n.recordId===r.id);return e__default.default.createElement("tr",{key:r.id,className:`border-b dark:border-gray-600 ${t?"bg-red-50 dark:bg-red-900/10":l?"bg-yellow-50 dark:bg-yellow-900/10":"bg-white dark:bg-gray-800"} hover:bg-gray-50 dark:hover:bg-gray-700`},e__default.default.createElement("td",{className:"px-4 py-3"},e__default.default.createElement("div",null,e__default.default.createElement("p",{className:"font-medium"},r.name),r.department&&e__default.default.createElement("p",{className:"text-xs text-gray-500 dark:text-gray-400"},r.department),t&&e__default.default.createElement("span",{className:"text-xs text-red-600 dark:text-red-400 font-medium"},"Review Overdue"))),e__default.default.createElement("td",{className:"px-4 py-3"},ue(r.lawfulBasis)),e__default.default.createElement("td",{className:"px-4 py-3"},e__default.default.createElement("p",{className:"text-xs text-gray-600 dark:text-gray-300 max-w-xs truncate"},r.dataCategories.join(", "))),e__default.default.createElement("td",{className:"px-4 py-3"},ne(r.status)),e__default.default.createElement("td",{className:"px-4 py-3 text-xs text-gray-500 dark:text-gray-400"},X(r.lastReviewedAt)),e__default.default.createElement("td",{className:"px-4 py-3"},e__default.default.createElement("div",{className:"flex space-x-2"},e__default.default.createElement("button",{onClick:()=>se(r),className:"text-blue-600 dark:text-blue-400 hover:underline text-xs"},"Edit"),r.status!=="archived"&&e__default.default.createElement("button",{onClick:()=>oe(r.id),className:"text-gray-600 dark:text-gray-400 hover:underline text-xs"},"Archive"))))}))))),be=()=>{if(!a)return null;let r=!s.records.find(t=>t.id===a.id);return e__default.default.createElement("div",null,e__default.default.createElement("div",{className:"flex justify-between items-center mb-4"},e__default.default.createElement("h3",{className:"text-lg font-medium"},r?"Add Processing Record":"Edit Processing Record"),e__default.default.createElement("button",{onClick:z,className:"text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 text-sm"},"Cancel")),A.length>0&&e__default.default.createElement("div",{className:"mb-4 p-3 bg-red-50 dark:bg-red-900/20 rounded-md"},e__default.default.createElement("p",{className:"text-sm font-medium text-red-800 dark:text-red-200 mb-1"},"Please fix the following errors:"),e__default.default.createElement("ul",{className:"list-disc list-inside"},A.map((t,l)=>e__default.default.createElement("li",{key:l,className:"text-xs text-red-600 dark:text-red-400"},t)))),e__default.default.createElement("div",{className:"space-y-6"},e__default.default.createElement("fieldset",{className:"border border-gray-200 dark:border-gray-600 rounded-md p-4"},e__default.default.createElement("legend",{className:"text-sm font-medium px-2"},"Basic Information"),e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"recordName",className:"block text-sm font-medium mb-1"},"Activity Name *"),e__default.default.createElement("input",{type:"text",id:"recordName",value:a.name,onChange:t=>o("name",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Customer Account Management"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"recordDepartment",className:"block text-sm font-medium mb-1"},"Department"),e__default.default.createElement("input",{type:"text",id:"recordDepartment",value:a.department||"",onChange:t=>o("department",t.target.value||void 0),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Marketing"})),e__default.default.createElement("div",{className:"md:col-span-2"},e__default.default.createElement("label",{htmlFor:"recordDescription",className:"block text-sm font-medium mb-1"},"Description *"),e__default.default.createElement("textarea",{id:"recordDescription",value:a.description,onChange:t=>o("description",t.target.value),rows:3,className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"Describe what personal data processing is performed..."})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"recordStatus",className:"block text-sm font-medium mb-1"},"Status *"),e__default.default.createElement("select",{id:"recordStatus",value:a.status,onChange:t=>o("status",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"},Q.map(t=>e__default.default.createElement("option",{key:t.value,value:t.value},t.label)))))),e__default.default.createElement("fieldset",{className:"border border-gray-200 dark:border-gray-600 rounded-md p-4"},e__default.default.createElement("legend",{className:"text-sm font-medium px-2"},"Controller Details"),e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"controllerName",className:"block text-sm font-medium mb-1"},"Controller Name *"),e__default.default.createElement("input",{type:"text",id:"controllerName",value:a.controllerDetails.name,onChange:t=>C("name",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"controllerContact",className:"block text-sm font-medium mb-1"},"Controller Contact *"),e__default.default.createElement("input",{type:"text",id:"controllerContact",value:a.controllerDetails.contact,onChange:t=>C("contact",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"})),e__default.default.createElement("div",{className:"md:col-span-2"},e__default.default.createElement("label",{htmlFor:"controllerAddress",className:"block text-sm font-medium mb-1"},"Controller Address *"),e__default.default.createElement("input",{type:"text",id:"controllerAddress",value:a.controllerDetails.address,onChange:t=>C("address",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"})))),e__default.default.createElement("fieldset",{className:"border border-gray-200 dark:border-gray-600 rounded-md p-4"},e__default.default.createElement("legend",{className:"text-sm font-medium px-2"},"Lawful Basis (NDPA Section 25)"),e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"lawfulBasis",className:"block text-sm font-medium mb-1"},"Lawful Basis *"),e__default.default.createElement("select",{id:"lawfulBasis",value:a.lawfulBasis,onChange:t=>o("lawfulBasis",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"},P.map(t=>e__default.default.createElement("option",{key:t.value,value:t.value},t.label)))),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"lawfulBasisJustification",className:"block text-sm font-medium mb-1"},"Justification *"),e__default.default.createElement("textarea",{id:"lawfulBasisJustification",value:a.lawfulBasisJustification,onChange:t=>o("lawfulBasisJustification",t.target.value),rows:2,className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"Explain why this lawful basis applies..."})))),e__default.default.createElement("fieldset",{className:"border border-gray-200 dark:border-gray-600 rounded-md p-4"},e__default.default.createElement("legend",{className:"text-sm font-medium px-2"},"Data Details"),e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"purposes",className:"block text-sm font-medium mb-1"},"Purposes * (comma-separated)"),e__default.default.createElement("input",{type:"text",id:"purposes",value:F,onChange:t=>B(t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Account management, Service delivery"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"dataCategories",className:"block text-sm font-medium mb-1"},"Data Categories * (comma-separated)"),e__default.default.createElement("input",{type:"text",id:"dataCategories",value:I,onChange:t=>M(t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Name, Email, Phone number"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"sensitiveData",className:"block text-sm font-medium mb-1"},"Sensitive Data Categories (comma-separated)"),e__default.default.createElement("input",{type:"text",id:"sensitiveData",value:L,onChange:t=>j(t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Health data, Biometric data"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"subjectCategories",className:"block text-sm font-medium mb-1"},"Data Subject Categories * (comma-separated)"),e__default.default.createElement("input",{type:"text",id:"subjectCategories",value:O,onChange:t=>_(t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Customers, Employees"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"recipients",className:"block text-sm font-medium mb-1"},"Recipients * (comma-separated)"),e__default.default.createElement("input",{type:"text",id:"recipients",value:E,onChange:t=>T(t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Payment processors, Cloud service providers"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"dataSource",className:"block text-sm font-medium mb-1"},"Data Source *"),e__default.default.createElement("select",{id:"dataSource",value:a.dataSource,onChange:t=>o("dataSource",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"},ve.map(t=>e__default.default.createElement("option",{key:t.value,value:t.value},t.label)))),a.dataSource==="third_party"&&e__default.default.createElement("div",{className:"md:col-span-2"},e__default.default.createElement("label",{htmlFor:"thirdPartyDetails",className:"block text-sm font-medium mb-1"},"Third-Party Source Details *"),e__default.default.createElement("input",{type:"text",id:"thirdPartyDetails",value:a.thirdPartySourceDetails||"",onChange:t=>o("thirdPartySourceDetails",t.target.value||void 0),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"Describe the third-party data source..."})))),e__default.default.createElement("fieldset",{className:"border border-gray-200 dark:border-gray-600 rounded-md p-4"},e__default.default.createElement("legend",{className:"text-sm font-medium px-2"},"Retention and Security"),e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"retentionPeriod",className:"block text-sm font-medium mb-1"},"Retention Period *"),e__default.default.createElement("input",{type:"text",id:"retentionPeriod",value:a.retentionPeriod,onChange:t=>o("retentionPeriod",t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., 5 years after account closure"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"retentionJustification",className:"block text-sm font-medium mb-1"},"Retention Justification"),e__default.default.createElement("input",{type:"text",id:"retentionJustification",value:a.retentionJustification||"",onChange:t=>o("retentionJustification",t.target.value||void 0),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"Why this retention period is necessary..."})),e__default.default.createElement("div",{className:"md:col-span-2"},e__default.default.createElement("label",{htmlFor:"securityMeasures",className:"block text-sm font-medium mb-1"},"Security Measures * (comma-separated)"),e__default.default.createElement("input",{type:"text",id:"securityMeasures",value:U,onChange:t=>$(t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., Encryption at rest, Access controls, Audit logging"})),e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"systemsUsed",className:"block text-sm font-medium mb-1"},"Systems Used (comma-separated)"),e__default.default.createElement("input",{type:"text",id:"systemsUsed",value:J,onChange:t=>q(t.target.value),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"e.g., CRM, ERP, Cloud Storage"})))),e__default.default.createElement("fieldset",{className:"border border-gray-200 dark:border-gray-600 rounded-md p-4"},e__default.default.createElement("legend",{className:"text-sm font-medium px-2"},"Risk Indicators"),e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4"},e__default.default.createElement("div",{className:"flex items-center space-x-2"},e__default.default.createElement("input",{type:"checkbox",id:"dpiaRequired",checked:a.dpiaRequired,onChange:t=>o("dpiaRequired",t.target.checked),className:"rounded border-gray-300 dark:border-gray-600"}),e__default.default.createElement("label",{htmlFor:"dpiaRequired",className:"text-sm font-medium"},"DPIA Required")),a.dpiaRequired&&e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"dpiaReference",className:"block text-sm font-medium mb-1"},"DPIA Reference *"),e__default.default.createElement("input",{type:"text",id:"dpiaReference",value:a.dpiaReference||"",onChange:t=>o("dpiaReference",t.target.value||void 0),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"Reference to the completed DPIA"})),e__default.default.createElement("div",{className:"flex items-center space-x-2"},e__default.default.createElement("input",{type:"checkbox",id:"automatedDecisionMaking",checked:a.automatedDecisionMaking,onChange:t=>o("automatedDecisionMaking",t.target.checked),className:"rounded border-gray-300 dark:border-gray-600"}),e__default.default.createElement("label",{htmlFor:"automatedDecisionMaking",className:"text-sm font-medium"},"Automated Decision-Making")),a.automatedDecisionMaking&&e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"automatedDecisionMakingDetails",className:"block text-sm font-medium mb-1"},"Automated Decision-Making Details *"),e__default.default.createElement("textarea",{id:"automatedDecisionMakingDetails",value:a.automatedDecisionMakingDetails||"",onChange:t=>o("automatedDecisionMakingDetails",t.target.value||void 0),rows:2,className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500",placeholder:"Describe the automated decision-making process..."})))),e__default.default.createElement("fieldset",{className:"border border-gray-200 dark:border-gray-600 rounded-md p-4"},e__default.default.createElement("legend",{className:"text-sm font-medium px-2"},"Review Schedule"),e__default.default.createElement("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4"},e__default.default.createElement("div",null,e__default.default.createElement("label",{htmlFor:"nextReviewDate",className:"block text-sm font-medium mb-1"},"Next Review Date"),e__default.default.createElement("input",{type:"date",id:"nextReviewDate",value:a.nextReviewDate?new Date(a.nextReviewDate).toISOString().slice(0,10):"",onChange:t=>o("nextReviewDate",t.target.value?new Date(t.target.value).getTime():void 0),className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"})))),e__default.default.createElement("div",{className:"flex justify-end space-x-3"},e__default.default.createElement("button",{onClick:z,className:"px-4 py-2 border border-gray-300 dark:border-gray-600 rounded hover:bg-gray-50 dark:hover:bg-gray-700 text-sm"},"Cancel"),e__default.default.createElement("button",{onClick:le,className:`px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700 text-sm ${D}`},r?"Add Record":"Save Changes"))))},pe=()=>e__default.default.createElement("div",{className:"flex space-x-4 mb-6 border-b border-gray-200 dark:border-gray-600"},e__default.default.createElement("button",{onClick:()=>c("list"),className:`pb-2 text-sm font-medium ${m==="list"?"border-b-2 border-blue-500 text-blue-600 dark:text-blue-400":"text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"}`},"Processing Records"),e__default.default.createElement("button",{onClick:()=>c("summary"),className:`pb-2 text-sm font-medium ${m==="summary"?"border-b-2 border-blue-500 text-blue-600 dark:text-blue-400":"text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300"}`},"Compliance Summary"));return e__default.default.createElement("div",{className:`bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md ${R}`},e__default.default.createElement("h2",{className:"text-xl font-bold mb-2"},Y),e__default.default.createElement("p",{className:"mb-6 text-gray-600 dark:text-gray-300"},Z),me(),m!=="form"&&pe(),m==="list"&&ge(),m==="summary"&&ce(),m==="form"&&be())};exports.a=he;//# sourceMappingURL=chunk-UUWVBENC.js.map
2
+ //# sourceMappingURL=chunk-UUWVBENC.js.map