- Add red asterisk (*) to all mandatory fields in Step 3
- Add "Required fields" legend at top of form
- Fields marked: First Name, Last Name, Company Name, Email, Password
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add same section headers and organization
- Add admin initialization settings
- Add platform limits section
- Add seed data configuration section
- Add Stripe billing with docs reference
- Update project name and version
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add step-by-step setup guide covering:
- Getting API keys from Stripe Dashboard
- Creating webhook endpoint and getting signing secret
- Local development with Stripe CLI
- Creating products and prices
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add shared/macros to Tailwind source scan for platform CSS
- Revert toggle macro to use Tailwind classes (translate-x-*)
- Rebuild CSS to include all required classes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use inline transform styles instead of Tailwind classes to ensure
the toggle thumb animates properly regardless of compiled CSS.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add reusable toggle_switch macro to inputs.html with size/color options
- Replace inline billing toggle with macro on homepage
- Add € currency signs to addon prices
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add fallback for tiers without annual pricing (like Enterprise) and
add € currency symbol to prices.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The platform homepage and content page routes in main.py were missing
i18n globals (_(), t(), current_language, etc.) which caused template
rendering errors when using translation functions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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 warehouse and bin_location fields to test fixtures
- Update InventoryService to include warehouse/bin_location when creating entries
- Fix all Inventory model instantiations in tests to include required fields
- All 119 inventory tests now pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove dependency on shared language_selector macro
- Add platformLanguageSelector() Alpine.js component
- Include flag-icons CSS CDN for language flags
- Fix 'languageSelector is not defined' error
🤖 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>
- Create platform_signup_service.py for signup flow operations
- Create platform_pricing_service.py for pricing data operations
- Refactor signup.py, pricing.py, letzshop_vendors.py to use services
- Add # public markers to all platform endpoints
- Update tests for correct mock paths and status codes
Fixes architecture validation errors (API-002, API-003, SVC-006).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive test coverage for platform marketing homepage API:
- test_pricing.py: 17 tests for tiers, add-ons, pricing endpoints
- test_letzshop_vendors.py: 22 tests for vendor lookup and claiming
- test_signup.py: 28 tests for multi-step signup flow
Fix signup.py to use correct password hashing from middleware/auth.py
and properly create Company with owner_user_id.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement complete marketing homepage for Wizamart targeting Letzshop
vendors in Luxembourg. Includes:
- Marketing homepage with hero, pricing tiers, and add-ons
- 4-step signup wizard with Stripe card collection (30-day trial)
- Letzshop vendor lookup for shop claiming
- Platform API endpoints for pricing, vendors, and signup
- Stripe SetupIntent integration for trial with card upfront
- Database fields for Letzshop vendor identity tracking
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Reorganize mkdocs navigation from 14 top-level items to 4:
1. Home
2. Getting Started - Installation, quickstart, configuration
3. Documentation - All technical docs (Architecture, API, Backend,
Frontend, Development, Migrations, Implementation, Testing,
Deployment, Operations, Troubleshooting)
4. Business - Features, User Guides, Marketing
This provides a cleaner navigation experience with logical grouping
while keeping all content accessible through submenus.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add orphaned implementation/subscription-workflow-plan.md to the
Implementation Plans section of mkdocs.yml navigation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move direct database queries in subscriptions.py to admin_subscription_service:
- Add get_vendor() method to verify vendor exists
- Add get_vendor_usage_counts() method for products/team counts
- Update API endpoints to use service methods
- Remove unused imports (func, Product, VendorUser)
Fixes architecture validation errors [API-002]
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Expand subscription-billing.md with complete system documentation
- Add background tasks section with scheduling examples
- Add capacity forecasting with API examples
- Document all new API endpoints (trends, recommendations, snapshot)
- Add CapacitySnapshot model documentation
- Include infrastructure scaling reference table
- Update capacity-monitoring.md with forecasting features
- Add subscription capacity tracking section
- Document growth trends API with example responses
- Add scaling recommendations with severity levels
- Include usage examples for capacity planning
- Add historical data and export options
🤖 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>
- Add get_tier_by_code and get_tier_id helper methods
- Update get_or_create_subscription to set tier_id
- Update create_subscription to set tier_id
- Update update_subscription to sync tier_id when tier changes
- Update upgrade_tier to set tier_id
All subscription CRUD operations now maintain the tier_id FK relationship
in sync with the tier code string.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tier_id column with FK to subscription_tiers table
- Add tier_obj relationship to VendorSubscription model
- Update tier_limits property to use database tier when available
- Create migration with SQLite batch mode support
- Backfill tier_id from existing tier code values
This enables proper database relationship between vendors and their
subscription tier, instead of just storing the tier code string.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
FastAPI was matching /stats as a vendor_id (expecting int), causing 422 error.
Move /stats and /billing/history endpoints BEFORE /{vendor_id} so they take precedence.
Route order now:
1. /tiers/* - tier management
2. / - list subscriptions
3. /stats - statistics (before /{vendor_id})
4. /billing/history - billing history (before /{vendor_id})
5. /{vendor_id} - vendor detail endpoints (catch-all for ints)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Update th_sortable macro to call handleSort(key) instead of inline logic
- Add handleSort method to subscriptions.js, subscription-tiers.js, billing-history.js
- Add sort_by and sort_order params to API calls in all three files
- Reset to page 1 when sort changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The subscription templates were importing th_sortable but the macro
didn't exist. Added the macro to tables.html with:
- Clickable header with sort indicator arrows
- Alpine.js integration for sorting state
- Visual feedback for current sort column and direction
Also removed unused empty_state import from subscription-tiers.html.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The table_header() macro doesn't support caller() - it takes a columns list.
Using {% call table_header() %} caused a Jinja2 error:
"macro 'table_header' was invoked with two values for the special caller argument"
Changes:
- Add table_header_custom() macro that supports caller() for custom headers
- Update subscriptions.html, subscription-tiers.html, billing-history.html
- Add TPL-008 architecture rule to detect this pattern
- Renumber TPL-009 (block names) and TPL-010 (Alpine vars)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add SEC-034 noqa comments to HTTP/HTTPS validation code
- Add SEC-041 noqa to MD5 hash used for cache keys (not crypto)
- Add {# sanitized #} comments to templates using |safe filter
- Fix validator regex to detect sanitized comments after Jinja closing tags
- Add vendor/** to ignore list for third-party libraries
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Use get_current_admin_api instead of non-existent get_current_admin
- Use get_db from app.core.database
- Replace generic NotFoundException with specific exceptions:
- TierNotFoundException for tier lookup failures
- ConflictException for duplicate tier codes
- BusinessLogicException for tier deletion with active subscriptions
- ResourceNotFoundException for subscription lookup failures
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create app/handlers/ directory for event handlers
- Move stripe_webhook_handler.py to app/handlers/stripe_webhook.py
- Update imports in webhooks.py, tests, and docs
- Handlers are distinct from services (event-driven vs request-driven)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add noqa: NAM-002 check in validate_architecture.py
- Mark stripe_webhook_handler.py with noqa (it's a handler, not a service)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move db.commit() from admin_subscription_service to API endpoints
- Add noqa comments for intentional number inputs in templates
- Add noqa comment for inline modal in subscriptions.html
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace page_header with page_header_flex to properly support
the call block pattern with refresh button.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add translations support with language tabs (EN, FR, DE, LU)
- Add product identifiers: vendor SKU with auto-generate, brand, GTIN, GTIN type
- Add pricing fields: price (incl. VAT), sale price, currency, VAT rate
- Add primary image field with preview
- Add product status (active, featured) checkboxes
- Add optional supplier info section
- Pre-populate form with existing product data from API
- Add form validation (isFormValid method)
- Make is_digital read-only (derived from marketplace product)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add warehouse and bin_location columns to Inventory model
- Create inventory_import_service for bulk TSV/CSV import
- Add POST /api/v1/admin/inventory/import endpoint
- Add Import button and modal to inventory admin page
- Support both single-unit rows and explicit QUANTITY column
File format: BIN, EAN, PRODUCT (optional), QUANTITY (optional)
Products matched by GTIN/EAN, unmatched items reported.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add "Create Product" button in header
- Update actions column to View, Edit, Delete
- Add create/edit pages with forms and vendor selector
- Add POST/PATCH API endpoints for vendor products
- Add create_product and update_product service methods
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Consolidate all tab-specific pagination into a unified pagination object
and use the shared pagination macro for consistent look and feel across
Orders, Products, Jobs, and Exceptions tabs.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Load rows per page from PlatformSettings in init()
- Apply setting to ordersLimit, exceptionsLimit, productsLimit, jobsPagination
- Replace alert() with Utils.showToast() for error display
- Improve viewJobErrors to show errors in modal instead of alert
- Update architecture validator to catch non-standard pagination patterns
(jobsPagination, ordersLimit, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add /admin/letzshop/jobs API endpoint for all jobs across vendors
- Update list_letzshop_jobs service to support optional vendor_id
- Remove x-if condition from Jobs tab button and panel
- Update JS to use global or vendor-specific endpoint based on selection
- Update jobs table subtitle to show context
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Pass back_url from routes to template
- Letzshop products go back to /admin/marketplace/letzshop
- Marketplace products go back to /admin/marketplace-products
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add new route that mirrors the letzshop orders pattern
- Update product links in letzshop-products-tab.html to use new route
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Remove x-if="selectedVendor" condition from Products tab button and panel
so products are visible when no vendor is selected.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add 'ban' icon to icons.js for empty state displays
- Fix products tab to load when no vendor filter is selected
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>