# Routine Automation at hh.ru — Full Technical Details > Portfolio site showcasing two internal automation tools built by Pavel Sidorov, Traffic Manager at hh.ru (HeadHunter — Russia's largest job platform, ~50M monthly users). ## Geo Synchronizer ### Problem hh.ru operates 9 independent services that each maintain geographic data (cities, regions, metro stations). When geographic changes occur (new cities, renamed regions, merged territories), a traffic manager must manually update each service — a process taking ~40 minutes per change, prone to inconsistencies. ### Solution A Python-based synchronization engine that propagates geographic changes across all 9 services through a single interface. ### Architecture - **Backend**: Python, FastAPI REST API with 4 endpoints - **Frontend**: Streamlit interactive dashboard - **Deployment**: Railway (API), Streamlit Cloud (UI) - **Codebase**: 9,972 lines of Python, 73 automated tests ### Algorithm (5-step sync) 1. **Collect** — Pull current geo data from all 9 services via APIs 2. **Normalize** — Standardize naming conventions, encoding, ID formats 3. **Compare** — Diff detection across services, identifying mismatches 4. **Resolve** — Apply conflict resolution rules (4 sync modes: full, partial, append, validate-only) 5. **Propagate** — Push resolved data to all services, with rollback on failure ### Sync Modes - **Full Sync**: Complete replacement of target data - **Partial Sync**: Update only changed fields - **Append**: Add new entries without modifying existing - **Validate Only**: Dry run — report differences without changes ### Key Metrics - Sync time: 40 min → 1.5 min (96% reduction) - Coverage: 18,000+ cities and regions - Annual savings: 660 hours/year - Error rate: Near-zero (automated validation vs manual copy-paste) ### Links - App: https://geosynchronize.streamlit.app/ - API: https://geo-sync.up.railway.app/docs --- ## SMS & Email Generator ### Problem Creating personalized SMS and email campaigns for different Russian regions requires manual text composition with correct morphological forms (Russian language has 6 grammatical cases). A traffic manager spends ~15 minutes per campaign crafting messages with proper declensions. ### Solution A morphology-aware text generation engine that produces grammatically correct campaign messages from templates. ### Architecture - **Backend**: Python, FastAPI REST API with 4 endpoints - **Morphology Engine**: 707 lines of Python, handles Russian noun/adjective declension - **Frontend**: Streamlit interactive dashboard - **Templates**: 25 pre-built campaign templates with variable slots - **Deployment**: Railway (API), Streamlit Cloud (UI) ### How It Works 1. User selects a campaign template and target regions 2. Engine extracts geographic names and determines grammatical gender/number 3. Morphology module declines names into required grammatical cases (genitive, prepositional, etc.) 4. Generated messages are previewed and exported (CSV/clipboard) for bulk sending ### Key Metrics - Generation time: 15 min → 1 min (93% reduction) - Templates: 25 campaign types - Annual savings: 130 hours/year - Grammatical accuracy: >99% (vs ~90% manual) ### Links - App: https://smshhru.streamlit.app/ - API: https://smshh.up.railway.app/docs --- ## Combined Impact | Metric | Before | After | Savings | |--------|--------|-------|---------| | Geo sync per task | 40 min | 1.5 min | 96% | | SMS/Email per campaign | 15 min | 1 min | 93% | | Total annual hours saved | — | — | 790 hours | | Error reduction | Manual | Automated | ~99% | --- ## Technology Stack - **Site**: Next.js 14, React 18, Remotion (video framework), Tailwind CSS, TypeScript - **Tools Backend**: Python, FastAPI, Streamlit - **Hosting**: Vercel (site), Railway (APIs), Streamlit Cloud (dashboards) - **Database**: Neon PostgreSQL (feedback collection) ## Author **Pavel Sidorov** - Role: Traffic Manager at hh.ru - Email: p.sidorov@hh.ru - Site: https://sidorov-vibecode.com