feat: make Product fully independent from MarketplaceProduct
- Add is_digital and product_type columns to Product model - Remove is_digital/product_type properties that derived from MarketplaceProduct - Update Create form with translation tabs, GTIN type, sale price, VAT rate, image - Update Edit form to allow editing is_digital (remove disabled state) - Add Availability field to Edit form - Fix Detail page for directly created products (no marketplace source) - Update vendor_product_service to handle new fields in create/update - Add VendorProductCreate/Update schema fields for translations and is_digital - Add unit tests for is_digital column and direct product creation - Add integration tests for create/update API with new fields - Create product-architecture.md documenting the independent copy pattern - Add migration y3d4e5f6g7h8 for is_digital and product_type columns 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# alembic/versions/x2c3d4e5f6g7_make_marketplace_product_id_nullable.py
|
||||
"""Make marketplace_product_id nullable for direct product creation.
|
||||
|
||||
Revision ID: x2c3d4e5f6g7
|
||||
Revises: w1b2c3d4e5f6
|
||||
Create Date: 2026-01-06 23:15:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "x2c3d4e5f6g7"
|
||||
down_revision: str = "w1b2c3d4e5f6"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
"""Make marketplace_product_id nullable to allow direct product creation."""
|
||||
# SQLite doesn't support ALTER COLUMN, so we need to recreate the table
|
||||
# For SQLite, we use batch mode which handles this automatically
|
||||
with op.batch_alter_table("products") as batch_op:
|
||||
batch_op.alter_column(
|
||||
"marketplace_product_id",
|
||||
existing_type=sa.Integer(),
|
||||
nullable=True,
|
||||
)
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Revert marketplace_product_id to NOT NULL."""
|
||||
# Note: This will fail if there are any NULL values in the column
|
||||
with op.batch_alter_table("products") as batch_op:
|
||||
batch_op.alter_column(
|
||||
"marketplace_product_id",
|
||||
existing_type=sa.Integer(),
|
||||
nullable=False,
|
||||
)
|
||||
47
alembic/versions/y3d4e5f6g7h8_add_product_type_columns.py
Normal file
47
alembic/versions/y3d4e5f6g7h8_add_product_type_columns.py
Normal file
@@ -0,0 +1,47 @@
|
||||
# alembic/versions/y3d4e5f6g7h8_add_product_type_columns.py
|
||||
"""Add is_digital and product_type columns to products table.
|
||||
|
||||
Makes Product fully independent from MarketplaceProduct for product type info.
|
||||
|
||||
Revision ID: y3d4e5f6g7h8
|
||||
Revises: x2c3d4e5f6g7
|
||||
Create Date: 2026-01-07 10:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "y3d4e5f6g7h8"
|
||||
down_revision: str = "x2c3d4e5f6g7"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
"""Add is_digital and product_type columns to products table."""
|
||||
with op.batch_alter_table("products") as batch_op:
|
||||
batch_op.add_column(
|
||||
sa.Column("is_digital", sa.Boolean(), nullable=False, server_default="0")
|
||||
)
|
||||
batch_op.add_column(
|
||||
sa.Column(
|
||||
"product_type",
|
||||
sa.String(20),
|
||||
nullable=False,
|
||||
server_default="physical",
|
||||
)
|
||||
)
|
||||
batch_op.create_index("idx_product_is_digital", ["is_digital"])
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
"""Remove is_digital and product_type columns."""
|
||||
with op.batch_alter_table("products") as batch_op:
|
||||
batch_op.drop_index("idx_product_is_digital")
|
||||
batch_op.drop_column("product_type")
|
||||
batch_op.drop_column("is_digital")
|
||||
Reference in New Issue
Block a user