fix(users): handle active discounts on delete
Ensure active_discounts cascades on user/promo removal, clean orphan rows during migration, and rely on DB cascade for user deletion.
This commit is contained in:
@@ -168,6 +168,48 @@ def _migration_0004_add_discount_promo_codes(connection: Connection) -> None:
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def _migration_0005_fix_active_discounts_fk_cascade(connection: Connection) -> None:
|
||||
inspector = inspect(connection)
|
||||
if not inspector.has_table("active_discounts"):
|
||||
return
|
||||
|
||||
connection.execute(
|
||||
text(
|
||||
"DELETE FROM active_discounts ad "
|
||||
"WHERE NOT EXISTS (SELECT 1 FROM users u WHERE u.user_id = ad.user_id) "
|
||||
"OR NOT EXISTS (SELECT 1 FROM promo_codes p WHERE p.promo_code_id = ad.promo_code_id)"
|
||||
)
|
||||
)
|
||||
|
||||
connection.execute(
|
||||
text("ALTER TABLE active_discounts DROP CONSTRAINT IF EXISTS active_discounts_user_id_fkey")
|
||||
)
|
||||
connection.execute(
|
||||
text("ALTER TABLE active_discounts DROP CONSTRAINT IF EXISTS fk_active_discounts_user")
|
||||
)
|
||||
connection.execute(
|
||||
text("ALTER TABLE active_discounts DROP CONSTRAINT IF EXISTS active_discounts_promo_code_id_fkey")
|
||||
)
|
||||
connection.execute(
|
||||
text("ALTER TABLE active_discounts DROP CONSTRAINT IF EXISTS fk_active_discounts_promo_code")
|
||||
)
|
||||
|
||||
connection.execute(
|
||||
text(
|
||||
"ALTER TABLE active_discounts "
|
||||
"ADD CONSTRAINT fk_active_discounts_user "
|
||||
"FOREIGN KEY (user_id) REFERENCES users (user_id) ON DELETE CASCADE"
|
||||
)
|
||||
)
|
||||
connection.execute(
|
||||
text(
|
||||
"ALTER TABLE active_discounts "
|
||||
"ADD CONSTRAINT fk_active_discounts_promo_code "
|
||||
"FOREIGN KEY (promo_code_id) REFERENCES promo_codes (promo_code_id) ON DELETE CASCADE"
|
||||
)
|
||||
)
|
||||
|
||||
MIGRATIONS: List[Migration] = [
|
||||
Migration(
|
||||
id="0001_add_channel_subscription_fields",
|
||||
@@ -189,6 +231,11 @@ MIGRATIONS: List[Migration] = [
|
||||
description="Add support for percentage discount promo codes",
|
||||
upgrade=_migration_0004_add_discount_promo_codes,
|
||||
),
|
||||
Migration(
|
||||
id="0005_fix_active_discounts_fk_cascade",
|
||||
description="Ensure active_discounts FKs cascade on user/promo delete",
|
||||
upgrade=_migration_0005_fix_active_discounts_fk_cascade,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
||||
+10
-2
@@ -210,8 +210,16 @@ class ActiveDiscount(Base):
|
||||
"""Tracks pending discount promo codes awaiting payment (permanent until used)"""
|
||||
__tablename__ = "active_discounts"
|
||||
|
||||
user_id = Column(BigInteger, ForeignKey("users.user_id"), primary_key=True)
|
||||
promo_code_id = Column(Integer, ForeignKey("promo_codes.promo_code_id"), nullable=False)
|
||||
user_id = Column(
|
||||
BigInteger,
|
||||
ForeignKey("users.user_id", ondelete="CASCADE"),
|
||||
primary_key=True,
|
||||
)
|
||||
promo_code_id = Column(
|
||||
Integer,
|
||||
ForeignKey("promo_codes.promo_code_id", ondelete="CASCADE"),
|
||||
nullable=False,
|
||||
)
|
||||
discount_percentage = Column(Integer, nullable=False)
|
||||
activated_at = Column(DateTime(timezone=True), server_default=func.now())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user