UNPKG

@tantainnovative/ndpr-toolkit

Version:

Nigeria Data Protection Toolkit — enterprise-grade compliance components for the Nigeria Data Protection Act (NDPA) 2023

1,437 lines (1,371 loc) 54.1 kB
import React__default from 'react'; /** * Adequacy status of a destination country */ declare type AdequacyStatus = 'adequate' | 'inadequate' | 'pending_review' | 'unknown'; /** * Breach notification types aligned with NDPA 2023 Section 40 * Data controllers must notify the NDPC within 72 hours of becoming aware of a breach * Data subjects must be notified without undue delay when breach is likely to result in high risk */ /** * Represents a data breach category */ declare interface BreachCategory { /** Unique identifier for the category */ id: string; /** Display name for the category */ name: string; /** Description of this breach category */ description: string; /** Default severity level for this category */ defaultSeverity: 'low' | 'medium' | 'high' | 'critical'; } /** * Represents the data submitted by the breach report form. */ declare interface BreachFormSubmission { /** Title/summary of the breach */ title: string; /** Detailed description of the breach */ description: string; /** Breach category identifier */ category: string; /** Timestamp (ms) when the breach was discovered */ discoveredAt: number; /** Timestamp (ms) when the breach occurred (if known) */ occurredAt?: number; /** Timestamp (ms) when the form was submitted */ reportedAt: number; /** Person reporting the breach */ reporter: { name: string; email: string; department: string; phone?: string; }; /** Systems or applications affected by the breach */ affectedSystems: string[]; /** Types of data involved in the breach */ dataTypes: string[]; /** Estimated number of affected data subjects */ estimatedAffectedSubjects?: number; /** * Approximate number of personal data RECORDS concerned. Distinct from * subject count (one subject may have many records). NDPA Section 40(2). */ approximateRecordCount?: number; /** * Categories of data subjects affected (e.g. customers, employees, minors). * NDPA Section 40(2). */ dataSubjectCategories?: string[]; /** Whether sensitive personal data (NDPA Section 30) is involved */ involvesSensitiveData?: boolean; /** * Likely consequences of the breach for affected data subjects. * Required content for the NDPC report and Section 40(3) communications. */ likelyConsequences?: string; /** * Measures taken or proposed to mitigate adverse effects. * NDPA Section 40(3). */ mitigationMeasures?: string; /** * Data Protection Officer contact details (Section 32(3)(c) — DPO is the * named NDPC contact). Falls back to organisation-level DPO if omitted. */ dpoContact?: { name: string; email: string; phone?: string; }; /** * Whether this is a phased / interim report submitted under Section 40(2) * before complete information is available. */ isPhasedReport?: boolean; /** ID of the prior phased report this report supplements, if any. */ supplementsReportId?: string; /** Current status of the breach */ status: 'ongoing' | 'contained' | 'resolved'; /** Initial actions taken to address the breach */ initialActions?: string; /** File attachments included with the report */ attachments: Array<{ name: string; type: string; size: number; file: File; }>; } declare interface BreachReportFormClassNames { root?: string; title?: string; form?: string; fieldGroup?: string; label?: string; input?: string; select?: string; textarea?: string; submitButton?: string; /** Alias for submitButton */ primaryButton?: string; notice?: string; /** Custom class applied when isSubmitting is true (e.g. a loading overlay) */ loadingOverlay?: string; /** Live NDPC-notification completeness panel */ completeness?: string; } declare interface ComplianceInput { consent: { hasConsentMechanism: boolean; hasPurposeSpecification: boolean; hasWithdrawalMechanism: boolean; hasMinorProtection: boolean; consentRecordsRetained: boolean; }; dsr: { hasRequestMechanism: boolean; supportsAccess: boolean; supportsRectification: boolean; supportsErasure: boolean; supportsPortability: boolean; supportsObjection: boolean; /** Expected max response time in days (>30 counts as a gap) */ responseTimelineDays: number; }; dpia: { conductedForHighRisk: boolean; documentedRisks: boolean; mitigationMeasures: boolean; }; breach: { hasNotificationProcess: boolean; notifiesWithin72Hours: boolean; hasRiskAssessment: boolean; hasRecordKeeping: boolean; }; policy: { hasPrivacyPolicy: boolean; isPubliclyAccessible: boolean; /** ISO date string (YYYY-MM-DD); >13 months old counts as a gap */ lastUpdated: string; coversAllSections: boolean; }; lawfulBasis: { documentedForAllProcessing: boolean; hasLegitimateInterestAssessment: boolean; }; crossBorder: { hasTransferMechanisms: boolean; adequacyAssessed: boolean; ndpcApprovalObtained: boolean; }; ropa: { maintained: boolean; includesAllProcessing: boolean; /** ISO date string (YYYY-MM-DD); >6 months since review counts as a gap */ lastReviewed: string; }; } declare interface ConsentBannerClassNames { root?: string; container?: string; title?: string; description?: string; optionsList?: string; optionItem?: string; optionCheckbox?: string; optionLabel?: string; optionDescription?: string; buttonGroup?: string; acceptButton?: string; rejectButton?: string; customizeButton?: string; saveButton?: string; customizePanel?: string; selectAllButton?: string; /** The optional on-page cookie scan panel (shown in the customize view) */ cookieScanPanel?: string; /** Alias for acceptButton */ primaryButton?: string; /** Alias for rejectButton */ secondaryButton?: string; } /** * Consent types aligned with NDPA 2023 Section 25-26 * Consent must be freely given, specific, informed, and unambiguous */ /** * Represents a consent option that can be presented to users */ declare interface ConsentOption { /** Unique identifier for the consent option */ id: string; /** Display label for the consent option */ label: string; /** Detailed description of what this consent option covers */ description: string; /** Whether this consent option is required (cannot be declined) */ required: boolean; /** * The specific purpose for which data will be processed * NDPA Section 25(2) requires consent to be specific to each purpose */ purpose: string; /** * Default state of the consent option * @default false */ defaultValue?: boolean; /** * Categories of personal data covered by this consent option */ dataCategories?: string[]; } /** * Represents the user's consent settings */ declare interface ConsentSettings { /** Map of consent option IDs to boolean values indicating consent status */ consents: Record<string, boolean>; /** Timestamp when consent was last updated */ timestamp: number; /** Version of the consent form that was accepted */ version: string; /** Method used to collect consent (e.g., "banner", "settings", "api") */ method: string; /** Whether the user has actively made a choice (as opposed to default settings) */ hasInteracted: boolean; /** * The lawful basis under which processing is conducted * Required by NDPA Section 25(1) */ lawfulBasis?: LawfulBasisType; } /** * Represents a cross-border data transfer record */ declare interface CrossBorderTransfer { /** Unique identifier */ id: string; /** Destination country or territory */ destinationCountry: string; /** ISO country code */ destinationCountryCode?: string; /** Adequacy status of the destination */ adequacyStatus: AdequacyStatus; /** The transfer mechanism being relied upon */ transferMechanism: TransferMechanism; /** Categories of personal data being transferred */ dataCategories: string[]; /** Whether sensitive personal data is included */ includesSensitiveData: boolean; /** Estimated number of data subjects whose data is transferred */ estimatedDataSubjects?: number; /** Name of the recipient organization */ recipientOrganization: string; /** Contact details of the recipient */ recipientContact: { name: string; email: string; phone?: string; address?: string; }; /** Purpose of the data transfer */ purpose: string; /** Safeguards in place to protect the data */ safeguards: string[]; /** Risk assessment summary */ riskAssessment: string; /** Risk level of the transfer */ riskLevel: 'low' | 'medium' | 'high'; /** NDPC approval details (required for some transfer mechanisms) */ ndpcApproval?: { required: boolean; applied: boolean; approved?: boolean; referenceNumber?: string; appliedAt?: number; approvedAt?: number; }; /** Whether a Transfer Impact Assessment has been conducted */ tiaCompleted: boolean; /** Reference to the TIA document */ tiaReference?: string; /** Frequency of the transfer */ frequency: 'one_time' | 'periodic' | 'continuous'; /** Start date of the transfer */ startDate: number; /** End date of the transfer (if applicable) */ endDate?: number; /** Status of the transfer */ status: 'active' | 'suspended' | 'terminated' | 'pending_approval'; /** Timestamp when the record was created */ createdAt: number; /** Timestamp when the record was last updated */ updatedAt: number; /** Next review date */ reviewDate?: number; } declare interface CrossBorderTransferManagerClassNames { root?: string; header?: string; title?: string; summary?: string; summaryCard?: string; transferList?: string; transferItem?: string; form?: string; input?: string; select?: string; submitButton?: string; /** Alias for submitButton */ primaryButton?: string; riskBadge?: string; statusBadge?: string; detailPanel?: string; approvalStatus?: string; } /** A user-defined section added to the policy outside the generated ones. */ declare interface CustomSection { id: string; title: string; content: string; order: number; required: false; } /** A logical category of personal data the organisation may collect. */ declare interface DataCategory { /** Machine-readable identifier. */ id: string; /** Human-readable label shown in the wizard. */ label: string; /** Grouping for display and compliance checks. */ group: 'identity' | 'financial' | 'behavioral' | 'sensitive' | 'children'; /** Specific data points within this category. */ dataPoints: string[]; /** Whether this category is currently selected by the user. */ selected: boolean; } /** A map of question IDs to their answer values */ declare type DPIAAnswerMap = Record<string, DPIAAnswerValue>; /** Possible value types for a DPIA answer */ declare type DPIAAnswerValue = string | number | boolean | string[]; /** * Data Protection Impact Assessment types aligned with NDPA 2023 Section 28 * A DPIA is required when processing is likely to result in high risk to data subjects */ /** * Represents a question in the DPIA questionnaire */ declare interface DPIAQuestion { /** Unique identifier for the question */ id: string; /** The text of the question */ text: string; /** Additional guidance for answering the question */ guidance?: string; /** Type of input required for the answer */ type: 'text' | 'textarea' | 'select' | 'radio' | 'checkbox' | 'scale'; /** Options for select, radio, or checkbox questions */ options?: Array<{ value: string; label: string; riskLevel?: 'low' | 'medium' | 'high'; }>; /** For scale questions, the minimum value */ minValue?: number; /** For scale questions, the maximum value */ maxValue?: number; /** For scale questions, labels for the scale points */ scaleLabels?: Record<number, string>; /** Whether the question is required */ required: boolean; /** Risk level associated with this question */ riskLevel?: 'low' | 'medium' | 'high'; /** Whether this question triggers additional questions based on the answer */ hasDependentQuestions?: boolean; /** Conditions that determine when this question should be shown */ showWhen?: Array<{ questionId: string; operator: 'equals' | 'contains' | 'greaterThan' | 'lessThan'; value: string | number | boolean; }>; } declare interface DPIAQuestionnaireClassNames { /** Outermost wrapper */ root?: string; /** Header area containing progress indicator */ header?: string; /** Section title */ title?: string; /** Section container */ section?: string; /** Section title heading */ sectionTitle?: string; /** Individual question wrapper */ question?: string; /** Question label text */ questionText?: string; /** Guidance / help text below a question */ guidance?: string; /** Text / textarea / select inputs */ input?: string; /** Radio option group container */ radioGroup?: string; /** Individual radio option row */ radioOption?: string; /** Navigation button container */ navigation?: string; /** Next / submit button */ nextButton?: string; /** Previous button */ prevButton?: string; /** Alias for nextButton */ primaryButton?: string; /** Alias for prevButton */ secondaryButton?: string; /** Progress bar wrapper */ progressBar?: string; } /** * Represents the result of a completed DPIA */ declare interface DPIAResult { /** Unique identifier for the DPIA */ id: string; /** Title of the DPIA */ title: string; /** Description of the processing activity being assessed */ processingDescription: string; /** Timestamp when the DPIA was started */ startedAt: number; /** Timestamp when the DPIA was completed */ completedAt?: number; /** Person responsible for conducting the DPIA */ assessor: { name: string; role: string; email: string; }; /** Answers to all questions in the DPIA */ answers: Record<string, string | number | boolean | string[]>; /** Risks identified in the DPIA */ risks: DPIARisk[]; /** Overall risk level of the processing activity */ overallRiskLevel: 'low' | 'medium' | 'high' | 'critical'; /** Whether the DPIA concluded that the processing can proceed */ canProceed: boolean; /** Reasons why the processing can or cannot proceed */ conclusion: string; /** Recommendations for the processing activity */ recommendations?: string[]; /** Next review date for the DPIA */ reviewDate?: number; /** Version of the DPIA questionnaire used */ version: string; /** * Whether prior consultation with NDPC is required * Per NDPA Section 28(2), consultation is required when DPIA indicates high residual risk */ ndpcConsultationRequired?: boolean; /** Date when NDPC consultation was initiated */ ndpcConsultationDate?: number; /** Reference number from NDPC consultation */ ndpcConsultationReference?: string; /** * The lawful basis for the processing activity being assessed */ lawfulBasis?: string; /** * Whether this DPIA involves cross-border data transfers */ involvesCrossBorderTransfer?: boolean; } /** * Represents a risk identified in the DPIA */ declare interface DPIARisk { /** Unique identifier for the risk */ id: string; /** Description of the risk */ description: string; /** Likelihood of the risk occurring (1-5) */ likelihood: number; /** Impact if the risk occurs (1-5) */ impact: number; /** Overall risk score (likelihood * impact) */ score: number; /** Risk level based on the score */ level: 'low' | 'medium' | 'high' | 'critical'; /** Measures to mitigate the risk */ mitigationMeasures?: string[]; /** Whether the risk has been mitigated */ mitigated: boolean; /** Residual risk score after mitigation */ residualScore?: number; /** Questions that identified this risk */ relatedQuestionIds: string[]; } /** * Represents a section in the DPIA questionnaire */ declare interface DPIASection { /** Unique identifier for the section */ id: string; /** Title of the section */ title: string; /** Description of the section */ description?: string; /** Questions in this section */ questions: DPIAQuestion[]; /** Order of the section in the questionnaire */ order: number; } /** * Represents the data submitted by the DSR request form. */ declare interface DSRFormSubmission { /** The selected request type identifier */ requestType: string; /** Data subject personal information */ dataSubject: { fullName: string; email: string; phone?: string; identifierType: string; identifierValue: string; }; /** Additional information provided for the selected request type */ additionalInfo?: Record<string, string | number | boolean | null>; /** Timestamp (ms) when the form was submitted */ submittedAt: number; } declare interface DSRRequestFormClassNames { root?: string; title?: string; description?: string; form?: string; fieldGroup?: string; label?: string; input?: string; select?: string; textarea?: string; submitButton?: string; /** Alias for submitButton */ primaryButton?: string; successMessage?: string; /** Custom class applied when isSubmitting is true (e.g. a loading overlay) */ loadingOverlay?: string; } /** * Policy engine types for the adaptive privacy policy generator. * These types power the wizard-driven policy builder, compliance checker, * and export functionality — all aligned with the NDPA 2023. */ /** Industry verticals with sector-specific compliance requirements. */ declare type Industry = 'fintech' | 'healthcare' | 'ecommerce' | 'saas' | 'education' | 'government' | 'other'; /** * Lawful Basis types aligned with NDPA 2023 Part III (Sections 24-28) * Every processing activity must have a documented lawful basis */ /** * The six lawful bases for processing personal data per NDPA Section 25(1) */ declare type LawfulBasis = 'consent' | 'contract' | 'legal_obligation' | 'vital_interests' | 'public_interest' | 'legitimate_interests'; declare interface LawfulBasisTrackerClassNames { root?: string; header?: string; title?: string; summary?: string; summaryCard?: string; table?: string; tableHeader?: string; tableRow?: string; form?: string; input?: string; select?: string; submitButton?: string; /** Alias for submitButton */ primaryButton?: string; statusBadge?: string; complianceScore?: string; gapAlert?: string; } /** * Lawful basis for processing personal data per NDPA Section 25(1) */ declare type LawfulBasisType = 'consent' | 'contract' | 'legal_obligation' | 'vital_interests' | 'public_interest' | 'legitimate_interests'; export declare const NDPRBreachReport: React__default.FC<NDPRBreachReportProps>; /** * UX copy overrides for the NDPRBreachReport preset. Pass any subset to * replace the default text without dropping to the lower-level * `<BreachReportForm>` API. */ export declare interface NDPRBreachReportCopy { /** Form heading. Default: "Report a Data Breach" */ title?: string; /** Body paragraph under the heading. */ description?: string; /** Submit button label. Default: "Submit Report" */ submitButton?: string; } export declare interface NDPRBreachReportProps { categories?: BreachCategory[]; adapter?: StorageAdapter<BreachFormSubmission>; classNames?: BreachReportFormClassNames; unstyled?: boolean; onSubmit?: (data: BreachFormSubmission) => void; /** * UX copy overrides — see {@link NDPRBreachReportCopy}. */ copy?: NDPRBreachReportCopy; /** * Body paragraph under the heading. */ description?: string; /** * Public-form mode. Use when the form should submit to your existing * backend workflow instead of being state-managed by an adapter. * * When `submitTo` is set: * - the form does NOT require an `adapter` * - on submit, the toolkit POSTs the JSON-serialised `BreachFormSubmission` * to this URL (with `Content-Type: application/json`) * - your `onSubmit` callback still fires (after the POST resolves) * - submit failures are surfaced via `onSubmitError` * * @example * <NDPRBreachReport submitTo="/api/breach" /> */ submitTo?: string; /** * Fetch options for the `submitTo` POST. Useful for adding `credentials` * (cookies/auth), `X-CSRF-Token`, or any other header your backend * requires. Ignored unless `submitTo` is set. * * @default { credentials: 'same-origin' } */ submitOptions?: { headers?: Record<string, string> | (() => Record<string, string>); credentials?: RequestCredentials; }; /** * Called when a `submitTo` POST fails (network error or non-2xx * response). Receives the underlying error or Response. */ onSubmitError?: (ctx: { error?: unknown; response?: Response; }) => void; /** * Called when a `submitTo` POST succeeds (2xx response). Receives the * `Response` object, the submitted `BreachFormSubmission` payload, and the * parsed JSON body if the server returned valid JSON. */ onSubmitSuccess?: (ctx: { response: Response; data: BreachFormSubmission; body?: unknown; }) => void; } /** * Preset wrapper for NDPRDashboard. * * Accepts raw ComplianceInput, computes the report via getComplianceScore(), * and delegates rendering to the NDPRDashboard component. */ export declare const NDPRComplianceDashboard: React__default.FC<NDPRDashboardPresetProps>; export declare const NDPRConsent: React__default.FC<NDPRConsentProps>; /** * UX copy overrides for the NDPRConsent preset. Pass any subset to * replace the default text without dropping to the lower-level * `<ConsentBanner>` API. Strings you omit fall back to the toolkit * defaults (which already cite NDPA Section 26). * * @example * <NDPRConsent copy={{ * title: 'Cookie preferences', * description: 'Acme uses cookies to keep you signed in and improve our store.', * acceptAll: 'Allow all', * rejectAll: 'Only essentials', * }} /> */ export declare interface NDPRConsentCopy { /** Banner heading. Default: "We Value Your Privacy" */ title?: string; /** Body paragraph under the heading. Default cites NDPA Section 26. */ description?: string; /** Primary CTA — accepts all categories. Default: "Accept All" */ acceptAll?: string; /** Secondary CTA — rejects all non-essential categories. Default: "Reject All" */ rejectAll?: string; /** Tertiary CTA — opens the per-category controls. Default: "Customize" */ customize?: string; /** Submit button on the per-category panel. Default: "Save Preferences" */ save?: string; } export declare interface NDPRConsentProps { /** * Consent categories to present. When omitted, the toolkit's * default options are used. (4.0: legacy `extraOptions` was removed — * pass the full options array here instead.) */ options?: ConsentOption[]; adapter?: StorageAdapter<ConsentSettings>; position?: 'top' | 'bottom' | 'center' | 'inline'; classNames?: ConsentBannerClassNames; unstyled?: boolean; onSave?: (settings: ConsentSettings) => void; /** * UX copy overrides — see {@link NDPRConsentCopy}. Lets you brand the * banner without dropping to the lower-level `<ConsentBanner>` API. */ copy?: NDPRConsentCopy; } export declare const NDPRCrossBorder: React__default.FC<NDPRCrossBorderProps>; /** * UX copy overrides for the NDPRCrossBorder preset. Pass any subset to * replace the default text without dropping to the lower-level * `<CrossBorderTransferManager>` API. */ export declare interface NDPRCrossBorderCopy { /** Manager heading. Default: "Cross-Border Data Transfer Manager" */ title?: string; /** Body paragraph under the heading. */ description?: string; } export declare interface NDPRCrossBorderProps { /** * Initial transfers to seed the manager. (4.0: the legacy * `initialTransfers` alias was removed.) */ initialData?: CrossBorderTransfer[]; adapter?: StorageAdapter<CrossBorderTransfer[]>; classNames?: CrossBorderTransferManagerClassNames; unstyled?: boolean; /** * UX copy overrides — see {@link NDPRCrossBorderCopy}. */ copy?: NDPRCrossBorderCopy; } declare interface NDPRDashboardClassNames { root?: string; header?: string; scoreCircle?: string; scoreValue?: string; ratingBadge?: string; modulesGrid?: string; moduleCard?: string; moduleTitle?: string; moduleScore?: string; moduleGaps?: string; recommendationsSection?: string; recommendationItem?: string; recommendationPriority?: string; recommendationTitle?: string; primaryButton?: string; secondaryButton?: string; } export declare interface NDPRDashboardPresetProps { /** Raw compliance input — the preset calls getComplianceScore() internally */ input: ComplianceInput; /** Dashboard heading. Defaults to "NDPA Compliance Dashboard" */ title?: string; /** Show/hide the recommendations section. Defaults to true */ showRecommendations?: boolean; /** Maximum number of recommendations to render. Defaults to 5 */ maxRecommendations?: number; /** Per-section class name overrides */ classNames?: NDPRDashboardClassNames; /** When true, strips all default classes so consumers can style from scratch */ unstyled?: boolean; } export declare const NDPRDPIA: React__default.FC<NDPRDPIAProps>; /** * UX copy overrides for the NDPRDPIA preset. Strings you omit fall back * to the lower-level `<DPIAQuestionnaire>` defaults. The DPIA wizard does * not render a single header (each section has its own title); the `title` * and `description` fields are reserved for future use and currently * accepted for API parity with the other presets. */ export declare interface NDPRDPIACopy { /** Reserved — DPIA sections render their own titles. */ title?: string; /** Reserved — DPIA sections render their own descriptions. */ description?: string; /** Final-step submit button label. Default: "Submit" */ submitButton?: string; /** Next-section button label. Default: "Next" */ nextButton?: string; /** Previous-section button label. Default: "Previous" */ prevButton?: string; } export declare interface NDPRDPIAProps { sections?: DPIASection[]; adapter?: StorageAdapter<DPIAAnswerMap>; classNames?: DPIAQuestionnaireClassNames; unstyled?: boolean; /** * Fired when the questionnaire is submitted, with the full `DPIAResult` * including risks, overall risk level, conclusion, and recommendations. */ onResult?: (result: DPIAResult) => void; /** * UX copy overrides — see {@link NDPRDPIACopy}. */ copy?: NDPRDPIACopy; /** * Public-form mode. Use when the questionnaire should submit to your * existing backend workflow instead of being state-managed by an adapter. * * When `submitTo` is set: * - the questionnaire does NOT require an `adapter` * - on completion, the toolkit POSTs the JSON-serialised `DPIAAnswerMap` * to this URL (with `Content-Type: application/json`) * - your `onResult` callback still fires (after the POST resolves) * - submit failures are surfaced via `onSubmitError` * * @example * <NDPRDPIA submitTo="/api/dpia" /> */ submitTo?: string; /** * Fetch options for the `submitTo` POST. Useful for adding `credentials` * (cookies/auth), `X-CSRF-Token`, or any other header your backend * requires. Ignored unless `submitTo` is set. * * @default { credentials: 'same-origin' } */ submitOptions?: { headers?: Record<string, string> | (() => Record<string, string>); credentials?: RequestCredentials; }; /** * Called when a `submitTo` POST fails (network error or non-2xx * response). */ onSubmitError?: (ctx: { error?: unknown; response?: Response; }) => void; /** * Called when a `submitTo` POST succeeds (2xx response). Receives the * `Response` object, the submitted `DPIAAnswerMap` payload, and the * parsed JSON body if the server returned valid JSON. */ onSubmitSuccess?: (ctx: { response: Response; data: DPIAAnswerMap; body?: unknown; }) => void; } export declare const NDPRLawfulBasis: React__default.FC<NDPRLawfulBasisProps>; /** * UX copy overrides for the NDPRLawfulBasis preset. Pass any subset to * replace the default text without dropping to the lower-level * `<LawfulBasisTracker>` API. */ export declare interface NDPRLawfulBasisCopy { /** Tracker heading. Default: "Lawful Basis Tracker" */ title?: string; /** Body paragraph under the heading. */ description?: string; } export declare interface NDPRLawfulBasisProps { /** * Initial activities to seed the tracker. (4.0: the legacy * `initialActivities` alias was removed.) */ initialData?: ProcessingActivity[]; adapter?: StorageAdapter<ProcessingActivity[]>; classNames?: LawfulBasisTrackerClassNames; unstyled?: boolean; /** * UX copy overrides — see {@link NDPRLawfulBasisCopy}. */ copy?: NDPRLawfulBasisCopy; } export declare const NDPRPrivacyPolicy: React__default.FC<NDPRPrivacyPolicyProps>; /** * UX copy overrides for the NDPRPrivacyPolicy preset. Strings you omit * fall back to the underlying `<AdaptivePolicyWizard>` defaults. * * Note: the wizard renders many step-specific labels; the fields here * cover the high-level header text. Step-specific copy is wired through * the `NDPRProvider` locale. */ export declare interface NDPRPrivacyPolicyCopy { /** Wizard heading. Default: "Privacy Policy Builder" */ title?: string; /** Optional body paragraph under the heading. */ description?: string; /** Submit / complete button label. */ submitButton?: string; } export declare interface NDPRPrivacyPolicyProps { adapter?: StorageAdapter<PolicyDraft>; onComplete?: (policy: PrivacyPolicy) => void; classNames?: Record<string, string>; unstyled?: boolean; /** * UX copy overrides — see the `NDPRPrivacyPolicyCopy` interface. The wizard * derives most of its labels from the active `NDPRProvider` locale; the * fields here cover the high-level header text. */ copy?: NDPRPrivacyPolicyCopy; /** * Pre-fill the policy wizard with a sector-specific starter template. * * Pass one of `'saas' | 'ecommerce' | 'school' | 'healthcare' | * 'procurement'` and the wizard opens already populated with the data * categories, lawful-basis defaults, sensitive-data / children / * cross-border / automated-decisions flags that org type usually needs. * The user can still flip every flag and rewrite every section. * * @example * <NDPRPrivacyPolicy * template="healthcare" * templateOverrides={{ orgName: 'Lagos Heart Centre' }} * /> * * @see templateContextFor in `/server` or `/core` for the underlying * factory if you'd rather build the context yourself. */ template?: OrgPolicyTemplateId; /** * Organisation-level overrides applied on top of the chosen template. * Ignored when `template` is unset. */ templateOverrides?: OrgPolicyTemplateOverrides; /** * Pass a fully-constructed `TemplateContext` to skip the template * lookup entirely. Takes precedence over `template` if both are set. */ initialContext?: TemplateContext; } export declare const NDPRROPA: React__default.FC<NDPRROPAProps>; /** * UX copy overrides for the NDPRROPA preset. Pass any subset to * replace the default text without dropping to the lower-level * `<ROPAManager>` API. */ export declare interface NDPRROPACopy { /** Manager heading. Default: "Record of Processing Activities (ROPA)" */ title?: string; /** Body paragraph under the heading. */ description?: string; } export declare interface NDPRROPAProps { initialData?: RecordOfProcessingActivities; adapter?: StorageAdapter<RecordOfProcessingActivities>; classNames?: ROPAManagerClassNames; unstyled?: boolean; /** * UX copy overrides — see {@link NDPRROPACopy}. */ copy?: NDPRROPACopy; } export declare const NDPRSubjectRights: React__default.FC<NDPRSubjectRightsProps>; export declare interface NDPRSubjectRightsProps { requestTypes?: RequestType[]; adapter?: StorageAdapter<DSRFormSubmission>; classNames?: DSRRequestFormClassNames; unstyled?: boolean; onSubmit?: (data: DSRFormSubmission) => void; /** * Public-form mode. Use when the form should submit to your existing * backend workflow instead of being state-managed by an adapter. * * When `submitTo` is set: * - the form does NOT require an `adapter` * - on submit, the toolkit POSTs the JSON-serialised `DSRFormSubmission` * to this URL (with `Content-Type: application/json`) * - your `onSubmit` callback still fires (after the POST resolves) * - submit failures are surfaced via `onSubmitError` * * For more control over headers, credentials, or retry behaviour, build * an `apiAdapter` (which now supports CSRF, retry, and error hooks in * 3.6.0) and pass that as `adapter` instead. `submitTo` is the * fire-and-forget shortcut for public forms. * * @example * <NDPRSubjectRights submitTo="/api/dsr" /> */ submitTo?: string; /** * Fetch options for the `submitTo` POST. Useful for adding `credentials` * (cookies/auth), `X-CSRF-Token`, or any other header your backend * requires. Ignored unless `submitTo` is set. * * @default { credentials: 'same-origin' } */ submitOptions?: { headers?: Record<string, string> | (() => Record<string, string>); credentials?: RequestCredentials; }; /** * Called when a `submitTo` POST fails (network error or non-2xx * response). Receives the underlying error or Response. */ onSubmitError?: (ctx: { error?: unknown; response?: Response; }) => void; /** * Called when a `submitTo` POST succeeds (2xx response). Receives the * `Response` object, the submitted `DSRFormSubmission` payload, and the * parsed JSON body if the server returned valid JSON. Use this to * display a server-generated reference number, redirect the user, or * trigger analytics. * * The `body` field is `undefined` if the response had no body or the * body was not valid JSON. It is typed `unknown` to force consumers to * narrow it themselves before reading fields. * * @example * <NDPRSubjectRights * submitTo="/api/dsr" * onSubmitSuccess={({ response, data, body }) => { * const ref = (body as { referenceId?: string })?.referenceId; * if (ref) router.push(`/dsr-confirmation?ref=${ref}`); * }} * /> */ onSubmitSuccess?: (ctx: { response: Response; data: DSRFormSubmission; body?: unknown; }) => void; } /** * Represents organization information for a privacy policy */ declare interface OrganizationInfo { /** Name of the organization */ name: string; /** Website URL of the organization */ website: string; /** Contact email for privacy inquiries */ privacyEmail: string; /** Physical address of the organization */ address?: string; /** Phone number for privacy inquiries */ privacyPhone?: string; /** Name of the Data Protection Officer */ dpoName?: string; /** Email of the Data Protection Officer */ dpoEmail?: string; /** Industry or sector of the organization */ industry?: string; /** NDPC registration number (if registered) */ ndpcRegistrationNumber?: string; } /** * Org-specific privacy-policy templates — pre-filled `TemplateContext` * factories for the most common Nigerian app shapes. * * Each template returns a fully-populated `TemplateContext` with: * - industry set to the matching `Industry` value * - the data categories the sector typically collects (selected: true) * - the processing purposes that match the business model * - sensitive-data / children / cross-border / automated-decisions flags * set to the defaults that org type usually needs (a school will have * children data, a hospital will have sensitive data, etc.) * * Templates are guidance starters. The wizard still walks the user through * every step — they can flip any flag, add/remove categories, or rewrite * any section before the policy is finalised. The legal-notice footer the * toolkit ships everywhere applies to the generated output. * * @example * import { templateContextFor } from '@tantainnovative/ndpr-toolkit/server'; * const ctx = templateContextFor('ecommerce', { orgName: 'Acme NG' }); * const draft = assemblePolicy(ctx); */ /** Identifiers for the bundled org templates. */ declare type OrgPolicyTemplateId = 'saas' | 'ecommerce' | 'school' | 'healthcare' | 'procurement'; /** Optional overrides applied on top of a template's defaults. */ declare interface OrgPolicyTemplateOverrides { /** Organisation name (e.g. "Acme Nigeria Ltd"). Default: empty. */ orgName?: string; /** Public website URL. */ website?: string; /** Privacy contact email. */ privacyEmail?: string; /** Postal address. */ address?: string; /** DPO name. Required for DCPMI under NDPA Section 32. */ dpoName?: string; /** DPO email. Required for the NDPC breach-notification contact. */ dpoEmail?: string; } /** Organisation size tiers — affects complexity of generated language. */ declare type OrgSize = 'startup' | 'midsize' | 'enterprise'; /** Represents an in-progress policy being built in the wizard. */ declare interface PolicyDraft { /** Unique identifier for the draft. */ id: string; /** The template context driving section generation. */ templateContext: TemplateContext; /** Custom sections added by the user. */ customSections: CustomSection[]; /** Per-section content overrides keyed by section id. */ sectionOverrides: Record<string, string>; /** Ordered list of section ids defining the final order. */ sectionOrder: string[]; /** Current wizard step (0-indexed). */ currentStep: number; /** Timestamp of the last save. */ lastSavedAt: number; /** The draft is always in "draft" status until finalised. */ status: 'draft'; } /** * Privacy policy types aligned with NDPA 2023 * Privacy policies must clearly inform data subjects of their rights under the NDPA */ /** * Represents a section in a privacy policy */ declare interface PolicySection { /** Unique identifier for the section */ id: string; /** Title of the section */ title: string; /** Description of the section */ description?: string; /** Order of the section in the policy */ order?: number; /** Whether the section is required by NDPA */ required: boolean; /** Template text for the section */ template: string; /** * Default content for the section (legacy field) * @deprecated Use template instead */ defaultContent?: string; /** * Custom content for the section (overrides default content) * @deprecated Use template instead */ customContent?: string; /** Whether the section is included in the policy */ included: boolean; /** Variables that can be used in the section content */ variables?: string[]; } /** * Represents a generated privacy policy */ declare interface PrivacyPolicy { /** Unique identifier for the policy */ id: string; /** Title of the policy */ title: string; /** Template used to generate the policy */ templateId: string; /** Organization information */ organizationInfo: OrganizationInfo; /** Sections of the policy */ sections: PolicySection[]; /** Values for the variables used in the policy */ variableValues: Record<string, string>; /** Effective date of the policy */ effectiveDate: number; /** Last updated date of the policy */ lastUpdated: number; /** Version of the policy */ version: string; /** * Applicable legal frameworks */ applicableFrameworks?: ('ndpa' | 'ndpr' | 'gdpr' | 'ccpa')[]; } /** * Represents a processing activity and its lawful basis */ declare interface ProcessingActivity { /** Unique identifier */ id: string; /** Name of the processing activity */ name: string; /** Description of what processing is performed */ description: string; /** The lawful basis for this processing activity */ lawfulBasis: LawfulBasis; /** Justification for why this lawful basis applies */ lawfulBasisJustification: string; /** Categories of personal data being processed */ dataCategories: string[]; /** Whether sensitive personal data is involved */ involvesSensitiveData: boolean; /** Condition for processing sensitive data (required if involvesSensitiveData is true) */ sensitiveDataCondition?: SensitiveDataCondition; /** Categories of data subjects */ dataSubjectCategories: string[]; /** Purposes of the processing */ purposes: string[]; /** Data retention period */ retentionPeriod: string; /** Justification for the retention period */ retentionJustification?: string; /** Recipients or categories of recipients */ recipients?: string[]; /** Whether data is transferred outside Nigeria */ crossBorderTransfer: boolean; /** Timestamp when the record was created */ createdAt: number; /** Timestamp when the record was last updated */ updatedAt: number; /** Next review date */ reviewDate?: number; /** Status of the processing activity */ status: 'active' | 'inactive' | 'under_review' | 'archived'; /** DPO approval details */ dpoApproval?: { approved: boolean; approvedBy: string; approvedAt: number; notes?: string; }; } /** Lawful processing purposes recognised under the NDPA. */ declare type ProcessingPurpose = 'service_delivery' | 'marketing' | 'analytics' | 'research' | 'legal_compliance' | 'fraud_prevention'; /** * Record of Processing Activities (ROPA) types aligned with NDPA 2023 * Data controllers must maintain comprehensive records of all processing activities */ /** * Represents a single processing record in the ROPA */ declare interface ProcessingRecord { /** Unique identifier */ id: string; /** Name of the processing activity */ name: string; /** Detailed description of the processing */ description: string; /** Data controller details */ controllerDetails: { name: string; contact: string; address: string; registrationNumber?: string; dpoContact?: string; }; /** Joint controller details (if applicable) */ jointControllerDetails?: { name: string; contact: string; address: string; responsibilities: string; }; /** Data processor details (if processing is outsourced) */ processorDetails?: { name: string; contact: string; address: string; contractReference?: string; }; /** Lawful basis for the processing */ lawfulBasis: LawfulBasis; /** Justification for the chosen lawful basis */ lawfulBasisJustification: string; /** Purposes of the processing */ purposes: string[]; /** Categories of personal data processed */ dataCategories: string[]; /** Categories of sensitive personal data (if any) */ sensitiveDataCategories?: string[]; /** Categories of data subjects */ dataSubjectCategories: string[]; /** Recipients or categories of recipients */ recipients: string[]; /** Cross-border transfer details */ crossBorderTransfers?: Array<{ destinationCountry: string; countryCode?: string; safeguards: string; transferMechanism: string; }>; /** Data retention period */ retentionPeriod: string; /** Justification for the retention period */ retentionJustification?: string; /** Technical and organizational security measures */ securityMeasures: string[]; /** Data source (directly from data subject or from third party) */ dataSource: 'data_subject' | 'third_party' | 'public_source' | 'other'; /** Third-party source details (if dataSource is 'third_party') */ thirdPartySourceDetails?: string; /** Whether a DPIA is required for this processing */ dpiaRequired: boolean; /** Reference to the DPIA (if conducted) */ dpiaReference?: string; /** Whether automated decision-making is involved */ automatedDecisionMaking: boolean; /** Details of automated decision-making (if applicable) */ automatedDecisionMakingDetails?: string; /** Status of the processing record */ status: 'active' | 'inactive' | 'archived'; /** Department or business unit responsible */ department?: string; /** System or application used for processing */ systemsUsed?: string[]; /** Timestamp when the record was created */ createdAt: number; /** Timestamp when the record was last updated */ updatedAt: number; /** Timestamp when the record was last reviewed */ lastReviewedAt?: number; /** Next review date */ nextReviewDate?: number; } /** * Represents a complete Record of Processing Activities */ declare interface RecordOfProcessingActivities { /** Unique identifier */ id: string; /** Organization name */ organizationName: string; /** Organization contact information */ organizationContact: string; /** Organization address */ organizationAddress: string; /** Data Protection Officer details */ dpoDetails?: { name: string; email: string; phone?: string; }; /** NDPC registration number */ ndpcRegistrationNumber?: string; /** All processing records */ records: ProcessingRecord[]; /** Timestamp when the ROPA was last updated */ lastUpdated: number; /** Version of the ROPA */ version: string; /** Export format options */ exportFormats?: ('pdf' | 'csv' | 'json' | 'xlsx')[]; } /** * Represents a type of data subject request (detailed configuration) */ declare interface RequestType { /** Unique identifier for the request type */ id: string; /** Display name for the request type */ name: string; /** Description of what this request type entails */ description: string; /** * NDPA 2023 section reference for this right * (e.g., "Section 34(1)(a)" for access, "Section 38" for portability). * Used for display purposes only — verify the exact subsection wi