Data Subject Rights Portal

NDPR-compliant portal for managing data subject rights requests

Overview

The Data Subject Rights Portal provides a complete solution for handling data subject access requests (DSARs) and other rights requests in compliance with the Nigeria Data Protection Regulation (NDPR). It includes a request submission form, admin dashboard for managing requests, and a tracking system for data subjects.

NDPR Data Subject Rights

Under the NDPR, data subjects have several rights, including the right to access their personal data, right to rectification, right to erasure, right to restrict processing, right to data portability, and right to object to processing. Organizations must respond to these requests within 30 days.

Installation

Install the NDPR Toolkit package which includes the Data Subject Rights components:

npm install @tantainnovative/ndpr-toolkit

Or if you're using yarn:

yarn add @tantainnovative/ndpr-toolkit

Components

The Data Subject Rights system includes several components that work together:

DSRRequestForm

A form for data subjects to submit rights requests, with support for different request types.

import { DSRRequestForm, DSRType } from '@tantainnovative/ndpr-toolkit';

<DSRRequestForm 
  onSubmit={handleSubmitRequest}
  requestTypes={[
    { id: 'access', label: 'Access my data' },
    { id: 'rectification', label: 'Correct my data' },
    { id: 'erasure', label: 'Delete my data' },
    { id: 'restriction', label: 'Restrict processing of my data' },
    { id: 'portability', label: 'Data portability' },
    { id: 'objection', label: 'Object to processing' }
  ]}
/>

DSRDashboard

An admin dashboard for managing and responding to data subject rights requests.

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

<DSRDashboard 
  requests={dsrRequests}
  onUpdateRequest={handleUpdateRequest}
  onDeleteRequest={handleDeleteRequest}
  onAssignRequest={handleAssignRequest}
/>

DSRTracker

A component for data subjects to track the status of their requests.

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

<DSRTracker 
  requestId="dsr-123456"
  onLookup={handleLookupRequest}
/>

BreachReportForm

A form for reporting data breaches, which is a requirement under the NDPR.

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

<BreachReportForm 
  onSubmit={handleSubmitBreachReport}
  formDescription="Report a data breach that has occurred within your organization."
  recipientEmail="dpo@example.com"
/>

Usage

Here's a complete example of how to implement the Data Subject Rights system in your application:

import { useState, useEffect } from 'react';
import { 
  DSRRequestForm, 
  DSRDashboard, 
  DSRTracker,
  useDSR,
  DSRType,
  DSRStatus
} from '@tantainnovative/ndpr-toolkit';

// Define your request types
const requestTypes = [
  { id: 'access', label: 'Access my data' },
  { id: 'rectification', label: 'Correct my data' },
  { id: 'erasure', label: 'Delete my data' },
  { id: 'restriction', label: 'Restrict processing of my data' },
  { id: 'portability', label: 'Data portability' },
  { id: 'objection', label: 'Object to processing' }
];

function DSRPortal() {
  const [activeTab, setActiveTab] = useState('submit');
  const [trackingId, setTrackingId] = useState('');
  
  const { 
    requests, 
    submitRequest, 
    updateRequest, 
    deleteRequest, 
    getRequestById 
  } = useDSR();
  
  const handleSubmitRequest = (request) => {
    const newRequest = submitRequest({
      type: request.type,
      subject: {
        name: request.name,
        email: request.email,
        phone: request.phone
      },
      details: request.details
    });
    
    // Show the tracking ID to the user
    alert(`Your request has been submitted. Your tracking ID is: ${newRequest.id}`);
  };
  
  const handleLookupRequest = (id) => {
    const request = getRequestById(id);
    return request;
  };
  
  return (
    <div>
      <nav>
        <button onClick={() => setActiveTab('submit')}>Submit Request</button>
        <button onClick={() => setActiveTab('track')}>Track Request</button>
        <button onClick={() => setActiveTab('admin')}>Admin Dashboard</button>
      </nav>
      
      {activeTab === 'submit' && (
        <DSRRequestForm 
          onSubmit={handleSubmitRequest}
          requestTypes={requestTypes}
        />
      )}
      
      {activeTab === 'track' && (
        <div>
          <h2>Track Your Request</h2>
          <input 
            type="text" 
            value={trackingId} 
            onChange={(e) => setTrackingId(e.target.value)}
            placeholder="Enter your tracking ID"
          />
          <button onClick={() => setActiveTab('tracking')}>Track</button>
          
          {activeTab === 'tracking' && trackingId && (
            <DSRTracker 
              requestId={trackingId}
              onLookup={handleLookupRequest}
            />
          )}
        </div>
      )}
      
      {activeTab === 'admin' && (
        <DSRDashboard 
          requests={requests}
          onUpdateRequest={updateRequest}
          onDeleteRequest={deleteRequest}
        />
      )}
    </div>
  );
}

