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>
components.js is a UI components library reference for developers,
so it belongs in dev_tools alongside icons-page.js, testing-*.js,
and code-quality-*.js.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
icons-page.js is a dev tool for browsing available icons, so it
belongs in dev_tools alongside testing-*.js and code-quality-*.js.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
users.js, user-detail.js, user-edit.js, user-create.js are for
managing platform/vendor users, not shop customers. Move them
back to static/admin/js/ where other platform admin files reside.
The customers module retains customers.js which manages actual
shop customers (people who buy from vendors).
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add AdminMenuConfig model for per-platform menu customization
- Add menu registry for centralized menu configuration
- Add my-menu-config and platform-menu-config admin pages
- Update sidebar with improved layout and Alpine.js interactions
- Add FrontendType enum for admin/vendor menu separation
- Document self-contained module patterns in session note
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add dedicated pages for viewing module details and configuring module
settings. Includes routes, templates, and JS components for module
info page showing features, menu items, dependencies, and self-contained
module paths. Also adds View/Configure navigation buttons to the platform
modules list.
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>
Added a complete Admin UI for managing platform modules:
API endpoints (app/api/v1/admin/modules.py):
- GET /modules - List all available modules
- GET /modules/platforms/{id} - Get platform modules
- PUT /modules/platforms/{id} - Update enabled modules
- POST /modules/platforms/{id}/enable - Enable a module
- POST /modules/platforms/{id}/disable - Disable a module
- POST /modules/platforms/{id}/enable-all - Enable all
- POST /modules/platforms/{id}/disable-optional - Core only
Admin UI:
- New page route: /admin/platforms/{code}/modules
- Template: platform-modules.html
- JavaScript: platform-modules.js
- Link added to platform-detail.html Super Admin section
Features:
- Toggle modules on/off with dependency resolution
- Enable all / Core only bulk actions
- Visual dependency indicators
- Separate sections for core vs optional modules
- Feature list preview per module
Also includes require_menu_access updates to page routes from Phase 2.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The API endpoint has a max limit of 500 but the stats query was
requesting 1000, causing a 422 validation error.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use inline template literals with {% raw %}{% endraw %} and HTML entities
(") for quotes, consistent with other copy code buttons on the page.
Removed the codeSnippets JS variables.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Store code snippets as JS variables in components.js and reference them
in the template. This avoids multi-line template literals in HTML
attributes while still providing copy functionality.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added documentation and interactive examples for both confirm_modal
and confirm_modal_dynamic macros, showing danger, warning, info variants
and dynamic message capabilities.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaced the native browser confirm() dialog with the styled confirm_modal
macro for a consistent UI experience when removing platform assignments
from admin users.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The admin user edit page now uses a dedicated template and JS file
that properly matches the /admin/admin-users/{id}/edit URL pattern.
The page allows super admins to:
- Toggle super admin status
- Toggle active status
- Manage platform assignments for platform admins
- Delete admin users
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /admin/admin-users routes for managing admin users (super admin only)
- Remove vendor role from user creation form (vendors created via company hierarchy)
- Add admin-users.html and admin-user-detail.html templates
- Add admin-users.js and admin-user-detail.js for frontend logic
- Move database operations to admin_platform_service (list, get, create, delete, toggle status)
- Update sidebar to show Admin Users section only for super admins
- Add isSuperAdmin computed property to init-alpine.js
- Fix /api/v1 prefix issues in JS files (apiClient already adds prefix)
- Update architecture rule JS-012 to catch more variable patterns (url, endpoint, path)
- Replace inline SVGs with $icon() helper in select-platform.html
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
User create page:
- When role=admin, show super admin toggle
- If not super admin, show platform multi-select
- Admin users created via /api/v1/admin/admin-users endpoint
- Vendor users created via existing /admin/users endpoint
Vendor create page:
- Add platform selection section
- Vendors can be assigned to multiple platforms on creation
- Update VendorCreate schema to accept platform_ids
- Update AdminService.create_vendor() to create VendorPlatform records
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Frontend implementation of platform admin flow:
- Update login.js to check for platform selection after login
- Add platform selection page (/admin/select-platform)
- Add platform context indicator in admin header
- Add is_super_admin to UserResponse schema
- Show "Super Admin" badge or platform name with switch option
Platform admins now:
1. Login normally at /admin/login
2. Get redirected to /admin/select-platform if they have multiple platforms
3. See current platform in header with option to switch
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add structured JSON sections to ContentPage for multi-language homepage editing:
Database:
- Add `sections` JSON column to content_pages table
- Migration z8i9j0k1l2m3 adds the column
Schema:
- New models/schema/homepage_sections.py with Pydantic schemas
- TranslatableText for language-keyed translations
- HeroSection, FeaturesSection, PricingSection, CTASection
Templates:
- New section partials in app/templates/platform/sections/
- Updated homepage-default.html to render sections dynamically
- Fallback to placeholder content when sections not configured
Service:
- update_homepage_sections() - validate and save all sections
- update_single_section() - update individual section
- get_default_sections() - empty structure for new homepages
API:
- GET /{page_id}/sections - get sections with platform languages
- PUT /{page_id}/sections - update all sections
- PUT /{page_id}/sections/{section_name} - update single section
Admin UI:
- Section editor appears when editing homepage (slug='home')
- Language tabs from platform.supported_languages
- Accordion sections for Hero, Features, Pricing, CTA
- Button/feature card repeaters with add/remove
Also fixes broken line 181 in z4e5f6a7b8c9 migration.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create platform_service.py to move DB queries from platforms.py API
- Create platform.py exceptions for PlatformNotFoundException
- Update platforms.py API to use platform_service
- Update vendor/content_pages.py to use vendor_service
- Add get_vendor_by_id_optional method to VendorService
- Fix platforms.js: add centralized logger and init guard
- Fix content-page-edit.html: use modal macro instead of inline modal
All 21 architecture validation errors resolved.
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>
Rename static/shared/js/vendor/ to static/shared/js/lib/ to avoid
confusion with the app's "vendor" (seller) dashboard code in
static/vendor/js/.
- Rename directory: vendor/ → lib/
- Update all template references to use new path
- Update CDN fallback documentation
- Fix .gitignore to use /lib/ (root only) instead of lib/ (everywhere)
Third-party libraries:
- alpine.min.js
- chart.umd.min.js
- flatpickr.min.js
- quill.js
- tom-select.complete.min.js
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix JS-008: Replace raw fetch() with apiClient in letzshop-vendor-directory.js
- Fix JS-005: Add init guard to letzshop-vendor-directory.js
- Fix JS-004: Increase search region in validator (800→2000 chars) to detect
currentPage in files with setup code before return statement
- Fix JS-001: Use centralized logger in media-picker.js
- Fix API-002: Move database query from onboarding.py to order_service.py
- Fix FE-001: Add noqa comment to search.html (shop uses custom themed pagination)
- Add audit validator to validate_all.py script
- Update frontend.yaml with vendor exclusion pattern
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add LetzshopVendorCache model to store cached vendor data from Letzshop API
- Create LetzshopVendorSyncService for syncing vendor directory
- Add Celery task for background vendor sync
- Create admin page at /admin/letzshop/vendor-directory with:
- Stats dashboard (total, claimed, unclaimed vendors)
- Searchable/filterable vendor list
- "Sync Now" button to trigger sync
- Ability to create platform vendors from Letzshop cache
- Add API endpoints for vendor directory management
- Add Pydantic schemas for API responses
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add admin media API endpoints for vendor media management
- Create reusable media_picker_modal macro in modals.html
- Create mediaPickerMixin Alpine.js helper for media selection
- Update product create/edit forms with media picker UI
- Support main image + additional images selection
- Add upload functionality within the picker modal
- Update vendor_product_service to handle additional_images
- Add additional_images field to Pydantic schemas
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added PATCH request method to the shared APIClient class. The method
was missing which caused "apiClient.patch is not a function" error
when saving product edits on the vendor-product-edit page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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>
Error and success messages were only shown at page top, not visible
when scrolled to Email tab. Now shows feedback directly below button.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Change icon from 'envelope' to 'mail' (envelope not in icons.js)
- Add default query param to GET /admin/settings/{key} endpoint
- Return AdminSettingDefaultResponse instead of 404 when default provided
- Update loadShippingSettings() to use default param for carrier settings
🤖 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>