Commit Graph

169 Commits

Author SHA1 Message Date
1169f1455f refactor(js): move components.js to dev_tools module
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>
2026-01-30 22:31:20 +01:00
33e8ec56b4 refactor(js): move icons-page.js to dev_tools module
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>
2026-01-30 22:30:08 +01:00
baf70d6eb1 fix(js): move platform user files back to static/admin/js
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>
2026-01-30 22:22:33 +01:00
0b4291d893 refactor(js): migrate JavaScript files to module directories
Move 47 JS files from static/{admin,vendor,shared}/js/ to their
respective module directories app/modules/*/static/*/js/:

- Orders: orders.js, order-detail.js
- Catalog: products.js (renamed from vendor-products.js), product-*.js
- Inventory: inventory.js (admin & vendor)
- Customers: customers.js, users.js, user-*.js
- Billing: billing-history.js, subscriptions.js, subscription-tiers.js,
  billing.js, invoices.js, feature-store.js, upgrade-prompts.js
- Messaging: messages.js, notifications.js, email-templates.js
- Marketplace: marketplace*.js, letzshop*.js, onboarding.js
- Monitoring: monitoring.js, background-tasks.js, imports.js, logs.js
- Dev Tools: testing-*.js, code-quality-*.js

Update 39 templates to reference new module static paths using
url_for('{module}_static', path='...') pattern.

Files staying in static/ (platform core):
- admin: dashboard, login, platforms, vendors, companies, admin-users,
  settings, components, init-alpine, module-config
- vendor: dashboard, login, profile, settings, team, media, init-alpine
- shared: api-client, utils, money, icons, log-config, vendor-selector,
  media-picker

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-30 22:08:20 +01:00
9a828999fe feat: add admin menu configuration and sidebar improvements
- 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>
2026-01-27 20:34:58 +01:00
33072057c2 feat: add module info and configuration pages to admin panel
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>
2026-01-26 22:55:12 +01:00
ec4ec045fc feat: complete CMS as fully autonomous self-contained module
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>
2026-01-26 22:42:46 +01:00
c419090531 feat: complete modular platform architecture (Phases 1-5)
Phase 1 - Vendor Router Integration:
- Wire up vendor module routers in app/api/v1/vendor/__init__.py
- Use lazy imports via __getattr__ to avoid circular dependencies

Phase 2 - Extract Remaining Modules:
- Create 6 new module directories: customers, cms, analytics, messaging,
  dev_tools, monitoring
- Each module has definition.py and route wrappers
- Update registry to import from extracted modules

Phase 3 - Database Table Migration:
- Add PlatformModule junction table for auditable module tracking
- Add migration zc2m3n4o5p6q7_add_platform_modules_table.py
- Add modules relationship to Platform model
- Update ModuleService with JSON-to-junction-table migration

