MetaMask / MetaMask/metamask-mobile

refactor(analytics): migrate analytics data deletion to AnalyticsPrivacyController

Open
#22,016 0 comments 0 reactions 1 assignee Claimed by @NicolasMassart View on GitHub
INVALID-ISSUE-TEMPLATE team-mobile-platform
Dominant language
TypeScript
Stars
3k
Forks
1.7k
Avg merge
1d 14h
Merged PRs (30d)
669

Description

## Description

This issue tracks the creation of an `AnalyticsPrivacyController` in the `@metamask/core` repository for analytics data deletion functionality. The controller will follow the same pattern as `@metamask/analytics-controller` and will be integrated into the Engine architecture.

### Current state

The analytics data deletion logic has already been extracted from `MetaMetrics` class into a standalone utility module:
- `app/util/analytics/analyticsDataDeletion.ts` — pure functions for Segment deletion API, storage caching
- `app/util/analytics/analyticsDataDeletion.test.ts` — full test coverage

**No migration from MetaMetrics is needed** — that step is already done.

## What remains to do

### 1. Remove `isDataRecorded` / `updateDataRecordingFlag` (dead code)

The `dataRecorded` flag and its two accessors (`isDataRecorded`, `updateDataRecordingFlag`) are no longer needed. The only consumer was the Settings deletion-status view, which has been refactored to work without it.

**Files to clean up:**

| File | What to remove / change |
|---|---|
| `app/util/analytics/analyticsDataDeletion.ts` (L223-242) | Remove `isDataRecorded()` and `updateDataRecordingFlag()` exports. Remove `dataRecorded` from the cache object and from `loadCacheFromStorage` / `setCache`. Remove `ANALYTICS_DATA_RECORDED` storage key usage. |
| `app/util/analytics/analyticsDataDeletion.test.ts` | Remove `isDataRecorded` and `updateDataRecordingFlag` test suites and imports. |
| `app/components/hooks/useAnalytics/useAnalytics.ts` | Remove `isDataRecorded` import/usage. Remove `updateDataRecordingFlagUtil` call inside `trackEvent`. Remove `saveDataRecording` parameter from `trackEvent`. |
| `app/components/hooks/useAnalytics/useAnalytics.types.ts` | Remove `isDataRecorded()` from `UseAnalyticsHook`. Remove `saveDataRecording` parameter from `trackEvent`. |
| `app/components/hooks/useAnalytics/__mocks__/useAnalytics.ts` | Remove `isDataRecorded` mock. |
| `app/components/hooks/useAnalyticsDataDeletion/useAnalyticsDataDeletion.ts` | Remove `isDataRecorded` and `updateDataRecordingFlag` imports/usage. |
| `app/components/hooks/useAnalyticsDataDeletion/useAnalyticsDataDeletion.types.ts` | Remove `isDataRecorded()` and `updateDataRecordingFlag()` from `UseAnalyticsDataDeletionHook`. |
| All test files mocking `useAnalytics` with `isDataRecorded` | Update mocks to remove it. |

### 2. Create `AnalyticsPrivacyController` in `@metamask/core`

Create `packages/analytics-privacy-controller/` extending `BaseController` with the remaining functions from `analyticsDataDeletion.ts`:

#### Controller State

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

#### Controller Actions

```typescript
interface AnalyticsPrivacyControllerActions {
createDataDeletionTask: () => Promise;
checkDataDeleteStatus: () => Promise;
getDeleteRegulationCreationDate: () => string | undefined;
getDeleteRegulationId: () => string | undefined;
}
```

#### Controller Constructor Options

```typescript
interface AnalyticsPrivacyControllerOptions {
analyticsId: string;
segmentSourceId?: string;
segmentRegulationsEndpoint?: string;
}
```

### 3. Integrate into Mobile Engine

- Create `analytics-privacy-controller-init.ts` in `app/core/Engine/controllers/analytics-privacy-controller/`
- Create `analytics-privacy-controller-messenger.ts` in `app/core/Engine/messengers/`
- Register in `Engine.ts`, add state to `EngineState` type

### 4. Replace `analyticsDataDeletion.ts` call sites with controller

| File | Change |
|---|---|
| `app/components/hooks/useAnalytics/useAnalytics.ts` | Use controller via Engine messenger instead of direct util imports |
| `app/components/hooks/useAnalyticsDataDeletion/useAnalyticsDataDeletion.ts` | Use controller via Engine messenger |
| `app/core/Authentication/Authentication.ts` | Use controller via Engine messenger for `createDataDeletionTask` |

### 5. Remove `analyticsDataDeletion.ts`

Once all call sites use the controller, delete:
- `app/util/analytics/analyticsDataDeletion.ts`
- `app/util/analytics/analyticsDataDeletion.test.ts`

### 6. Migration: delete `ANALYTICS_DATA_RECORDED` from storage

see app/constants/storage.ts
```ts
export const ANALYTICS_DATA_RECORDED = `${prefix}analyticsDataRecorded`;
```

## References

- [Segment Deletion API Documentation](https://segment.com/docs/privacy/user-deletion-and-suppression/)
- [Segment Regulations API](https://docs.segmentapis.com/tag/Deletion-and-Suppression#operation/createSourceRegulation)
- [Analytics Controller Implementation](https://github.com/MetaMask/core/tree/main/packages/analytics-controller)
- Current extraction: `app/util/analytics/analyticsDataDeletion.ts`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.