Add Info Broker Removal service (FRE-5402)

New service for helping clients remove personal listings from data broker sites.

Service features:
- BrokerRegistry: Catalog of 20+ data brokers with removal methods
- RemoveBrokersService: Core service for scanning, creating removal requests,
  submitting removals, and verifying completions
- RemoveBrokersScheduler: Automated processing of pending removals and
  verification of completed removals
- BrokerAlertPipeline: Alert integration for listing discoveries and removal status

API endpoints (/removebrokers):
- GET /brokers - List available data brokers
- GET /status - Get removal request status and stats
- POST /scan - Scan for personal listings across brokers
- POST /request - Create a new removal request
- GET /request/:id - Get specific removal request details
- DELETE /request/:id - Cancel a removal request
- POST /process - Trigger processing of pending removals
- POST /verify/:id - Manually verify a removal completion

DB models: InfoBroker, RemovalRequest, BrokerListing
Types: BrokerStatus, RemovalStatus, RemovalMethod, and related interfaces
This commit is contained in:
Founding Engineer
2026-05-17 00:58:23 -04:00
committed by Michael Freno
parent 590e15e66e
commit bd881045f4
14 changed files with 1808 additions and 0 deletions

View File

@@ -0,0 +1,69 @@
import { AlertSource, AlertCategory, Severity, EntityType } from "@shieldai/types";
export interface BrokerAlertInput {
userId: string;
brokerName: string;
brokerId: string;
category: AlertCategory;
severity: Severity;
title: string;
description: string;
entities: Array<{ type: EntityType; value: string }>;
metadata?: Record<string, unknown>;
}
export class BrokerAlertPipeline {
async sendListingFoundAlert(input: BrokerAlertInput) {
const alert = {
source: AlertSource.INFO_BROKER,
category: AlertCategory.INFO_BROKER_LISTING,
severity: input.severity,
userId: input.userId,
title: input.title,
description: input.description,
entities: input.entities,
sourceAlertId: `broker_listing_${input.brokerId}_${Date.now()}`,
payload: {
brokerId: input.brokerId,
brokerName: input.brokerName,
...input.metadata,
},
timestamp: new Date(),
};
return this.normalizeAndSend(alert);
}
async sendRemovalStatusAlert(input: BrokerAlertInput) {
const alert = {
source: AlertSource.INFO_BROKER,
category: AlertCategory.INFO_BROKER_REMOVAL,
severity: input.severity,
userId: input.userId,
title: input.title,
description: input.description,
entities: input.entities,
sourceAlertId: `broker_removal_${input.brokerId}_${Date.now()}`,
payload: {
brokerId: input.brokerId,
brokerName: input.brokerName,
...input.metadata,
},
timestamp: new Date(),
};
return this.normalizeAndSend(alert);
}
private async normalizeAndSend(alert: any) {
try {
const { correlationPipeline } = await import("@shieldai/correlation");
return correlationPipeline.normalizeAlert(alert);
} catch {
console.error("[BrokerAlert] Failed to send alert:", alert.sourceAlertId);
return alert;
}
}
}
export const brokerAlertPipeline = new BrokerAlertPipeline();