Files
orion/app/modules/hosting/migrations/versions/hosting_001_initial.py
Samir Boulahtit 8b147f53c6
Some checks failed
CI / pytest (push) Failing after 49m20s
CI / validate (push) Successful in 24s
CI / dependency-scanning (push) Successful in 33s
CI / docs (push) Has been skipped
CI / deploy (push) Has been skipped
CI / ruff (push) Successful in 10s
feat(hosting): add HostWizard platform module and fix migration chain
- Add complete hosting module (models, routes, schemas, services, templates, migrations)
- Add HostWizard platform to init_production seed (code=hosting, domain=hostwizard.lu)
- Fix cms_002 migration down_revision to z_unique_subdomain_domain
- Fix prospecting_001 migration to chain after cms_002 (remove branch label)
- Add hosting/prospecting version_locations to alembic.ini
- Fix admin_services delete endpoint to use proper response model
- Add hostwizard.lu to deployment docs (DNS, Caddy, Cloudflare)
- Add hosting and prospecting user journey docs to mkdocs nav

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-03 19:34:56 +01:00

126 lines
4.3 KiB
Python

"""hosting: initial tables for hosted sites and client services
Revision ID: hosting_001
Revises: prospecting_001
Create Date: 2026-03-03
"""
import sqlalchemy as sa
from alembic import op
revision = "hosting_001"
down_revision = "prospecting_001"
branch_labels = None
depends_on = None
def upgrade() -> None:
# --- hosted_sites ---
op.create_table(
"hosted_sites",
sa.Column("id", sa.Integer(), primary_key=True, index=True),
sa.Column(
"store_id",
sa.Integer(),
sa.ForeignKey("stores.id", ondelete="CASCADE"),
nullable=False,
unique=True,
),
sa.Column(
"prospect_id",
sa.Integer(),
sa.ForeignKey("prospects.id", ondelete="SET NULL"),
nullable=True,
),
sa.Column(
"status",
sa.String(20),
nullable=False,
server_default="draft",
),
sa.Column("business_name", sa.String(255), nullable=False),
sa.Column("contact_name", sa.String(255), nullable=True),
sa.Column("contact_email", sa.String(255), nullable=True),
sa.Column("contact_phone", sa.String(50), nullable=True),
sa.Column("proposal_sent_at", sa.DateTime(), nullable=True),
sa.Column("proposal_accepted_at", sa.DateTime(), nullable=True),
sa.Column("went_live_at", sa.DateTime(), nullable=True),
sa.Column("proposal_notes", sa.Text(), nullable=True),
sa.Column("live_domain", sa.String(255), nullable=True, unique=True),
sa.Column("internal_notes", sa.Text(), nullable=True),
sa.Column(
"created_at",
sa.DateTime(),
server_default=sa.func.now(),
nullable=False,
),
sa.Column(
"updated_at",
sa.DateTime(),
server_default=sa.func.now(),
nullable=False,
),
)
op.create_index("ix_hosted_sites_status", "hosted_sites", ["status"])
op.create_index("ix_hosted_sites_prospect_id", "hosted_sites", ["prospect_id"])
# --- client_services ---
op.create_table(
"client_services",
sa.Column("id", sa.Integer(), primary_key=True, index=True),
sa.Column(
"hosted_site_id",
sa.Integer(),
sa.ForeignKey("hosted_sites.id", ondelete="CASCADE"),
nullable=False,
index=True,
),
sa.Column("service_type", sa.String(30), nullable=False),
sa.Column("name", sa.String(255), nullable=False),
sa.Column("description", sa.Text(), nullable=True),
sa.Column(
"status",
sa.String(20),
nullable=False,
server_default="pending",
),
sa.Column("billing_period", sa.String(20), nullable=True),
sa.Column("price_cents", sa.Integer(), nullable=True),
sa.Column("currency", sa.String(3), nullable=False, server_default="EUR"),
sa.Column(
"addon_product_id",
sa.Integer(),
sa.ForeignKey("addon_products.id", ondelete="SET NULL"),
nullable=True,
),
sa.Column("domain_name", sa.String(255), nullable=True),
sa.Column("registrar", sa.String(100), nullable=True),
sa.Column("mailbox_count", sa.Integer(), nullable=True),
sa.Column("expires_at", sa.DateTime(), nullable=True),
sa.Column("period_start", sa.DateTime(), nullable=True),
sa.Column("period_end", sa.DateTime(), nullable=True),
sa.Column("auto_renew", sa.Boolean(), nullable=False, server_default="true"),
sa.Column("notes", sa.Text(), nullable=True),
sa.Column(
"created_at",
sa.DateTime(),
server_default=sa.func.now(),
nullable=False,
),
sa.Column(
"updated_at",
sa.DateTime(),
server_default=sa.func.now(),
nullable=False,
),
)
op.create_index("ix_client_services_service_type", "client_services", ["service_type"])
op.create_index("ix_client_services_status", "client_services", ["status"])
op.create_index("ix_client_services_expires_at", "client_services", ["expires_at"])
def downgrade() -> None:
op.drop_table("client_services")
op.drop_table("hosted_sites")