feat: initial commit
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
"""Remove product variant system — products are unique, no variant concept.
|
||||
|
||||
Revision ID: 027
|
||||
Revises: 026
|
||||
Create Date: 2026-03-03
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
revision = "027"
|
||||
down_revision = "026"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
NIL_UUID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# Drop variant-aware unique indexes on order_lines
|
||||
op.execute("DROP INDEX IF EXISTS uq_order_lines_tracking")
|
||||
op.execute("DROP INDEX IF EXISTS uq_order_lines_render")
|
||||
|
||||
# Drop variant_id column from order_lines
|
||||
op.execute("ALTER TABLE order_lines DROP COLUMN IF EXISTS variant_id")
|
||||
|
||||
# Deduplicate tracking-only lines (output_type_id IS NULL) — keep the newest row per
|
||||
# (order_id, product_id) pair so the unique index can be created cleanly.
|
||||
op.execute("""
|
||||
DELETE FROM order_lines
|
||||
WHERE output_type_id IS NULL
|
||||
AND id NOT IN (
|
||||
SELECT DISTINCT ON (order_id, product_id) id
|
||||
FROM order_lines
|
||||
WHERE output_type_id IS NULL
|
||||
ORDER BY order_id, product_id, created_at DESC
|
||||
)
|
||||
""")
|
||||
|
||||
# Deduplicate render lines — keep the newest row per (order_id, product_id, output_type_id).
|
||||
op.execute("""
|
||||
DELETE FROM order_lines
|
||||
WHERE output_type_id IS NOT NULL
|
||||
AND id NOT IN (
|
||||
SELECT DISTINCT ON (order_id, product_id, output_type_id) id
|
||||
FROM order_lines
|
||||
WHERE output_type_id IS NOT NULL
|
||||
ORDER BY order_id, product_id, output_type_id, created_at DESC
|
||||
)
|
||||
""")
|
||||
|
||||
# Recreate simpler unique indexes without variant_id
|
||||
op.execute(
|
||||
"CREATE UNIQUE INDEX uq_order_lines_tracking "
|
||||
"ON order_lines (order_id, product_id) "
|
||||
"WHERE output_type_id IS NULL"
|
||||
)
|
||||
op.execute(
|
||||
"CREATE UNIQUE INDEX uq_order_lines_render "
|
||||
"ON order_lines (order_id, product_id, output_type_id) "
|
||||
"WHERE output_type_id IS NOT NULL"
|
||||
)
|
||||
|
||||
# Drop product_variants table (CASCADE removes its indexes automatically)
|
||||
op.execute("DROP TABLE IF EXISTS product_variants CASCADE")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# Recreate product_variants table
|
||||
op.execute("""
|
||||
CREATE TABLE product_variants (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
product_id UUID NOT NULL REFERENCES products(id) ON DELETE CASCADE,
|
||||
name VARCHAR(500) NOT NULL,
|
||||
gewuenschte_bildnummer VARCHAR(500),
|
||||
components JSONB NOT NULL DEFAULT '[]',
|
||||
is_default BOOLEAN NOT NULL DEFAULT false,
|
||||
source_excel VARCHAR(1000),
|
||||
created_at TIMESTAMP NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMP NOT NULL DEFAULT NOW()
|
||||
)
|
||||
""")
|
||||
op.execute(
|
||||
"CREATE UNIQUE INDEX uq_product_variants_product_name "
|
||||
"ON product_variants (product_id, lower(name))"
|
||||
)
|
||||
op.execute("CREATE INDEX ON product_variants (product_id)")
|
||||
|
||||
# Add back variant_id to order_lines
|
||||
op.execute(
|
||||
"ALTER TABLE order_lines ADD COLUMN variant_id UUID "
|
||||
"REFERENCES product_variants(id) ON DELETE SET NULL"
|
||||
)
|
||||
|
||||
# Drop simple indexes and restore variant-aware indexes
|
||||
op.execute("DROP INDEX IF EXISTS uq_order_lines_tracking")
|
||||
op.execute("DROP INDEX IF EXISTS uq_order_lines_render")
|
||||
|
||||
op.execute(
|
||||
"CREATE UNIQUE INDEX uq_order_lines_tracking "
|
||||
f"ON order_lines (order_id, product_id, COALESCE(variant_id, '{NIL_UUID}'::uuid)) "
|
||||
"WHERE output_type_id IS NULL"
|
||||
)
|
||||
op.execute(
|
||||
"CREATE UNIQUE INDEX uq_order_lines_render "
|
||||
"ON order_lines (order_id, product_id, output_type_id, "
|
||||
f"COALESCE(variant_id, '{NIL_UUID}'::uuid)) "
|
||||
"WHERE output_type_id IS NOT NULL"
|
||||
)
|
||||
Reference in New Issue
Block a user