rebranding
This commit is contained in:
96
tasks/kordant-unified-restructure/18-hometitle-router.md
Normal file
96
tasks/kordant-unified-restructure/18-hometitle-router.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# 18. Backend Router — HomeTitle (Property Monitoring)
|
||||
|
||||
meta:
|
||||
id: kordant-unified-restructure-18
|
||||
feature: kordant-unified-restructure
|
||||
priority: P1
|
||||
depends_on: [kordant-unified-restructure-12, kordant-unified-restructure-13, kordant-unified-restructure-14]
|
||||
tags: [backend, trpc, hometitle, property, api]
|
||||
|
||||
objective:
|
||||
- Build the tRPC router for HomeTitle, the property fraud monitoring service. Port all logic from `services/hometitle/` and `packages/api/src/routes/hometitle.routes.ts` into a unified `hometitle` router and service layer.
|
||||
|
||||
deliverables:
|
||||
- `web/src/server/api/routers/hometitle.ts` — HomeTitle router:
|
||||
- `hometitle.getProperties` — `protectedProcedure` returning watched properties
|
||||
- `hometitle.addProperty` — `protectedProcedure` adding property to watchlist
|
||||
- `hometitle.removeProperty` — `protectedProcedure` removing property
|
||||
- `hometitle.getSnapshots` — `protectedProcedure` returning property record snapshots
|
||||
- `hometitle.getChanges` — `protectedProcedure` returning detected property changes
|
||||
- `hometitle.runScan` — `protectedProcedure` triggering manual property scan
|
||||
- `hometitle.getAlerts` — `protectedProcedure` returning property fraud alerts
|
||||
- `web/src/server/services/hometitle.service.ts` — Core business logic:
|
||||
- `addProperty(subscriptionId, address, parcelId?, ownerName?)` — geocode address, save record
|
||||
- `removeProperty(userId, propertyId)` — delete and cascade
|
||||
- `getSnapshots(propertyId)` — query snapshot history
|
||||
- `getChanges(propertyId, filters?)` — query changes with severity filtering
|
||||
- `runScan(userId)` — scan all watched properties:
|
||||
- Fetch current county records
|
||||
- Compare with last snapshot
|
||||
- Detect changes: ownership transfer, lien filing, tax change, metadata change
|
||||
- `generateAlert(change)` — create alert if change severity is warning/critical
|
||||
- `web/src/server/services/hometitle/scanner.ts` — County record scanning:
|
||||
- `fetchCountyRecords(parcelId, county, state)` — query county assessor/recorder APIs
|
||||
- `parseDeedRecords(html)` — extract ownership, date, lien info from HTML/PDF
|
||||
- `geocodeAddress(address)` — convert address to lat/lng using geocoding API
|
||||
- `web/src/server/services/hometitle/change.detector.ts` — Change detection:
|
||||
- `detectChanges(oldSnapshot, newData)` — compare fields and classify changes
|
||||
- `severityForChange(changeType, magnitude)` — determine severity level
|
||||
- `fuzzyMatchNames(name1, name2)` — Levenshtein distance for owner name comparison
|
||||
|
||||
steps:
|
||||
1. Create `web/src/server/api/routers/hometitle.ts`.
|
||||
2. Define Zod schemas:
|
||||
- `addPropertySchema`: `address: z.string()`, `parcelId: z.string().optional()`, `ownerName: z.string().optional()`
|
||||
- `changeFilterSchema`: `severity: z.enum(['info', 'warning', 'critical']).optional()`, `changeType: z.enum([...]).optional()`
|
||||
3. Implement router procedures:
|
||||
- Property CRUD with subscription scoping
|
||||
- Snapshot and change queries
|
||||
- Manual scan with tier limit enforcement
|
||||
4. Create `web/src/server/services/hometitle.service.ts`:
|
||||
- Port from `services/hometitle/src/`
|
||||
- Implement property geocoding on add
|
||||
- Implement scan orchestration
|
||||
5. Create scanner module:
|
||||
- `fetchCountyRecords`: placeholder for county API integration. Many counties lack APIs — document which counties are supported.
|
||||
- `parseDeedRecords`: HTML parsing with Cheerio or similar
|
||||
- `geocodeAddress`: use Google Maps, OpenStreetMap, or similar geocoding service
|
||||
6. Create change detector:
|
||||
- Compare snapshot fields: ownerName, address, deedDate, taxAmount, lienCount
|
||||
- Use fuzzy string matching for owner names
|
||||
- Classify changes into: ownership_transfer, lien_filing, tax_change, metadata_change
|
||||
7. Implement alert pipeline:
|
||||
- On significant change (warning/critical), create `Alert` and `NormalizedAlert`
|
||||
- Trigger notification via task 14 service
|
||||
8. Wire router into `web/src/server/api/root.ts`.
|
||||
9. Write unit tests with mocked county data.
|
||||
|
||||
steps:
|
||||
- Unit: `addProperty` geocodes address and creates record
|
||||
- Unit: `detectChanges` identifies ownership transfer and lien filing
|
||||
- Unit: `fuzzyMatchNames` handles minor spelling variations
|
||||
- Unit: `severityForChange` returns correct severity per change type
|
||||
- Integration: tRPC procedures enforce subscription scoping
|
||||
|
||||
acceptance_criteria:
|
||||
- [ ] Properties can be added with address geocoding and optional parcel ID
|
||||
- [ ] Properties are scoped to the user's subscription
|
||||
- [ ] Snapshots capture property record state at a point in time
|
||||
- [ ] Changes are detected by comparing new data to last snapshot
|
||||
- [ ] Manual scan can be triggered and respects tier limits
|
||||
- [ ] Alerts are generated for warning/critical changes
|
||||
- [ ] Fuzzy matching handles minor variations in owner names
|
||||
|
||||
validation:
|
||||
- Add a test property, verify geocoding and record creation
|
||||
- Simulate a snapshot change, verify change detection identifies the difference
|
||||
- Run manual scan and verify scan completion
|
||||
- Run `cd web && pnpm test` for HomeTitle unit tests
|
||||
|
||||
notes:
|
||||
- Reference legacy: `services/hometitle/src/`, `packages/api/src/routes/hometitle.routes.ts`
|
||||
- County record APIs are highly fragmented. The scanner should be designed as a plugin system where each county has its own adapter.
|
||||
- For unsupported counties, the scan should gracefully degrade and inform the user.
|
||||
- Property data may be sensitive. Ensure all records are encrypted at rest if required by compliance.
|
||||
- Consider integrating with a third-party property data provider (e.g., CoreLogic, ATTOM) for broader coverage.
|
||||
- The change detector should be configurable: users can choose which change types they want alerts for.
|
||||
Reference in New Issue
Block a user