Change register_user() to use db.flush() instead of db.commit()
and remove db.rollback() to follow the established architecture:
- Services use flush() for database operations
- Endpoints handle transaction commit
- Exception handlers manage rollback
This resolves SVC-006 architecture violation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add missing features identified in TailAdmin gap analysis:
cards.html:
- stat_card_with_trend: Stats card with up/down trend indicator and percentage
- card_with_menu: Card with dropdown menu in header
- card_with_menu_simple: Simplified version with menu_items parameter
tables.html:
- sortable_table_header: Table header with sortable columns, sort indicators,
and Alpine.js integration for sort state management
forms.html:
- searchable_select: Dropdown with search/filter functionality
- multi_select: Multi-select dropdown with tag display
This completes feature parity with TailAdmin free template.
The tailadmin-free-tailwind-dashboard-template folder can now be deleted.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update admin components page with documentation for:
- New Macros section listing all available shared macros with imports
- Pagination section with live interactive examples
- Copy-to-clipboard functionality for code snippets
- Dark mode support for all new sections
This serves as a living style guide for developers implementing
new admin pages using the shared component library.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update pagination in code-quality-violations to match companies/vendors:
- Add numbered page buttons with ellipsis for large page counts
- Add startIndex and endIndex computed properties
- Add goToPage(pageNum) method for direct page navigation
- Use consistent grid layout (col-span-3, col-span-9)
This standardizes pagination UI across all admin tables.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add rules to enforce consistent frontend component usage:
- FE-001 (warning): Use pagination macro instead of inline HTML
- FE-002 (warning): Use $icon() helper instead of inline SVGs
- FE-003 (info): Use table macros for consistent styling
- FE-004 (info): Use form macros for consistent styling
Update validate_architecture.py to check FE-001 and FE-002
anti-patterns in templates, with exceptions for macro definitions
and the components showcase page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Services now use db.flush() instead of db.commit() for database operations
- API endpoints handle transaction commit after service calls
- Remove db.rollback() from services (let exception handlers manage this)
- Ensures consistent transaction boundaries at API layer
This pattern gives API endpoints full control over when to commit,
allowing for better error handling and potential multi-operation transactions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move database queries to service layer and use proper Pydantic responses:
Schema changes (models/schema/marketplace_import_job.py):
- Add AdminMarketplaceImportJobResponse with extra fields (id, error_details,
created_by_name)
- Add AdminMarketplaceImportJobListResponse with items/total/page/limit format
Service changes (app/services/marketplace_import_job_service.py):
- Add convert_to_admin_response_model() for admin-specific response
- Add get_all_import_jobs_paginated() for admin listing
- Add get_import_job_by_id_admin() without access control
API changes (app/api/v1/admin/marketplace.py):
- Use service methods instead of direct DB queries
- Use proper Pydantic response models instead of dicts
- All business logic now in service layer
Cleanup:
- Remove duplicate methods from admin_service.py
Architecture validation now passes with 0 violations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Improvements:
- Extract _job_to_dict() helper to eliminate code duplication
- Move all imports to top of file (removed local imports)
- Remove unused vendor_name query parameter
- Use service layer consistently (convert_to_response_model for POST)
- Cleaner, more readable code structure
The endpoint now follows better practices while maintaining
the same functionality and frontend compatibility.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Changes to match the working vendor marketplace import:
1. Make POST endpoint async (was sync)
2. Use positional args for background task (was keyword args)
3. Import process_marketplace_import at top of file (was inside function)
4. Fix route order: /stats now defined BEFORE /{job_id}
to avoid FastAPI route conflicts
5. Remove unused admin_service import
These changes align the admin endpoint with the vendor endpoint
pattern that was already working correctly.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Issues fixed:
1. GET endpoint now returns {items, total, page, limit} format
instead of plain list (frontend expects this format)
2. Add GET /{job_id} endpoint for viewing single job details
3. Add 'id' field alongside 'job_id' for frontend compatibility
4. Add 'error_details' and 'created_by_name' fields to response
5. Trigger background processing when creating import job
(jobs were created but never processed)
The import jobs will now actually process the CSV files and
import products into the database.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add POST /api/v1/admin/marketplace-import-jobs endpoint to allow
admins to create import jobs for any vendor.
Changes:
- Add AdminMarketplaceImportJobRequest schema with vendor_id field
- Add create_marketplace_import_job endpoint in admin/marketplace.py
- Make vendor_code and vendor_name optional in response model
to handle edge cases where vendor relationship may not be loaded
This fixes the 405 Method Not Allowed error when trying to import
products from the admin marketplace page.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add comprehensive section on SQLAlchemy fixture best practices:
- Explain why db.expunge() is an anti-pattern in test fixtures
- Document how test isolation works via the db fixture
- Provide examples of correct vs incorrect fixture patterns
- Show how to use db.refresh() for fresh data instead of expunge
This documents the lessons learned from the fixture refactoring
and helps prevent future issues with DetachedInstanceError.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updates to work with refactored fixtures (no expunge):
- Re-query entities when modifying state in tests
- Remove assertions on expunged object properties
Auth service tests:
- Update to use email_or_username field instead of username
Admin service tests:
- Fix statistics test to use stats_service module
- Remove vendor_name filter test (field removed)
- Update import job assertions
Inventory/Marketplace/Stats/Vendor service tests:
- Refactor to work with attached session objects
- Update assertions for changed response formats
- Improve test isolation and cleanup
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Split the monolithic test_database_models.py into focused test modules:
Database model tests (tests/unit/models/database/):
- test_customer.py: Customer model and authentication tests
- test_inventory.py: Inventory model tests
- test_marketplace_import_job.py: Import job model tests
- test_marketplace_product.py: Marketplace product model tests
- test_order.py: Order and OrderItem model tests
- test_product.py: Product model tests
- test_team.py: Team invitation and membership tests
- test_user.py: User model tests
- test_vendor.py: Vendor model tests
Schema validation tests (tests/unit/models/schema/):
- test_auth.py: Auth schema validation tests
- test_customer.py: Customer schema validation tests
- test_inventory.py: Inventory schema validation tests
- test_marketplace_import_job.py: Import job schema tests
- test_order.py: Order schema validation tests
- test_product.py: Product schema validation tests
This improves test organization and makes it easier to find
and maintain tests for specific models.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Remove db.expunge() calls that were causing DetachedInstanceError
when accessing lazy-loaded relationships in tests.
Changes:
- conftest.py: Add documentation about fixture best practices
- auth_fixtures: Remove expunge, keep objects attached to session
- customer_fixtures: Remove expunge, add proper relationship loading
- vendor_fixtures: Remove expunge, add test_company and other_company
fixtures for proper company-vendor relationship setup
- marketplace_import_job_fixtures: Remove expunge calls
- marketplace_product_fixtures: Remove expunge calls
The db fixture already provides test isolation by dropping/recreating
tables after each test, so expunge is unnecessary and harmful.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Services:
- admin_service: Add source_url to import job response, fix vendor_name
to use vendor.name relationship instead of vendor_name field
- marketplace_product_service: Include reserved_quantity and
available_quantity in InventoryLocationResponse
- vendor_service: Fix _get_product_by_id_or_raise to use database ID
(int) instead of marketplace_product_id (str)
Schema:
- Add InventorySummaryResponse model for marketplace product service
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Update architecture rules to be stricter (API-003 now blocks ALL exception
raising in endpoints, not just HTTPException)
- Update get_current_vendor_api dependency to guarantee token_vendor_id presence
- Remove redundant _get_vendor_from_token helpers from all vendor API files
- Move vendor access validation to service layer methods
- Add Pydantic response models for media, notification, and payment endpoints
- Add get_active_vendor_by_code service method for public vendor lookup
- Add get_import_job_for_vendor service method with vendor validation
- Update validation script to detect exception raising patterns in endpoints
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Sidebar sections can now be collapsed/expanded by clicking the header.
State is persisted to localStorage so sections remain open/closed
across page navigation and browser sessions.
Changes:
- init-alpine.js: Added openSections state, toggleSection(),
expandSectionForCurrentPage(), and localStorage helpers
- sidebar.html: Refactored with Jinja2 macros for DRY code,
added collapsible sections with CSS transitions and rotating
chevron icons
Features:
- Click section header to toggle expand/collapse
- Chevron rotates 180 degrees when expanded
- Smooth CSS transitions (no extra Alpine plugins needed)
- State persists in localStorage (admin_sidebar_sections key)
- Default: Platform Administration open, others closed
- Dashboard and Settings always visible (not collapsible)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Updated documentation to reflect new sidebar structure:
- Added Platform Administration section
- Added Customers page to navigation
- Updated page mapping table with all current pages
- Updated sidebar organization in page-templates.md
- Added customers logger to pre-configured loggers list
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Contact fields now look consistent with other fields (like Letzshop URLs).
The "(from company)" label still indicates inheritance status.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added company_business_address and company_tax_number to:
- VendorDetailResponse schema
- API response builder
Template now shows actual company values as placeholders instead of
generic "Using company address/tax number" text.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixed the inheritance UI to be based on formData content rather than
stale server state (vendor._inherited flags):
- "(from company)" shows when formData field is empty
- "Reset" shows when formData field has a value
- Purple border shows when formData field is empty
- formData initialization: empty for inherited, actual value for overrides
This ensures each field's UI is independent and reactive to user input.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add UI for vendor contact field inheritance from company:
- Show "(from company)" indicator for inherited fields
- Add "Reset" button per field to clear override
- Add "Reset All to Company" button for bulk reset
- Purple border styling for inherited fields
- Dynamic placeholder showing company values
JavaScript methods:
- resetFieldToCompany(fieldName): Reset individual field
- resetAllContactToCompany(): Reset all contact fields
- hasAnyContactOverride(): Check if any field is overridden
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Vendors can now override company contact information for specific branding.
Fields are nullable - if null, value is inherited from parent company.
Database changes:
- Add vendor.contact_email, contact_phone, website, business_address, tax_number
- All nullable (null = inherit from company)
- Alembic migration: 28d44d503cac
Model changes:
- Add effective_* properties for resolved values
- Add get_contact_info_with_inheritance() helper
Schema changes:
- VendorCreate: Optional contact fields for override at creation
- VendorUpdate: Contact fields + reset_contact_to_company flag
- VendorDetailResponse: Resolved values + *_inherited flags
API changes:
- GET/PUT vendor endpoints return resolved contact info
- PUT accepts contact overrides (empty string = reset to inherit)
- _build_vendor_detail_response helper for consistent responses
Service changes:
- admin_service.update_vendor handles reset_contact_to_company flag
- Empty strings converted to None for inheritance
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
vendor_service.py:
- Remove 6 db.commit() calls from service methods
- Use db.flush() in create methods to get IDs without committing
- Remove db.rollback() calls (endpoint handles transaction)
- Methods affected: create_vendor, toggle_verification, set_verification,
toggle_status, set_status, add_product_to_catalog
vendors.py (endpoints):
- Add db.commit() after set_verification() call
- Add db.commit() after set_status() call
This follows the industry pattern: one request = one transaction,
with commit controlled at the API endpoint level.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
API-002 updated:
- Remove db.commit() from anti-patterns (allowed at endpoint level)
- Add db.delete() to anti-patterns (business logic)
- Clarify that transaction control != business logic
SVC-006 added (new rule):
- Services should NOT call db.commit()
- Transaction control belongs at endpoint level
- Exception: log_service.py for audit log commits
- Severity: warning (to allow gradual migration)
This aligns with industry standard:
- One request = one transaction
- Services do work, endpoints control commits
- Enables composing multiple service calls in single transaction
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- seed_demo.py: Change company owner role from "user" to "vendor"
- header.html: Update header partial styling/content
- marketplace.js: Minor JS updates
- marketplace.html: Template updates
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Icons added to icons.js:
- user-plus, user-check, user-x: User action icons
- shield: Plain shield icon
- store: E-commerce store icon
Loggers added to log-config.js:
- companies: For company management logging
- marketplace: For marketplace operations logging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Rewrite pagination.md for server-side pagination approach
- Update quick-start guide with new implementation pattern
- Document shared pattern across Vendors, Companies, Users pages
- Add examples for filters, search, and API integration
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Companies and Vendors pages now use server-side pagination:
- Moved from client-side to server-side pagination
- Added search with debounced input
- Added status and verification filters
- Added pagination state object (page, per_page, total, pages)
- Added pageNumbers computed with ellipsis support
- Updated templates with search bar and filter dropdowns
Benefits:
- Better performance with large datasets
- Consistent UX across all admin list pages
- Reduced initial page load time
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
API endpoints (app/api/v1/admin/users.py):
- GET /users: Paginated list with search and filters
- POST /users: Create new user
- GET /users/{id}: Get user details with related counts
- PUT /users/{id}: Update user information
- PUT /users/{id}/status: Toggle active status
- DELETE /users/{id}: Delete user (with ownership check)
Pydantic schemas (models/schema/auth.py):
- UserCreate: For creating new users
- UserUpdate: For updating user information
- UserDetailResponse: Extended user details with counts
- UserListResponse: Paginated list response
Frontend:
- Updated users.html with server-side pagination and filters
- New user-create.html/js for user creation form
- New user-detail.html/js for viewing user details
- New user-edit.html/js for editing users
Routes added for user create, detail, and edit pages.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
vendor_themes.py:
- Return ThemePresetListResponse instead of raw dict (API-001 fix)
- Add ThemePresetResponse response_model to apply_theme_preset
- Add ThemeDeleteResponse response_model to delete endpoint
vendor_domain.py:
- Remove _get_vendor_by_id helper with direct DB query
- Use vendor_service.get_vendor_by_id() instead (API-002 fix)
models/schema/vendor_theme.py:
- Add ThemeDeleteResponse model for delete endpoint response
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add vendor-create.html template:
- Company dropdown with dynamic loading
- Vendor code and subdomain fields with auto-generation
- Name, description, and optional marketplace CSV URL fields
- Extends admin/base.html with proper layout
Add vendor-create.js:
- Uses centralized logger (vendorCreateLog)
- Alpine.js component for form handling
- Company loading from API
- Subdomain auto-generation from vendor name
- Form submission with validation
Route was already defined in admin_pages.py.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Add new methods to vendor_service.py:
- get_vendor_by_id(): Fetch vendor by ID with proper exception
- get_vendor_by_identifier(): Fetch by ID or code
- toggle_verification/set_verification(): Manage vendor verification
- toggle_status/set_status(): Manage vendor active status
Refactor vendors.py API endpoints:
- Remove _get_vendor_by_identifier helper with direct DB queries
- All endpoints now use vendor_service methods
- Remove direct db.commit() calls from endpoints
This fixes API-002 violations and improves architecture compliance.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Change API-003 from "must catch exceptions" to "must NOT raise HTTPException
directly". This aligns with the architecture where:
- Domain exceptions bubble up to global exception handler
- Endpoints should NOT catch and convert exceptions
- HTTPException should only be used by the global handler
Also adds:
- EXC-004: Domain exceptions must inherit from WizamartException
- EXC-005: Global exception handler must be registered
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Convert direct console.log/error/warn calls to use centralized logger:
- imports.js: 13 violations fixed using adminImportsLog
- vendor-themes.js: 5 violations fixed using vendorThemesLog
- code-quality-dashboard.js: 2 violations fixed using codeQualityLog
- code-quality-violations.js: 1 violation fixed using codeQualityViolationsLog
- settings.js: 1 violation fixed using settingsLog
All files now use window.LogConfig.loggers.* for consistent logging.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>