MetaMask / MetaMask/metamask-mobile
refactor(analytics): migrate analytics data deletion to AnalyticsPrivacyController
- 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
Assessment
This issue has not been assessed yet.