60 lines
3.7 KiB
Markdown
60 lines
3.7 KiB
Markdown
---
|
|
id: TASK-6
|
|
title: Integrate Google Geocoding and Places lead discovery
|
|
status: Done
|
|
assignee: []
|
|
created_date: '2026-06-03 19:12'
|
|
updated_date: '2026-06-04 13:24'
|
|
labels:
|
|
- mvp
|
|
- integrations
|
|
- leads
|
|
dependencies:
|
|
- TASK-5
|
|
references:
|
|
- PRD.md
|
|
priority: high
|
|
ordinal: 6000
|
|
---
|
|
|
|
## Description
|
|
|
|
<!-- SECTION:DESCRIPTION:BEGIN -->
|
|
Connect the campaign runner to Google Geocoding and Google Places. The system geocodes German postal codes, searches local businesses by category or custom niche within the configured radius, applies per-run limits, and stores source-backed lead records without sending outreach.
|
|
<!-- SECTION:DESCRIPTION:END -->
|
|
|
|
## Acceptance Criteria
|
|
<!-- AC:BEGIN -->
|
|
- [x] #1 German PLZ values are geocoded to coordinates and cached on the campaign or run
|
|
- [x] #2 Google Places searches use category mappings or custom niche text plus configured radius
|
|
- [x] #3 Lead records store Place ID, business name, address, category, website, phone, rating metadata for internal use, and source timestamps where available
|
|
- [x] #4 Runs respect max new leads and never start if another agent run is already active
|
|
- [x] #5 API failures, empty results, skipped duplicates, and skipped blacklisted entities are visible in run logs
|
|
<!-- AC:END -->
|
|
|
|
## Implementation Plan
|
|
|
|
<!-- SECTION:PLAN:BEGIN -->
|
|
1. Add failing helper tests for Google category/query mapping, response parsing, duplicate/blacklist decisions, and source metadata.
|
|
2. Implement pure lead discovery helpers with GOOGLE_GEOCODING_API_KEY and GOOGLE_PLACES_API_KEY contract.
|
|
3. Add failing Convex/schema tests or type checks for campaign requestRun guard, scheduled processing, geocode caching, and lead source persistence.
|
|
4. Implement Convex leadDiscovery processing, run transitions, logging, limits, duplicate and blacklist skips.
|
|
5. Run pnpm test, pnpm exec tsc -p tsconfig.json, pnpm lint; review and fix findings.
|
|
<!-- SECTION:PLAN:END -->
|
|
|
|
## Implementation Notes
|
|
|
|
<!-- SECTION:NOTES:BEGIN -->
|
|
Starting TASK-6 after TASK-5 completion. Adjusted plan: reuse campaigns.requestRun and existing campaign run status UI; use split GOOGLE_GEOCODING_API_KEY and GOOGLE_PLACES_API_KEY from .env.local; no outreach or audit creation in this task.
|
|
|
|
Implemented TASK-6 subagent-driven and test-driven. Worker 1 built pure Google discovery helpers with RED/GREEN tests. Spec reviewer requested website URL persistence; fixed with TDD mapper and re-review approved. Code-quality reviewer requested exact blacklist lookups and moving campaign timestamp updates to actual run start; fixed and re-review approved. Final verification: npx convex codegen passed; pnpm exec tsc -p tsconfig.json passed; pnpm test passed 51/51; pnpm lint passed with only existing generated BetterAuth warnings.
|
|
|
|
Bugfix after manual UI test: campaigns.requestRun previously treated any pending run as active forever, so old Task-5 pending runs blocked new lead discovery starts. Added TDD coverage for stale pending runs, a 10-minute pending grace period, and automatic cancellation/logging of stale pending runs before creating a new run. Verification: pnpm exec tsc -p tsconfig.json passed; pnpm test passed 52/52; pnpm lint passed with only existing generated BetterAuth warnings; npx convex codegen passed.
|
|
<!-- SECTION:NOTES:END -->
|
|
|
|
## Final Summary
|
|
|
|
<!-- SECTION:FINAL_SUMMARY:BEGIN -->
|
|
TASK-6 shipped Google Geocoding and Places lead discovery wired into the existing campaign run flow. It geocodes German PLZ values, caches coordinates, searches Places with preset mappings or custom text plus radius, stores Google source-backed lead metadata, respects per-run limits and active-run guards, logs failures/empty/duplicate/blacklist outcomes, and includes the stale-pending-run cleanup discovered during manual UI testing.
|
|
<!-- SECTION:FINAL_SUMMARY:END -->
|