"""initial_schema_20251015_1229

Revision ID: 93d6ea3dc888
Revises:
Create Date: 2025-10-15 12:29:52.767171+02:00

"""
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 = '93d6ea3dc888'
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:
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('alert_rules',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('rule_name', sa.String(length=255), nullable=False),
    sa.Column('rule_description', sa.Text(), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('alert_type', sa.Enum('POOR_QUALITY', 'LATE_DELIVERY', 'PRICE_INCREASE', 'LOW_PERFORMANCE', 'CONTRACT_EXPIRY', 'COMPLIANCE_ISSUE', 'FINANCIAL_RISK', 'COMMUNICATION_ISSUE', 'CAPACITY_CONSTRAINT', 'CERTIFICATION_EXPIRY', name='alerttype'), nullable=False),
    sa.Column('severity', sa.Enum('CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO', name='alertseverity'), nullable=False),
    sa.Column('metric_type', sa.Enum('DELIVERY_PERFORMANCE', 'QUALITY_SCORE', 'PRICE_COMPETITIVENESS', 'COMMUNICATION_RATING', 'ORDER_ACCURACY', 'RESPONSE_TIME', 'COMPLIANCE_SCORE', 'FINANCIAL_STABILITY', name='performancemetrictype'), nullable=True),
    sa.Column('trigger_condition', sa.String(length=50), nullable=False),
    sa.Column('threshold_value', sa.Float(), nullable=False),
    sa.Column('consecutive_violations', sa.Integer(), nullable=False),
    sa.Column('supplier_categories', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('supplier_ids', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('exclude_suppliers', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('evaluation_period', sa.Enum('DAILY', 'WEEKLY', 'MONTHLY', 'QUARTERLY', 'YEARLY', name='performanceperiod'), nullable=False),
    sa.Column('time_window_hours', sa.Integer(), nullable=True),
    sa.Column('business_hours_only', sa.Boolean(), nullable=False),
    sa.Column('auto_resolve', sa.Boolean(), nullable=False),
    sa.Column('auto_resolve_threshold', sa.Float(), nullable=True),
    sa.Column('auto_resolve_duration_hours', sa.Integer(), nullable=True),
    sa.Column('notification_enabled', sa.Boolean(), nullable=False),
    sa.Column('notification_recipients', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('escalation_minutes', sa.Integer(), nullable=True),
    sa.Column('escalation_recipients', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('recommended_actions', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('auto_actions', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('priority', sa.Integer(), nullable=False),
    sa.Column('tags', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_by', sa.UUID(), nullable=False),
    sa.Column('last_triggered', sa.DateTime(timezone=True), nullable=True),
    sa.Column('trigger_count', sa.Integer(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_alert_rules_alert_type'), 'alert_rules', ['alert_type'], unique=False)
    op.create_index('ix_alert_rules_metric_type', 'alert_rules', ['metric_type'], unique=False)
    op.create_index('ix_alert_rules_priority', 'alert_rules', ['priority'], unique=False)
    op.create_index('ix_alert_rules_tenant_active', 'alert_rules', ['tenant_id', 'is_active'], unique=False)
    op.create_index(op.f('ix_alert_rules_tenant_id'), 'alert_rules', ['tenant_id'], unique=False)
    op.create_index('ix_alert_rules_type_severity', 'alert_rules', ['alert_type', 'severity'], unique=False)
    op.create_table('audit_logs',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('user_id', sa.UUID(), nullable=False),
    sa.Column('action', sa.String(length=100), nullable=False),
    sa.Column('resource_type', sa.String(length=100), nullable=False),
    sa.Column('resource_id', sa.String(length=255), nullable=True),
    sa.Column('severity', sa.String(length=20), nullable=False),
    sa.Column('service_name', sa.String(length=100), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('changes', postgresql.JSON(astext_type=sa.Text()), nullable=True),
    sa.Column('audit_metadata', postgresql.JSON(astext_type=sa.Text()), nullable=True),
    sa.Column('ip_address', sa.String(length=45), nullable=True),
    sa.Column('user_agent', sa.Text(), nullable=True),
    sa.Column('endpoint', sa.String(length=255), nullable=True),
    sa.Column('method', sa.String(length=10), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_audit_resource_type_action', 'audit_logs', ['resource_type', 'action'], unique=False)
    op.create_index('idx_audit_service_created', 'audit_logs', ['service_name', 'created_at'], unique=False)
    op.create_index('idx_audit_severity_created', 'audit_logs', ['severity', 'created_at'], unique=False)
    op.create_index('idx_audit_tenant_created', 'audit_logs', ['tenant_id', 'created_at'], unique=False)
    op.create_index('idx_audit_user_created', 'audit_logs', ['user_id', 'created_at'], unique=False)
    op.create_index(op.f('ix_audit_logs_action'), 'audit_logs', ['action'], unique=False)
    op.create_index(op.f('ix_audit_logs_created_at'), 'audit_logs', ['created_at'], unique=False)
    op.create_index(op.f('ix_audit_logs_resource_id'), 'audit_logs', ['resource_id'], unique=False)
    op.create_index(op.f('ix_audit_logs_resource_type'), 'audit_logs', ['resource_type'], unique=False)
    op.create_index(op.f('ix_audit_logs_service_name'), 'audit_logs', ['service_name'], unique=False)
    op.create_index(op.f('ix_audit_logs_severity'), 'audit_logs', ['severity'], unique=False)
    op.create_index(op.f('ix_audit_logs_tenant_id'), 'audit_logs', ['tenant_id'], unique=False)
    op.create_index(op.f('ix_audit_logs_user_id'), 'audit_logs', ['user_id'], unique=False)
    op.create_table('supplier_benchmarks',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('benchmark_name', sa.String(length=255), nullable=False),
    sa.Column('benchmark_type', sa.String(length=50), nullable=False),
    sa.Column('supplier_category', sa.String(length=100), nullable=True),
    sa.Column('metric_type', sa.Enum('DELIVERY_PERFORMANCE', 'QUALITY_SCORE', 'PRICE_COMPETITIVENESS', 'COMMUNICATION_RATING', 'ORDER_ACCURACY', 'RESPONSE_TIME', 'COMPLIANCE_SCORE', 'FINANCIAL_STABILITY', name='performancemetrictype'), nullable=False),
    sa.Column('excellent_threshold', sa.Float(), nullable=False),
    sa.Column('good_threshold', sa.Float(), nullable=False),
    sa.Column('acceptable_threshold', sa.Float(), nullable=False),
    sa.Column('poor_threshold', sa.Float(), nullable=False),
    sa.Column('data_source', sa.String(length=255), nullable=True),
    sa.Column('sample_size', sa.Integer(), nullable=True),
    sa.Column('confidence_level', sa.Float(), nullable=True),
    sa.Column('effective_date', sa.DateTime(timezone=True), nullable=False),
    sa.Column('expiry_date', sa.DateTime(timezone=True), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('methodology', sa.Text(), nullable=True),
    sa.Column('notes', sa.Text(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_by', sa.UUID(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('ix_benchmarks_active', 'supplier_benchmarks', ['is_active'], unique=False)
    op.create_index('ix_benchmarks_category', 'supplier_benchmarks', ['supplier_category'], unique=False)
    op.create_index('ix_benchmarks_metric_type', 'supplier_benchmarks', ['metric_type'], unique=False)
    op.create_index('ix_benchmarks_tenant_type', 'supplier_benchmarks', ['tenant_id', 'benchmark_type'], unique=False)
    op.create_index(op.f('ix_supplier_benchmarks_benchmark_type'), 'supplier_benchmarks', ['benchmark_type'], unique=False)
    op.create_index(op.f('ix_supplier_benchmarks_metric_type'), 'supplier_benchmarks', ['metric_type'], unique=False)
    op.create_index(op.f('ix_supplier_benchmarks_supplier_category'), 'supplier_benchmarks', ['supplier_category'], unique=False)
    op.create_index(op.f('ix_supplier_benchmarks_tenant_id'), 'supplier_benchmarks', ['tenant_id'], unique=False)
    op.create_table('suppliers',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('name', sa.String(length=255), nullable=False),
    sa.Column('supplier_code', sa.String(length=50), nullable=True),
    sa.Column('tax_id', sa.String(length=50), nullable=True),
    sa.Column('registration_number', sa.String(length=100), nullable=True),
    sa.Column('supplier_type', sa.Enum('ingredients', 'packaging', 'equipment', 'services', 'utilities', 'multi', name='suppliertype'), nullable=False),
    sa.Column('status', sa.Enum('active', 'inactive', 'pending_approval', 'suspended', 'blacklisted', name='supplierstatus'), nullable=False),
    sa.Column('contact_person', sa.String(length=200), nullable=True),
    sa.Column('email', sa.String(length=254), nullable=True),
    sa.Column('phone', sa.String(length=30), nullable=True),
    sa.Column('mobile', sa.String(length=30), nullable=True),
    sa.Column('website', sa.String(length=255), nullable=True),
    sa.Column('address_line1', sa.String(length=255), nullable=True),
    sa.Column('address_line2', sa.String(length=255), nullable=True),
    sa.Column('city', sa.String(length=100), nullable=True),
    sa.Column('state_province', sa.String(length=100), nullable=True),
    sa.Column('postal_code', sa.String(length=20), nullable=True),
    sa.Column('country', sa.String(length=100), nullable=True),
    sa.Column('payment_terms', sa.Enum('cod', 'net_15', 'net_30', 'net_45', 'net_60', 'prepaid', 'credit_terms', name='paymentterms'), nullable=False),
    sa.Column('credit_limit', sa.Numeric(precision=12, scale=2), nullable=True),
    sa.Column('currency', sa.String(length=3), nullable=False),
    sa.Column('standard_lead_time', sa.Integer(), nullable=False),
    sa.Column('minimum_order_amount', sa.Numeric(precision=10, scale=2), nullable=True),
    sa.Column('delivery_area', sa.String(length=255), nullable=True),
    sa.Column('quality_rating', sa.Float(), nullable=True),
    sa.Column('delivery_rating', sa.Float(), nullable=True),
    sa.Column('total_orders', sa.Integer(), nullable=False),
    sa.Column('total_amount', sa.Numeric(precision=12, scale=2), nullable=False),
    sa.Column('trust_score', sa.Float(), nullable=False, server_default='0.0'),
    sa.Column('is_preferred_supplier', sa.Boolean(), nullable=False, server_default='false'),
    sa.Column('auto_approve_enabled', sa.Boolean(), nullable=False, server_default='false'),
    sa.Column('total_pos_count', sa.Integer(), nullable=False, server_default='0'),
    sa.Column('approved_pos_count', sa.Integer(), nullable=False, server_default='0'),
    sa.Column('on_time_delivery_rate', sa.Float(), nullable=False, server_default='0.0'),
    sa.Column('fulfillment_rate', sa.Float(), nullable=False, server_default='0.0'),
    sa.Column('last_performance_update', sa.DateTime(timezone=True), nullable=True),
    sa.Column('approved_by', sa.UUID(), nullable=True),
    sa.Column('approved_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('rejection_reason', sa.Text(), nullable=True),
    sa.Column('notes', sa.Text(), nullable=True),
    sa.Column('certifications', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('business_hours', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('specializations', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_by', sa.UUID(), nullable=False),
    sa.Column('updated_by', sa.UUID(), nullable=False),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_suppliers_name'), 'suppliers', ['name'], unique=False)
    op.create_index('ix_suppliers_quality_rating', 'suppliers', ['quality_rating'], unique=False)
    op.create_index(op.f('ix_suppliers_status'), 'suppliers', ['status'], unique=False)
    op.create_index(op.f('ix_suppliers_supplier_code'), 'suppliers', ['supplier_code'], unique=False)
    op.create_index(op.f('ix_suppliers_supplier_type'), 'suppliers', ['supplier_type'], unique=False)
    op.create_index(op.f('ix_suppliers_tenant_id'), 'suppliers', ['tenant_id'], unique=False)
    op.create_index('ix_suppliers_tenant_name', 'suppliers', ['tenant_id', 'name'], unique=False)
    op.create_index('ix_suppliers_tenant_status', 'suppliers', ['tenant_id', 'status'], unique=False)
    op.create_index('ix_suppliers_tenant_type', 'suppliers', ['tenant_id', 'supplier_type'], unique=False)
    op.create_index('ix_suppliers_trust_score', 'suppliers', ['trust_score'], unique=False)
    op.create_index('ix_suppliers_preferred', 'suppliers', ['is_preferred_supplier'], unique=False)
    op.create_index('ix_suppliers_auto_approve', 'suppliers', ['auto_approve_enabled'], unique=False)
    op.create_table('supplier_performance_metrics',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('supplier_id', sa.UUID(), nullable=False),
    sa.Column('metric_type', sa.Enum('DELIVERY_PERFORMANCE', 'QUALITY_SCORE', 'PRICE_COMPETITIVENESS', 'COMMUNICATION_RATING', 'ORDER_ACCURACY', 'RESPONSE_TIME', 'COMPLIANCE_SCORE', 'FINANCIAL_STABILITY', name='performancemetrictype'), nullable=False),
    sa.Column('period', sa.Enum('DAILY', 'WEEKLY', 'MONTHLY', 'QUARTERLY', 'YEARLY', name='performanceperiod'), nullable=False),
    sa.Column('period_start', sa.DateTime(timezone=True), nullable=False),
    sa.Column('period_end', sa.DateTime(timezone=True), nullable=False),
    sa.Column('metric_value', sa.Float(), nullable=False),
    sa.Column('target_value', sa.Float(), nullable=True),
    sa.Column('previous_value', sa.Float(), nullable=True),
    sa.Column('total_orders', sa.Integer(), nullable=False),
    sa.Column('total_deliveries', sa.Integer(), nullable=False),
    sa.Column('on_time_deliveries', sa.Integer(), nullable=False),
    sa.Column('late_deliveries', sa.Integer(), nullable=False),
    sa.Column('quality_issues', sa.Integer(), nullable=False),
    sa.Column('total_amount', sa.Numeric(precision=12, scale=2), nullable=False),
    sa.Column('metrics_data', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('trend_direction', sa.String(length=20), nullable=True),
    sa.Column('trend_percentage', sa.Float(), nullable=True),
    sa.Column('notes', sa.Text(), nullable=True),
    sa.Column('external_factors', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('calculated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('calculated_by', sa.UUID(), nullable=True),
    sa.ForeignKeyConstraint(['supplier_id'], ['suppliers.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('ix_performance_metrics_period_dates', 'supplier_performance_metrics', ['period_start', 'period_end'], unique=False)
    op.create_index('ix_performance_metrics_tenant_supplier', 'supplier_performance_metrics', ['tenant_id', 'supplier_id'], unique=False)
    op.create_index('ix_performance_metrics_type_period', 'supplier_performance_metrics', ['metric_type', 'period'], unique=False)
    op.create_index('ix_performance_metrics_value', 'supplier_performance_metrics', ['metric_value'], unique=False)
    op.create_index(op.f('ix_supplier_performance_metrics_metric_type'), 'supplier_performance_metrics', ['metric_type'], unique=False)
    op.create_index(op.f('ix_supplier_performance_metrics_period'), 'supplier_performance_metrics', ['period'], unique=False)
    op.create_index(op.f('ix_supplier_performance_metrics_period_end'), 'supplier_performance_metrics', ['period_end'], unique=False)
    op.create_index(op.f('ix_supplier_performance_metrics_period_start'), 'supplier_performance_metrics', ['period_start'], unique=False)
    op.create_index(op.f('ix_supplier_performance_metrics_supplier_id'), 'supplier_performance_metrics', ['supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_performance_metrics_tenant_id'), 'supplier_performance_metrics', ['tenant_id'], unique=False)
    op.create_table('supplier_price_lists',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('supplier_id', sa.UUID(), nullable=False),
    sa.Column('inventory_product_id', sa.UUID(), nullable=False),
    sa.Column('product_code', sa.String(length=100), nullable=True),
    sa.Column('unit_price', sa.Numeric(precision=10, scale=4), nullable=False),
    sa.Column('unit_of_measure', sa.String(length=20), nullable=False),
    sa.Column('minimum_order_quantity', sa.Integer(), nullable=True),
    sa.Column('price_per_unit', sa.Numeric(precision=10, scale=4), nullable=False),
    sa.Column('tier_pricing', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('effective_date', sa.DateTime(timezone=True), nullable=False),
    sa.Column('expiry_date', sa.DateTime(timezone=True), nullable=True),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('brand', sa.String(length=100), nullable=True),
    sa.Column('packaging_size', sa.String(length=50), nullable=True),
    sa.Column('origin_country', sa.String(length=100), nullable=True),
    sa.Column('shelf_life_days', sa.Integer(), nullable=True),
    sa.Column('storage_requirements', sa.Text(), nullable=True),
    sa.Column('quality_specs', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('allergens', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_by', sa.UUID(), nullable=False),
    sa.Column('updated_by', sa.UUID(), nullable=False),
    sa.ForeignKeyConstraint(['supplier_id'], ['suppliers.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('ix_price_lists_active', 'supplier_price_lists', ['is_active'], unique=False)
    op.create_index('ix_price_lists_effective_date', 'supplier_price_lists', ['effective_date'], unique=False)
    op.create_index('ix_price_lists_inventory_product', 'supplier_price_lists', ['inventory_product_id'], unique=False)
    op.create_index('ix_price_lists_tenant_supplier', 'supplier_price_lists', ['tenant_id', 'supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_price_lists_inventory_product_id'), 'supplier_price_lists', ['inventory_product_id'], unique=False)
    op.create_index(op.f('ix_supplier_price_lists_supplier_id'), 'supplier_price_lists', ['supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_price_lists_tenant_id'), 'supplier_price_lists', ['tenant_id'], unique=False)
    op.create_table('supplier_scorecards',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('supplier_id', sa.UUID(), nullable=False),
    sa.Column('scorecard_name', sa.String(length=255), nullable=False),
    sa.Column('period', sa.Enum('DAILY', 'WEEKLY', 'MONTHLY', 'QUARTERLY', 'YEARLY', name='performanceperiod'), nullable=False),
    sa.Column('period_start', sa.DateTime(timezone=True), nullable=False),
    sa.Column('period_end', sa.DateTime(timezone=True), nullable=False),
    sa.Column('overall_score', sa.Float(), nullable=False),
    sa.Column('quality_score', sa.Float(), nullable=False),
    sa.Column('delivery_score', sa.Float(), nullable=False),
    sa.Column('cost_score', sa.Float(), nullable=False),
    sa.Column('service_score', sa.Float(), nullable=False),
    sa.Column('overall_rank', sa.Integer(), nullable=True),
    sa.Column('category_rank', sa.Integer(), nullable=True),
    sa.Column('total_suppliers_evaluated', sa.Integer(), nullable=True),
    sa.Column('on_time_delivery_rate', sa.Float(), nullable=False),
    sa.Column('quality_rejection_rate', sa.Float(), nullable=False),
    sa.Column('order_accuracy_rate', sa.Float(), nullable=False),
    sa.Column('response_time_hours', sa.Float(), nullable=False),
    sa.Column('cost_variance_percentage', sa.Float(), nullable=False),
    sa.Column('total_orders_processed', sa.Integer(), nullable=False),
    sa.Column('total_amount_processed', sa.Numeric(precision=12, scale=2), nullable=False),
    sa.Column('average_order_value', sa.Numeric(precision=10, scale=2), nullable=False),
    sa.Column('cost_savings_achieved', sa.Numeric(precision=10, scale=2), nullable=False),
    sa.Column('score_trend', sa.String(length=20), nullable=True),
    sa.Column('score_change_percentage', sa.Float(), nullable=True),
    sa.Column('strengths', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('improvement_areas', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('recommended_actions', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('is_final', sa.Boolean(), nullable=False),
    sa.Column('approved_by', sa.UUID(), nullable=True),
    sa.Column('approved_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('notes', sa.Text(), nullable=True),
    sa.Column('attachments', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('generated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('generated_by', sa.UUID(), nullable=False),
    sa.ForeignKeyConstraint(['supplier_id'], ['suppliers.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('ix_scorecards_final', 'supplier_scorecards', ['is_final'], unique=False)
    op.create_index('ix_scorecards_overall_score', 'supplier_scorecards', ['overall_score'], unique=False)
    op.create_index('ix_scorecards_period', 'supplier_scorecards', ['period'], unique=False)
    op.create_index('ix_scorecards_period_dates', 'supplier_scorecards', ['period_start', 'period_end'], unique=False)
    op.create_index('ix_scorecards_tenant_supplier', 'supplier_scorecards', ['tenant_id', 'supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_scorecards_period'), 'supplier_scorecards', ['period'], unique=False)
    op.create_index(op.f('ix_supplier_scorecards_period_end'), 'supplier_scorecards', ['period_end'], unique=False)
    op.create_index(op.f('ix_supplier_scorecards_period_start'), 'supplier_scorecards', ['period_start'], unique=False)
    op.create_index(op.f('ix_supplier_scorecards_supplier_id'), 'supplier_scorecards', ['supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_scorecards_tenant_id'), 'supplier_scorecards', ['tenant_id'], unique=False)
    op.create_table('supplier_alerts',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('supplier_id', sa.UUID(), nullable=False),
    sa.Column('alert_type', sa.Enum('POOR_QUALITY', 'LATE_DELIVERY', 'PRICE_INCREASE', 'LOW_PERFORMANCE', 'CONTRACT_EXPIRY', 'COMPLIANCE_ISSUE', 'FINANCIAL_RISK', 'COMMUNICATION_ISSUE', 'CAPACITY_CONSTRAINT', 'CERTIFICATION_EXPIRY', name='alerttype'), nullable=False),
    sa.Column('severity', sa.Enum('CRITICAL', 'HIGH', 'MEDIUM', 'LOW', 'INFO', name='alertseverity'), nullable=False),
    sa.Column('status', sa.Enum('ACTIVE', 'ACKNOWLEDGED', 'IN_PROGRESS', 'RESOLVED', 'DISMISSED', name='alertstatus'), nullable=False),
    sa.Column('title', sa.String(length=255), nullable=False),
    sa.Column('message', sa.Text(), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('trigger_value', sa.Float(), nullable=True),
    sa.Column('threshold_value', sa.Float(), nullable=True),
    sa.Column('metric_type', sa.Enum('DELIVERY_PERFORMANCE', 'QUALITY_SCORE', 'PRICE_COMPETITIVENESS', 'COMMUNICATION_RATING', 'ORDER_ACCURACY', 'RESPONSE_TIME', 'COMPLIANCE_SCORE', 'FINANCIAL_STABILITY', name='performancemetrictype'), nullable=True),
    sa.Column('purchase_order_id', sa.UUID(), nullable=True),
    sa.Column('delivery_id', sa.UUID(), nullable=True),
    sa.Column('performance_metric_id', sa.UUID(), nullable=True),
    sa.Column('triggered_at', sa.DateTime(timezone=True), nullable=False),
    sa.Column('acknowledged_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('acknowledged_by', sa.UUID(), nullable=True),
    sa.Column('resolved_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('resolved_by', sa.UUID(), nullable=True),
    sa.Column('recommended_actions', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('actions_taken', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('resolution_notes', sa.Text(), nullable=True),
    sa.Column('auto_resolve', sa.Boolean(), nullable=False),
    sa.Column('auto_resolve_condition', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('escalated', sa.Boolean(), nullable=False),
    sa.Column('escalated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('escalated_to', sa.UUID(), nullable=True),
    sa.Column('notification_sent', sa.Boolean(), nullable=False),
    sa.Column('notification_sent_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('notification_recipients', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('priority_score', sa.Integer(), nullable=False),
    sa.Column('business_impact', sa.String(length=50), nullable=True),
    sa.Column('tags', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('updated_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('created_by', sa.UUID(), nullable=True),
    sa.ForeignKeyConstraint(['performance_metric_id'], ['supplier_performance_metrics.id'], ),
    sa.ForeignKeyConstraint(['supplier_id'], ['suppliers.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_supplier_alerts_alert_type'), 'supplier_alerts', ['alert_type'], unique=False)
    op.create_index(op.f('ix_supplier_alerts_delivery_id'), 'supplier_alerts', ['delivery_id'], unique=False)
    op.create_index(op.f('ix_supplier_alerts_metric_type'), 'supplier_alerts', ['metric_type'], unique=False)
    op.create_index('ix_supplier_alerts_priority', 'supplier_alerts', ['priority_score'], unique=False)
    op.create_index(op.f('ix_supplier_alerts_purchase_order_id'), 'supplier_alerts', ['purchase_order_id'], unique=False)
    op.create_index(op.f('ix_supplier_alerts_severity'), 'supplier_alerts', ['severity'], unique=False)
    op.create_index(op.f('ix_supplier_alerts_status'), 'supplier_alerts', ['status'], unique=False)
    op.create_index('ix_supplier_alerts_status_triggered', 'supplier_alerts', ['status', 'triggered_at'], unique=False)
    op.create_index(op.f('ix_supplier_alerts_supplier_id'), 'supplier_alerts', ['supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_alerts_tenant_id'), 'supplier_alerts', ['tenant_id'], unique=False)
    op.create_index('ix_supplier_alerts_tenant_supplier', 'supplier_alerts', ['tenant_id', 'supplier_id'], unique=False)
    op.create_index('ix_supplier_alerts_type_severity', 'supplier_alerts', ['alert_type', 'severity'], unique=False)
    op.create_table('supplier_quality_reviews',
    sa.Column('id', sa.UUID(), nullable=False),
    sa.Column('tenant_id', sa.UUID(), nullable=False),
    sa.Column('supplier_id', sa.UUID(), nullable=False),
    sa.Column('purchase_order_id', sa.UUID(), nullable=True),
    sa.Column('delivery_id', sa.UUID(), nullable=True),
    sa.Column('review_date', sa.DateTime(timezone=True), nullable=False),
    sa.Column('review_type', sa.String(length=50), nullable=False),
    sa.Column('quality_rating', sa.Enum('excellent', 'good', 'average', 'poor', 'very_poor', name='qualityrating'), nullable=False),
    sa.Column('delivery_rating', sa.Enum('excellent', 'good', 'average', 'poor', 'very_poor', name='deliveryrating'), nullable=False),
    sa.Column('communication_rating', sa.Integer(), nullable=False),
    sa.Column('overall_rating', sa.Float(), nullable=False),
    sa.Column('quality_comments', sa.Text(), nullable=True),
    sa.Column('delivery_comments', sa.Text(), nullable=True),
    sa.Column('communication_comments', sa.Text(), nullable=True),
    sa.Column('improvement_suggestions', sa.Text(), nullable=True),
    sa.Column('quality_issues', postgresql.JSONB(astext_type=sa.Text()), nullable=True),
    sa.Column('corrective_actions', sa.Text(), nullable=True),
    sa.Column('follow_up_required', sa.Boolean(), nullable=False),
    sa.Column('follow_up_date', sa.DateTime(timezone=True), nullable=True),
    sa.Column('is_final', sa.Boolean(), nullable=False),
    sa.Column('approved_by', sa.UUID(), nullable=True),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('reviewed_by', sa.UUID(), nullable=False),
    sa.ForeignKeyConstraint(['supplier_id'], ['suppliers.id'], ),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('ix_quality_reviews_date', 'supplier_quality_reviews', ['review_date'], unique=False)
    op.create_index('ix_quality_reviews_overall_rating', 'supplier_quality_reviews', ['overall_rating'], unique=False)
    op.create_index('ix_quality_reviews_tenant_supplier', 'supplier_quality_reviews', ['tenant_id', 'supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_quality_reviews_delivery_id'), 'supplier_quality_reviews', ['delivery_id'], unique=False)
    op.create_index(op.f('ix_supplier_quality_reviews_purchase_order_id'), 'supplier_quality_reviews', ['purchase_order_id'], unique=False)
    op.create_index(op.f('ix_supplier_quality_reviews_supplier_id'), 'supplier_quality_reviews', ['supplier_id'], unique=False)
    op.create_index(op.f('ix_supplier_quality_reviews_tenant_id'), 'supplier_quality_reviews', ['tenant_id'], unique=False)

    # Initialize trust scores for existing suppliers based on their ratings and history
    op.execute("""
        UPDATE suppliers
        SET
            trust_score = LEAST(1.0, GREATEST(0.0,
                (COALESCE(quality_rating, 0) / 5.0 * 0.4) +
                (COALESCE(delivery_rating, 0) / 5.0 * 0.4) +
                (CASE WHEN total_orders > 10 THEN 0.2 ELSE total_orders / 50.0 END)
            )),
            is_preferred_supplier = (
                total_orders >= 10 AND
                quality_rating >= 4.0 AND
                delivery_rating >= 4.0 AND
                status = 'active'
            ),
            auto_approve_enabled = (
                total_orders >= 20 AND
                quality_rating >= 4.5 AND
                delivery_rating >= 4.5 AND
                status = 'active'
            ),
            total_pos_count = total_orders,
            approved_pos_count = total_orders,
            on_time_delivery_rate = COALESCE(delivery_rating / 5.0, 0.0),
            fulfillment_rate = COALESCE(quality_rating / 5.0, 0.0),
            last_performance_update = NOW()
        WHERE status = 'active'
    """)
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_index(op.f('ix_supplier_quality_reviews_tenant_id'), table_name='supplier_quality_reviews')
    op.drop_index(op.f('ix_supplier_quality_reviews_supplier_id'), table_name='supplier_quality_reviews')
    op.drop_index(op.f('ix_supplier_quality_reviews_purchase_order_id'), table_name='supplier_quality_reviews')
    op.drop_index(op.f('ix_supplier_quality_reviews_delivery_id'), table_name='supplier_quality_reviews')
    op.drop_index('ix_quality_reviews_tenant_supplier', table_name='supplier_quality_reviews')
    op.drop_index('ix_quality_reviews_overall_rating', table_name='supplier_quality_reviews')
    op.drop_index('ix_quality_reviews_date', table_name='supplier_quality_reviews')
    op.drop_table('supplier_quality_reviews')
    op.drop_index('ix_supplier_alerts_type_severity', table_name='supplier_alerts')
    op.drop_index('ix_supplier_alerts_tenant_supplier', table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_tenant_id'), table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_supplier_id'), table_name='supplier_alerts')
    op.drop_index('ix_supplier_alerts_status_triggered', table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_status'), table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_severity'), table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_purchase_order_id'), table_name='supplier_alerts')
    op.drop_index('ix_supplier_alerts_priority', table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_metric_type'), table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_delivery_id'), table_name='supplier_alerts')
    op.drop_index(op.f('ix_supplier_alerts_alert_type'), table_name='supplier_alerts')
    op.drop_table('supplier_alerts')
    op.drop_index(op.f('ix_supplier_scorecards_tenant_id'), table_name='supplier_scorecards')
    op.drop_index(op.f('ix_supplier_scorecards_supplier_id'), table_name='supplier_scorecards')
    op.drop_index(op.f('ix_supplier_scorecards_period_start'), table_name='supplier_scorecards')
    op.drop_index(op.f('ix_supplier_scorecards_period_end'), table_name='supplier_scorecards')
    op.drop_index(op.f('ix_supplier_scorecards_period'), table_name='supplier_scorecards')
    op.drop_index('ix_scorecards_tenant_supplier', table_name='supplier_scorecards')
    op.drop_index('ix_scorecards_period_dates', table_name='supplier_scorecards')
    op.drop_index('ix_scorecards_period', table_name='supplier_scorecards')
    op.drop_index('ix_scorecards_overall_score', table_name='supplier_scorecards')
    op.drop_index('ix_scorecards_final', table_name='supplier_scorecards')
    op.drop_table('supplier_scorecards')
    op.drop_index(op.f('ix_supplier_price_lists_tenant_id'), table_name='supplier_price_lists')
    op.drop_index(op.f('ix_supplier_price_lists_supplier_id'), table_name='supplier_price_lists')
    op.drop_index(op.f('ix_supplier_price_lists_inventory_product_id'), table_name='supplier_price_lists')
    op.create_index('ix_price_lists_tenant_supplier', 'supplier_price_lists', ['tenant_id', 'supplier_id'], unique=False)
    op.drop_index('ix_price_lists_inventory_product', table_name='supplier_price_lists')
    op.drop_index('ix_price_lists_effective_date', table_name='supplier_price_lists')
    op.drop_index('ix_price_lists_active', table_name='supplier_price_lists')
    op.drop_table('supplier_price_lists')
    op.drop_index(op.f('ix_supplier_performance_metrics_tenant_id'), table_name='supplier_performance_metrics')
    op.drop_index(op.f('ix_supplier_performance_metrics_supplier_id'), table_name='supplier_performance_metrics')
    op.drop_index(op.f('ix_supplier_performance_metrics_period_start'), table_name='supplier_performance_metrics')
    op.drop_index(op.f('ix_supplier_performance_metrics_period_end'), table_name='supplier_performance_metrics')
    op.drop_index(op.f('ix_supplier_performance_metrics_period'), table_name='supplier_performance_metrics')
    op.drop_index(op.f('ix_supplier_performance_metrics_metric_type'), table_name='supplier_performance_metrics')
    op.drop_index('ix_performance_metrics_value', table_name='supplier_performance_metrics')
    op.drop_index('ix_performance_metrics_type_period', table_name='supplier_performance_metrics')
    op.drop_index('ix_performance_metrics_tenant_supplier', table_name='supplier_performance_metrics')
    op.drop_index('ix_performance_metrics_period_dates', table_name='supplier_performance_metrics')
    op.drop_table('supplier_performance_metrics')
    op.drop_index('ix_suppliers_auto_approve', table_name='suppliers')
    op.drop_index('ix_suppliers_preferred', table_name='suppliers')
    op.drop_index('ix_suppliers_trust_score', table_name='suppliers')
    op.drop_index('ix_suppliers_tenant_type', table_name='suppliers')
    op.drop_index('ix_suppliers_tenant_status', table_name='suppliers')
    op.drop_index('ix_suppliers_tenant_name', table_name='suppliers')
    op.drop_index(op.f('ix_suppliers_tenant_id'), table_name='suppliers')
    op.drop_index(op.f('ix_suppliers_supplier_type'), table_name='suppliers')
    op.drop_index(op.f('ix_suppliers_supplier_code'), table_name='suppliers')
    op.drop_index(op.f('ix_suppliers_status'), table_name='suppliers')
    op.drop_index('ix_suppliers_quality_rating', table_name='suppliers')
    op.drop_index(op.f('ix_suppliers_name'), table_name='suppliers')
    op.drop_table('suppliers')
    op.drop_index(op.f('ix_supplier_benchmarks_tenant_id'), table_name='supplier_benchmarks')
    op.drop_index(op.f('ix_supplier_benchmarks_supplier_category'), table_name='supplier_benchmarks')
    op.drop_index(op.f('ix_supplier_benchmarks_metric_type'), table_name='supplier_benchmarks')
    op.drop_index(op.f('ix_supplier_benchmarks_benchmark_type'), table_name='supplier_benchmarks')
    op.drop_index('ix_benchmarks_tenant_type', table_name='supplier_benchmarks')
    op.drop_index('ix_benchmarks_metric_type', table_name='supplier_benchmarks')
    op.drop_index('ix_benchmarks_category', table_name='supplier_benchmarks')
    op.drop_index('ix_benchmarks_active', table_name='supplier_benchmarks')
    op.drop_table('supplier_benchmarks')
    op.drop_index(op.f('ix_audit_logs_user_id'), table_name='audit_logs')
    op.drop_index(op.f('ix_audit_logs_tenant_id'), table_name='audit_logs')
    op.drop_index(op.f('ix_audit_logs_severity'), table_name='audit_logs')
    op.drop_index(op.f('ix_audit_logs_service_name'), table_name='audit_logs')
    op.drop_index(op.f('ix_audit_logs_resource_type'), table_name='audit_logs')
    op.drop_index(op.f('ix_audit_logs_resource_id'), table_name='audit_logs')
    op.drop_index(op.f('ix_audit_logs_created_at'), table_name='audit_logs')
    op.drop_index(op.f('ix_audit_logs_action'), table_name='audit_logs')
    op.drop_index('idx_audit_user_created', table_name='audit_logs')
    op.drop_index('idx_audit_tenant_created', table_name='audit_logs')
    op.drop_index('idx_audit_severity_created', table_name='audit_logs')
    op.drop_index('idx_audit_service_created', table_name='audit_logs')
    op.drop_index('idx_audit_resource_type_action', table_name='audit_logs')
    op.drop_table('audit_logs')
    op.drop_index('ix_alert_rules_type_severity', table_name='alert_rules')
    op.drop_index(op.f('ix_alert_rules_tenant_id'), table_name='alert_rules')
    op.drop_index('ix_alert_rules_tenant_active', table_name='alert_rules')
    op.drop_index('ix_alert_rules_priority', table_name='alert_rules')
    op.drop_index('ix_alert_rules_metric_type', table_name='alert_rules')
    op.drop_index(op.f('ix_alert_rules_alert_type'), table_name='alert_rules')
    op.drop_table('alert_rules')
    # ### end Alembic commands ###
