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>
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 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 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>
- Add transfer-ownership endpoint to companies API
- Add user search endpoint for autocomplete (/admin/users/search)
- Update company detail endpoint to include owner info and vendors list
- Update vendor endpoints to use company relationship for ownership
- Update deps.py vendor access check to use company.owner_user_id
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
JavaScript Logging (18 violations fixed):
- Replace console.log with centralized logger in marketplace.js
- Replace console.log with centralized logger in vendor-themes.js
- Replace console.log with centralized logger in settings.js
- Replace console.log with centralized logger in imports.js
API Layer Transaction Control (documented):
- Add comments to db.commit() calls in companies.py
- Document that commits at API level are intentional for transaction boundary control
- Service layer handles business logic, API layer controls transactions
Remaining Violations (221):
- API-002: Database commits in endpoints (intentional for transaction control)
- API-001: Raw dict responses (legacy code, will refactor incrementally)
- Service layer patterns (legacy code, will refactor incrementally)
Architecture Decision:
Following standard pattern where:
- Service Layer: Contains business logic
- API Layer: Controls transaction boundaries (commit/rollback)
This is a common and acceptable pattern in FastAPI applications.
- Create companies list page with stats (total, verified, active, vendor count)
- Add company creation form with owner account generation
- Implement companies.js with full CRUD operations (list, create, edit, delete)
- Add Companies menu item to admin sidebar (desktop + mobile)
- Create company admin page routes (/admin/companies, /admin/companies/create)
- Register companies API router in admin __init__.py
Features:
- List all companies with pagination
- Create company with automatic owner user creation
- Display temporary password for new owner accounts
- Edit company information
- Delete company (only if no vendors)
- Toggle active/verified status
- Show vendor count per company
UI Components:
- Stats cards (total companies, verified, active, total vendors)
- Company table with status badges
- Create form with validation
- Success/error messaging
- Responsive design with dark mode support
- Add database migration to make vendor.owner_user_id nullable
- Update Vendor model to support company-based ownership (DEPRECATED vendor.owner_user_id)
- Implement company_service with singleton pattern (consistent with vendor_service)
- Create Company model with proper relationships to vendors and users
- Add company exception classes for proper error handling
- Refactor companies API to use singleton service pattern
Architecture Change:
- OLD: Each vendor has its own owner (vendor.owner_user_id)
- NEW: Vendors belong to a company, company has one owner (company.owner_user_id)
- This allows one company owner to manage multiple vendor brands
Technical Details:
- Company service uses singleton pattern (not factory)
- Company service accepts db: Session as parameter (follows SVC-003)
- Uses AuthManager for password hashing (consistent with admin_service)
- Added _generate_temp_password() helper method
Problem:
- GET /api/v1/admin/code-quality/stats returned 500 error
- Pydantic validation error: "last_scan Field required"
- When no scan data exists, service returned dict without last_scan field
- DashboardStatsResponse model required last_scan field
Solution:
1. Added last_scan: None to empty state return dictionary
2. Made last_scan field explicitly optional with default value (= None)
3. Ensures field is always present in response
Changes:
- app/services/code_quality_service.py: Added "last_scan": None
- app/api/v1/admin/code_quality.py: Changed to last_scan: str | None = None
This fixes the 500 error when accessing /admin/code-quality page
with no architecture scan data in the database.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problem:
- Ruff removed 'from app.core.database import Base' from models/database/base.py
- Import appeared "unused" (F401) but was actually a critical re-export
- Caused ImportError: cannot import name 'Base' at runtime
- Re-export pattern: import in one file to export from package
Solution:
1. Added F401 ignore for models/database/base.py in pyproject.toml
2. Created scripts/verify_critical_imports.py verification script
3. Integrated verification into make check and CI pipeline
4. Updated documentation with explanation
New Verification Script:
- Checks all critical re-export imports exist
- Detects import variations (parentheses, 'as' clauses)
- Handles SQLAlchemy declarative_base alternatives
- Runs as part of make check automatically
Protected Files:
- models/database/base.py - Re-exports Base for all models
- models/__init__.py - Exports Base for Alembic
- models/database/__init__.py - Exports Base from package
- All __init__.py files (already protected)
Makefile Changes:
- make verify-imports - Run import verification
- make check - Now includes verify-imports
- make ci - Includes verify-imports in pipeline
Documentation Updated:
- Code quality guide explains re-export protection
- Pre-commit workflow includes verification
- Examples of why re-exports matter
This prevents future issues where linters remove seemingly
"unused" imports that are actually critical for application structure.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace black, isort, and flake8 with Ruff (all-in-one linter and formatter)
- Add comprehensive pyproject.toml configuration
- Simplify Makefile code quality targets
- Configure exclusions for venv/.venv in pyproject.toml
- Auto-fix 1,359 linting issues across codebase
Benefits:
- Much faster builds (Ruff is written in Rust)
- Single tool replaces multiple tools
- More comprehensive rule set (UP, B, C4, SIM, PIE, RET, Q)
- All configuration centralized in pyproject.toml
- Better import sorting and formatting consistency
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Standardize quote style (single to double quotes)
- Reorder and group imports alphabetically
- Fix line breaks and indentation for consistency
- Apply PEP 8 formatting standards
Also updated Makefile to exclude both venv and .venv from code quality checks.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement comprehensive code quality dashboard (Phase 2-4) to track and manage
architecture violations found by the validation script.
Backend Implementation:
- Add JSON output support to validate_architecture.py script
- Create CodeQualityService with scan management, violation tracking, and statistics
- Implement REST API endpoints for code quality management:
* POST /admin/code-quality/scan - trigger new architecture scan
* GET /admin/code-quality/scans - list scan history
* GET /admin/code-quality/violations - list violations with filtering/pagination
* GET /admin/code-quality/violations/{id} - get violation details
* POST /admin/code-quality/violations/{id}/assign - assign to developer
* POST /admin/code-quality/violations/{id}/resolve - mark as resolved
* POST /admin/code-quality/violations/{id}/ignore - mark as ignored
* POST /admin/code-quality/violations/{id}/comments - add comments
* GET /admin/code-quality/stats - dashboard statistics
- Fix architecture_scan model imports to use app.core.database
Frontend Implementation:
- Create code quality dashboard page (code-quality-dashboard.html)
* Summary cards for total violations, errors, warnings, health score
* Status breakdown (open, assigned, resolved, ignored)
* Trend visualization for last 7 scans
* Top violating files list
* Violations by rule and module
* Quick action links
- Create violations list page (code-quality-violations.html)
* Filterable table by severity, status, rule ID, file path
* Pagination support
* Violation detail view links
- Add Alpine.js components (code-quality-dashboard.js, code-quality-violations.js)
* Dashboard state management and scan triggering
* Violations list with filtering and pagination
* API integration with authentication
- Add "Code Quality" navigation link in admin sidebar (Developer Tools section)
Routes:
- GET /admin/code-quality - dashboard page
- GET /admin/code-quality/violations - violations list
- GET /admin/code-quality/violations/{id} - violation details
Features:
- Real-time scan execution from UI
- Technical debt score calculation (0-100 scale)
- Violation workflow: open → assigned → resolved/ignored
- Trend tracking across multiple scans
- File and module-level insights
- Assignment system with priorities and due dates
- Collaborative comments on violations
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement secure customer authentication system with dedicated JWT tokens,
separate from admin/vendor authentication.
Backend Changes:
- Add customer JWT token support in deps.py
- New get_current_customer_from_cookie_or_header dependency
- Validates customer-specific tokens with type checking
- Returns Customer object instead of User for shop routes
- Extend AuthService with customer token support
- Add verify_password() method
- Add create_access_token_with_data() for custom token payloads
- Update CustomerService authentication
- Generate customer-specific JWT tokens with type="customer"
- Use vendor-scoped customer lookup
- Enhance exception handler
- Sanitize validation errors to prevent password leaks in logs
- Fix shop login redirect to support multi-access routing
- Improve vendor context detection from Referer header
- Consistent "path" detection method for cookie path logic
Schema Changes:
- Rename UserLogin.username to email_or_username for flexibility
- Update field validators accordingly
API Changes:
- Update admin/vendor auth endpoints to use email_or_username
- Customer auth already uses email field correctly
Route Changes:
- Update shop account routes to use Customer dependency
- Add /account redirect (without trailing slash)
- Change parameter names from current_user to current_customer
Frontend Changes:
- Update login forms to use email_or_username in API calls
- Change button text from "Log in" to "Sign in" for consistency
- Improve loading spinner layout with flexbox
Security Improvements:
- Customer tokens scoped to vendor_id
- Token type validation prevents cross-context token usage
- Password inputs redacted from validation error logs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implemented a complete shopping cart system with database persistence,
replacing the previous stub implementation. The cart now properly stores
items across sessions and follows the project's architecture patterns.
Database Changes:
- Add cart_items table with vendor_id, session_id, product_id, quantity, price_at_add
- Create unique constraint to prevent duplicate items per session
- Add indexes for session lookups and old cart cleanup
- Run migration a2064e1dfcd4 to create cart_items table
New Models & Schemas:
- models/database/cart.py: CartItem SQLAlchemy model with relationships
- models/schema/cart.py: Pydantic schemas for requests/responses
* AddToCartRequest, UpdateCartItemRequest
* CartResponse, CartItemResponse, CartOperationResponse, ClearCartResponse
Exception Handling:
- app/exceptions/cart.py: Cart-specific exceptions following project patterns
* CartItemNotFoundException - item not found in cart
* InsufficientInventoryForCartException - not enough inventory for cart operation
* InvalidCartQuantityException - invalid quantity validation
* CartValidationException - general cart validation
* EmptyCartException - operations on empty cart
* ProductNotAvailableForCartException - product unavailable
- Updated app/exceptions/__init__.py to export cart exceptions
Service Layer:
- Implement cart_service.get_cart() - fetch cart from database with totals
- Implement cart_service.add_to_cart() - create or update cart items with inventory checks
- Implement cart_service.update_cart_item() - update quantity with validation
- Implement cart_service.remove_from_cart() - delete cart item
- Implement cart_service.clear_cart() - remove all items for session
- Replace generic exceptions with cart-specific ones
- Fix InsufficientInventoryException usage (was using wrong parameters)
API Layer:
- Update app/api/v1/shop/cart.py to use Pydantic schemas
- Add response_model declarations to all endpoints
- Add return type hints for type safety
- Convert service dict responses to Pydantic models
Features:
- Cart items persist in database across server restarts
- Inventory validation before adding/updating items
- Price captured at time of adding to cart
- Duplicate items update quantity instead of creating new entries
- Full CRUD operations with proper error handling
- Type-safe API with auto-generated OpenAPI documentation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Major improvements to shop URL routing and vendor landing page system:
## Landing Page System
- Add template field to ContentPage model for flexible landing page designs
- Create 4 landing page templates: default, minimal, modern, and full
- Implement smart root handler to serve landing pages or redirect to shop
- Add create_landing_page.py script for easy landing page management
- Support both domain/subdomain and path-based vendor access
- Add comprehensive landing page documentation
## Route Fixes
- Fix duplicate /shop prefix in shop_pages.py routes
- Correct product detail page routing (was /shop/shop/products/{id})
- Update all shop routes to work with router prefix mounting
- Remove unused public vendor endpoints (/api/v1/public/vendors)
## Template Link Corrections
- Fix all shop template links to include /shop/ prefix
- Update breadcrumb 'Home' links to point to vendor root (landing page)
- Update header navigation 'Home' link to point to vendor root
- Correct CMS page links in footer navigation
- Fix account, cart, and error page navigation links
## Navigation Architecture
- Establish two-tier navigation: landing page (/) and shop (/shop/)
- Document complete navigation flow and URL hierarchy
- Support for vendors with or without landing pages (auto-redirect fallback)
- Consistent breadcrumb and header navigation behavior
## Documentation
- Add vendor-landing-pages.md feature documentation
- Add navigation-flow.md with complete URL hierarchy
- Update shop architecture docs with error handling section
- Add orphaned docs to mkdocs.yml navigation
- Document multi-access routing patterns
## Database
- Migration f68d8da5315a: add template field to content_pages table
- Support template values: default, minimal, modern, full
This establishes a complete landing page system allowing vendors to have
custom marketing homepages separate from their e-commerce shop, with
flexible template options and proper navigation hierarchy.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fix ImportError by using correct authentication dependency names:
- Use get_current_admin_api instead of get_current_admin_user
- Use get_current_vendor_api instead of get_current_vendor_user
These are the correct dependency names for API endpoints that require
Authorization header authentication (no cookie support).
Fixes: ImportError: cannot import name 'get_current_admin_user'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implement complete CMS business logic and REST API:
Service Layer (content_page_service.py):
- get_page_for_vendor() - Two-tier lookup with fallback
- list_pages_for_vendor() - Merge vendor + platform pages
- create_page(), update_page(), delete_page() - CRUD operations
- Support for published/draft workflow
- Footer/header navigation filtering
API Endpoints:
Admin API (/api/v1/admin/content-pages):
- POST /platform - Create platform defaults
- GET /platform - List platform defaults
- GET / - List all pages with vendor filtering
- PUT /{id} - Update any page
- DELETE /{id} - Delete any page
Vendor API (/api/v1/vendor/{code}/content-pages):
- GET / - List available pages (vendor + platform merged)
- GET /overrides - List only vendor overrides
- POST / - Create vendor override
- PUT /{id} - Update vendor page
- DELETE /{id} - Delete vendor page
Shop API (/api/v1/shop/content-pages):
- GET /navigation - Get footer/header navigation pages
- GET /{slug} - Get specific page (public, with fallback)
All endpoints include proper authentication, authorization,
and validation using Pydantic schemas.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>