DPIA Questionnaire

Interactive questionnaire for Data Protection Impact Assessments

Overview

The DPIA Questionnaire component provides an interactive form for conducting Data Protection Impact Assessments (DPIAs) in compliance with the Nigeria Data Protection Regulation (NDPR). This component helps organizations identify and minimize data protection risks in their projects or systems.

When to use a DPIA

Under the NDPR, a DPIA is required when processing is likely to result in a high risk to the rights and freedoms of individuals. This includes systematic and extensive profiling, processing of special categories of data on a large scale, or systematic monitoring of public areas.

Installation

Install the NDPR Toolkit package which includes the DPIA Questionnaire component:

npm install @tantainnovative/ndpr-toolkit
# Or with legacy peer deps if using React 19 npm install @tantainnovative/ndpr-toolkit --legacy-peer-deps

Or if you're using yarn:

yarn add @tantainnovative/ndpr-toolkit
# Or with legacy peer deps if using React 19 yarn add @tantainnovative/ndpr-toolkit --legacy-peer-deps

Usage

Import and use the DPIAQuestionnaire component in your React application:

import { DPIAQuestionnaire } from '@tantainnovative/ndpr-toolkit';

// Define your DPIA questions
const dpiaQuestions = [
  {
    id: 'data_collection',
    question: 'What types of personal data will be collected?',
    options: [
      { value: 1, label: 'Basic contact information only' },
      { value: 2, label: 'Personal identifiers and contact information' },
      { value: 3, label: 'Sensitive personal data (health, biometric, etc.)' }
    ]
  },
  {
    id: 'data_volume',
    question: 'What is the volume of data being processed?',
    options: [
      { value: 1, label: 'Small scale (fewer than 100 data subjects)' },
      { value: 2, label: 'Medium scale (100-1000 data subjects)' },
      { value: 3, label: 'Large scale (more than 1000 data subjects)' }
    ]
  },
  // Add more questions as needed
];

function MyDPIAForm() {
  const handleSubmit = (answers, projectName) => {
    console.log('Project Name:', projectName);
    console.log('DPIA Answers:', answers);
    
    // Calculate risk score or send to your backend
    // ...
  };

  return (
    <div>
      <h1>Data Protection Impact Assessment</h1>
      <DPIAQuestionnaire 
        questions={dpiaQuestions}
        onSubmit={handleSubmit}
      />
    </div>
  );
}

Props

NameTypeRequiredDescription
questionsDPIAQuestion[]YesArray of DPIA questions to display in the questionnaire
onSubmit(answers: Record<string, number>, projectName: string) => voidYesCallback function when user submits the assessment
initialAnswersRecord<string, number>NoInitial answers for the questionnaire
initialProjectNamestringNoInitial project name
classNamestringNoAdditional CSS class names

DPIAQuestion Type

type DPIAQuestion = {
  id: string;
  question: string;
  options: {
    value: number;
    label: string;
  }[];
  helpText?: string;
};

Examples

Basic Example

import { DPIAQuestionnaire } from '@tantainnovative/ndpr-toolkit';

const basicQuestions = [
  {
    id: 'q1',
    question: 'Does the project involve collecting personal data?',
    options: [
      { value: 1, label: 'No personal data collected' },
      { value: 2, label: 'Limited personal data collected' },
      { value: 3, label: 'Extensive personal data collected' }
    ]
  },
  {
    id: 'q2',
    question: 'Will the data be shared with third parties?',
    options: [
      { value: 1, label: 'No sharing with third parties' },
      { value: 2, label: 'Limited sharing with trusted partners' },
      { value: 3, label: 'Extensive sharing with multiple third parties' }
    ]
  }
];

function BasicDPIA() {
  return (
    <DPIAQuestionnaire 
      questions={basicQuestions}
      onSubmit={(answers, projectName) => {
        console.log(answers, projectName);
      }}
    />
  );
}

With Initial Values

import { DPIAQuestionnaire } from '@tantainnovative/ndpr-toolkit';

function DPIAWithInitialValues() {
  const initialAnswers = {
    'q1': 2,
    'q2': 1
  };

  return (
    <DPIAQuestionnaire 
      questions={basicQuestions}
      initialAnswers={initialAnswers}
      initialProjectName="E-commerce Platform"
      onSubmit={(answers, projectName) => {
        console.log(answers, projectName);
      }}
    />
  );
}

With Risk Calculation

import { DPIAQuestionnaire } from '@tantainnovative/ndpr-toolkit';
import { useState } from 'react';

