@tantainnovative/ndpr-toolkit 5.1.3 → 5.2.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,31 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [5.2.0](https://github.com/mr-tanta/ndpr-toolkit/compare/v5.1.4...v5.2.0) (2026-05-30)
6
+
7
+
8
+ ### Features
9
+
10
+ * **car:** add NDPC GAID 2025 Compliance Audit Returns scheduler ([30d399a](https://github.com/mr-tanta/ndpr-toolkit/commit/30d399a38b51632f8a3fdcb01a329f983eb7ca06))
11
+ * **dcpmi:** add NDPC GAID 2025 DCPMI tier classifier ([179a5c1](https://github.com/mr-tanta/ndpr-toolkit/commit/179a5c1d6a7b9a3fba89947ff2d943b2159a142c))
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * address findings from the A–Z verification pass ([4ede74f](https://github.com/mr-tanta/ndpr-toolkit/commit/4ede74f9aece2c74d8377a91068522d534daa6fc))
17
+
18
+
19
+ ### Documentation
20
+
21
+ * document DCPMI classifier and Compliance Audit Returns ([a7fefe1](https://github.com/mr-tanta/ndpr-toolkit/commit/a7fefe1a07b58d1b4d9e6f0a8b20b3a4c8f4fef6))
22
+
23
+ ## [5.1.4](https://github.com/mr-tanta/ndpr-toolkit/compare/v5.1.3...v5.1.4) (2026-05-28)
24
+
25
+
26
+ ### Bug Fixes
27
+
28
+ * **deps:** remove unused tailwind-merge peer dependency ([5aec54b](https://github.com/mr-tanta/ndpr-toolkit/commit/5aec54ba4fbdc9cdb69368f7477b87016af7755d))
29
+
5
30
  ## [5.1.3](https://github.com/mr-tanta/ndpr-toolkit/compare/v5.1.2...v5.1.3) (2026-05-28)
6
31
 
7
32
 
package/README.md CHANGED
@@ -449,6 +449,63 @@ import { NDPRComplianceDashboard } from '@tantainnovative/ndpr-toolkit/presets';
449
449
 
450
450
  ---
451
451
 
452
+ ## DCPMI & Compliance Audit Returns
453
+
454
+ Two pure utilities for the NDPC **General Application and Implementation Directive (GAID) 2025** registration regime — no React, safe to run server-side or in CI.
455
+
456
+ `classifyDCPMI()` derives an organisation's **Data Controller/Processor of Major Importance** tier from the number of data subjects processed in a six-month window, with its annual registration fee and filing obligations:
457
+
458
+ ```ts
459
+ import { classifyDCPMI } from '@tantainnovative/ndpr-toolkit/core';
460
+
461
+ const result = classifyDCPMI({ dataSubjectsInSixMonths: 6200 });
462
+
463
+ result.tier; // "UHL" (>5,000 → Ultra High Level)
464
+ result.isDCPMI; // true
465
+ result.annualFeeNGN; // 250000
466
+ result.registration.renewsAnnually; // false (UHL/EHL register once, file CAR yearly)
467
+ result.compliance.auditReturnsAnnual; // true
468
+ result.compliance.initialAuditWithinMonths; // 15
469
+ ```
470
+
471
+ | Tier | Data subjects / 6 months | Annual fee (₦) |
472
+ |------|--------------------------|----------------|
473
+ | **UHL** — Ultra High Level | more than 5,000 | 250,000 |
474
+ | **EHL** — Extra High Level | 1,000 – 5,000 | 100,000 |
475
+ | **OHL** — Ordinary High Level | 200 – 999 | 10,000 |
476
+ | below 200 | — | not a DCPMI by volume |
477
+
478
+ Thresholds and fees are the September 2025 GAID baseline and are configurable (`classifyDCPMI(input, { thresholds, fees })`) since the NDPC revises them. Pass `isDesignated: true` for an organisation the Commission has separately listed — it resolves to the `'listed'` tier regardless of volume.
479
+
480
+ `generateComplianceAuditReturn()` schedules a DCPMI's **Compliance Audit Returns** — the initial audit due within 15 months of commencement, then the next annual filing deadline (NDPC baseline 31 March, filed via the NDPC Information Management Portal / NIMP):
481
+
482
+ ```ts
483
+ import { generateComplianceAuditReturn } from '@tantainnovative/ndpr-toolkit/core';
484
+
485
+ const car = generateComplianceAuditReturn({
486
+ commencementDate: '2025-01-15',
487
+ asOf: '2026-03-21',
488
+ tier: 'UHL',
489
+ });
490
+
491
+ car.schedule.initialAuditDueDate; // "2026-04-15" (commencement + 15 months)
492
+ car.schedule.nextFilingDeadline; // "2026-03-31"
493
+ car.status.daysUntilNextDeadline; // 10
494
+ car.status.initialAuditDue; // false
495
+
496
+ // NDPC deadlines shift — the 2026 filing was extended to 30 May:
497
+ generateComplianceAuditReturn(
498
+ { commencementDate: '2025-01-15', asOf: '2026-04-01', tier: 'UHL' },
499
+ { deadlineOverrides: { 2026: '2026-05-30' } },
500
+ ).schedule.nextFilingDeadline; // "2026-05-30"
501
+ ```
502
+
503
+ Both ship as memoised hooks for React UIs — `useDCPMI(input, options?)` and `useComplianceAuditReturn(input, options?)` from `@tantainnovative/ndpr-toolkit/hooks`.
504
+
505
+ > These utilities compute registration tiers and filing dates from the GAID 2025 baseline; they are not legal advice. The NDPC revises metrics and extends deadlines — verify against current NDPC guidance before relying on them.
506
+
507
+ ---
508
+
452
509
  ## Backend Integration
453
510
 
454
511
  ### CLI scaffolder
@@ -1 +1 @@
1
- var m=["critical","high","medium","low"];function p(e){let i=new Date(e).getTime();if(isNaN(i))return 1/0;let t=(Date.now()-i)/(1e3*60*60*24*30.44);return Math.max(0,t)}function u(e){if(e.length===0)return 100;let i=e.filter(t=>t.pass).length;return Math.round(i/e.length*100)}function f(e){return [{key:"hasConsentMechanism",label:"Consent collection mechanism",priority:"critical",effort:"high",recommendation:"Implement a clear, affirmative consent collection mechanism before processing personal data.",ndpaSection:"Section 25",pass:e.hasConsentMechanism},{key:"hasPurposeSpecification",label:"Purpose specification at collection",priority:"critical",effort:"medium",recommendation:"Specify and communicate the purpose of data collection at the point of consent.",ndpaSection:"Section 25",pass:e.hasPurposeSpecification},{key:"hasWithdrawalMechanism",label:"Consent withdrawal mechanism",priority:"high",effort:"medium",recommendation:"Provide a simple mechanism for data subjects to withdraw consent at any time.",ndpaSection:"Section 26",pass:e.hasWithdrawalMechanism},{key:"hasMinorProtection",label:"Minor (child) data protection controls",priority:"high",effort:"high",recommendation:"Implement age-verification and parental-consent controls for processing data of minors.",ndpaSection:"Section 31",pass:e.hasMinorProtection},{key:"consentRecordsRetained",label:"Consent records retained",priority:"medium",effort:"low",recommendation:"Retain records of all consents obtained, including what was agreed to and when.",ndpaSection:"Section 25",pass:e.consentRecordsRetained}]}function g(e){let i=e.responseTimelineDays<=30;return [{key:"hasRequestMechanism",label:"DSR submission mechanism",priority:"critical",effort:"high",recommendation:"Implement a formal channel (e.g. a web form or email address) for data subjects to submit requests.",ndpaSection:"Section 34",pass:e.hasRequestMechanism},{key:"supportsAccess",label:"Right of access supported",priority:"high",effort:"medium",recommendation:"Enable data subjects to request and receive a copy of their personal data.",ndpaSection:"Section 34(1)(a)\u2013(b)",pass:e.supportsAccess},{key:"supportsRectification",label:"Right to rectification supported",priority:"high",effort:"medium",recommendation:"Allow data subjects to request correction of inaccurate or incomplete personal data.",ndpaSection:"Section 34(1)(c)",pass:e.supportsRectification},{key:"supportsErasure",label:"Right to erasure supported",priority:"high",effort:"high",recommendation:"Implement processes to delete personal data upon valid erasure requests.",ndpaSection:"Section 34(1)(d), Section 34(2)",pass:e.supportsErasure},{key:"supportsPortability",label:"Right to data portability supported",priority:"medium",effort:"high",recommendation:"Provide personal data in a structured, machine-readable format upon request.",ndpaSection:"Section 38",pass:e.supportsPortability},{key:"supportsObjection",label:"Right to object supported",priority:"medium",effort:"medium",recommendation:"Honour objections to processing where no compelling legitimate grounds override the data subject's interests.",ndpaSection:"Section 36",pass:e.supportsObjection},{key:"responseTimeline",label:"DSR response within 30 days",priority:"high",effort:"medium",recommendation:"Reduce DSR response time to 30 days or less per NDPC guidance (GAID 2025).",ndpaSection:"Section 34 (NDPC GAID 2025 timeline guidance)",pass:i}]}function y(e){return [{key:"conductedForHighRisk",label:"DPIA conducted for high-risk processing",priority:"critical",effort:"high",recommendation:"Conduct a Data Protection Impact Assessment before undertaking high-risk processing activities.",ndpaSection:"Section 28",pass:e.conductedForHighRisk},{key:"documentedRisks",label:"Risks documented in DPIA",priority:"high",effort:"medium",recommendation:"Document identified risks to data subjects' rights and freedoms within the DPIA.",ndpaSection:"Section 28",pass:e.documentedRisks},{key:"mitigationMeasures",label:"Mitigation measures documented",priority:"high",effort:"medium",recommendation:"Document mitigation measures and residual risk acceptance within the DPIA.",ndpaSection:"Section 28",pass:e.mitigationMeasures}]}function b(e){return [{key:"hasNotificationProcess",label:"Breach notification process in place",priority:"critical",effort:"high",recommendation:"Establish a documented breach notification process covering detection, assessment, and reporting.",ndpaSection:"Section 40",pass:e.hasNotificationProcess},{key:"notifiesWithin72Hours",label:"NDPC notified within 72 hours",priority:"critical",effort:"medium",recommendation:"Ensure the NDPC is notified of qualifying breaches within 72 hours of discovery.",ndpaSection:"Section 40",pass:e.notifiesWithin72Hours},{key:"hasRiskAssessment",label:"Breach risk assessment performed",priority:"high",effort:"medium",recommendation:"Perform a risk assessment for every identified breach to determine notification obligations.",ndpaSection:"Section 40",pass:e.hasRiskAssessment},{key:"hasRecordKeeping",label:"Breach records maintained",priority:"medium",effort:"low",recommendation:"Maintain a breach register documenting all incidents, assessments, and actions taken.",ndpaSection:"Section 40",pass:e.hasRecordKeeping}]}function S(e){let t=p(e.lastUpdated)<=13;return [{key:"hasPrivacyPolicy",label:"Privacy policy exists",priority:"critical",effort:"high",recommendation:"Draft and publish a comprehensive privacy policy that satisfies NDPA requirements.",ndpaSection:"Section 27",pass:e.hasPrivacyPolicy},{key:"isPubliclyAccessible",label:"Privacy policy publicly accessible",priority:"high",effort:"low",recommendation:"Make the privacy policy easily accessible to data subjects on your website or app.",ndpaSection:"Section 27",pass:e.isPubliclyAccessible},{key:"policyUpToDate",label:"Privacy policy reviewed within 13 months",priority:"medium",effort:"medium",recommendation:"Review and update the privacy policy at least annually to reflect current practices.",ndpaSection:"Section 27",pass:t},{key:"coversAllSections",label:"Privacy policy covers all required sections",priority:"high",effort:"medium",recommendation:"Ensure the privacy policy addresses all NDPA-mandated disclosures including lawful basis, retention, and subject rights.",ndpaSection:"Section 27",pass:e.coversAllSections}]}function R(e){return [{key:"documentedForAllProcessing",label:"Lawful basis documented for all processing",priority:"critical",effort:"high",recommendation:"Identify and document a valid lawful basis for every processing activity before it begins.",ndpaSection:"Section 25(1)",pass:e.documentedForAllProcessing},{key:"hasLegitimateInterestAssessment",label:"Legitimate interest assessment completed",priority:"medium",effort:"medium",recommendation:"Complete a Legitimate Interest Assessment (LIA) where legitimate interests is the chosen lawful basis.",ndpaSection:"Section 25(1)",pass:e.hasLegitimateInterestAssessment}]}function v(e){return [{key:"hasTransferMechanisms",label:"Transfer mechanisms in place",priority:"critical",effort:"high",recommendation:"Implement appropriate transfer mechanisms (SCCs, BCRs, adequacy decisions, or Section 43 derogations) for all cross-border transfers.",ndpaSection:"Section 41",pass:e.hasTransferMechanisms},{key:"adequacyAssessed",label:"Adequacy of destination country assessed",priority:"high",effort:"medium",recommendation:"Assess whether the destination country provides an adequate level of data protection before transferring.",ndpaSection:"Section 42",pass:e.adequacyAssessed},{key:"ndpcApprovalObtained",label:"NDPC approval obtained where required",priority:"high",effort:"high",recommendation:"Obtain NDPC approval (e.g. for binding corporate rules, codes of conduct, or certification mechanisms) for transfers to countries without adequacy decisions where required.",ndpaSection:"Section 42(5)",pass:e.ndpcApprovalObtained}]}function w(e){let t=p(e.lastReviewed)<=6;return [{key:"maintained",label:"Record of Processing Activities maintained",priority:"critical",effort:"high",recommendation:"Create and maintain a comprehensive Record of Processing Activities (ROPA) as required by the NDPA.",ndpaSection:"Section 29",pass:e.maintained},{key:"includesAllProcessing",label:"ROPA includes all processing activities",priority:"high",effort:"medium",recommendation:"Ensure the ROPA captures every processing activity across all departments and systems.",ndpaSection:"Section 29",pass:e.includesAllProcessing},{key:"ropaUpToDate",label:"ROPA reviewed within 6 months",priority:"medium",effort:"low",recommendation:"Review and update the ROPA at least every six months to reflect changes in processing activities.",ndpaSection:"Section 29",pass:t}]}var k=[{name:"consent",weight:.2,ndpaSections:["Section 25","Section 26"],evaluate:e=>f(e.consent)},{name:"dsr",weight:.15,ndpaSections:["Section 34","Section 35","Section 36","Section 37","Section 38"],evaluate:e=>g(e.dsr)},{name:"breach",weight:.15,ndpaSections:["Section 40"],evaluate:e=>b(e.breach)},{name:"policy",weight:.12,ndpaSections:["Section 27"],evaluate:e=>S(e.policy)},{name:"dpia",weight:.12,ndpaSections:["Section 28"],evaluate:e=>y(e.dpia)},{name:"lawfulBasis",weight:.1,ndpaSections:["Section 25(1)"],evaluate:e=>R(e.lawfulBasis)},{name:"crossBorder",weight:.08,ndpaSections:["Section 41","Section 42","Section 43"],evaluate:e=>v(e.crossBorder)},{name:"ropa",weight:.08,ndpaSections:["Section 29"],evaluate:e=>w(e.ropa)}];function P(e){return e>=90?"excellent":e>=70?"good":e>=40?"needs-work":"critical"}function C(e){let i={},t=[],s=0;for(let o of k){let a=o.evaluate(e),c=u(a),l=c*o.weight;s+=l;let d=[];for(let n of a)n.pass||(d.push(n.label),t.push({module:o.name,key:n.key,label:n.label,priority:n.priority,effort:n.effort,recommendation:n.recommendation,ndpaSection:n.ndpaSection}));i[o.name]={name:o.name,score:c,maxScore:100,weightedScore:Math.round(l*100)/100,ndpaSections:o.ndpaSections,gaps:d};}t.sort((o,a)=>m.indexOf(o.priority)-m.indexOf(a.priority));let r=Math.round(s),h=[{section:"Section 25",title:"Consent and lawful basis for processing"},{section:"Section 26",title:"Withdrawal of consent and minor protection"},{section:"Section 27",title:"Privacy notice requirements"},{section:"Section 28",title:"Data Protection Impact Assessment (including Section 28(2) NDPC consultation)"},{section:"Section 29",title:"Records of processing activities"},{section:"Section 34",title:"Data subject rights (access, rectification, erasure, restriction)"},{section:"Section 35",title:"Right to withdraw consent"},{section:"Section 36",title:"Right to object"},{section:"Section 37",title:"Rights related to automated decision-making"},{section:"Section 38",title:"Right to data portability"},{section:"Section 40",title:"Data breach notification"},{section:"Section 41",title:"Cross-border transfer mechanisms (SCCs / BCRs)"},{section:"Section 42",title:"Cross-border adequacy decisions"},{section:"Section 43",title:"Cross-border transfer derogations"}];return {score:r,rating:P(r),modules:i,recommendations:t,regulatoryReferences:h,generatedAt:new Date().toISOString()}}export{C as a};
1
+ var m=["critical","high","medium","low"];function p(e){let i=new Date(e).getTime();if(isNaN(i))return 1/0;let t=(Date.now()-i)/(1e3*60*60*24*30.44);return Math.max(0,t)}function h(e){if(e.length===0)return 100;let i=e.filter(t=>t.pass).length;return Math.round(i/e.length*100)}function f(e){return [{key:"hasConsentMechanism",label:"Consent collection mechanism",priority:"critical",effort:"high",recommendation:"Implement a clear, affirmative consent collection mechanism before processing personal data.",ndpaSection:"Section 25",pass:e.hasConsentMechanism},{key:"hasPurposeSpecification",label:"Purpose specification at collection",priority:"critical",effort:"medium",recommendation:"Specify and communicate the purpose of data collection at the point of consent.",ndpaSection:"Section 25",pass:e.hasPurposeSpecification},{key:"hasWithdrawalMechanism",label:"Consent withdrawal mechanism",priority:"high",effort:"medium",recommendation:"Provide a simple mechanism for data subjects to withdraw consent at any time.",ndpaSection:"Section 26",pass:e.hasWithdrawalMechanism},{key:"hasMinorProtection",label:"Minor (child) data protection controls",priority:"high",effort:"high",recommendation:"Implement age-verification and parental-consent controls for processing data of minors.",ndpaSection:"Section 31",pass:e.hasMinorProtection},{key:"consentRecordsRetained",label:"Consent records retained",priority:"medium",effort:"low",recommendation:"Retain records of all consents obtained, including what was agreed to and when.",ndpaSection:"Section 25",pass:e.consentRecordsRetained}]}function g(e){let i=e.responseTimelineDays<=30;return [{key:"hasRequestMechanism",label:"DSR submission mechanism",priority:"critical",effort:"high",recommendation:"Implement a formal channel (e.g. a web form or email address) for data subjects to submit requests.",ndpaSection:"Section 34",pass:e.hasRequestMechanism},{key:"supportsAccess",label:"Right of access supported",priority:"high",effort:"medium",recommendation:"Enable data subjects to request and receive a copy of their personal data.",ndpaSection:"Section 34(1)(a)\u2013(b)",pass:e.supportsAccess},{key:"supportsRectification",label:"Right to rectification supported",priority:"high",effort:"medium",recommendation:"Allow data subjects to request correction of inaccurate or incomplete personal data.",ndpaSection:"Section 34(1)(c)",pass:e.supportsRectification},{key:"supportsErasure",label:"Right to erasure supported",priority:"high",effort:"high",recommendation:"Implement processes to delete personal data upon valid erasure requests.",ndpaSection:"Section 34(1)(d), Section 34(2)",pass:e.supportsErasure},{key:"supportsPortability",label:"Right to data portability supported",priority:"medium",effort:"high",recommendation:"Provide personal data in a structured, machine-readable format upon request.",ndpaSection:"Section 38",pass:e.supportsPortability},{key:"supportsObjection",label:"Right to object supported",priority:"medium",effort:"medium",recommendation:"Honour objections to processing where no compelling legitimate grounds override the data subject's interests.",ndpaSection:"Section 36",pass:e.supportsObjection},{key:"responseTimeline",label:"DSR response within 30 days",priority:"high",effort:"medium",recommendation:"Reduce DSR response time to 30 days or less per NDPC guidance (GAID 2025).",ndpaSection:"Section 34 (NDPC GAID 2025 timeline guidance)",pass:i}]}function y(e){return [{key:"conductedForHighRisk",label:"DPIA conducted for high-risk processing",priority:"critical",effort:"high",recommendation:"Conduct a Data Protection Impact Assessment before undertaking high-risk processing activities.",ndpaSection:"Section 28",pass:e.conductedForHighRisk},{key:"documentedRisks",label:"Risks documented in DPIA",priority:"high",effort:"medium",recommendation:"Document identified risks to data subjects' rights and freedoms within the DPIA.",ndpaSection:"Section 28",pass:e.documentedRisks},{key:"mitigationMeasures",label:"Mitigation measures documented",priority:"high",effort:"medium",recommendation:"Document mitigation measures and residual risk acceptance within the DPIA.",ndpaSection:"Section 28",pass:e.mitigationMeasures}]}function b(e){return [{key:"hasNotificationProcess",label:"Breach notification process in place",priority:"critical",effort:"high",recommendation:"Establish a documented breach notification process covering detection, assessment, and reporting.",ndpaSection:"Section 40",pass:e.hasNotificationProcess},{key:"notifiesWithin72Hours",label:"NDPC notified within 72 hours",priority:"critical",effort:"medium",recommendation:"Ensure the NDPC is notified of qualifying breaches within 72 hours of discovery.",ndpaSection:"Section 40",pass:e.notifiesWithin72Hours},{key:"hasRiskAssessment",label:"Breach risk assessment performed",priority:"high",effort:"medium",recommendation:"Perform a risk assessment for every identified breach to determine notification obligations.",ndpaSection:"Section 40",pass:e.hasRiskAssessment},{key:"hasRecordKeeping",label:"Breach records maintained",priority:"medium",effort:"low",recommendation:"Maintain a breach register documenting all incidents, assessments, and actions taken.",ndpaSection:"Section 40",pass:e.hasRecordKeeping}]}function S(e){let t=p(e.lastUpdated)<=13;return [{key:"hasPrivacyPolicy",label:"Privacy policy exists",priority:"critical",effort:"high",recommendation:"Draft and publish a comprehensive privacy policy that satisfies NDPA requirements.",ndpaSection:"Section 27",pass:e.hasPrivacyPolicy},{key:"isPubliclyAccessible",label:"Privacy policy publicly accessible",priority:"high",effort:"low",recommendation:"Make the privacy policy easily accessible to data subjects on your website or app.",ndpaSection:"Section 27",pass:e.isPubliclyAccessible},{key:"policyUpToDate",label:"Privacy policy reviewed within 13 months",priority:"medium",effort:"medium",recommendation:"Review and update the privacy policy at least annually to reflect current practices.",ndpaSection:"Section 27",pass:t},{key:"coversAllSections",label:"Privacy policy covers all required sections",priority:"high",effort:"medium",recommendation:"Ensure the privacy policy addresses all NDPA-mandated disclosures including lawful basis, retention, and subject rights.",ndpaSection:"Section 27",pass:e.coversAllSections}]}function R(e){return [{key:"documentedForAllProcessing",label:"Lawful basis documented for all processing",priority:"critical",effort:"high",recommendation:"Identify and document a valid lawful basis for every processing activity before it begins.",ndpaSection:"Section 25(1)",pass:e.documentedForAllProcessing},{key:"hasLegitimateInterestAssessment",label:"Legitimate interest assessment completed",priority:"medium",effort:"medium",recommendation:"Complete a Legitimate Interest Assessment (LIA) where legitimate interests is the chosen lawful basis.",ndpaSection:"Section 25(1)",pass:e.hasLegitimateInterestAssessment}]}function v(e){return [{key:"hasTransferMechanisms",label:"Transfer mechanisms in place",priority:"critical",effort:"high",recommendation:"Implement appropriate transfer mechanisms (SCCs, BCRs, adequacy decisions, or Section 43 derogations) for all cross-border transfers.",ndpaSection:"Section 41",pass:e.hasTransferMechanisms},{key:"adequacyAssessed",label:"Adequacy of destination country assessed",priority:"high",effort:"medium",recommendation:"Assess whether the destination country provides an adequate level of data protection before transferring.",ndpaSection:"Section 42",pass:e.adequacyAssessed},{key:"ndpcApprovalObtained",label:"NDPC approval obtained where required",priority:"high",effort:"high",recommendation:"Obtain NDPC approval (e.g. for binding corporate rules, codes of conduct, or certification mechanisms) for transfers to countries without adequacy decisions where required.",ndpaSection:"Section 42(5)",pass:e.ndpcApprovalObtained}]}function w(e){let t=p(e.lastReviewed)<=6;return [{key:"maintained",label:"Record of Processing Activities maintained",priority:"critical",effort:"high",recommendation:"Create and maintain a comprehensive Record of Processing Activities (ROPA) as required by the NDPA.",ndpaSection:"Section 29",pass:e.maintained},{key:"includesAllProcessing",label:"ROPA includes all processing activities",priority:"high",effort:"medium",recommendation:"Ensure the ROPA captures every processing activity across all departments and systems.",ndpaSection:"Section 29",pass:e.includesAllProcessing},{key:"ropaUpToDate",label:"ROPA reviewed within 6 months",priority:"medium",effort:"low",recommendation:"Review and update the ROPA at least every six months to reflect changes in processing activities.",ndpaSection:"Section 29",pass:t}]}var k=[{name:"consent",weight:.2,ndpaSections:["Section 25","Section 26"],evaluate:e=>f(e.consent)},{name:"dsr",weight:.15,ndpaSections:["Section 34","Section 35","Section 36","Section 37","Section 38"],evaluate:e=>g(e.dsr)},{name:"breach",weight:.15,ndpaSections:["Section 40"],evaluate:e=>b(e.breach)},{name:"policy",weight:.12,ndpaSections:["Section 27"],evaluate:e=>S(e.policy)},{name:"dpia",weight:.12,ndpaSections:["Section 28"],evaluate:e=>y(e.dpia)},{name:"lawfulBasis",weight:.1,ndpaSections:["Section 25(1)"],evaluate:e=>R(e.lawfulBasis)},{name:"crossBorder",weight:.08,ndpaSections:["Section 41","Section 42","Section 43"],evaluate:e=>v(e.crossBorder)},{name:"ropa",weight:.08,ndpaSections:["Section 29"],evaluate:e=>w(e.ropa)}];function P(e){return e>=90?"excellent":e>=70?"good":e>=40?"needs-work":"critical"}function C(e){let i={},t=[],s=0;for(let o of k){let a=o.evaluate(e),c=h(a),l=c*o.weight;s+=l;let d=[];for(let n of a)n.pass||(d.push(n.label),t.push({module:o.name,key:n.key,label:n.label,priority:n.priority,effort:n.effort,recommendation:n.recommendation,ndpaSection:n.ndpaSection}));i[o.name]={name:o.name,score:c,maxScore:100,weightedScore:Math.round(l*100)/100,ndpaSections:o.ndpaSections,gaps:d};}t.sort((o,a)=>m.indexOf(o.priority)-m.indexOf(a.priority));let r=Math.round(s),u=[{section:"Section 25",title:"Consent and lawful basis for processing"},{section:"Section 26",title:"Consent"},{section:"Section 27",title:"Privacy notice requirements"},{section:"Section 28",title:"Data Protection Impact Assessment (including Section 28(2) NDPC consultation)"},{section:"Section 29",title:"Records of processing activities"},{section:"Section 34",title:"Data subject rights (access, rectification, erasure, restriction)"},{section:"Section 35",title:"Right to withdraw consent"},{section:"Section 36",title:"Right to object"},{section:"Section 37",title:"Rights related to automated decision-making"},{section:"Section 38",title:"Right to data portability"},{section:"Section 40",title:"Data breach notification"},{section:"Section 41",title:"Cross-border transfer mechanisms (SCCs / BCRs)"},{section:"Section 42",title:"Cross-border adequacy decisions"},{section:"Section 43",title:"Cross-border transfer derogations"}];return {score:r,rating:P(r),modules:i,recommendations:t,regulatoryReferences:u,generatedAt:new Date().toISOString()}}export{C as a};
@@ -1 +1 @@
1
- 'use strict';var m=["critical","high","medium","low"];function p(e){let i=new Date(e).getTime();if(isNaN(i))return 1/0;let t=(Date.now()-i)/(1e3*60*60*24*30.44);return Math.max(0,t)}function u(e){if(e.length===0)return 100;let i=e.filter(t=>t.pass).length;return Math.round(i/e.length*100)}function f(e){return [{key:"hasConsentMechanism",label:"Consent collection mechanism",priority:"critical",effort:"high",recommendation:"Implement a clear, affirmative consent collection mechanism before processing personal data.",ndpaSection:"Section 25",pass:e.hasConsentMechanism},{key:"hasPurposeSpecification",label:"Purpose specification at collection",priority:"critical",effort:"medium",recommendation:"Specify and communicate the purpose of data collection at the point of consent.",ndpaSection:"Section 25",pass:e.hasPurposeSpecification},{key:"hasWithdrawalMechanism",label:"Consent withdrawal mechanism",priority:"high",effort:"medium",recommendation:"Provide a simple mechanism for data subjects to withdraw consent at any time.",ndpaSection:"Section 26",pass:e.hasWithdrawalMechanism},{key:"hasMinorProtection",label:"Minor (child) data protection controls",priority:"high",effort:"high",recommendation:"Implement age-verification and parental-consent controls for processing data of minors.",ndpaSection:"Section 31",pass:e.hasMinorProtection},{key:"consentRecordsRetained",label:"Consent records retained",priority:"medium",effort:"low",recommendation:"Retain records of all consents obtained, including what was agreed to and when.",ndpaSection:"Section 25",pass:e.consentRecordsRetained}]}function g(e){let i=e.responseTimelineDays<=30;return [{key:"hasRequestMechanism",label:"DSR submission mechanism",priority:"critical",effort:"high",recommendation:"Implement a formal channel (e.g. a web form or email address) for data subjects to submit requests.",ndpaSection:"Section 34",pass:e.hasRequestMechanism},{key:"supportsAccess",label:"Right of access supported",priority:"high",effort:"medium",recommendation:"Enable data subjects to request and receive a copy of their personal data.",ndpaSection:"Section 34(1)(a)\u2013(b)",pass:e.supportsAccess},{key:"supportsRectification",label:"Right to rectification supported",priority:"high",effort:"medium",recommendation:"Allow data subjects to request correction of inaccurate or incomplete personal data.",ndpaSection:"Section 34(1)(c)",pass:e.supportsRectification},{key:"supportsErasure",label:"Right to erasure supported",priority:"high",effort:"high",recommendation:"Implement processes to delete personal data upon valid erasure requests.",ndpaSection:"Section 34(1)(d), Section 34(2)",pass:e.supportsErasure},{key:"supportsPortability",label:"Right to data portability supported",priority:"medium",effort:"high",recommendation:"Provide personal data in a structured, machine-readable format upon request.",ndpaSection:"Section 38",pass:e.supportsPortability},{key:"supportsObjection",label:"Right to object supported",priority:"medium",effort:"medium",recommendation:"Honour objections to processing where no compelling legitimate grounds override the data subject's interests.",ndpaSection:"Section 36",pass:e.supportsObjection},{key:"responseTimeline",label:"DSR response within 30 days",priority:"high",effort:"medium",recommendation:"Reduce DSR response time to 30 days or less per NDPC guidance (GAID 2025).",ndpaSection:"Section 34 (NDPC GAID 2025 timeline guidance)",pass:i}]}function y(e){return [{key:"conductedForHighRisk",label:"DPIA conducted for high-risk processing",priority:"critical",effort:"high",recommendation:"Conduct a Data Protection Impact Assessment before undertaking high-risk processing activities.",ndpaSection:"Section 28",pass:e.conductedForHighRisk},{key:"documentedRisks",label:"Risks documented in DPIA",priority:"high",effort:"medium",recommendation:"Document identified risks to data subjects' rights and freedoms within the DPIA.",ndpaSection:"Section 28",pass:e.documentedRisks},{key:"mitigationMeasures",label:"Mitigation measures documented",priority:"high",effort:"medium",recommendation:"Document mitigation measures and residual risk acceptance within the DPIA.",ndpaSection:"Section 28",pass:e.mitigationMeasures}]}function b(e){return [{key:"hasNotificationProcess",label:"Breach notification process in place",priority:"critical",effort:"high",recommendation:"Establish a documented breach notification process covering detection, assessment, and reporting.",ndpaSection:"Section 40",pass:e.hasNotificationProcess},{key:"notifiesWithin72Hours",label:"NDPC notified within 72 hours",priority:"critical",effort:"medium",recommendation:"Ensure the NDPC is notified of qualifying breaches within 72 hours of discovery.",ndpaSection:"Section 40",pass:e.notifiesWithin72Hours},{key:"hasRiskAssessment",label:"Breach risk assessment performed",priority:"high",effort:"medium",recommendation:"Perform a risk assessment for every identified breach to determine notification obligations.",ndpaSection:"Section 40",pass:e.hasRiskAssessment},{key:"hasRecordKeeping",label:"Breach records maintained",priority:"medium",effort:"low",recommendation:"Maintain a breach register documenting all incidents, assessments, and actions taken.",ndpaSection:"Section 40",pass:e.hasRecordKeeping}]}function S(e){let t=p(e.lastUpdated)<=13;return [{key:"hasPrivacyPolicy",label:"Privacy policy exists",priority:"critical",effort:"high",recommendation:"Draft and publish a comprehensive privacy policy that satisfies NDPA requirements.",ndpaSection:"Section 27",pass:e.hasPrivacyPolicy},{key:"isPubliclyAccessible",label:"Privacy policy publicly accessible",priority:"high",effort:"low",recommendation:"Make the privacy policy easily accessible to data subjects on your website or app.",ndpaSection:"Section 27",pass:e.isPubliclyAccessible},{key:"policyUpToDate",label:"Privacy policy reviewed within 13 months",priority:"medium",effort:"medium",recommendation:"Review and update the privacy policy at least annually to reflect current practices.",ndpaSection:"Section 27",pass:t},{key:"coversAllSections",label:"Privacy policy covers all required sections",priority:"high",effort:"medium",recommendation:"Ensure the privacy policy addresses all NDPA-mandated disclosures including lawful basis, retention, and subject rights.",ndpaSection:"Section 27",pass:e.coversAllSections}]}function R(e){return [{key:"documentedForAllProcessing",label:"Lawful basis documented for all processing",priority:"critical",effort:"high",recommendation:"Identify and document a valid lawful basis for every processing activity before it begins.",ndpaSection:"Section 25(1)",pass:e.documentedForAllProcessing},{key:"hasLegitimateInterestAssessment",label:"Legitimate interest assessment completed",priority:"medium",effort:"medium",recommendation:"Complete a Legitimate Interest Assessment (LIA) where legitimate interests is the chosen lawful basis.",ndpaSection:"Section 25(1)",pass:e.hasLegitimateInterestAssessment}]}function v(e){return [{key:"hasTransferMechanisms",label:"Transfer mechanisms in place",priority:"critical",effort:"high",recommendation:"Implement appropriate transfer mechanisms (SCCs, BCRs, adequacy decisions, or Section 43 derogations) for all cross-border transfers.",ndpaSection:"Section 41",pass:e.hasTransferMechanisms},{key:"adequacyAssessed",label:"Adequacy of destination country assessed",priority:"high",effort:"medium",recommendation:"Assess whether the destination country provides an adequate level of data protection before transferring.",ndpaSection:"Section 42",pass:e.adequacyAssessed},{key:"ndpcApprovalObtained",label:"NDPC approval obtained where required",priority:"high",effort:"high",recommendation:"Obtain NDPC approval (e.g. for binding corporate rules, codes of conduct, or certification mechanisms) for transfers to countries without adequacy decisions where required.",ndpaSection:"Section 42(5)",pass:e.ndpcApprovalObtained}]}function w(e){let t=p(e.lastReviewed)<=6;return [{key:"maintained",label:"Record of Processing Activities maintained",priority:"critical",effort:"high",recommendation:"Create and maintain a comprehensive Record of Processing Activities (ROPA) as required by the NDPA.",ndpaSection:"Section 29",pass:e.maintained},{key:"includesAllProcessing",label:"ROPA includes all processing activities",priority:"high",effort:"medium",recommendation:"Ensure the ROPA captures every processing activity across all departments and systems.",ndpaSection:"Section 29",pass:e.includesAllProcessing},{key:"ropaUpToDate",label:"ROPA reviewed within 6 months",priority:"medium",effort:"low",recommendation:"Review and update the ROPA at least every six months to reflect changes in processing activities.",ndpaSection:"Section 29",pass:t}]}var k=[{name:"consent",weight:.2,ndpaSections:["Section 25","Section 26"],evaluate:e=>f(e.consent)},{name:"dsr",weight:.15,ndpaSections:["Section 34","Section 35","Section 36","Section 37","Section 38"],evaluate:e=>g(e.dsr)},{name:"breach",weight:.15,ndpaSections:["Section 40"],evaluate:e=>b(e.breach)},{name:"policy",weight:.12,ndpaSections:["Section 27"],evaluate:e=>S(e.policy)},{name:"dpia",weight:.12,ndpaSections:["Section 28"],evaluate:e=>y(e.dpia)},{name:"lawfulBasis",weight:.1,ndpaSections:["Section 25(1)"],evaluate:e=>R(e.lawfulBasis)},{name:"crossBorder",weight:.08,ndpaSections:["Section 41","Section 42","Section 43"],evaluate:e=>v(e.crossBorder)},{name:"ropa",weight:.08,ndpaSections:["Section 29"],evaluate:e=>w(e.ropa)}];function P(e){return e>=90?"excellent":e>=70?"good":e>=40?"needs-work":"critical"}function C(e){let i={},t=[],s=0;for(let o of k){let a=o.evaluate(e),c=u(a),l=c*o.weight;s+=l;let d=[];for(let n of a)n.pass||(d.push(n.label),t.push({module:o.name,key:n.key,label:n.label,priority:n.priority,effort:n.effort,recommendation:n.recommendation,ndpaSection:n.ndpaSection}));i[o.name]={name:o.name,score:c,maxScore:100,weightedScore:Math.round(l*100)/100,ndpaSections:o.ndpaSections,gaps:d};}t.sort((o,a)=>m.indexOf(o.priority)-m.indexOf(a.priority));let r=Math.round(s),h=[{section:"Section 25",title:"Consent and lawful basis for processing"},{section:"Section 26",title:"Withdrawal of consent and minor protection"},{section:"Section 27",title:"Privacy notice requirements"},{section:"Section 28",title:"Data Protection Impact Assessment (including Section 28(2) NDPC consultation)"},{section:"Section 29",title:"Records of processing activities"},{section:"Section 34",title:"Data subject rights (access, rectification, erasure, restriction)"},{section:"Section 35",title:"Right to withdraw consent"},{section:"Section 36",title:"Right to object"},{section:"Section 37",title:"Rights related to automated decision-making"},{section:"Section 38",title:"Right to data portability"},{section:"Section 40",title:"Data breach notification"},{section:"Section 41",title:"Cross-border transfer mechanisms (SCCs / BCRs)"},{section:"Section 42",title:"Cross-border adequacy decisions"},{section:"Section 43",title:"Cross-border transfer derogations"}];return {score:r,rating:P(r),modules:i,recommendations:t,regulatoryReferences:h,generatedAt:new Date().toISOString()}}exports.a=C;
1
+ 'use strict';var m=["critical","high","medium","low"];function p(e){let i=new Date(e).getTime();if(isNaN(i))return 1/0;let t=(Date.now()-i)/(1e3*60*60*24*30.44);return Math.max(0,t)}function h(e){if(e.length===0)return 100;let i=e.filter(t=>t.pass).length;return Math.round(i/e.length*100)}function f(e){return [{key:"hasConsentMechanism",label:"Consent collection mechanism",priority:"critical",effort:"high",recommendation:"Implement a clear, affirmative consent collection mechanism before processing personal data.",ndpaSection:"Section 25",pass:e.hasConsentMechanism},{key:"hasPurposeSpecification",label:"Purpose specification at collection",priority:"critical",effort:"medium",recommendation:"Specify and communicate the purpose of data collection at the point of consent.",ndpaSection:"Section 25",pass:e.hasPurposeSpecification},{key:"hasWithdrawalMechanism",label:"Consent withdrawal mechanism",priority:"high",effort:"medium",recommendation:"Provide a simple mechanism for data subjects to withdraw consent at any time.",ndpaSection:"Section 26",pass:e.hasWithdrawalMechanism},{key:"hasMinorProtection",label:"Minor (child) data protection controls",priority:"high",effort:"high",recommendation:"Implement age-verification and parental-consent controls for processing data of minors.",ndpaSection:"Section 31",pass:e.hasMinorProtection},{key:"consentRecordsRetained",label:"Consent records retained",priority:"medium",effort:"low",recommendation:"Retain records of all consents obtained, including what was agreed to and when.",ndpaSection:"Section 25",pass:e.consentRecordsRetained}]}function g(e){let i=e.responseTimelineDays<=30;return [{key:"hasRequestMechanism",label:"DSR submission mechanism",priority:"critical",effort:"high",recommendation:"Implement a formal channel (e.g. a web form or email address) for data subjects to submit requests.",ndpaSection:"Section 34",pass:e.hasRequestMechanism},{key:"supportsAccess",label:"Right of access supported",priority:"high",effort:"medium",recommendation:"Enable data subjects to request and receive a copy of their personal data.",ndpaSection:"Section 34(1)(a)\u2013(b)",pass:e.supportsAccess},{key:"supportsRectification",label:"Right to rectification supported",priority:"high",effort:"medium",recommendation:"Allow data subjects to request correction of inaccurate or incomplete personal data.",ndpaSection:"Section 34(1)(c)",pass:e.supportsRectification},{key:"supportsErasure",label:"Right to erasure supported",priority:"high",effort:"high",recommendation:"Implement processes to delete personal data upon valid erasure requests.",ndpaSection:"Section 34(1)(d), Section 34(2)",pass:e.supportsErasure},{key:"supportsPortability",label:"Right to data portability supported",priority:"medium",effort:"high",recommendation:"Provide personal data in a structured, machine-readable format upon request.",ndpaSection:"Section 38",pass:e.supportsPortability},{key:"supportsObjection",label:"Right to object supported",priority:"medium",effort:"medium",recommendation:"Honour objections to processing where no compelling legitimate grounds override the data subject's interests.",ndpaSection:"Section 36",pass:e.supportsObjection},{key:"responseTimeline",label:"DSR response within 30 days",priority:"high",effort:"medium",recommendation:"Reduce DSR response time to 30 days or less per NDPC guidance (GAID 2025).",ndpaSection:"Section 34 (NDPC GAID 2025 timeline guidance)",pass:i}]}function y(e){return [{key:"conductedForHighRisk",label:"DPIA conducted for high-risk processing",priority:"critical",effort:"high",recommendation:"Conduct a Data Protection Impact Assessment before undertaking high-risk processing activities.",ndpaSection:"Section 28",pass:e.conductedForHighRisk},{key:"documentedRisks",label:"Risks documented in DPIA",priority:"high",effort:"medium",recommendation:"Document identified risks to data subjects' rights and freedoms within the DPIA.",ndpaSection:"Section 28",pass:e.documentedRisks},{key:"mitigationMeasures",label:"Mitigation measures documented",priority:"high",effort:"medium",recommendation:"Document mitigation measures and residual risk acceptance within the DPIA.",ndpaSection:"Section 28",pass:e.mitigationMeasures}]}function b(e){return [{key:"hasNotificationProcess",label:"Breach notification process in place",priority:"critical",effort:"high",recommendation:"Establish a documented breach notification process covering detection, assessment, and reporting.",ndpaSection:"Section 40",pass:e.hasNotificationProcess},{key:"notifiesWithin72Hours",label:"NDPC notified within 72 hours",priority:"critical",effort:"medium",recommendation:"Ensure the NDPC is notified of qualifying breaches within 72 hours of discovery.",ndpaSection:"Section 40",pass:e.notifiesWithin72Hours},{key:"hasRiskAssessment",label:"Breach risk assessment performed",priority:"high",effort:"medium",recommendation:"Perform a risk assessment for every identified breach to determine notification obligations.",ndpaSection:"Section 40",pass:e.hasRiskAssessment},{key:"hasRecordKeeping",label:"Breach records maintained",priority:"medium",effort:"low",recommendation:"Maintain a breach register documenting all incidents, assessments, and actions taken.",ndpaSection:"Section 40",pass:e.hasRecordKeeping}]}function S(e){let t=p(e.lastUpdated)<=13;return [{key:"hasPrivacyPolicy",label:"Privacy policy exists",priority:"critical",effort:"high",recommendation:"Draft and publish a comprehensive privacy policy that satisfies NDPA requirements.",ndpaSection:"Section 27",pass:e.hasPrivacyPolicy},{key:"isPubliclyAccessible",label:"Privacy policy publicly accessible",priority:"high",effort:"low",recommendation:"Make the privacy policy easily accessible to data subjects on your website or app.",ndpaSection:"Section 27",pass:e.isPubliclyAccessible},{key:"policyUpToDate",label:"Privacy policy reviewed within 13 months",priority:"medium",effort:"medium",recommendation:"Review and update the privacy policy at least annually to reflect current practices.",ndpaSection:"Section 27",pass:t},{key:"coversAllSections",label:"Privacy policy covers all required sections",priority:"high",effort:"medium",recommendation:"Ensure the privacy policy addresses all NDPA-mandated disclosures including lawful basis, retention, and subject rights.",ndpaSection:"Section 27",pass:e.coversAllSections}]}function R(e){return [{key:"documentedForAllProcessing",label:"Lawful basis documented for all processing",priority:"critical",effort:"high",recommendation:"Identify and document a valid lawful basis for every processing activity before it begins.",ndpaSection:"Section 25(1)",pass:e.documentedForAllProcessing},{key:"hasLegitimateInterestAssessment",label:"Legitimate interest assessment completed",priority:"medium",effort:"medium",recommendation:"Complete a Legitimate Interest Assessment (LIA) where legitimate interests is the chosen lawful basis.",ndpaSection:"Section 25(1)",pass:e.hasLegitimateInterestAssessment}]}function v(e){return [{key:"hasTransferMechanisms",label:"Transfer mechanisms in place",priority:"critical",effort:"high",recommendation:"Implement appropriate transfer mechanisms (SCCs, BCRs, adequacy decisions, or Section 43 derogations) for all cross-border transfers.",ndpaSection:"Section 41",pass:e.hasTransferMechanisms},{key:"adequacyAssessed",label:"Adequacy of destination country assessed",priority:"high",effort:"medium",recommendation:"Assess whether the destination country provides an adequate level of data protection before transferring.",ndpaSection:"Section 42",pass:e.adequacyAssessed},{key:"ndpcApprovalObtained",label:"NDPC approval obtained where required",priority:"high",effort:"high",recommendation:"Obtain NDPC approval (e.g. for binding corporate rules, codes of conduct, or certification mechanisms) for transfers to countries without adequacy decisions where required.",ndpaSection:"Section 42(5)",pass:e.ndpcApprovalObtained}]}function w(e){let t=p(e.lastReviewed)<=6;return [{key:"maintained",label:"Record of Processing Activities maintained",priority:"critical",effort:"high",recommendation:"Create and maintain a comprehensive Record of Processing Activities (ROPA) as required by the NDPA.",ndpaSection:"Section 29",pass:e.maintained},{key:"includesAllProcessing",label:"ROPA includes all processing activities",priority:"high",effort:"medium",recommendation:"Ensure the ROPA captures every processing activity across all departments and systems.",ndpaSection:"Section 29",pass:e.includesAllProcessing},{key:"ropaUpToDate",label:"ROPA reviewed within 6 months",priority:"medium",effort:"low",recommendation:"Review and update the ROPA at least every six months to reflect changes in processing activities.",ndpaSection:"Section 29",pass:t}]}var k=[{name:"consent",weight:.2,ndpaSections:["Section 25","Section 26"],evaluate:e=>f(e.consent)},{name:"dsr",weight:.15,ndpaSections:["Section 34","Section 35","Section 36","Section 37","Section 38"],evaluate:e=>g(e.dsr)},{name:"breach",weight:.15,ndpaSections:["Section 40"],evaluate:e=>b(e.breach)},{name:"policy",weight:.12,ndpaSections:["Section 27"],evaluate:e=>S(e.policy)},{name:"dpia",weight:.12,ndpaSections:["Section 28"],evaluate:e=>y(e.dpia)},{name:"lawfulBasis",weight:.1,ndpaSections:["Section 25(1)"],evaluate:e=>R(e.lawfulBasis)},{name:"crossBorder",weight:.08,ndpaSections:["Section 41","Section 42","Section 43"],evaluate:e=>v(e.crossBorder)},{name:"ropa",weight:.08,ndpaSections:["Section 29"],evaluate:e=>w(e.ropa)}];function P(e){return e>=90?"excellent":e>=70?"good":e>=40?"needs-work":"critical"}function C(e){let i={},t=[],s=0;for(let o of k){let a=o.evaluate(e),c=h(a),l=c*o.weight;s+=l;let d=[];for(let n of a)n.pass||(d.push(n.label),t.push({module:o.name,key:n.key,label:n.label,priority:n.priority,effort:n.effort,recommendation:n.recommendation,ndpaSection:n.ndpaSection}));i[o.name]={name:o.name,score:c,maxScore:100,weightedScore:Math.round(l*100)/100,ndpaSections:o.ndpaSections,gaps:d};}t.sort((o,a)=>m.indexOf(o.priority)-m.indexOf(a.priority));let r=Math.round(s),u=[{section:"Section 25",title:"Consent and lawful basis for processing"},{section:"Section 26",title:"Consent"},{section:"Section 27",title:"Privacy notice requirements"},{section:"Section 28",title:"Data Protection Impact Assessment (including Section 28(2) NDPC consultation)"},{section:"Section 29",title:"Records of processing activities"},{section:"Section 34",title:"Data subject rights (access, rectification, erasure, restriction)"},{section:"Section 35",title:"Right to withdraw consent"},{section:"Section 36",title:"Right to object"},{section:"Section 37",title:"Rights related to automated decision-making"},{section:"Section 38",title:"Right to data portability"},{section:"Section 40",title:"Data breach notification"},{section:"Section 41",title:"Cross-border transfer mechanisms (SCCs / BCRs)"},{section:"Section 42",title:"Cross-border adequacy decisions"},{section:"Section 43",title:"Cross-border transfer derogations"}];return {score:r,rating:P(r),modules:i,recommendations:t,regulatoryReferences:u,generatedAt:new Date().toISOString()}}exports.a=C;
@@ -0,0 +1 @@
1
+ 'use strict';var chunkWKY26JLT_js=require('./chunk-WKY26JLT.js'),chunk7TTXS7JX_js=require('./chunk-7TTXS7JX.js'),react=require('react');function a({input:e}){let o=JSON.stringify(e);return react.useMemo(()=>chunk7TTXS7JX_js.a(e),[o])}function f(e,o){return react.useMemo(()=>chunkWKY26JLT_js.c(e,o),[e.dataSubjectsInSixMonths,e.isDesignated,o])}function R(e,o){return react.useMemo(()=>chunkWKY26JLT_js.d(e,o),[e.commencementDate,e.asOf,e.tier,o])}exports.a=a;exports.b=f;exports.c=R;
@@ -0,0 +1 @@
1
+ import {a}from'./chunk-ZJYULEER.mjs';var N={ohl:200,ehl:1e3,uhl:5e3},x={UHL:25e4,EHL:1e5,OHL:1e4};function T(e,i={}){let t=a(a({},N),i.thresholds),a$1=a(a({},x),i.fees),r=e==null?void 0:e.dataSubjectsInSixMonths,l=typeof r=="number"&&r>0?Math.floor(r):0,n;l>t.uhl?n="UHL":l>=t.ehl?n="EHL":l>=t.ohl?n="OHL":e!=null&&e.isDesignated?n="listed":n="none";let s=n!=="none",c=n==="UHL"||n==="EHL"||n==="OHL"?a$1[n]:0,o=[];return n==="listed"&&o.push("Designated as a DCPMI below the volume tiers \u2014 confirm the applicable registration tier and fee with the NDPC."),s&&o.push(n==="OHL"?"OHL organisations renew their NDPC registration annually and file Compliance Audit Returns (CAR) each year.":"Register once with the NDPC, then file Compliance Audit Returns (CAR) annually."),o.push("Thresholds, fees, and filing dates follow the NDPC GAID 2025 baseline and can change \u2014 verify against current NDPC guidance before relying on them."),{tier:n,isDCPMI:s,annualFeeNGN:c,registration:{required:s,renewsAnnually:n==="OHL"},compliance:{auditReturnsAnnual:s,initialAuditWithinMonths:15},notes:o,dataSubjectsConsidered:l}}function O(e){return String(e).padStart(2,"0")}function y(e){let[i,t,a]=e.split("-").map(Number);return new Date(Date.UTC(i,t-1,a))}function H(e){return e.toISOString().slice(0,10)}function S(e,i){let[t,a,r]=e.split("-").map(Number);return H(new Date(Date.UTC(t,a-1+i,r)))}function R(){return new Date().toISOString().slice(0,10)}function U(e,i={}){var f,C,b,g,p,M,I;let t=(f=e.asOf)!=null?f:R(),a=(C=i.initialAuditWithinMonths)!=null?C:15,r=(g=(b=i.annualDeadline)==null?void 0:b.month)!=null?g:3,l=(M=(p=i.annualDeadline)==null?void 0:p.day)!=null?M:31,n=(I=i.deadlineOverrides)!=null?I:{},s=e.tier===void 0?true:e.tier!=="none",c=S(e.commencementDate,a),o=P=>{var A;return (A=n[P])!=null?A:`${P}-${O(r)}-${O(l)}`},h=Number(t.slice(0,4)),D=o(h);t>D&&(h+=1,D=o(h));let L=Math.round((y(D).getTime()-y(t).getTime())/864e5),m=t>=c,u=[];return s?(u.push("File the Compliance Audit Return with the NDPC via the NDPC Information Management Portal (NIMP)."),m&&u.push("The initial compliance-audit window has elapsed \u2014 ensure the initial audit has been conducted.")):u.push("Compliance Audit Returns apply only to Data Controllers/Processors of Major Importance."),u.push("Filing deadlines follow the NDPC GAID 2025 baseline and can be extended \u2014 verify the current deadline with the NDPC."),{applicable:s,schedule:{commencementDate:e.commencementDate,initialAuditWithinMonths:a,initialAuditDueDate:c,nextFilingDeadline:D,filingYear:h},status:{initialAuditDue:m,daysUntilNextDeadline:L},notes:u,asOf:t}}export{N as a,x as b,T as c,U as d};
@@ -0,0 +1 @@
1
+ import {c,d}from'./chunk-SZXHNJGG.mjs';import {a as a$1}from'./chunk-6A7M4CGJ.mjs';import {useMemo}from'react';function a({input:e}){let o=JSON.stringify(e);return useMemo(()=>a$1(e),[o])}function f(e,o){return useMemo(()=>c(e,o),[e.dataSubjectsInSixMonths,e.isDesignated,o])}function R(e,o){return useMemo(()=>d(e,o),[e.commencementDate,e.asOf,e.tier,o])}export{a,f as b,R as c};
@@ -0,0 +1 @@
1
+ 'use strict';var chunkRFPLZDIO_js=require('./chunk-RFPLZDIO.js');var N={ohl:200,ehl:1e3,uhl:5e3},x={UHL:25e4,EHL:1e5,OHL:1e4};function T(e,i={}){let t=chunkRFPLZDIO_js.a(chunkRFPLZDIO_js.a({},N),i.thresholds),a=chunkRFPLZDIO_js.a(chunkRFPLZDIO_js.a({},x),i.fees),r=e==null?void 0:e.dataSubjectsInSixMonths,l=typeof r=="number"&&r>0?Math.floor(r):0,n;l>t.uhl?n="UHL":l>=t.ehl?n="EHL":l>=t.ohl?n="OHL":e!=null&&e.isDesignated?n="listed":n="none";let s=n!=="none",c=n==="UHL"||n==="EHL"||n==="OHL"?a[n]:0,o=[];return n==="listed"&&o.push("Designated as a DCPMI below the volume tiers \u2014 confirm the applicable registration tier and fee with the NDPC."),s&&o.push(n==="OHL"?"OHL organisations renew their NDPC registration annually and file Compliance Audit Returns (CAR) each year.":"Register once with the NDPC, then file Compliance Audit Returns (CAR) annually."),o.push("Thresholds, fees, and filing dates follow the NDPC GAID 2025 baseline and can change \u2014 verify against current NDPC guidance before relying on them."),{tier:n,isDCPMI:s,annualFeeNGN:c,registration:{required:s,renewsAnnually:n==="OHL"},compliance:{auditReturnsAnnual:s,initialAuditWithinMonths:15},notes:o,dataSubjectsConsidered:l}}function O(e){return String(e).padStart(2,"0")}function y(e){let[i,t,a]=e.split("-").map(Number);return new Date(Date.UTC(i,t-1,a))}function H(e){return e.toISOString().slice(0,10)}function S(e,i){let[t,a,r]=e.split("-").map(Number);return H(new Date(Date.UTC(t,a-1+i,r)))}function R(){return new Date().toISOString().slice(0,10)}function U(e,i={}){var f,C,b,g,p,M,I;let t=(f=e.asOf)!=null?f:R(),a=(C=i.initialAuditWithinMonths)!=null?C:15,r=(g=(b=i.annualDeadline)==null?void 0:b.month)!=null?g:3,l=(M=(p=i.annualDeadline)==null?void 0:p.day)!=null?M:31,n=(I=i.deadlineOverrides)!=null?I:{},s=e.tier===void 0?true:e.tier!=="none",c=S(e.commencementDate,a),o=P=>{var A;return (A=n[P])!=null?A:`${P}-${O(r)}-${O(l)}`},h=Number(t.slice(0,4)),D=o(h);t>D&&(h+=1,D=o(h));let L=Math.round((y(D).getTime()-y(t).getTime())/864e5),m=t>=c,u=[];return s?(u.push("File the Compliance Audit Return with the NDPC via the NDPC Information Management Portal (NIMP)."),m&&u.push("The initial compliance-audit window has elapsed \u2014 ensure the initial audit has been conducted.")):u.push("Compliance Audit Returns apply only to Data Controllers/Processors of Major Importance."),u.push("Filing deadlines follow the NDPC GAID 2025 baseline and can be extended \u2014 verify the current deadline with the NDPC."),{applicable:s,schedule:{commencementDate:e.commencementDate,initialAuditWithinMonths:a,initialAuditDueDate:c,nextFilingDeadline:D,filingYear:h},status:{initialAuditDue:m,daysUntilNextDeadline:L},notes:u,asOf:t}}exports.a=N;exports.b=x;exports.c=T;exports.d=U;
package/dist/core.d.mts CHANGED
@@ -214,6 +214,74 @@ export declare function calculateBreachSeverity(report: BreachReport, assessment
214
214
  justification: string;
215
215
  };
216
216
 
217
+ /**
218
+ * Compliance Audit Returns (CAR) scheduling under the NDPC General Application
219
+ * and Implementation Directive (GAID) 2025.
220
+ *
221
+ * A Data Controller/Processor of Major Importance (DCPMI) must conduct an
222
+ * initial compliance audit within 15 months of commencing data processing, and
223
+ * thereafter file a Compliance Audit Return with the NDPC annually (default
224
+ * deadline 31 March, filed through the NDPC Information Management Portal/NIMP).
225
+ *
226
+ * This computes the schedule (initial-audit due date, the next annual filing
227
+ * deadline relative to a reference date) and a light status. NDPC deadlines
228
+ * shift (the 2026 filing was extended to 30 May), so the annual deadline is
229
+ * configurable and per-year overrides are supported. The audit *content* itself
230
+ * is the organisation's compliance posture — pair this with `getComplianceScore`.
231
+ *
232
+ * @see NDPC General Application and Implementation Directive (GAID) 2025
233
+ */
234
+
235
+ export declare interface CARInput {
236
+ /** ISO date (YYYY-MM-DD) the organisation commenced data processing. */
237
+ commencementDate: string;
238
+ /** Reference date to evaluate against (YYYY-MM-DD). Defaults to today. */
239
+ asOf?: string;
240
+ /** DCPMI tier; CAR applies to DCPMIs only. Omit to assume applicable. */
241
+ tier?: DCPMITier;
242
+ }
243
+
244
+ export declare interface CAROptions {
245
+ /** Default annual filing deadline (month is 1-12). Defaults to 31 March. */
246
+ annualDeadline?: {
247
+ month: number;
248
+ day: number;
249
+ };
250
+ /** Per-year overrides for the annual deadline, e.g. `{ 2026: '2026-05-30' }`. */
251
+ deadlineOverrides?: Record<number, string>;
252
+ /** Months after commencement the initial audit is due. Defaults to 15. */
253
+ initialAuditWithinMonths?: number;
254
+ }
255
+
256
+ /**
257
+ * Classify an organisation's DCPMI status, registration tier, annual fee, and
258
+ * Compliance Audit Returns obligations under NDPC GAID 2025.
259
+ */
260
+ export declare function classifyDCPMI(input: DCPMIInput, options?: DCPMIClassificationOptions): DCPMIClassification;
261
+
262
+ export declare interface ComplianceAuditReturn {
263
+ /** Whether CAR applies (false for non-DCPMI organisations). */
264
+ applicable: boolean;
265
+ schedule: {
266
+ commencementDate: string;
267
+ initialAuditWithinMonths: number;
268
+ /** Commencement date + the initial-audit window. */
269
+ initialAuditDueDate: string;
270
+ /** The next annual filing deadline on or after `asOf`. */
271
+ nextFilingDeadline: string;
272
+ /** The year the next filing deadline falls in. */
273
+ filingYear: number;
274
+ };
275
+ status: {
276
+ /** Whether the initial-audit obligation has arisen (asOf ≥ due date). */
277
+ initialAuditDue: boolean;
278
+ /** Whole days from `asOf` to the next filing deadline. */
279
+ daysUntilNextDeadline: number;
280
+ };
281
+ notes: string[];
282
+ asOf: string;
283
+ }
284
+
217
285
  /** A single gap found during NDPA compliance evaluation. */
218
286
  export declare interface ComplianceGap {
219
287
  /** Machine-readable requirement identifier. */
@@ -580,6 +648,90 @@ export declare interface DataCategory {
580
648
  selected: boolean;
581
649
  }
582
650
 
651
+ export declare interface DCPMIClassification {
652
+ /** Registration tier (or `'none'` when not a DCPMI). */
653
+ tier: DCPMITier;
654
+ /** Whether the organisation is a Data Controller/Processor of Major Importance. */
655
+ isDCPMI: boolean;
656
+ /** Annual registration fee in Nigerian Naira (0 when not a volume-tiered DCPMI). */
657
+ annualFeeNGN: number;
658
+ registration: {
659
+ /** Whether NDPC registration is required. */
660
+ required: boolean;
661
+ /** OHL renews registration annually; UHL/EHL register once and file CAR annually. */
662
+ renewsAnnually: boolean;
663
+ };
664
+ compliance: {
665
+ /** Whether the organisation must file annual Compliance Audit Returns (CAR). */
666
+ auditReturnsAnnual: boolean;
667
+ /** Initial compliance audit is due within this many months of commencing processing. */
668
+ initialAuditWithinMonths: number;
669
+ };
670
+ /** Human-readable caveats and next steps. */
671
+ notes: string[];
672
+ /** The count actually used for classification, after defensive normalisation. */
673
+ dataSubjectsConsidered: number;
674
+ }
675
+
676
+ export declare interface DCPMIClassificationOptions {
677
+ thresholds?: Partial<DCPMIThresholds>;
678
+ fees?: Partial<DCPMIFees>;
679
+ }
680
+
681
+ export declare interface DCPMIFees {
682
+ UHL: number;
683
+ EHL: number;
684
+ OHL: number;
685
+ }
686
+
687
+ export declare interface DCPMIInput {
688
+ /** Distinct data subjects whose data was processed in the relevant six-month window. */
689
+ dataSubjectsInSixMonths?: number;
690
+ /** True if the Commission has separately designated/listed the organisation as a DCPMI. */
691
+ isDesignated?: boolean;
692
+ }
693
+
694
+ export declare interface DCPMIThresholds {
695
+ /** Lower bound (inclusive) for OHL. */
696
+ ohl: number;
697
+ /** Lower bound (inclusive) for EHL. */
698
+ ehl: number;
699
+ /** A count strictly greater than this is UHL. */
700
+ uhl: number;
701
+ }
702
+
703
+ /**
704
+ * Data Controller/Processor of Major Importance (DCPMI) classification under the
705
+ * NDPC General Application and Implementation Directive (GAID) 2025.
706
+ *
707
+ * Volume-based tiers — data subjects processed within a six-month window:
708
+ * - UHL (Ultra High Level): more than 5,000 → ₦250,000 / year
709
+ * - EHL (Extra High Level): 1,000 – 5,000 → ₦100,000 / year
710
+ * - OHL (Ordinary High Level): 200 – 999 → ₦10,000 / year
711
+ * - below 200: not a DCPMI by volume
712
+ *
713
+ * Boundaries: the 1,000 mark resolves to EHL (so OHL is 200–999); UHL is
714
+ * strictly greater than 5,000 (so 5,000 itself is EHL). The NDPC has revised
715
+ * classification metrics before and shifts filing deadlines, so thresholds and
716
+ * fees are configurable — treat the defaults as the September 2025 GAID
717
+ * baseline, not a constant.
718
+ *
719
+ * `isDesignated` marks an organisation the Commission has otherwise listed as a
720
+ * DCPMI; it is then a DCPMI regardless of volume. Below the volume tiers such an
721
+ * organisation is reported as `'listed'` with the fee left at 0 and a note to
722
+ * confirm the applicable tier/fee with the NDPC.
723
+ *
724
+ * @see NDPC General Application and Implementation Directive (GAID) 2025
725
+ * @see NDPC Guidance Notice on the Registration of Data Controllers and Processors of Major Importance
726
+ */
727
+ export declare type DCPMITier = 'UHL' | 'EHL' | 'OHL' | 'listed' | 'none';
728
+
729
+ /** September 2025 GAID baseline annual fees (NGN). */
730
+ export declare const DEFAULT_DCPMI_FEES_NGN: DCPMIFees;
731
+
732
+ /** September 2025 GAID baseline — override via {@link DCPMIClassificationOptions} as the rules evolve. */
733
+ export declare const DEFAULT_DCPMI_THRESHOLDS: DCPMIThresholds;
734
+
583
735
  /**
584
736
  * Default NDPA-compliant privacy policy sections.
585
737
  * Each section uses {{variable}} placeholders that are resolved at generation time.
@@ -954,6 +1106,11 @@ export declare const frenchLocale: Required<{
954
1106
  [K in keyof NDPRLocale]: Required<NonNullable<NDPRLocale[K]>>;
955
1107
  }>;
956
1108
 
1109
+ /**
1110
+ * Derive the CAR schedule and status for a DCPMI under NDPC GAID 2025.
1111
+ */
1112
+ export declare function generateComplianceAuditReturn(input: CARInput, options?: CAROptions): ComplianceAuditReturn;
1113
+
957
1114
  /**
958
1115
  * Generates a summary of all lawful basis documentation across processing activities.
959
1116
  *
package/dist/core.d.ts CHANGED
@@ -214,6 +214,74 @@ export declare function calculateBreachSeverity(report: BreachReport, assessment
214
214
  justification: string;
215
215
  };
216
216
 
217
+ /**
218
+ * Compliance Audit Returns (CAR) scheduling under the NDPC General Application
219
+ * and Implementation Directive (GAID) 2025.
220
+ *
221
+ * A Data Controller/Processor of Major Importance (DCPMI) must conduct an
222
+ * initial compliance audit within 15 months of commencing data processing, and
223
+ * thereafter file a Compliance Audit Return with the NDPC annually (default
224
+ * deadline 31 March, filed through the NDPC Information Management Portal/NIMP).
225
+ *
226
+ * This computes the schedule (initial-audit due date, the next annual filing
227
+ * deadline relative to a reference date) and a light status. NDPC deadlines
228
+ * shift (the 2026 filing was extended to 30 May), so the annual deadline is
229
+ * configurable and per-year overrides are supported. The audit *content* itself
230
+ * is the organisation's compliance posture — pair this with `getComplianceScore`.
231
+ *
232
+ * @see NDPC General Application and Implementation Directive (GAID) 2025
233
+ */
234
+
235
+ export declare interface CARInput {
236
+ /** ISO date (YYYY-MM-DD) the organisation commenced data processing. */
237
+ commencementDate: string;
238
+ /** Reference date to evaluate against (YYYY-MM-DD). Defaults to today. */
239
+ asOf?: string;
240
+ /** DCPMI tier; CAR applies to DCPMIs only. Omit to assume applicable. */
241
+ tier?: DCPMITier;
242
+ }
243
+
244
+ export declare interface CAROptions {
245
+ /** Default annual filing deadline (month is 1-12). Defaults to 31 March. */
246
+ annualDeadline?: {
247
+ month: number;
248
+ day: number;
249
+ };
250
+ /** Per-year overrides for the annual deadline, e.g. `{ 2026: '2026-05-30' }`. */
251
+ deadlineOverrides?: Record<number, string>;
252
+ /** Months after commencement the initial audit is due. Defaults to 15. */
253
+ initialAuditWithinMonths?: number;
254
+ }
255
+
256
+ /**
257
+ * Classify an organisation's DCPMI status, registration tier, annual fee, and
258
+ * Compliance Audit Returns obligations under NDPC GAID 2025.
259
+ */
260
+ export declare function classifyDCPMI(input: DCPMIInput, options?: DCPMIClassificationOptions): DCPMIClassification;
261
+
262
+ export declare interface ComplianceAuditReturn {
263
+ /** Whether CAR applies (false for non-DCPMI organisations). */
264
+ applicable: boolean;
265
+ schedule: {
266
+ commencementDate: string;
267
+ initialAuditWithinMonths: number;
268
+ /** Commencement date + the initial-audit window. */
269
+ initialAuditDueDate: string;
270
+ /** The next annual filing deadline on or after `asOf`. */
271
+ nextFilingDeadline: string;
272
+ /** The year the next filing deadline falls in. */
273
+ filingYear: number;
274
+ };
275
+ status: {
276
+ /** Whether the initial-audit obligation has arisen (asOf ≥ due date). */
277
+ initialAuditDue: boolean;
278
+ /** Whole days from `asOf` to the next filing deadline. */
279
+ daysUntilNextDeadline: number;
280
+ };
281
+ notes: string[];
282
+ asOf: string;
283
+ }
284
+
217
285
  /** A single gap found during NDPA compliance evaluation. */
218
286
  export declare interface ComplianceGap {
219
287
  /** Machine-readable requirement identifier. */
@@ -580,6 +648,90 @@ export declare interface DataCategory {
580
648
  selected: boolean;
581
649
  }
582
650
 
651
+ export declare interface DCPMIClassification {
652
+ /** Registration tier (or `'none'` when not a DCPMI). */
653
+ tier: DCPMITier;
654
+ /** Whether the organisation is a Data Controller/Processor of Major Importance. */
655
+ isDCPMI: boolean;
656
+ /** Annual registration fee in Nigerian Naira (0 when not a volume-tiered DCPMI). */
657
+ annualFeeNGN: number;
658
+ registration: {
659
+ /** Whether NDPC registration is required. */
660
+ required: boolean;
661
+ /** OHL renews registration annually; UHL/EHL register once and file CAR annually. */
662
+ renewsAnnually: boolean;
663
+ };
664
+ compliance: {
665
+ /** Whether the organisation must file annual Compliance Audit Returns (CAR). */
666
+ auditReturnsAnnual: boolean;
667
+ /** Initial compliance audit is due within this many months of commencing processing. */
668
+ initialAuditWithinMonths: number;
669
+ };
670
+ /** Human-readable caveats and next steps. */
671
+ notes: string[];
672
+ /** The count actually used for classification, after defensive normalisation. */
673
+ dataSubjectsConsidered: number;
674
+ }
675
+
676
+ export declare interface DCPMIClassificationOptions {
677
+ thresholds?: Partial<DCPMIThresholds>;
678
+ fees?: Partial<DCPMIFees>;
679
+ }
680
+
681
+ export declare interface DCPMIFees {
682
+ UHL: number;
683
+ EHL: number;
684
+ OHL: number;
685
+ }
686
+
687
+ export declare interface DCPMIInput {
688
+ /** Distinct data subjects whose data was processed in the relevant six-month window. */
689
+ dataSubjectsInSixMonths?: number;
690
+ /** True if the Commission has separately designated/listed the organisation as a DCPMI. */
691
+ isDesignated?: boolean;
692
+ }
693
+
694
+ export declare interface DCPMIThresholds {
695
+ /** Lower bound (inclusive) for OHL. */
696
+ ohl: number;
697
+ /** Lower bound (inclusive) for EHL. */
698
+ ehl: number;
699
+ /** A count strictly greater than this is UHL. */
700
+ uhl: number;
701
+ }
702
+
703
+ /**
704
+ * Data Controller/Processor of Major Importance (DCPMI) classification under the
705
+ * NDPC General Application and Implementation Directive (GAID) 2025.
706
+ *
707
+ * Volume-based tiers — data subjects processed within a six-month window:
708
+ * - UHL (Ultra High Level): more than 5,000 → ₦250,000 / year
709
+ * - EHL (Extra High Level): 1,000 – 5,000 → ₦100,000 / year
710
+ * - OHL (Ordinary High Level): 200 – 999 → ₦10,000 / year
711
+ * - below 200: not a DCPMI by volume
712
+ *
713
+ * Boundaries: the 1,000 mark resolves to EHL (so OHL is 200–999); UHL is
714
+ * strictly greater than 5,000 (so 5,000 itself is EHL). The NDPC has revised
715
+ * classification metrics before and shifts filing deadlines, so thresholds and
716
+ * fees are configurable — treat the defaults as the September 2025 GAID
717
+ * baseline, not a constant.
718
+ *
719
+ * `isDesignated` marks an organisation the Commission has otherwise listed as a
720
+ * DCPMI; it is then a DCPMI regardless of volume. Below the volume tiers such an
721
+ * organisation is reported as `'listed'` with the fee left at 0 and a note to
722
+ * confirm the applicable tier/fee with the NDPC.
723
+ *
724
+ * @see NDPC General Application and Implementation Directive (GAID) 2025
725
+ * @see NDPC Guidance Notice on the Registration of Data Controllers and Processors of Major Importance
726
+ */
727
+ export declare type DCPMITier = 'UHL' | 'EHL' | 'OHL' | 'listed' | 'none';
728
+
729
+ /** September 2025 GAID baseline annual fees (NGN). */
730
+ export declare const DEFAULT_DCPMI_FEES_NGN: DCPMIFees;
731
+
732
+ /** September 2025 GAID baseline — override via {@link DCPMIClassificationOptions} as the rules evolve. */
733
+ export declare const DEFAULT_DCPMI_THRESHOLDS: DCPMIThresholds;
734
+
583
735
  /**
584
736
  * Default NDPA-compliant privacy policy sections.
585
737
  * Each section uses {{variable}} placeholders that are resolved at generation time.
@@ -954,6 +1106,11 @@ export declare const frenchLocale: Required<{
954
1106
  [K in keyof NDPRLocale]: Required<NonNullable<NDPRLocale[K]>>;
955
1107
  }>;
956
1108
 
1109
+ /**
1110
+ * Derive the CAR schedule and status for a DCPMI under NDPC GAID 2025.
1111
+ */
1112
+ export declare function generateComplianceAuditReturn(input: CARInput, options?: CAROptions): ComplianceAuditReturn;
1113
+
957
1114
  /**
958
1115
  * Generates a summary of all lawful basis documentation across processing activities.
959
1116
  *
package/dist/core.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var chunkLP5KXMBY_js=require('./chunk-LP5KXMBY.js'),chunkNUOHT3LO_js=require('./chunk-NUOHT3LO.js'),chunkJVMHWM3I_js=require('./chunk-JVMHWM3I.js'),chunk3YTAOT5O_js=require('./chunk-3YTAOT5O.js'),chunkD2ZKDQVL_js=require('./chunk-D2ZKDQVL.js'),chunk6LJHLE6G_js=require('./chunk-6LJHLE6G.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js'),chunkWZYCBW2R_js=require('./chunk-WZYCBW2R.js'),chunk4CVBQC66_js=require('./chunk-4CVBQC66.js'),chunk3IA3KDII_js=require('./chunk-3IA3KDII.js'),chunkDKLJ5DYN_js=require('./chunk-DKLJ5DYN.js'),chunkUXUMYP4L_js=require('./chunk-UXUMYP4L.js'),chunkR2ZZMATR_js=require('./chunk-R2ZZMATR.js'),chunkTQZWJGJ2_js=require('./chunk-TQZWJGJ2.js'),chunkZVOIR4QH_js=require('./chunk-ZVOIR4QH.js'),chunkI5ZDNSX5_js=require('./chunk-I5ZDNSX5.js'),chunk7563FVMY_js=require('./chunk-7563FVMY.js');require('./chunk-RFPLZDIO.js');Object.defineProperty(exports,"arabicLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.e}});Object.defineProperty(exports,"frenchLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.f}});Object.defineProperty(exports,"hausaLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.c}});Object.defineProperty(exports,"igboLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.b}});Object.defineProperty(exports,"pidginLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.d}});Object.defineProperty(exports,"yorubaLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.a}});Object.defineProperty(exports,"ORG_POLICY_TEMPLATE_REGISTRY",{enumerable:true,get:function(){return chunkNUOHT3LO_js.a}});Object.defineProperty(exports,"createOrgTemplate",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"templateContextFor",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"getComplianceScore",{enumerable:true,get:function(){return chunkJVMHWM3I_js.a}});Object.defineProperty(exports,"calculateBreachSeverity",{enumerable:true,get:function(){return chunk3YTAOT5O_js.a}});Object.defineProperty(exports,"DEFAULT_POLICY_SECTIONS",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.c}});Object.defineProperty(exports,"DEFAULT_POLICY_VARIABLES",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.d}});Object.defineProperty(exports,"createBusinessPolicyTemplate",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.e}});Object.defineProperty(exports,"findUnfilledTokens",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.a}});Object.defineProperty(exports,"generatePolicyText",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.b}});Object.defineProperty(exports,"assemblePolicy",{enumerable:true,get:function(){return chunk6LJHLE6G_js.c}});Object.defineProperty(exports,"createDefaultContext",{enumerable:true,get:function(){return chunk6LJHLE6G_js.e}});Object.defineProperty(exports,"evaluatePolicyCompliance",{enumerable:true,get:function(){return chunk6LJHLE6G_js.f}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});Object.defineProperty(exports,"assessComplianceGaps",{enumerable:true,get:function(){return chunkWZYCBW2R_js.c}});Object.defineProperty(exports,"generateLawfulBasisSummary",{enumerable:true,get:function(){return chunkWZYCBW2R_js.d}});Object.defineProperty(exports,"getLawfulBasisDescription",{enumerable:true,get:function(){return chunkWZYCBW2R_js.b}});Object.defineProperty(exports,"validateProcessingActivity",{enumerable:true,get:function(){return chunkWZYCBW2R_js.a}});Object.defineProperty(exports,"exportROPAToCSV",{enumerable:true,get:function(){return chunk4CVBQC66_js.c}});Object.defineProperty(exports,"generateROPASummary",{enumerable:true,get:function(){return chunk4CVBQC66_js.b}});Object.defineProperty(exports,"identifyComplianceGaps",{enumerable:true,get:function(){return chunk4CVBQC66_js.d}});Object.defineProperty(exports,"validateProcessingRecord",{enumerable:true,get:function(){return chunk4CVBQC66_js.a}});Object.defineProperty(exports,"appendAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.c}});Object.defineProperty(exports,"createAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.a}});Object.defineProperty(exports,"getAuditLog",{enumerable:true,get:function(){return chunk3IA3KDII_js.b}});Object.defineProperty(exports,"validateConsentOptionsStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.b}});Object.defineProperty(exports,"validateConsentStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.a}});Object.defineProperty(exports,"sanitizeInput",{enumerable:true,get:function(){return chunkUXUMYP4L_js.a}});Object.defineProperty(exports,"formatDSRRequestStructured",{enumerable:true,get:function(){return chunkR2ZZMATR_js.b}});Object.defineProperty(exports,"validateDsrSubmissionStructured",{enumerable:true,get:function(){return chunkR2ZZMATR_js.a}});Object.defineProperty(exports,"assessDPIARisk",{enumerable:true,get:function(){return chunkTQZWJGJ2_js.a}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_LONG",{enumerable:true,get:function(){return chunkZVOIR4QH_js.b}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_SHORT",{enumerable:true,get:function(){return chunkZVOIR4QH_js.a}});Object.defineProperty(exports,"legalDisclaimerBlock",{enumerable:true,get:function(){return chunkZVOIR4QH_js.c}});Object.defineProperty(exports,"NDPRProvider",{enumerable:true,get:function(){return chunkI5ZDNSX5_js.a}});Object.defineProperty(exports,"useNDPRConfig",{enumerable:true,get:function(){return chunkI5ZDNSX5_js.b}});Object.defineProperty(exports,"useNDPRLocale",{enumerable:true,get:function(){return chunkI5ZDNSX5_js.c}});Object.defineProperty(exports,"defaultLocale",{enumerable:true,get:function(){return chunk7563FVMY_js.a}});Object.defineProperty(exports,"mergeLocale",{enumerable:true,get:function(){return chunk7563FVMY_js.b}});
1
+ 'use strict';var chunkLP5KXMBY_js=require('./chunk-LP5KXMBY.js'),chunkNUOHT3LO_js=require('./chunk-NUOHT3LO.js'),chunkWKY26JLT_js=require('./chunk-WKY26JLT.js'),chunk7TTXS7JX_js=require('./chunk-7TTXS7JX.js'),chunk3YTAOT5O_js=require('./chunk-3YTAOT5O.js'),chunkD2ZKDQVL_js=require('./chunk-D2ZKDQVL.js'),chunk6LJHLE6G_js=require('./chunk-6LJHLE6G.js'),chunkYFBDJ4FH_js=require('./chunk-YFBDJ4FH.js'),chunkWZYCBW2R_js=require('./chunk-WZYCBW2R.js'),chunk4CVBQC66_js=require('./chunk-4CVBQC66.js'),chunk3IA3KDII_js=require('./chunk-3IA3KDII.js'),chunkDKLJ5DYN_js=require('./chunk-DKLJ5DYN.js'),chunkUXUMYP4L_js=require('./chunk-UXUMYP4L.js'),chunkR2ZZMATR_js=require('./chunk-R2ZZMATR.js'),chunkTQZWJGJ2_js=require('./chunk-TQZWJGJ2.js'),chunkZVOIR4QH_js=require('./chunk-ZVOIR4QH.js'),chunkI5ZDNSX5_js=require('./chunk-I5ZDNSX5.js'),chunk7563FVMY_js=require('./chunk-7563FVMY.js');require('./chunk-RFPLZDIO.js');Object.defineProperty(exports,"arabicLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.e}});Object.defineProperty(exports,"frenchLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.f}});Object.defineProperty(exports,"hausaLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.c}});Object.defineProperty(exports,"igboLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.b}});Object.defineProperty(exports,"pidginLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.d}});Object.defineProperty(exports,"yorubaLocale",{enumerable:true,get:function(){return chunkLP5KXMBY_js.a}});Object.defineProperty(exports,"ORG_POLICY_TEMPLATE_REGISTRY",{enumerable:true,get:function(){return chunkNUOHT3LO_js.a}});Object.defineProperty(exports,"createOrgTemplate",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"templateContextFor",{enumerable:true,get:function(){return chunkNUOHT3LO_js.b}});Object.defineProperty(exports,"DEFAULT_DCPMI_FEES_NGN",{enumerable:true,get:function(){return chunkWKY26JLT_js.b}});Object.defineProperty(exports,"DEFAULT_DCPMI_THRESHOLDS",{enumerable:true,get:function(){return chunkWKY26JLT_js.a}});Object.defineProperty(exports,"classifyDCPMI",{enumerable:true,get:function(){return chunkWKY26JLT_js.c}});Object.defineProperty(exports,"generateComplianceAuditReturn",{enumerable:true,get:function(){return chunkWKY26JLT_js.d}});Object.defineProperty(exports,"getComplianceScore",{enumerable:true,get:function(){return chunk7TTXS7JX_js.a}});Object.defineProperty(exports,"calculateBreachSeverity",{enumerable:true,get:function(){return chunk3YTAOT5O_js.a}});Object.defineProperty(exports,"DEFAULT_POLICY_SECTIONS",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.c}});Object.defineProperty(exports,"DEFAULT_POLICY_VARIABLES",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.d}});Object.defineProperty(exports,"createBusinessPolicyTemplate",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.e}});Object.defineProperty(exports,"findUnfilledTokens",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.a}});Object.defineProperty(exports,"generatePolicyText",{enumerable:true,get:function(){return chunkD2ZKDQVL_js.b}});Object.defineProperty(exports,"assemblePolicy",{enumerable:true,get:function(){return chunk6LJHLE6G_js.c}});Object.defineProperty(exports,"createDefaultContext",{enumerable:true,get:function(){return chunk6LJHLE6G_js.e}});Object.defineProperty(exports,"evaluatePolicyCompliance",{enumerable:true,get:function(){return chunk6LJHLE6G_js.f}});Object.defineProperty(exports,"assessTransferRisk",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.h}});Object.defineProperty(exports,"getTransferMechanismDescription",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.f}});Object.defineProperty(exports,"isNDPCApprovalRequired",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.e}});Object.defineProperty(exports,"validateTransfer",{enumerable:true,get:function(){return chunkYFBDJ4FH_js.g}});Object.defineProperty(exports,"assessComplianceGaps",{enumerable:true,get:function(){return chunkWZYCBW2R_js.c}});Object.defineProperty(exports,"generateLawfulBasisSummary",{enumerable:true,get:function(){return chunkWZYCBW2R_js.d}});Object.defineProperty(exports,"getLawfulBasisDescription",{enumerable:true,get:function(){return chunkWZYCBW2R_js.b}});Object.defineProperty(exports,"validateProcessingActivity",{enumerable:true,get:function(){return chunkWZYCBW2R_js.a}});Object.defineProperty(exports,"exportROPAToCSV",{enumerable:true,get:function(){return chunk4CVBQC66_js.c}});Object.defineProperty(exports,"generateROPASummary",{enumerable:true,get:function(){return chunk4CVBQC66_js.b}});Object.defineProperty(exports,"identifyComplianceGaps",{enumerable:true,get:function(){return chunk4CVBQC66_js.d}});Object.defineProperty(exports,"validateProcessingRecord",{enumerable:true,get:function(){return chunk4CVBQC66_js.a}});Object.defineProperty(exports,"appendAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.c}});Object.defineProperty(exports,"createAuditEntry",{enumerable:true,get:function(){return chunk3IA3KDII_js.a}});Object.defineProperty(exports,"getAuditLog",{enumerable:true,get:function(){return chunk3IA3KDII_js.b}});Object.defineProperty(exports,"validateConsentOptionsStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.b}});Object.defineProperty(exports,"validateConsentStructured",{enumerable:true,get:function(){return chunkDKLJ5DYN_js.a}});Object.defineProperty(exports,"sanitizeInput",{enumerable:true,get:function(){return chunkUXUMYP4L_js.a}});Object.defineProperty(exports,"formatDSRRequestStructured",{enumerable:true,get:function(){return chunkR2ZZMATR_js.b}});Object.defineProperty(exports,"validateDsrSubmissionStructured",{enumerable:true,get:function(){return chunkR2ZZMATR_js.a}});Object.defineProperty(exports,"assessDPIARisk",{enumerable:true,get:function(){return chunkTQZWJGJ2_js.a}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_LONG",{enumerable:true,get:function(){return chunkZVOIR4QH_js.b}});Object.defineProperty(exports,"LEGAL_DISCLAIMER_SHORT",{enumerable:true,get:function(){return chunkZVOIR4QH_js.a}});Object.defineProperty(exports,"legalDisclaimerBlock",{enumerable:true,get:function(){return chunkZVOIR4QH_js.c}});Object.defineProperty(exports,"NDPRProvider",{enumerable:true,get:function(){return chunkI5ZDNSX5_js.a}});Object.defineProperty(exports,"useNDPRConfig",{enumerable:true,get:function(){return chunkI5ZDNSX5_js.b}});Object.defineProperty(exports,"useNDPRLocale",{enumerable:true,get:function(){return chunkI5ZDNSX5_js.c}});Object.defineProperty(exports,"defaultLocale",{enumerable:true,get:function(){return chunk7563FVMY_js.a}});Object.defineProperty(exports,"mergeLocale",{enumerable:true,get:function(){return chunk7563FVMY_js.b}});