Media library management is part of content management (CMS).
This matches the Python pattern where:
- Core media service (upload, storage) stays in platform
- Media library UI (browsing, organizing) goes to CMS module
- Media picker component stays shared (used by products, CMS, etc.)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Transform CMS from a thin wrapper into a fully self-contained module with
all code living within app/modules/cms/:
Module Structure:
- models/: ContentPage model (canonical location with dynamic discovery)
- schemas/: Pydantic schemas for API validation
- services/: ContentPageService business logic
- exceptions/: Module-specific exceptions
- routes/api/: REST API endpoints (admin, vendor, shop)
- routes/pages/: HTML page routes (admin, vendor)
- templates/cms/: Jinja2 templates (namespaced)
- static/: JavaScript files (admin/vendor)
- locales/: i18n translations (en, fr, de, lb)
Key Changes:
- Move ContentPage model to module with dynamic model discovery
- Create Pydantic schemas package for request/response validation
- Extract API routes from app/api/v1/*/ to module
- Extract page routes from admin_pages.py/vendor_pages.py to module
- Move static JS files to module with dedicated mount point
- Update templates to use cms_static for module assets
- Add module static file mounting in main.py
- Delete old scattered files (no shims - hard errors on old imports)
This establishes the pattern for migrating other modules to be
fully autonomous and independently deployable.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 2 - OMS Migration & Integration:
- Fix platform_pages.py to use get_platform_page for marketing pages
- Fix shop_pages.py to pass platform_id to content page service calls
Phase 3 - Admin Interface:
- Add platform management API (app/api/v1/admin/platforms.py)
- Add platforms admin page with stats cards
- Add Platforms menu item to admin sidebar
- Update content pages admin with platform filter and four-tab tier system
Phase 4 - Documentation:
- Add comprehensive architecture docs (docs/architecture/multi-platform-cms.md)
- Update implementation plan with completion status
Phase 5 - Vendor Dashboard:
- Add CMS usage API endpoint with tier limits
- Add usage progress bar to vendor content pages
- Add platform-default/{slug} API for preview
- Add View Default button and modal in page editor
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add is_digital and product_type columns to Product model
- Remove is_digital/product_type properties that derived from MarketplaceProduct
- Update Create form with translation tabs, GTIN type, sale price, VAT rate, image
- Update Edit form to allow editing is_digital (remove disabled state)
- Add Availability field to Edit form
- Fix Detail page for directly created products (no marketplace source)
- Update vendor_product_service to handle new fields in create/update
- Add VendorProductCreate/Update schema fields for translations and is_digital
- Add unit tests for is_digital column and direct product creation
- Add integration tests for create/update API with new fields
- Create product-architecture.md documenting the independent copy pattern
- Add migration y3d4e5f6g7h8 for is_digital and product_type columns
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add proper media exceptions (MediaNotFoundException, MediaUploadException, etc.)
- Update media service to use exceptions from app/exceptions/media
- Remove direct HTTPException raises from vendor/media.py and vendor/customers.py
- Move db.query from customers API to service layer (get_customer_orders)
- Fix pagination macro call in vendor/media.html template
- Update media.js: add parent init call, PlatformSettings, apiClient.postFormData
- Add try/catch error handling to media.js init method
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add full-text product search in ProductService.search_products()
searching titles, descriptions, SKUs, brands, and GTINs
- Implement complete vendor media library with file uploads,
thumbnails, folders, and product associations
- Implement vendor customers API with listing, details, orders,
statistics, and status management
- Add shop search results UI with pagination and add-to-cart
- Add vendor media library UI with drag-drop upload and grid view
- Add database migration for media_files and product_media tables
- Update TODO file with current launch status (~95% complete)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- JS-005: Add initialization guards to email-templates.js (admin/vendor)
- JS-006: Add try/catch error handling to content-pages.js init
- SVC-006: Move db.commit() from services to endpoints for proper
transaction control in email_template_service and vendor_team_service
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace direct console.error calls with centralized logger pattern
in both admin and vendor email templates JavaScript files.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive email template management for both admin and vendors:
Admin Features:
- Email templates management page at /admin/email-templates
- Edit platform templates with language support (en, fr, de, lb)
- Preview templates with sample variables
- Send test emails
- View email logs per template
Vendor Features:
- Email templates customization page at /vendor/{code}/email-templates
- Override platform templates with vendor-specific versions
- Preview and test customized templates
- Revert to platform defaults
Technical Changes:
- Migration for vendor_email_templates table
- VendorEmailTemplate model with override management
- Enhanced EmailService with language resolution chain
(customer preferred -> vendor preferred -> platform default)
- Branding resolution (Wizamart default, removed for whitelabel)
- Platform-only template protection (billing templates)
- Admin and vendor API endpoints with full CRUD
- Updated seed script with billing and team templates
Files: 22 changed, ~3,900 lines added
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add structured API response with business_info, localization, letzshop,
invoice_settings, theme_settings, domains, and stripe_info sections
- Add PUT /vendor/settings/business-info with reset_to_company capability
- Add PUT /vendor/settings/letzshop with validation for tax rates, delivery
- Add 9 settings sections: General, Business Info, Localization, Marketplace,
Invoices, Branding, Domains, API & Payments, Notifications
- Business Info shows "Inherited" badges and Reset buttons for company fields
- Marketplace section includes Letzshop CSV URLs and feed options
- Read-only sections for Invoices, Branding, Domains, API with contact support
- Add globe-alt icon for Domains section
- Document email templates architecture for future implementation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Added all vendor page loggers to vendorLoggers config
- Added safe fallback pattern to marketplace.js and dashboard.js
- Logger names now match what JS files expect
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Vendor API endpoints use JWT authentication, not URL path parameters.
The vendorCode should only be used for page URLs (navigation), not API calls.
Fixed API paths in 10 vendor JS files:
- analytics.js, customers.js, inventory.js, notifications.js
- order-detail.js, orders.js, products.js, profile.js
- settings.js, team.js
Added architecture rule JS-014 to prevent this pattern from recurring.
Added validation check _check_vendor_api_paths to validate_architecture.py.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add new route /vendor/{code}/orders/{order_id} for order details
- Create order-detail.html template with:
- Order summary with status and totals
- Order items with per-item shipment status and ship buttons
- Customer and shipping address display
- Invoice section (create invoice or view existing)
- Quick actions (confirm, ship all, mark delivered, cancel)
- Status update modal with tracking info fields
- Ship all modal for bulk shipment with tracking
- Create order-detail.js with full functionality:
- Load order details, shipment status, and linked invoice
- Individual item shipping with partial shipment support
- Ship all remaining items with tracking info
- Create invoice from order
- Download invoice PDF
- Status management with automatic shipment handling
- Update orders list to navigate to detail page instead of modal
- Add partially_shipped status (orange) to orders list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add selection and bulk actions to products, orders, and inventory:
- Products: bulk activate/deactivate, feature/unfeature, delete
- Orders: bulk status update, CSV export
- Inventory: bulk stock adjustment, CSV export
All pages include select-all checkbox, row selection highlighting,
and action bars with operation buttons.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New pages:
- Notifications center: view, mark read, delete, settings modal
- Analytics: period selector, stats overview, feature-gated advanced metrics
Changes:
- Add routes for /vendor/{code}/notifications and /analytics
- Create notifications.js and analytics.js with full functionality
- Create notifications.html and analytics.html templates
- Update sidebar with Analytics link and Notifications in Customers section
- Update vendor-frontend-parity-plan.md to mark Phase 3 complete
Vendor frontend now at ~95% parity with admin.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 1 - Sidebar Refactor:
- Refactor sidebar to use collapsible sections with Alpine.js
- Add localStorage persistence for section states
- Reorganize navigation into logical groups
Phase 2 - Core JS Files:
- Add products.js: product CRUD, search, filtering, toggle active/featured
- Add orders.js: order list, status management, filtering
- Add inventory.js: stock tracking, adjust/set quantity modals
- Add customers.js: customer list, order history, messaging
- Add team.js: member invite, role management, remove members
- Add profile.js: profile editing with form validation
- Add settings.js: tabbed settings (general, marketplace, notifications)
Templates updated from placeholders to full functional UIs.
Vendor frontend now at ~90% parity with admin.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The last visited page should persist across logout/login cycles so users
return to where they were. Only auth tokens should be cleared on logout.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Users are now redirected to their last visited page after logging in,
instead of always going to the dashboard.
Implementation:
- Track current page in localStorage on every page load
- Exclude login, logout, onboarding, and error pages from tracking
- On login success, redirect to last visited page if valid
- Clear last visited page on logout
Admin:
- static/admin/js/init-alpine.js: Save page to admin_last_visited_page
- static/admin/js/login.js: Redirect to last page after login
- app/templates/admin/partials/header.html: Clear on logout
Vendor:
- static/vendor/js/init-alpine.js: Save page to vendor_last_visited_page
- static/vendor/js/login.js: Redirect to last page (validates vendor code)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaced custom apiGet/apiPost/apiDelete methods with apiClient calls.
The apiClient automatically handles JWT authentication from cookies,
fixing 401 Unauthorized errors on billing API endpoints.
Also replaced showNotification with Utils.showToast for consistency
with JS-009 architecture rule.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The JS-003 architecture rule only matches function names starting with
admin*, vendor*, or shop*. Renamed billingData() to vendorBilling() to
follow the vendor JS naming convention and ensure future violations are
caught by architecture validation.
Also added currentPage: 'billing' for JS-004 compliance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Extended TPL-009 architecture rule to check vendor templates for invalid
block names (was only checking admin templates)
- Fixed billing.js to inherit base Alpine data via ...data() spread,
resolving undefined errors for dark, isSideMenuOpen, vendorCode
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add routes for vendor content pages list, create, and edit
- Create content-pages.html with tabs for Platform Defaults and My Pages
- Create content-page-edit.html for creating/editing pages
- Add JavaScript for both list and edit views
- Add "Content Pages" link to vendor sidebar under new "Shop" section
- Add show_in_legal field to vendor content pages API schemas
- Platform Defaults tab shows pages that can be overridden
- My Pages tab shows vendor's custom pages and overrides
Vendors can now:
- View platform default pages and override them with custom content
- Create entirely new custom pages for their shop
- Manage navigation placement (header, footer, legal)
- Publish/unpublish pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace console.log/error calls with onboardingLog in handleLogout
function to comply with architecture rules.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The onboarding page was a standalone page with no way to log out,
leaving users stuck. Added:
- Logout button in the header
- handleLogout() function to clear vendor tokens and redirect to login
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This fixes the "Authorization header required for API calls" error during
vendor onboarding after signup.
Changes:
- Generate JWT access token on signup completion
- Set vendor_token cookie for page navigation
- Return access_token in signup response for localStorage
- Store vendor_token in localStorage after signup completion
- Make clearTokens() context-aware to prevent cross-portal interference
- Fix vendor logout to not clear admin/customer tokens
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove redundant 1/4 progress counter from header
- Make step indicators mobile-friendly (smaller circles, hidden labels)
- Add CSV URL help text pointing to Letzshop Admin > API > Export Products
- Fix AttributeError in order sync progress (use correct model attributes)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add language selector with English, French, and German translations
- Fix API key help text to reference Letzshop Support team
- Update shop slug input with URL prefix and clearer example
- Fix step validation bug by adding db.commit() to all POST endpoints
- Translate all form labels, buttons, and messages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Include static/vendor/js and static/shared/js in JS validation
- Fix onboarding.js: use apiClient (not window.apiClient), use logger
- Fix onboarding.js: use relative paths (not /api/v1/ prefix)
- Add noqa comments for standalone pages (login, onboarding)
- Add ...data() to messages.js for layout inheritance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes JavaScript error "can't access property 'get', window.apiClient is undefined"
by following the codebase pattern where apiClient is accessed directly as a global
variable rather than via window object.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement 4-step onboarding flow for new vendors after signup:
- Step 1: Company profile setup
- Step 2: Letzshop API configuration with connection testing
- Step 3: Product & order import CSV URL configuration
- Step 4: Historical order sync with progress bar
Key features:
- Blocks dashboard access until completed
- Step indicators with visual progress
- Resume capability (progress persisted in DB)
- Admin skip capability for support cases
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Phase 6 - Database-driven tiers:
- Update subscription_service to query database first with legacy fallback
- Add get_tier_info() db parameter and _get_tier_from_legacy() method
Phase 7 - Platform health integration:
- Add get_subscription_capacity() for theoretical vs actual capacity
- Include subscription capacity in full health report
Phase 8 - Background subscription tasks:
- Add reset_period_counters() for billing period resets
- Add check_trial_expirations() for trial management
- Add sync_stripe_status() for Stripe synchronization
- Add cleanup_stale_subscriptions() for maintenance
- Add capture_capacity_snapshot() for daily metrics
Phase 10 - Capacity planning & forecasting:
- Add CapacitySnapshot model for historical tracking
- Create capacity_forecast_service with growth trends
- Add /subscription-capacity, /trends, /recommendations endpoints
- Add /snapshot endpoint for manual captures
Also includes billing API enhancements from phase 4:
- Add upcoming-invoice, change-tier, addon purchase/cancel endpoints
- Add UsageSummary schema for billing page
- Enhance billing.js with addon management functions
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
UI Components:
- Add vendor invoices page route in vendor_pages.py
- Create invoices.html template with stats cards, invoice table,
settings tab, and create invoice modal
- Add invoices.js Alpine.js component for CRUD operations,
PDF download, and settings management
- Add Invoices link to vendor sidebar in Sales section
Unit Tests (35 tests):
- VAT calculation (EU rates, regimes, labels)
- Invoice settings CRUD and number generation
- Invoice retrieval, listing, and pagination
- Status management and validation
- Statistics calculation
Integration Tests (34 tests):
- Settings API endpoints (GET/POST/PUT)
- Stats API endpoint
- Invoice list with filtering and pagination
- Invoice detail retrieval
- Invoice creation from orders
- Status update transitions
- PDF generation endpoints
- Authentication/authorization checks
🤖 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>
Add complete frontend UI for Letzshop marketplace integration:
Admin portal (/admin/letzshop):
- Vendor overview with Letzshop status cards
- Vendor table with configuration state and sync info
- Configuration modal for API credentials
- Connection testing and manual sync triggers
- Orders modal for viewing vendor orders
Vendor portal (/vendor/{code}/letzshop):
- Orders tab with import, confirm, reject actions
- Settings tab for API credentials management
- Tracking modal for shipment updates
- Order details modal with line items
- Stats display for order status counts
Also includes:
- Routes for both admin and vendor Letzshop pages
- Sidebar navigation updates for both portals
- Alpine.js data functions for reactive UI state
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Rebuild all frontend CSS files to include styles for:
- Number stepper component
- Tab components
- E-commerce shop components
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>