Phase 4 - Module-Specific Configuration UI:
- Add /api/v1/admin/module-config/* endpoints
- Add module-config.html template and JS

Phase 5 - Integration Tests:
- Add tests/fixtures/module_fixtures.py
- Add tests/integration/api/v1/admin/test_modules.py
- Add tests/integration/api/v1/modules/test_module_access.py

Architecture fixes:
- Fix JS-003 errors: use ...data() directly in Alpine components
- Fix JS-005 warnings: add init() guards to prevent duplicate init
- Fix API-001 errors: add MenuActionResponse Pydantic model
- Add FE-008 noqa for dynamic number input in template

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 18:19:00 +01:00
7ecd554454 feat: add Admin UI for platform module management (Phase 5)
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>
2026-01-25 22:08:13 +01:00
f7ca6c0747 refactor: align copy code pattern with rest of components page
Use inline template literals with {% raw %}{% endraw %} and HTML entities
(&quot;) 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>
2026-01-24 21:53:15 +01:00
2bac4dfc90 fix: restore copy functionality for confirm modal code snippets
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>
2026-01-24 21:51:49 +01:00
3cd4781724 fix: replace problematic code copy buttons with static pre blocks
Multi-line template literals in HTML attributes cause Alpine.js parsing
errors. Replaced @click="copyCode(...)" with static <pre><code> blocks.
Also simplified the x-text expression to use template literals.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 21:48:46 +01:00
265395b71a fix: escape Jinja2 syntax in components page code snippets
Added {% raw %}{% endraw %} tags around the confirm_modal code snippets
to prevent Jinja2 from interpreting the {{ }} as template tags.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 21:45:51 +01:00
9e79a9fd81 docs: add confirm_modal_dynamic documentation to components page
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>
2026-01-24 21:43:13 +01:00
aa6f22e1b3 feat: add confirm_modal_dynamic macro for dynamic confirmation messages
Added a new macro that accepts an Alpine.js expression for the message,
allowing runtime data to be included in confirmation dialogs. Updated
admin-user-edit.html to use this macro for platform removal confirmation.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 21:40:26 +01:00
fe94ec8581 fix: show platform name in removal confirmation modal
Changed from static confirm_modal macro to custom modal with Alpine.js
binding to display the platform name dynamically in the confirmation
message.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 21:39:11 +01:00
a0e6833a75 fix: use confirm_modal macro instead of browser confirm for platform removal
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>
2026-01-24 21:36:31 +01:00
011744966b feat: add dedicated admin user edit page with platform management
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>
2026-01-24 21:32:28 +01:00
7e68b93132 feat: implement admin-users management with super admin restriction
- 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>
2026-01-24 21:28:46 +01:00
3cbe7e2979 feat: add platform assignment to user and vendor creation forms
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>
2026-01-24 19:49:40 +01:00
300f49c5a1 feat: add platform selection frontend for platform admins
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>
2026-01-24 18:54:59 +01:00
7e39bb0564 fix: resolve homepage sections editor and rendering issues
- Fix sections editor not showing by converting isHomepage getter to property
- Add Alpine Collapse plugin for accordion animations
- Fix Quill editor content not syncing after page load
- Add platform dropdown to content page edit form
- Create shared templates config (app/templates_config.py) with i18n globals
  to make _() translation function available in Jinja2 macros
- Fix pricing template field names (monthly_price → price_monthly)
- Fix translation key (pricing.save_20 → pricing.save_months)
- Add tiers context to CMS homepage route for pricing section
- Fix architecture validation issues (language defaults, inline SVGs → $icon)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 20:03:13 +01:00
dca52d004e feat: implement section-based homepage management system
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>
2026-01-23 14:31:23 +01:00
3d3b8cae22 feat: add platform detail/edit admin UI and service enhancements
- Add platform detail and edit admin pages with templates and JS
- Add ContentPageService methods: list_all_platform_pages, list_all_vendor_defaults
- Deprecate /admin/platform-homepage route (redirects to /admin/platforms)
- Add migration to fix content_page nullable columns
- Refine platform and vendor context middleware
- Add platform context middleware unit tests
- Update platforms.js with improved functionality
- Add section-based homepage plan documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-23 14:08:02 +01:00
968002630e feat: complete multi-platform CMS phases 2-5
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>
2026-01-19 16:30:31 +01:00
013d8e3d10 feat: integrate Quill rich text editor in admin templates
- Add Quill editor to content-page-edit.html
- Add Quill editor to vendor-product-edit.html
- Add Quill snow theme CSS
- Update background-tasks.html and platform-homepage.html templates

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 20:37:54 +01:00
7a7b612519 refactor: rename third-party JS libs folder from vendor to lib
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>
2026-01-13 20:36:53 +01:00
ccfbbcb804 feat: add Letzshop vendor directory with sync and admin management
- 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>
2026-01-13 20:35:46 +01:00
2792414395 feat: add Celery/Redis task queue with feature flag support
Migrate background tasks from FastAPI BackgroundTasks to Celery with Redis
for persistent task queuing, retries, and scheduled jobs.

Key changes:
- Add Celery configuration with Redis broker/backend
- Create task dispatcher with USE_CELERY feature flag for gradual rollout
- Add Celery task wrappers for all background operations:
  - Marketplace imports
  - Letzshop historical imports
  - Product exports
  - Code quality scans
  - Test runs
  - Subscription scheduled tasks (via Celery Beat)
- Add celery_task_id column to job tables for Flower integration
- Add Flower dashboard link to admin background tasks page
- Update docker-compose.yml with worker, beat, and flower services
- Add Makefile targets: celery-worker, celery-beat, celery-dev, flower

When USE_CELERY=false (default), system falls back to FastAPI BackgroundTasks
for development without Redis dependency.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 17:35:16 +01:00
f3b4df5825 fix: change image URL input type to text for relative paths
The media library returns relative paths like /uploads/... which
don't pass HTML5 url validation. Changed to type="text" to accept
both full URLs and relative paths from the media library.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 02:39:52 +01:00
5271ecb378 feat: add media library picker for product images
- 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>
2026-01-08 02:16:55 +01:00
8f284e5aaa refactor: remove outdated "Override" badges from product detail page
The override concept is no longer relevant with the independent copy
architecture. Products are fully independent entities, not inherited
from marketplace products. Removed all Override badges and updated
the info banner text to reflect the new architecture.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 01:28:34 +01:00
fa2a3bf89a feat: make Product fully independent from MarketplaceProduct
- 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>
2026-01-08 01:11:00 +01:00
4c2f7f1121 fix: add 10-second timeout to all SMTP connections
SMTP connections with no timeout were causing indefinite hangs when
connecting to invalid hosts. Also improved error display template.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 23:11:24 +01:00
ed4ea72f35 fix: add local error/success display for test email button
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>
2026-01-05 22:59:49 +01:00
e1c0c117c2 fix: resolve settings page icon and 404 errors
- 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>
2026-01-05 22:46:27 +01:00
36603178c3 feat: add email settings with database overrides for admin and vendor
Platform Email Settings (Admin):
- Add GET/PUT/DELETE /admin/settings/email/* endpoints
- Settings stored in admin_settings table override .env values
- Support all providers: SMTP, SendGrid, Mailgun, Amazon SES
- Edit mode UI with provider-specific configuration forms
- Reset to .env defaults functionality
- Test email to verify configuration

Vendor Email Settings:
- Add VendorEmailSettings model with one-to-one vendor relationship
- Migration: v0a1b2c3d4e5_add_vendor_email_settings.py
- Service: vendor_email_settings_service.py with tier validation
- API endpoints: /vendor/email-settings/* (CRUD, status, verify)
- Email tab in vendor settings page with full configuration
- Warning banner until email is configured (like billing warnings)
- Premium providers (SendGrid, Mailgun, SES) tier-gated to Business+

Email Service Updates:
- get_platform_email_config(db) checks DB first, then .env
- Configurable provider classes accept config dict
- EmailService uses database-aware providers
- Vendor emails use vendor's own SMTP (Wizamart doesn't pay)
- "Powered by Wizamart" footer for Essential/Professional tiers
- White-label (no footer) for Business/Enterprise tiers

Other:
- Add scripts/install.py for first-time platform setup
- Add make install target
- Update init-prod to include email template seeding

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 22:23:47 +01:00
5155ef7445 fix: resolve all architecture validation errors (62 -> 0)
Major refactoring to achieve zero architecture violations:

API Layer:
- vendor/settings.py: Move validation to Pydantic field validators
  (tax rate, delivery method, boost sort, preorder days, languages, locales)
- admin/email_templates.py: Add Pydantic response models
  (TemplateListResponse, CategoriesResponse)
- shop/auth.py: Move password reset logic to CustomerService

Service Layer:
- customer_service.py: Add password reset methods
  (get_customer_for_password_reset, validate_and_reset_password)

Exception Layer:
- customer.py: Add InvalidPasswordResetTokenException,
  PasswordTooShortException

Frontend:
- admin/email-templates.js: Use apiClient, Utils.showToast()
- vendor/email-templates.js: Use apiClient, parent init pattern

Templates:
- admin/email-templates.html: Fix block name to extra_scripts
- shop/base.html: Add language default filter

Tooling:
- validate_architecture.py: Fix LANG-001 false positive for
  SUPPORTED_LANGUAGES and SUPPORTED_LOCALES blocks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-03 18:48:59 +01:00
c52af2a155 feat: implement email template system with vendor overrides
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>
2026-01-03 18:29:26 +01:00
d803e1c911 feat: add feature assignment to admin tier management UI
- Add slide-over panel for assigning features to subscription tiers
- Features grouped by category with select all/deselect all
- Add puzzle-piece icon button in tier table actions
- Add feature management methods to subscription-tiers.js
- Fix JS-006 by adding try/catch to init function

Documentation:
- Update feature-gating-system.md with Admin Tier Management UI section
- Update subscription-billing.md with tier management overview
- Add new admin user guide: subscription-tier-management.md
- Add guide to mkdocs.yml navigation

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-01 12:58:09 +01:00
71c66aa237 fix: don't clear last visited page on logout
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>
2026-01-01 00:12:41 +01:00
673748ed27 feat: remember last visited page after login
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>
2025-12-31 23:41:43 +01:00
7adf19c04c fix: components page copyCode Alpine error and add TPL-012 rule
- Fixed copyCode template literal by using single quotes for outer attribute
- Added TPL-012 architecture rule to detect double quotes inside multi-line
  copyCode template literals that break HTML attribute parsing
- Pattern: @click="copyCode(`...`)" with inner double quotes breaks parsing
- Solution: Use @click='copyCode(`...`)' with single quotes for outer attribute

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 23:15:07 +01:00
03209eb691 fix: escape quotes in components.html copyCode template literal
Changed escaped double quotes to single quotes inside Jinja template
strings to prevent Alpine.js parsing error "Unexpected end of input".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 23:05:16 +01:00
9423ff350d fix: remove duplicate vendor-selector.js include from vendor-themes
The script was being loaded twice - once from base.html and again from
vendor-themes.html, causing "vendorSelectorLog has already been declared".

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 23:00:59 +01:00
6e6971fd32 fix: add TPL-011 rule for deprecated macros, fix billing-history pagination
- Add TPL-011 architecture rule to detect deprecated macros
- Add pagination_full to deprecated macros list (expects flat vars)
- Fix billing-history.html to use standard pagination macro
- Add deprecation notice to pagination_full macro in pagination.html

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 22:57:07 +01:00
ace931aaf8 fix: add chevron-double icons and fix subscriptions pagination
- Add chevron-double-left and chevron-double-right icons to icons.js
- Switch subscriptions page from pagination_full to pagination macro
  (pagination_full expects flat variables but component uses nested pagination object)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 22:49:56 +01:00
3d739c0ccc fix: remove escaped quotes in x-text expression causing Alpine error
The x-text expression had escaped quotes (\") which broke Alpine.js
parsing: 'Click \"Import Orders\" to fetch...'

Removed the quotes around "Import Orders" to fix the syntax error.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 22:44:36 +01:00
94677f946b fix: resolve architecture validation warnings
- Replace window.apiClient with apiClient in feature-store.js (JS-002)
- Replace window.apiClient with apiClient in upgrade-prompts.js (JS-002)
- Replace inline SVGs with $icon() helper in features.html (FE-002)
- Add check-circle-filled icon to icons.js

Architecture validation now passes with 0 errors, 0 warnings.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 18:59:41 +01:00
7d1a421826 feat: add comprehensive tier-based feature management system
Implement database-driven feature gating with contextual upgrade prompts:

- Add Feature model with 30 features across 8 categories
- Create FeatureService with caching for tier-based feature checking
- Add @require_feature decorator and RequireFeature dependency for backend enforcement
- Create vendor features API (6 endpoints) and admin features API
- Add Alpine.js feature store and upgrade prompts store for frontend
- Create Jinja macros: feature_gate, feature_locked, limit_warning, usage_bar
- Add usage API for tracking orders/products/team limits with upgrade info
- Fix Stripe webhook to create VendorAddOn records on addon purchase
- Integrate upgrade prompts into vendor dashboard with tier badge and usage bars

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 18:28:40 +01:00