refactor: product independence - remove inheritance pattern

Change Product/ProductTranslation from "override/inheritance" pattern
(NULL = inherit from marketplace) to "independent copy" pattern
(all fields populated at creation).

Key changes:
- Remove OVERRIDABLE_FIELDS, effective_* properties, reset_* methods
- Rename get_override_info() → get_source_comparison_info()
- Update copy_to_vendor_catalog() to copy ALL fields + translations
- Replace effective_* with direct field access in services
- Remove *_overridden fields from schema, keep *_source for comparison
- Add migration to populate NULL fields from marketplace products

The marketplace_product_id FK is kept for "view original source" feature.
Rollback tag: v1.0.0-pre-product-independence

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-24 23:41:20 +01:00
parent 4ba911e263
commit 508e121a0e
10 changed files with 444 additions and 418 deletions

View File

@@ -25,8 +25,8 @@ class VendorProductListItem(BaseModel):
vendor_sku: str | None = None
title: str | None = None
brand: str | None = None
effective_price: float | None = None
effective_currency: str | None = None
price: float | None = None
currency: str | None = None
is_active: bool | None = None
is_featured: bool | None = None
is_digital: bool | None = None
@@ -73,7 +73,11 @@ class CatalogVendorsResponse(BaseModel):
class VendorProductDetail(BaseModel):
"""Detailed vendor product information."""
"""Detailed vendor product information.
Products are independent entities - all fields are populated at creation.
Source values are kept for "view original source" comparison only.
"""
id: int
vendor_id: int
@@ -81,27 +85,22 @@ class VendorProductDetail(BaseModel):
vendor_code: str | None = None
marketplace_product_id: int
vendor_sku: str | None = None
# Override info from get_override_info()
# Product fields with source comparison
price: float | None = None
price_overridden: bool | None = None
price_source: float | None = None
price_cents: int | None = None
price_source: float | None = None # For "view original source" feature
sale_price: float | None = None
sale_price_overridden: bool | None = None
sale_price_cents: int | None = None
sale_price_source: float | None = None
currency: str | None = None
currency_overridden: bool | None = None
currency_source: str | None = None
brand: str | None = None
brand_overridden: bool | None = None
brand_source: str | None = None
condition: str | None = None
condition_overridden: bool | None = None
condition_source: str | None = None
availability: str | None = None
availability_overridden: bool | None = None
availability_source: str | None = None
primary_image_url: str | None = None
primary_image_url_overridden: bool | None = None
primary_image_url_source: str | None = None
is_digital: bool | None = None
product_type: str | None = None