ADR-002: Contact Enrichment Strategy
Status
Accepted
Context
Contact enrichment is critical for providing value to users and driving viral growth. We need a strategy that balances data quality, cost, performance, and privacy while supporting our credit-based business model.
Decision
Implement a multi-provider orchestrated enrichment system with intelligent caching, progressive enhancement, and credit-based access control.
Enrichment Architecture
User Action → Enrichment Queue → Orchestrator
↓
Provider Selection
↙ ↓ ↓ ↘
Clearbit Full Hunter Custom
Contact Scrapers
↘ ↓ ↓ ↙
Data Merger
↓
Cache + Storage
Rationale
- Multi-Provider Redundancy: No single point of failure
- Cost Optimization: Use cheapest provider first
- Progressive Enhancement: Basic → Premium data
- Credit Economy: Users contribute data to earn credits
- Privacy Compliant: User controls what data is enriched
Implementation Details
Provider Priority Order
- Cache (0 credits): Check 7-day cache first
- User Contributions (0 credits): Community-verified data
- Hunter.io (1 credit): Email verification only
- Clearbit (3 credits): Company data
- FullContact (5 credits): Social profiles
- Custom Scrapers (2 credits): LinkedIn, Twitter
Caching Strategy
- L1 Cache: Redis with 1-hour TTL for active contacts
- L2 Cache: PostgreSQL with 7-day TTL for all enrichments
- L3 Cache: Cold storage after 30 days
Credit System
- Earning: Import (10), Verify (5), Referral (50)
- Spending: Basic (1-2), Premium (3-5), Export (10)
- Balance: Start with 100, max 10,000
Consequences
Positive
- High data availability through redundancy
- Cost-effective through intelligent routing
- Encourages user contribution
- Scales with usage
Negative
- Complex orchestration logic
- Multiple API integrations to maintain
- Credit system requires careful balancing
- Cache invalidation complexity
Alternatives Considered
- Single Provider: Rejected - vendor lock-in risk
- Real-time Only: Rejected - too expensive
- Batch Only: Rejected - poor user experience
- Unlimited Free: Rejected - unsustainable costs