function DPIAWithRiskCalculation() {
  const [riskScore, setRiskScore] = useState(0);
  const [riskLevel, setRiskLevel] = useState('');
  const [recommendations, setRecommendations] = useState([]);

  const handleSubmit = (answers, projectName) => {
    // Calculate total risk score
    const totalScore = Object.values(answers).reduce((sum, value) => sum + value, 0);
    const maxPossibleScore = Object.keys(answers).length * 3; // Assuming max value per question is 3
    const percentageScore = (totalScore / maxPossibleScore) * 100;
    
    setRiskScore(percentageScore);
    
    // Determine risk level
    let level = '';
    let recs = [];
    
    if (percentageScore < 40) {
      level = 'Low Risk';
      recs = ['Regular review of data processing activities'];
    } else if (percentageScore < 70) {
      level = 'Medium Risk';
      recs = [
        'Implement additional security measures',
        'Conduct regular staff training',
        'Review data retention policies'
      ];
    } else {
      level = 'High Risk';
      recs = [
        'Consult with NITDA before proceeding',
        'Implement strict access controls',
        'Conduct comprehensive security audit',
        'Consider data minimization strategies',
        'Implement regular compliance monitoring'
      ];
    }
    
    setRiskLevel(level);
    setRecommendations(recs);
  };

  return (
    <div>
      <DPIAQuestionnaire 
        questions={comprehensiveQuestions}
        onSubmit={handleSubmit}
      />
      
      {riskScore > 0 && (
        <div className="mt-8 p-6 bg-white dark:bg-gray-800 rounded-lg shadow">
          <h2>DPIA Results: {riskLevel}</h2>
          <div className="w-full bg-gray-200 rounded-full h-2.5 mb-4">
            <div 
              className={`h-2.5 rounded-full ${
                riskScore < 40 ? 'bg-green-600' : 
                riskScore < 70 ? 'bg-yellow-500' : 'bg-red-600'
              }`}
              style={{ width: `${riskScore}%` }}
            ></div>
          </div>
          <p>Risk Score: {riskScore.toFixed(1)}%</p>
          
          <h3 className="mt-4">Recommendations:</h3>
          <ul>
            {recommendations.map((rec, index) => (
              <li key={index}>{rec}</li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

API Reference

DPIAQuestion Interface

export 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;
  
  /**
   * Whether the question is required
   */
  required: boolean;
  
  /**
   * Risk level associated with this question
   */
  riskLevel?: 'low' | 'medium' | 'high';
  
  /**
   * Conditions that determine when this question should be shown
   */
  showWhen?: Array<{
    questionId: string;
    operator: 'equals' | 'contains' | 'greaterThan' | 'lessThan';
    value: any;
  }>;
}

DPIASection Interface

export 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;
}

DPIARisk Interface

export 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;
  
  /**
   * Questions that identified this risk
   */
  relatedQuestionIds: string[];
}

DPIAResult Interface

export 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, any>;
  
  /**
   * 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;
  
  /**
   * Recommendations for the processing activity
   */
  recommendations?: string[];
}

useDPIA Hook

// Import the hook
import { useDPIA } from '@tantainnovative/ndpr-toolkit';

// Use the hook in your component
const { 
  dpias,                // Array of all DPIAs
  startDPIA,            // Function to start a new DPIA
  updateDPIA,           // Function to update an existing DPIA
  completeDPIA,         // Function to complete a DPIA
  getDPIAById,          // Function to get a DPIA by ID
  identifyRisks,        // Function to identify risks based on answers
  assessRisk,           // Function to assess a specific risk
  generateReport        // Function to generate a DPIA report
} = useDPIA();

// Start a new DPIA
const newDPIA = startDPIA({
  title: 'Customer Data Analytics Platform',
  processingDescription: 'Processing customer data for analytics and personalization',
  assessor: {
    name: 'Jane Smith',
    role: 'Data Protection Officer',
    email: 'jane@example.com'
  }
});

// Update DPIA with answers
updateDPIA(newDPIA.id, {
  answers: {
    'data-types': ['personal', 'behavioral'],
    'data-volume': 'large',
    'automated-processing': true,
    'sensitive-data': false
  }
});

// Identify risks based on answers
const risks = identifyRisks(newDPIA.id);

// Complete the DPIA
completeDPIA(newDPIA.id, {
  risks: risks,
  overallRiskLevel: 'medium',
  canProceed: true,
  conclusion: 'The processing can proceed with appropriate safeguards.',
  recommendations: [
    'Implement data minimization practices',
    'Enhance access controls',
    'Conduct regular security audits'
  ]
});

// Generate a DPIA report
const report = generateReport(newDPIA.id);

Best Practices

  • Comprehensive Questions: Include questions that cover all aspects of data processing, including collection, storage, sharing, and deletion.
  • Risk Scoring: Implement a risk scoring system to help identify high-risk areas that need additional mitigation measures.
  • Documentation: Ensure the DPIA results are documented and stored for compliance purposes. The NDPR requires organizations to maintain records of processing activities.
  • Regular Reviews: DPIAs should be reviewed periodically, especially when there are changes to the processing activities.
  • Consultation: For high-risk processing, consider consulting with NITDA or a data protection expert.

Accessibility

The DPIAQuestionnaire component is built with accessibility in mind:

  • All form elements have proper labels and ARIA attributes
  • Focus states are clearly visible
  • Color contrast meets WCAG 2.1 AA standards
  • Keyboard navigation is fully supported

To ensure maximum accessibility, make sure to provide clear and descriptive question text and help text where appropriate.

Need Help?

If you have questions about implementing the DPIA Questionnaire or need assistance with NDPR compliance, check out these resources:

GitHub Issues

Report bugs or request features on our GitHub repository.

View Issues

NDPR Resources

Learn more about NDPR compliance requirements.

NDPR Framework