Skip to content

feat: create analytics data deletion controller #7618

@NicolasMassart

Description

@NicolasMassart

Description

Create a new AnalyticsPrivacyController in the @metamask/core repository to manage analytics privacy and data deletion functionality. This controller will handle GDPR/CCPA compliance features including data deletion requests, tracking deletion status, and managing data recording flags.

Controller Requirements

State Management

The controller should extend BaseController and manage the following state:

interface AnalyticsPrivacyControllerState {
  dataRecorded: boolean;
  deleteRegulationId: string | undefined;
  deleteRegulationDate: string | undefined; // DD/MM/YYYY format
}

Actions

The controller should expose the following actions:

  1. createDataDeletionTask()

    • Creates a new delete regulation for the user via Segment API
    • Returns: Promise<IDeleteRegulationResponse>
    • Purpose: GDPR/CCPA compliance - initiates data deletion request
  2. checkDataDeleteStatus()

    • Checks the latest delete regulation status
    • Returns: Promise<IDeleteRegulationStatus>
    • Purpose: Get current status of data deletion request
  3. getDeleteRegulationCreationDate()

    • Gets the latest delete regulation request date
    • Returns: string | undefined (format: DD/MM/YYYY)
    • Purpose: Retrieve when deletion request was created
  4. getDeleteRegulationId()

    • Gets the latest delete regulation request ID
    • Returns: string | undefined
    • Purpose: Retrieve Segment regulation ID for status checks
  5. isDataRecorded()

    • Indicates if events have been recorded since the last deletion request
    • Returns: boolean
    • Purpose: Track if analytics data was collected after deletion request
  6. updateDataRecordingFlag(saveDataRecording?: boolean)

    • Updates the data recording flag after tracking events
    • Returns: void
    • Purpose: Maintain data recording state for deletion workflows

Events

The controller should emit the following events:

interface AnalyticsPrivacyControllerEvents {
  /**
   * Emitted when controller state changes
   */
  stateChange: (state: AnalyticsPrivacyControllerState) => void;
  
  /**
   * Emitted when data deletion task is created
   */
  dataDeletionTaskCreated: (response: IDeleteRegulationResponse) => void;
  
  /**
   * Emitted when data recording flag is updated
   */
  dataRecordingFlagUpdated: (isRecorded: boolean) => void;
}

Controller Options

The controller should accept the following options during initialization:

interface AnalyticsPrivacyControllerOptions {
  /**
   * The analytics ID for the current user
   * Used as subjectIds in deletion request payload
   */
  analyticsId: string;
  
  /**
   * Segment API source ID (optional, can be passed during initialization)
   */
  segmentSourceId?: string;
  
  /**
   * Segment regulations API endpoint (optional, can be passed during initialization)
   */
  segmentRegulationsEndpoint?: string;
}

Type Definitions

enum DataDeleteStatus {
  failed = 'FAILED',
  finished = 'FINISHED',
  initialized = 'INITIALIZED',
  invalid = 'INVALID',
  notSupported = 'NOT_SUPPORTED',
  partialSuccess = 'PARTIAL_SUCCESS',
  running = 'RUNNING',
  unknown = 'UNKNOWN',
}

enum DataDeleteResponseStatus {
  ok = 'ok',
  error = 'error',
}

interface IDeleteRegulationResponse {
  status: DataDeleteResponseStatus;
  error?: string;
}

interface IDeleteRegulationStatus {
  deletionRequestDate?: string;
  hasCollectedDataSinceDeletionRequest: boolean;
  dataDeletionRequestStatus: DataDeleteStatus;
}

interface IDeleteRegulationStatusResponse {
  status: DataDeleteResponseStatus;
  dataDeleteStatus: DataDeleteStatus;
}

type DataDeleteDate = string | undefined;
type DataDeleteRegulationId = string | undefined;

Implementation Details

HTTP Requests

  • Use core repository's fetch implementation for HTTP requests
  • No platform adapter needed - controller handles HTTP requests internally
  • Make requests to Segment API endpoints:
    • POST to /regulations/sources/{sourceId} for creating deletion tasks
    • GET to /regulations/{regulationId} for checking deletion status

Segment API Integration

The controller should:

  • Use Segment API headers: Content-Type: application/vnd.segment.v1+json
  • Create deletion regulations with:
    • regulationType: 'DELETE_ONLY'
    • subjectType: 'USER_ID'
    • subjectIds: [analyticsId]

State Persistence

  • Controller state should be persisted via BaseController's built-in persistence mechanism
  • State includes: dataRecorded, deleteRegulationId, deleteRegulationDate

Package Structure

Follow the same structure as @metamask/analytics-controller:

  • packages/analytics-privacy-controller/
    • src/
      • AnalyticsPrivacyController.ts - Main controller implementation
      • AnalyticsPrivacyController.test.ts - Unit tests
      • index.ts - Exports
      • selectors.ts - State selectors (if needed)
    • package.json
    • README.md
    • CHANGELOG.md

References

Metadata

Metadata

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions