# 19. Backend Router — RemoveBrokers (Data Broker Removal)

meta:
  id: shieldai-unified-restructure-19
  feature: shieldai-unified-restructure
  priority: P1
  depends_on: [shieldai-unified-restructure-12, shieldai-unified-restructure-13, shieldai-unified-restructure-14]
  tags: [backend, trpc, removebrokers, privacy, api]

objective:
- Build the tRPC router for RemoveBrokers, the data broker removal service. Port all logic from `services/removebrokers/` and `packages/api/src/routes/removebrokers.routes.ts` into a unified `removebrokers` router and service layer.

deliverables:
- `web/src/server/api/routers/removebrokers.ts` — RemoveBrokers router:
  - `removebrokers.getBrokerRegistry` — `protectedProcedure` returning list of supported brokers
  - `removebrokers.getRemovalRequests` — `protectedProcedure` returning user's removal requests
  - `removebrokers.createRemovalRequest` — `protectedProcedure` initiating removal for a broker
  - `removebrokers.getRequestStatus` — `protectedProcedure` checking removal progress
  - `removebrokers.getBrokerListings` — `protectedProcedure` returning found listings
  - `removebrokers.scanForListings` — `protectedProcedure` scanning brokers for user's data
  - `removebrokers.getStats` — `protectedProcedure` returning removal statistics
- `web/src/server/services/removebrokers.service.ts` — Core business logic:
  - `getBrokerRegistry()` — return all active brokers with metadata
  - `createRemovalRequest(subscriptionId, brokerId, personalInfo)` — validate, create request, initiate removal
  - `getRequestStatus(requestId)` — return current status and history
  - `scanForListings(subscriptionId, brokerId)` — search broker site for user's data
  - `processRemovals()` — batch processor for pending removals
  - `updateRequestStatus(requestId, status, metadata)` — update after broker response
- `web/src/server/services/removebrokers/broker.registry.ts` — Broker definitions:
  - Static registry of supported data brokers
  - Each entry: name, domain, category, removalMethod, removalUrl, requiresAccount, estimatedDays
  - Methods: AUTOMATED, MANUAL_FORM, EMAIL, PHONE, MAIL
- `web/src/server/services/removebrokers/removal.engine.ts` — Removal automation:
  - `submitAutomatedRemoval(broker, personalInfo)` — API-based removal where available
  - `generateFormPayload(broker, personalInfo)` — prepare form data for manual submission
  - `sendRemovalEmail(broker, personalInfo)` — email-based removal request
  - `trackRemovalStatus(broker, requestId)` — poll broker for status updates

steps:
1. Create `web/src/server/api/routers/removebrokers.ts`.
2. Define Zod schemas:
   - `createRequestSchema`: `brokerId: z.string().uuid()`, `personalInfo: z.object({ fullName: z.string(), email: z.string().optional(), phone: z.string().optional(), address: z.string().optional(), dob: z.string().optional() })`
   - `scanSchema`: `brokerId: z.string().uuid().optional()` (if omitted, scan all)
3. Implement router procedures:
   - Broker registry listing (public or protected)
   - Removal request CRUD
   - Listing scan and results
   - Stats aggregation
4. Create `web/src/server/services/removebrokers.service.ts`:
   - Port from `services/removebrokers/src/`
   - Implement request lifecycle: PENDING → SUBMITTED → IN_PROGRESS → COMPLETED/FAILED
5. Create broker registry:
   - Hardcode initial list of 20-50 major data brokers
   - Include removal instructions and URLs
   - Allow admin updates via API (future enhancement)
6. Create removal engine:
   - `submitAutomatedRemoval`: call broker API if available (rare)
   - `generateFormPayload`: create structured data for form filling
   - `sendRemovalEmail`: use notification service (task 14) to send removal request email
   - `trackRemovalStatus`: placeholder for polling logic
7. Implement listing scanner:
   - Search broker websites for user's name, email, phone
   - Use web scraping (Cheerio, Playwright) where APIs are unavailable
   - Store found listings in `BrokerListing` table
8. Implement scheduler integration:
   - Pending removals should be picked up by background job (task 22)
   - Retries for failed removals with exponential backoff
9. Wire router into `web/src/server/api/root.ts`.
10. Write unit tests with mocked broker interactions.

steps:
- Unit: `createRemovalRequest` creates record with PENDING status
- Unit: `processRemovals` advances eligible requests to SUBMITTED
- Unit: `scanForListings` creates BrokerListing records for found data
- Unit: Broker registry returns correct metadata for known brokers
- Integration: tRPC procedures enforce subscription scoping

acceptance_criteria:
- [ ] Broker registry lists all supported data brokers with removal methods
- [ ] Removal requests can be created per broker with personal info
- [ ] Request status tracks lifecycle from PENDING to COMPLETED/FAILED
- [ ] Listings scanner finds user's data on broker sites
- [ ] Automated removals use APIs where available; manual methods generate instructions
- [ ] Failed removals are retried with exponential backoff
- [ ] Stats endpoint shows removal progress (total, completed, pending, failed)

validation:
- List brokers and verify registry data
- Create a removal request and verify DB record
- Simulate a scan and verify listing records created
- Run `cd web && pnpm test` for RemoveBrokers unit tests

notes:
- Reference legacy: `services/removebrokers/src/`, `packages/api/src/routes/removebrokers.routes.ts`
- Data broker removal is often a manual process. The automation layer should handle the easy cases and provide clear instructions for manual cases.
- Web scraping broker sites may violate Terms of Service. Use public APIs where available and document legal considerations.
- Personal info submitted for removal should be handled carefully. Do not log raw PII.
- The removal engine should be designed as a plugin system: each broker can have its own adapter for API, form, or email removal.
- Consider integrating with a third-party service (e.g., DeleteMe, Optery) for broader broker coverage if building individual adapters is impractical.
