Multi-Market Implementation: Overview and Roadmap¶
Summary¶
This directory contains 8 detailed implementation plans for adding multi-market support to the Bean.Business backend system. The plans are designed to be executed sequentially, with each phase building on the previous ones.
Quick Links¶
- Source Material:
multi-market-architecture-plan.md - Phase 1: Core Entities and Validation
- Phase 2: Database Migration and Data Migration
- Phase 3: Services Layer
- Phase 4: Cache Invalidation and Repository Updates
- Phase 5: API Integration
- Phase 6: EasyAdmin Controllers
- Phase 7: Bean-Centric Buying Options UI (Optional)
- Phase 8: Remove CoffeeBean.available
Implementation Phases¶
Phase 1: Core Entities and Validation¶
Status: Planning Duration: 3-4 hours Dependencies: None
Creates the foundational entities:
Market- Consumer markets with countries and affiliate programsAffiliateProgram- URL transformation templates using TwigBuyingOption- Sparse manual URL overrides
Deliverables:
- 3 new entities with full validation
- Database migration for new tables
- Repository classes
- Unit tests
Phase 2: Database Migration and Data Migration¶
Status: Planning Duration: 2-3 hours Dependencies: Phase 1
Adds fields to existing entities and migrates data:
- Add
marketandprioritytoRoasterCrawlConfig - Add
availabletoCrawlUrl - Migrate
CoffeeBean.available→CrawlUrl.available
Deliverables:
- Schema migration
- Data migration
- Reversible migrations (up/down)
- Transition period support
Phase 3: Services Layer¶
Status: Planning Duration: 4-5 hours Dependencies: Phase 1, 2
Implements core business logic:
AffiliateUrlService- URL transformation with Twig templatesBuyingOptionService- URL resolution with priority cascadeMarketRepository::findByCountry()- Market lookup
Deliverables:
- 2 services with comprehensive tests
- Twig sandbox security
- Cache integration
- Priority cascade logic
Phase 4: Cache Invalidation and Repository Updates¶
Status: Planning Duration: 3-4 hours Dependencies: Phase 1, 2, 3
Extends caching and repository layer:
- Update
CacheInvalidationSubscriberfor multi-market entities - Add availability methods to
CoffeeBeanRepository - Update
findByRequest()for market-based filtering
Deliverables:
- Cache tag mappings
- Repository methods for availability checks
- N+1 query prevention
- Integration tests
Phase 5: API Integration¶
Status: Planning Duration: 3-4 hours Dependencies: Phase 1, 2, 3, 4
Integrates multi-market system into API:
- Refactor
EntityToDtoMapperto useBuyingOptionService - Update URL resolution logic
- Market-based availability calculation
Deliverables:
- Updated EntityToDtoMapper
- API endpoints return affiliate URLs
- Backward compatibility maintained
- Performance tests
Phase 6: EasyAdmin Controllers¶
Status: Planning Duration: 4-6 hours Dependencies: Phase 1, 2, 3, 4, 5
Creates admin interfaces:
MarketCrudControllerwith shipping region selectorAffiliateProgramCrudControllerwith template validationBuyingOptionCrudControllerfor manual overrides- Update
RoasterCrawlConfigCrudControllerwith market/priority
Deliverables:
- 4 CRUD controllers
- Navigation menu updates
- Form validation
- Admin user guide
Phase 7: Bean-Centric Buying Options Matrix UI (Optional)¶
Status: Planning Duration: 4-6 hours Dependencies: Phase 1, 2, 3, 6
Optional enhancement for better UX:
- Matrix view on bean detail page
- Inline editing with AJAX
- Visual comparison of calculated vs manual URLs
Deliverables:
- Custom EasyAdmin field
- AJAX endpoints
- JavaScript for inline editing
- Enhanced admin UX
Note: This phase is optional. Phase 6 provides all necessary functionality.
Phase 8: Remove CoffeeBean.available Field¶
Status: Planning Duration: 2-3 hours Dependencies: Phase 1-7 (AFTER full system transition)
Final cleanup after transition:
- Remove
CoffeeBean.availablefield - Drop database column
- Update documentation
Deliverables:
- Clean entity definition
- Database migration
- Breaking change documentation
- Verification scripts
CRITICAL: Do not execute until ALL RoasterCrawlConfigs have markets assigned.
Total Timeline¶
Minimum (Phases 1-6, 8): 21-27 hours With Optional UI (Phases 1-8): 25-33 hours
Prerequisites¶
Before starting:
- Symfony 6.x or 7.x
- Doctrine ORM configured
- EasyAdmin bundle installed
- Twig component available
- Tag-aware cache configured
- Test environment set up
Architecture Overview¶
Core Entities¶
Market (new)
├── countries: ManyToMany<Country>
├── affiliateProgram: ManyToOne<AffiliateProgram>
└── roasterCrawlConfigs: OneToMany<RoasterCrawlConfig>
AffiliateProgram (new)
├── provider: enum (IMPACT, AWIN, PARTNERIZE, AMAZON_ASSOCIATES, CUSTOM)
├── urlPattern: Twig template
└── parameters: JSON
BuyingOption (new) - SPARSE
├── coffeeBean: ManyToOne<CoffeeBean>
├── market: ManyToOne<Market>
└── urlOverride: string (NOT NULL)
RoasterCrawlConfig (updated)
├── market: ManyToOne<Market> (nullable during transition)
└── priority: int (default 50)
CrawlUrl (updated)
└── available: bool (default true)
URL Resolution Priority Cascade¶
For a visitor from country X viewing bean Y:
- Manual Override - Check
BuyingOptionfor (bean Y, market serving X) - RCC Priority - Find
CrawlUrlswhere config.market serves X, sort by priority DESC - Affiliate Transform - Apply market's affiliate program to URL
- NULL - Bean not available for this country
Key Design Decisions¶
- RCC → Market is ManyToOne - Each config serves exactly one market
- BuyingOption is sparse - Only created for manual overrides
- Priority-based selection - Higher priority wins when multiple options exist
- Availability per CrawlUrl - Not global per bean
- Twig templates for affiliates - Flexible, supports complex patterns
- Transition period support - Legacy mode (market = NULL) works alongside new system
Testing Strategy¶
Each phase includes:
- Unit tests - Test individual components
- Integration tests - Test component interactions
- Manual tests - Verify admin workflows
- Performance tests - Ensure acceptable query counts
Deployment Strategy¶
Development¶
- Execute phases sequentially
- Test each phase before proceeding
- Use feature branches and code reviews
Staging¶
- Deploy code without running migrations
- Run verification scripts
- Execute migrations
- Full smoke testing
Production¶
- Database backup
- Blue-green deployment recommended
- Run migrations
- Monitor closely
- Rollback plan ready
Common Pitfalls to Avoid¶
- ManyToMany without by_reference: false - Won't persist correctly
- Not checking market.isActive - Inactive markets should be filtered
- N+1 queries - Always use joins for related entities
- Skipping cache tags - Cache won't invalidate correctly
- Removing CoffeeBean.available too early - Wait for full transition
Success Metrics¶
- ✅ All RoasterCrawlConfigs have markets assigned
- ✅ API returns affiliate-transformed URLs
- ✅ Manual overrides work correctly
- ✅ Cache hit rate remains high (>90%)
- ✅ Query count acceptable (<10 per request)
- ✅ All tests pass
- ✅ Admin can manage system without developer help
- ✅ Zero production errors related to multi-market system
Post-Implementation¶
After all phases complete:
- Monitor production for 1 week
- Train admin users
- Gather feedback
- Plan future enhancements:
- Additional affiliate providers
- Enhanced analytics
- A/B testing affiliate programs
- More granular market segmentation
Support¶
For questions or issues during implementation:
- Check source material:
multi-market-architecture-plan.md - Review specific phase plan
- Search codebase for existing patterns
- Run verification scripts
Changelog¶
- 2025-11-07: Initial plan structure created
- Plans based on comprehensive architecture document
- 8 phases with detailed implementation steps