The merchant team page was read-only. Now merchant owners can invite,
edit roles, and remove team members across all their stores from a
single hub view.
Architecture: No new models — delegates to existing store_team_service.
Members are deduplicated across stores with per-store role badges.
New:
- 5 API endpoints: GET team (member-centric), GET store roles, POST
invite (multi-store), PUT update role, DELETE remove member
- merchant-team.js Alpine component with invite/edit/remove modals
- Full CRUD template with stats cards, store filter, member table
- 7 Pydantic schemas for merchant team request/response
- 2 service methods: validate_store_ownership, get_merchant_team_members
- 25 new i18n keys across 4 tenancy locales + 1 core common key
Tests: 434 tenancy tests passing, arch-check green.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix platform-grouped merchant sidebar menu with core items at root level
- Add merchant store management (detail page, create store, team page)
- Fix store settings 500 error by removing dead stripe/API tab
- Move onboarding translations to module-owned locale files
- Fix onboarding banner i18n with server-side rendering + context inheritance
- Refactor login language selectors to use languageSelector() function (LANG-002)
- Move HTTPException handling to global exception handler in merchant routes (API-003)
- Add language selector to all login pages and portal headers
- Fix customer module: drop order stats from customer model, add to orders module
- Fix admin menu config visibility for super admin platform context
- Fix storefront auth and layout issues
- Add missing i18n translations for onboarding steps (en/fr/de/lb)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit completes the migration to a fully module-driven architecture:
## Models Migration
- Moved all domain models from models/database/ to their respective modules:
- tenancy: User, Admin, Vendor, Company, Platform, VendorDomain, etc.
- cms: MediaFile, VendorTheme
- messaging: Email, VendorEmailSettings, VendorEmailTemplate
- core: AdminMenuConfig
- models/database/ now only contains Base and TimestampMixin (infrastructure)
## Schemas Migration
- Moved all domain schemas from models/schema/ to their respective modules:
- tenancy: company, vendor, admin, team, vendor_domain
- cms: media, image, vendor_theme
- messaging: email
- models/schema/ now only contains base.py and auth.py (infrastructure)
## Routes Migration
- Moved admin routes from app/api/v1/admin/ to modules:
- menu_config.py -> core module
- modules.py -> tenancy module
- module_config.py -> tenancy module
- app/api/v1/admin/ now only aggregates auto-discovered module routes
## Menu System
- Implemented module-driven menu system with MenuDiscoveryService
- Extended FrontendType enum: PLATFORM, ADMIN, VENDOR, STOREFRONT
- Added MenuItemDefinition and MenuSectionDefinition dataclasses
- Each module now defines its own menu items in definition.py
- MenuService integrates with MenuDiscoveryService for template rendering
## Documentation
- Updated docs/architecture/models-structure.md
- Updated docs/architecture/menu-management.md
- Updated architecture validation rules for new exceptions
## Architecture Validation
- Updated MOD-019 rule to allow base.py in models/schema/
- Created core module exceptions.py and schemas/ directory
- All validation errors resolved (only warnings remain)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix toggle button alignment with consistent min-widths
- Add € currency signs to all prices
- Show all tier features with greyed unavailable ones
- Add multi-channel integration feature for Enterprise tier
- Change Contact Sales to mailto link (fixes 404)
- Restore footer CMS page links (About, FAQ, Contact)
- Add footer link translations for all 4 languages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add platform translation keys to all locale files (en, fr, de, lb)
- Integrate language selector in platform base template header
- Translate homepage-wizamart.html (hero, pricing, addons, find-shop, CTA)
- Translate pricing.html, find-shop.html, signup-success.html
- Add i18n context to platform routes via get_jinja2_globals()
- Support variable interpolation for trial_days, count parameters
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add database fields for language preferences:
- Vendor: dashboard_language, storefront_language, storefront_languages
- User: preferred_language
- Customer: preferred_language
- Add language middleware for request-level language detection:
- Cookie-based persistence
- Browser Accept-Language fallback
- Vendor storefront language constraints
- Add language API endpoints (/api/v1/language/*):
- POST /set - Set language preference
- GET /current - Get current language info
- GET /list - List available languages
- DELETE /clear - Clear preference
- Add i18n utilities (app/utils/i18n.py):
- JSON-based translation loading
- Jinja2 template integration
- Language resolution helpers
- Add reusable language selector macros for templates
- Add languageSelector() Alpine.js component
- Add translation files (en, fr, de, lb) in static/locales/
- Add architecture rules documentation for language implementation
- Update marketplace-product-detail.js to use native language names
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>