"""Initial database schema Revision ID: 001_initial Revises: Create Date: 2026-01-29 """ from typing import Sequence, Union from alembic import op import sqlalchemy as sa from sqlalchemy.dialects import postgresql # revision identifiers, used by Alembic. revision: str = "001_initial" down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None def upgrade() -> None: # Customers table op.create_table( "customers", sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("email", sa.String(255), nullable=False), sa.Column("stripe_customer_id", sa.String(255), nullable=True), sa.Column("created_at", sa.DateTime(), nullable=True), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_customers_email", "customers", ["email"], unique=True) # Carts table op.create_table( "carts", sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("customer_id", postgresql.UUID(as_uuid=True), nullable=True), sa.Column("created_at", sa.DateTime(), nullable=True), sa.Column("updated_at", sa.DateTime(), nullable=True), sa.Column("expires_at", sa.DateTime(), nullable=True), sa.ForeignKeyConstraint(["customer_id"], ["customers.id"]), sa.PrimaryKeyConstraint("id"), ) # Cart items table op.create_table( "cart_items", sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("cart_id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("product_slug", sa.String(100), nullable=False), sa.Column("product_name", sa.String(255), nullable=False), sa.Column("variant", sa.String(50), nullable=True), sa.Column("quantity", sa.Integer(), nullable=False), sa.Column("unit_price", sa.Numeric(10, 2), nullable=False), sa.Column("created_at", sa.DateTime(), nullable=True), sa.ForeignKeyConstraint(["cart_id"], ["carts.id"], ondelete="CASCADE"), sa.PrimaryKeyConstraint("id"), ) # Orders table op.create_table( "orders", sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("customer_id", postgresql.UUID(as_uuid=True), nullable=True), sa.Column("stripe_session_id", sa.String(255), nullable=True), sa.Column("stripe_payment_intent_id", sa.String(255), nullable=True), sa.Column("status", sa.String(50), nullable=True), sa.Column("shipping_name", sa.String(255), nullable=True), sa.Column("shipping_email", sa.String(255), nullable=True), sa.Column("shipping_address_line1", sa.String(255), nullable=True), sa.Column("shipping_address_line2", sa.String(255), nullable=True), sa.Column("shipping_city", sa.String(100), nullable=True), sa.Column("shipping_state", sa.String(100), nullable=True), sa.Column("shipping_postal_code", sa.String(20), nullable=True), sa.Column("shipping_country", sa.String(2), nullable=True), sa.Column("subtotal", sa.Numeric(10, 2), nullable=True), sa.Column("shipping_cost", sa.Numeric(10, 2), nullable=True), sa.Column("tax", sa.Numeric(10, 2), nullable=True), sa.Column("total", sa.Numeric(10, 2), nullable=True), sa.Column("currency", sa.String(3), nullable=True), sa.Column("created_at", sa.DateTime(), nullable=True), sa.Column("updated_at", sa.DateTime(), nullable=True), sa.Column("paid_at", sa.DateTime(), nullable=True), sa.Column("shipped_at", sa.DateTime(), nullable=True), sa.Column("delivered_at", sa.DateTime(), nullable=True), sa.ForeignKeyConstraint(["customer_id"], ["customers.id"]), sa.PrimaryKeyConstraint("id"), ) # Order items table op.create_table( "order_items", sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("order_id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("product_slug", sa.String(100), nullable=False), sa.Column("product_name", sa.String(255), nullable=False), sa.Column("variant", sa.String(50), nullable=True), sa.Column("quantity", sa.Integer(), nullable=False), sa.Column("unit_price", sa.Numeric(10, 2), nullable=False), sa.Column("pod_provider", sa.String(50), nullable=True), sa.Column("pod_order_id", sa.String(255), nullable=True), sa.Column("pod_status", sa.String(50), nullable=True), sa.Column("pod_tracking_number", sa.String(100), nullable=True), sa.Column("pod_tracking_url", sa.Text(), nullable=True), sa.Column("created_at", sa.DateTime(), nullable=True), sa.ForeignKeyConstraint(["order_id"], ["orders.id"], ondelete="CASCADE"), sa.PrimaryKeyConstraint("id"), ) # Admin users table op.create_table( "admin_users", sa.Column("id", postgresql.UUID(as_uuid=True), nullable=False), sa.Column("email", sa.String(255), nullable=False), sa.Column("password_hash", sa.String(255), nullable=False), sa.Column("is_active", sa.Boolean(), nullable=True), sa.Column("created_at", sa.DateTime(), nullable=True), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_admin_users_email", "admin_users", ["email"], unique=True) # Product overrides table op.create_table( "product_overrides", sa.Column("slug", sa.String(100), nullable=False), sa.Column("is_active", sa.Boolean(), nullable=True), sa.Column("price_override", sa.Numeric(10, 2), nullable=True), sa.Column("updated_at", sa.DateTime(), nullable=True), sa.PrimaryKeyConstraint("slug"), ) def downgrade() -> None: op.drop_table("product_overrides") op.drop_index("ix_admin_users_email", table_name="admin_users") op.drop_table("admin_users") op.drop_table("order_items") op.drop_table("orders") op.drop_table("cart_items") op.drop_table("carts") op.drop_index("ix_customers_email", table_name="customers") op.drop_table("customers")