API Reference

DSRRequestForm Props

PropTypeDefaultDescription
onSubmit(request: DSRFormData) => voidRequiredCallback function when form is submitted
requestTypesArray<{id: string, label: string}>RequiredArray of request types to display
titlestring'Submit a Data Subject Rights Request'Form title
descriptionstring'Use this form to submit a request...'Form description
submitButtonTextstring'Submit Request'Text for the submit button

useDSR Hook

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

// Use the hook in your component
const { 
  requests,                // Array of all DSR requests
  submitRequest,           // Function to submit a new request
  updateRequest,           // Function to update an existing request
  deleteRequest,           // Function to delete a request
  getRequestById,          // Function to get a request by ID
  filterRequestsByStatus,  // Function to filter requests by status
  filterRequestsByType     // Function to filter requests by type
} = useDSR();

// Submit a new request
const newRequest = submitRequest({
  type: 'access',
  subject: {
    name: 'John Doe',
    email: 'john@example.com',
    phone: '1234567890'
  },
  details: 'I would like to access all my personal data.'
});

// Update a request
updateRequest('request-id', {
  status: 'inProgress',
  assignedTo: 'data-officer@example.com'
});

// Get a request by ID
const request = getRequestById('request-id');

// Filter requests
const pendingRequests = filterRequestsByStatus('pending');
const accessRequests = filterRequestsByType('access');

DSRType Enum

export type DSRType = 'access' | 'rectification' | 'erasure' | 'restriction' | 'portability' | 'objection';

DSRStatus Enum

export type DSRStatus = 'pending' | 'awaitingVerification' | 'inProgress' | 'completed' | 'rejected';

DSRRequest Interface

export interface DSRRequest {
  /**
   * Unique identifier for the request
   */
  id: string;
  
  /**
   * Type of request
   */
  type: DSRType;
  
  /**
   * Current status of the request
   */
  status: DSRStatus;
  
  /**
   * Timestamp when the request was submitted
   */
  createdAt: number;
  
  /**
   * Timestamp when the request was last updated
   */
  updatedAt: number;
  
  /**
   * Timestamp when the request was completed (if applicable)
   */
  completedAt?: number;
  
  /**
   * Timestamp when the identity was verified (if applicable)
   */
  verifiedAt?: number;
  
  /**
   * Due date for responding to the request (timestamp)
   */
  dueDate?: number;
  
  /**
   * Description or details of the request
   */
  description?: string;
  
  /**
   * Data subject information
   */
  subject: {
    /**
     * Name of the data subject
     */
    name: string;
    
    /**
     * Email address of the data subject
     */
    email: string;
    
    /**
     * Phone number of the data subject (optional)
     */
    phone?: string;
    
    /**
     * Identifier used to verify the data subject's identity (optional)
     */
    identifierValue?: string;
    
    /**
     * Type of identifier used (e.g., "email", "account", "customer_id") (optional)
     */
    identifierType?: string;
  };
  
  /**
   * Additional information provided by the data subject
   */
  additionalInfo?: Record<string, any>;
  
  /**
   * Notes added by staff processing the request
   */
  internalNotes?: Array<{
    timestamp: number;
    author: string;
    note: string;
  }>;
}

Best Practices

  • Verification Process: Implement a verification process to confirm the identity of the data subject making the request.
  • Response Timeframe: The NDPR requires organizations to respond to DSARs within 30 days. Ensure your process allows for timely responses.
  • Complete Responses: Provide complete information in response to access requests, including what data you hold, how it's used, who it's shared with, and its source.
  • Record Keeping: Maintain records of all DSARs and your responses to them. The DSRDashboard component helps with this.
  • Staff Training: Ensure staff handling DSARs are trained on the requirements of the NDPR and your internal processes.

Accessibility

The Data Subject Rights components are 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
  • Error messages are announced to screen readers

Need Help?

If you have questions about implementing the Data Subject Rights system 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