- 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>
Phase 1 OMS implementation:
Invoicing:
- Add Invoice and VendorInvoiceSettings database models
- Full EU VAT support (27 countries, OSS, B2B reverse charge)
- Invoice PDF generation with WeasyPrint + Jinja2 templates
- Vendor invoice API endpoints for settings, creation, PDF download
Subscription Tiers:
- Add VendorSubscription model with 4 tiers (Essential/Professional/Business/Enterprise)
- Tier limit enforcement for orders, products, team members
- Feature gating based on subscription tier
- Automatic trial subscription creation for new vendors
- Integrate limit checks into order creation (direct and Letzshop sync)
Marketing:
- Update pricing documentation with 4-tier structure
- Revise back-office positioning strategy
- Update homepage with Veeqo-inspired Letzshop-focused messaging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add job cancellation and retry functionality
- Improve jobs table with better status display
- Add background task improvements
- Update Letzshop order service
- Update documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace browser alert with proper modal for job details view
- Show job info, status, records, timestamps in modal
- Display export file details (languages, file sizes) for export jobs
- Include error_details in API response for export and order_sync jobs
- Add selectedJobDetails state and showJobDetailsModal flag
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Export operations now create LetzshopSyncLog entries with type 'product_export'
- Added log_export method to LetzshopExportService (follows architecture rules)
- Updated list_letzshop_jobs to include export jobs
- Added export filter option back to jobs dropdown
- Export jobs display with blue badge and cloud-upload icon
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Money Handling Architecture:
- Store all monetary values as integer cents (€105.91 = 10591)
- Add app/utils/money.py with Money class and conversion helpers
- Add static/shared/js/money.js for frontend formatting
- Update all database models to use _cents columns (Product, Order, etc.)
- Update CSV processor to convert prices to cents on import
- Add Alembic migration for Float to Integer conversion
- Create .architecture-rules/money.yaml with 7 validation rules
- Add docs/architecture/money-handling.md documentation
Order Details Page Fixes:
- Fix customer name showing 'undefined undefined' - use flat field names
- Fix vendor info empty - add vendor_name/vendor_code to OrderDetailResponse
- Fix shipping address using wrong nested object structure
- Enrich order detail API response with vendor info
Vendor Filter Persistence Fixes:
- Fix orders.js: restoreSavedVendor now sets selectedVendor and filters
- Fix orders.js: init() only loads orders if no saved vendor to restore
- Fix marketplace-letzshop.js: restoreSavedVendor calls selectVendor()
- Fix marketplace-letzshop.js: clearVendorSelection clears TomSelect dropdown
- Align vendor selector placeholder text between pages
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Orders were being flushed but only committed every 10 orders via the
progress callback. With slow imports (~1.5 min/order), no commits
happened before the first 10 orders, causing data loss if the import
failed or was interrupted.
Changes:
- Add db.commit() after each successful order creation
- Add db.rollback() on order creation failure to prevent corrupt state
- Add db.commit() after order updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Historical import jobs were not appearing in the recent jobs list because
list_letzshop_jobs() only queried marketplace_import_jobs and letzshop_sync_logs.
Changes:
- Add LetzshopHistoricalImportJob query to list_letzshop_jobs()
- Add current_phase and error_message fields to LetzshopJobItem schema
- Fixed stuck job 8 (marked as failed)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When create_letzshop_order raises an exception (e.g., product not found by GTIN)
after flushing the order to the database, the session is left in an inconsistent
state. Without rollback, subsequent database operations fail or hang, causing
the import to get stuck at "0 processed...".
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update API endpoints and schemas to use the unified Order model:
- Update Letzshop order schemas with OrderItem support
- Update API responses to use new field names (external_*, status, etc.)
- Update confirm/reject endpoints to use OrderItem.external_item_id
- Update Letzshop order service for unified Order model queries
- Update documentation to reflect completed implementation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add historical order import functionality
- Add order detail page route
- Update API endpoints for order confirmation flow
Note: These files need further updates to use the new unified order model.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Per Letzshop API, each inventory unit must be confirmed/declined individually.
This enables partial confirmation (some items confirmed, others declined).
Admin API endpoints:
- POST /vendors/{id}/orders/{id}/confirm - confirm all items
- POST /vendors/{id}/orders/{id}/reject - decline all items
- POST /vendors/{id}/orders/{id}/items/{id}/confirm - confirm single item
- POST /vendors/{id}/orders/{id}/items/{id}/decline - decline single item
Order detail modal now shows:
- Product name, EAN, SKU, MPN, price per item
- Per-item state badge (unconfirmed/confirmed/declined)
- Per-item confirm/decline buttons for pending items
- Bulk confirm/decline all buttons
Order status logic:
- If all items declined -> order is "declined"
- If any item confirmed -> order is "confirmed"
- Partial confirmation supported
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix historical import to also update sync_status when it's out of
sync with letzshop_state (e.g., confirmed orders showing as pending)
- Fix frontend to read stats from response.statistics nested object
- Orders with matching letzshop_state but wrong sync_status now get fixed
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add historical order import with pagination support
- Add customer_locale, shipping_country_iso, billing_country_iso columns
- Add gtin/gtin_type columns to Product table for EAN matching
- Fix order stats to count all orders server-side (not just visible page)
- Add GraphQL introspection script with tracking workaround tests
- Enrich inventory units with EAN, MPN, SKU, product name
- Add LetzshopOrderStats schema for proper status counts
Migrations:
- a9a86cef6cca: Add locale and country fields to letzshop_orders
- cb88bc9b5f86: Add gtin columns to products table
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add new Marketplace section in admin sidebar with Letzshop sub-item
- Remove old Import and Letzshop Orders items from Product Catalog
- Create unified Letzshop management page with 3 tabs:
- Products tab: Import/Export functionality
- Orders tab: Order management with confirm/reject/tracking
- Settings tab: API credentials and CSV URLs
- Add unified jobs table showing imports, exports, and order syncs
- Implement vendor autocomplete using Tom Select library (CDN + fallback)
- Add /vendors/{vendor_id}/jobs API endpoint for unified job listing
- Move database queries to service layer (LetzshopOrderService)
- Add LetzshopJobItem and LetzshopJobsListResponse schemas
- Include Tom Select CSS/JS assets as local fallback
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove |safe from |tojson in HTML attributes (x-data) - quotes must
become " for browsers to parse correctly
- Update LANG-002 and LANG-003 architecture rules to document correct
|tojson usage patterns:
- HTML attributes: |tojson (no |safe)
- Script blocks: |tojson|safe
- Fix validator to warn when |tojson|safe is used in x-data (breaks
HTML attribute parsing)
- Improve code quality across services, APIs, and tests
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Service layer:
- Remove db.commit() calls from credentials_service.py (SVC-006)
- Move transaction control to API endpoint level
- Rename client.py -> client_service.py (NAM-002)
- Rename credentials.py -> credentials_service.py (NAM-002)
JavaScript:
- Use centralized logger in admin letzshop.js (JS-001)
- Replace console.log/error with LogConfig logger
Frontend templates:
- Use page_header_flex macro for page header (FE-007)
- Use error_state macro for error display (FE-003)
- Use table_wrapper macro for vendors table (FE-005)
- Use modal macro for configuration and orders modals (FE-004)
All 31 Letzshop tests pass. Architecture validation: 0 errors, 0 warnings.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>