Analysis of the GEO product migration from Firebase Functions to FastAPI/PostgreSQL, identifying redundancies, extracting core primitives, and planning modular refactoring.
Four major areas where duplicate code, dual data models, or parallel systems create unnecessary complexity and maintenance burden.
| Redundancy | Impact | Location | Status |
|---|---|---|---|
|
Dual Search Systems
Both search.py and mention_scraper.py independently call DataForSEO API with separate implementations
|
HIGH |
geo/api/search.py:245
functions/mention_scraper.py:89
|
Planned |
|
Schema Split Chaos
geo_saves exists in both public and geo schemas. Foreign keys reference wrong schema.
|
HIGH |
migrations/012_geo_tables.sql:15
migrations/014_geo_mentions.sql:42
|
Planned |
|
Triple Progress Tracking
Progress tracked in 3 places: mention_scans.status, reports.status, and async_operations table
|
MEDIUM |
migrations/014_geo_mentions.sql:68
migrations/015_geo_remaining_apis.sql:116
|
Planned |
|
Classification Locked in Mentions
Sentiment/relevance analysis only available to mentions pipeline, but reports could benefit from same analysis
|
MEDIUM |
geo/pipeline/mention_classifier.py:1
|
Planned |
Four fundamental operations that underpin all GEO features. These should be extracted as standalone services.
Execute query across search engines (Google, ChatGPT, Perplexity, Gemini). Returns structured SERP data with positions, URLs, snippets.
Classify search results by sentiment (-1 to 1), relevance score (0-100), authority metrics. Uses GPT-4o for semantic analysis.
Find where user's domain appears in search results. Track rank changes over time with delta calculations.
Track async operation status with real-time updates. WebSocket notifications for UI feedback during long-running jobs.
Consolidate all DataForSEO calls into a single service. Eliminates duplicate code in search.py and mention_scraper.py.
Create geo/services/search_service.py with unified interface:
Update callers to use new service:
Consolidate public.geo_saves and geo.geo_saves into single schema. Fix all foreign key references.
Update all code references:
Remove custom status fields from geo.mention_scans and geo.reports. Use only shared.async_operations for all progress.
Update code to use async_operations:
Make sentiment/relevance analysis standalone. Reports can optionally use classification on their search results.
Usage patterns:
Phased rollout of architecture improvements. Each Quick Win can be implemented independently.
| Phase | Quick Win | Effort | Files Changed | Priority |
|---|---|---|---|---|
| Phase 1 | Extract search_service.py | 4 hours | 3 files | Critical |
| Phase 1 | Unify geo_saves schema | 2 hours | 8 files + migration | Critical |
| Phase 2 | Centralize progress tracking | 3 hours | 5 files + migration | High |
| Phase 2 | Extract classification service | 3 hours | 4 files | High |
Search result caching was rejected. SERPs are cheap and client wants live data. Each query executes fresh API call.
Mentions and Reports run independently. But can use data together when for same site (via save_id linking).
Classification not forced. Mentions always uses it. Reports can optionally enable for specific use cases.
All GEO tables moving to geo.* schema. Shared infra (auth, async ops) stays in shared.*.
Ask me about your projects, reports, brand mentions, backlinks, or anything on the platform.