fix: make db-reset work in non-interactive mode

- Add FORCE_RESET environment variable to skip confirmation prompt
- Update Makefile db-reset target to use FORCE_RESET=true
- Handle EOFError gracefully with helpful message
- Fix duplicate translation creation in seed script
- Check for existing translations before inserting

🤖 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-12 22:36:49 +01:00
parent 48ff56a993
commit 65f296e883
2 changed files with 63 additions and 18 deletions

View File

@@ -21,10 +21,16 @@ Usage:
make seed-demo # Normal demo seeding
make seed-demo-minimal # Minimal seeding (1 vendor only)
make seed-demo-reset # Delete all data and reseed (DANGEROUS!)
make db-reset # Full reset (migrate down/up + init + seed reset)
Environment Variables:
SEED_MODE=normal|minimal|reset - Seeding mode (default: normal)
FORCE_RESET=true - Skip confirmation in reset mode (for non-interactive use)
This script is idempotent when run normally.
"""
import argparse
import sys
from datetime import UTC, datetime
from decimal import Decimal
@@ -51,6 +57,7 @@ from models.database.company import Company
from models.database.customer import Customer, CustomerAddress
from models.database.marketplace_import_job import MarketplaceImportJob
from models.database.marketplace_product import MarketplaceProduct
from models.database.marketplace_product_translation import MarketplaceProductTranslation
from models.database.order import Order, OrderItem
from models.database.product import Product
from models.database.user import User
@@ -59,6 +66,7 @@ from models.database.vendor_domain import VendorDomain
from models.database.vendor_theme import VendorTheme
SEED_MODE = os.getenv("SEED_MODE", "normal") # normal, minimal, reset
FORCE_RESET = os.getenv("FORCE_RESET", "false").lower() in ("true", "1", "yes")
# =============================================================================
# DEMO DATA CONFIGURATION
@@ -243,11 +251,20 @@ def reset_all_data(db: Session):
print(" This will delete all vendors, customers, orders, etc.")
print(" Admin user will be preserved.")
# Get confirmation
response = input("\n Type 'DELETE ALL DATA' to confirm: ")
if response != "DELETE ALL DATA":
print(" Reset cancelled.")
sys.exit(0)
# Skip confirmation if FORCE_RESET is set (for non-interactive use)
if FORCE_RESET:
print_warning("FORCE_RESET enabled - skipping confirmation")
else:
# Get confirmation interactively
try:
response = input("\n Type 'DELETE ALL DATA' to confirm: ")
if response != "DELETE ALL DATA":
print(" Reset cancelled.")
sys.exit(0)
except EOFError:
print_error("No interactive terminal available.")
print(" Use FORCE_RESET=true to skip confirmation in non-interactive mode.")
sys.exit(1)
# Delete in correct order (respecting foreign keys)
tables_to_clear = [
@@ -514,10 +531,10 @@ def create_demo_products(db: Session, vendor: Vendor, count: int) -> list[Produc
marketplace_product_id = f"{vendor.vendor_code}-MP-{i:04d}"
product_id = f"{vendor.vendor_code}-PROD-{i:03d}"
# Check if this product already exists
# Check if this product already exists (by vendor_sku)
existing_product = (
db.query(Product)
.filter(Product.vendor_id == vendor.id, Product.product_id == product_id)
.filter(Product.vendor_id == vendor.id, Product.vendor_sku == product_id)
.first()
)
@@ -538,9 +555,7 @@ def create_demo_products(db: Session, vendor: Vendor, count: int) -> list[Produc
# Create the MarketplaceProduct (base product data)
marketplace_product = MarketplaceProduct(
marketplace_product_id=marketplace_product_id,
title=f"Sample Product {i} - {vendor.name}",
description=f"This is a demo product for testing purposes in {vendor.name}. High quality and affordable.",
link=f"https://{vendor.subdomain}.example.com/products/sample-{i}",
source_url=f"https://{vendor.subdomain}.example.com/products/sample-{i}",
image_link=f"https://{vendor.subdomain}.example.com/images/product-{i}.jpg",
price=str(Decimal(f"{(i * 10) % 500 + 9.99}")), # Store as string
brand=vendor.name,
@@ -557,19 +572,34 @@ def create_demo_products(db: Session, vendor: Vendor, count: int) -> list[Produc
db.add(marketplace_product)
db.flush() # Flush to get the marketplace_product.id
# Check if English translation already exists
existing_translation = (
db.query(MarketplaceProductTranslation)
.filter(
MarketplaceProductTranslation.marketplace_product_id
== marketplace_product.id,
MarketplaceProductTranslation.language == "en",
)
.first()
)
if not existing_translation:
# Create English translation
translation = MarketplaceProductTranslation(
marketplace_product_id=marketplace_product.id,
language="en",
title=f"Sample Product {i} - {vendor.name}",
description=f"This is a demo product for testing purposes in {vendor.name}. High quality and affordable.",
)
db.add(translation)
# Create the Product (vendor-specific entry)
product = Product(
vendor_id=vendor.id,
marketplace_product_id=marketplace_product.id,
product_id=product_id,
vendor_sku=product_id, # Use vendor_sku for vendor's internal product reference
price=float(Decimal(f"{(i * 10) % 500 + 9.99}")), # Store as float
availability="in stock",
condition="new",
currency="EUR",
is_active=True,
is_featured=(i % 5 == 0), # Every 5th product is featured
display_order=i,
min_quantity=1,
created_at=datetime.now(UTC),
updated_at=datetime.now(UTC),
)