from sqlalchemy import Column, String, Float, Integer, Boolean, DateTime, Date, ForeignKey, CheckConstraint, Enum from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.sql import func import enum Base = declarative_base() class ReservationOutcome(str, enum.Enum): SUCCESS = "success" LOCK_TIMEOUT = "lock_timeout" INSUFFICIENT_STOCK = "insufficient_stock" class DarkStore(Base): __tablename__ = 'dark_stores' id = Column(String(50), primary_key=True) name = Column(String(100), nullable=False) city = Column(String(100), nullable=False) lat = Column(Float, nullable=False) lng = Column(Float, nullable=False) class Inventory(Base): __tablename__ = 'inventory' store_id = Column(String(50), ForeignKey('dark_stores.id'), primary_key=True) sku_id = Column(String(50), primary_key=True) sku_name = Column(String(100), nullable=False) qty_available = Column(Integer, nullable=False) __table_args__ = ( CheckConstraint('qty_available >= 0', name='check_qty_positive'), ) class SalesEvent(Base): __tablename__ = 'sales_events' id = Column(Integer, primary_key=True, autoincrement=True) store_id = Column(String(50), ForeignKey('dark_stores.id'), nullable=False) sku_id = Column(String(50), nullable=False) observed_sales = Column(Float, nullable=False) censored = Column(Boolean, default=False, nullable=False) oos_time = Column(DateTime(timezone=True), nullable=True) event_date = Column(Date, nullable=False) hour_bucket = Column(Integer, nullable=False) weather_temp = Column(Float, nullable=True) weather_rain = Column(Float, nullable=True) time_elapsed_sec = Column(Float, nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) class ForecastResult(Base): __tablename__ = 'forecast_results' id = Column(Integer, primary_key=True, autoincrement=True) store_id = Column(String(50), ForeignKey('dark_stores.id'), nullable=False) sku_id = Column(String(50), nullable=False) horizon_hours = Column(Integer, nullable=False) point_forecast = Column(Float, nullable=False) ci_lower = Column(Float, nullable=False) ci_upper = Column(Float, nullable=False) safety_stock_units = Column(Float, nullable=False) restock_recommended = Column(Boolean, nullable=False) model_version = Column(String(50), nullable=False) class InventoryReservation(Base): __tablename__ = 'inventory_reservations' id = Column(Integer, primary_key=True, autoincrement=True) order_id = Column(String(100), nullable=False) store_id = Column(String(50), ForeignKey('dark_stores.id'), nullable=False) sku_id = Column(String(50), nullable=False) qty_requested = Column(Integer, nullable=False) outcome = Column(Enum(ReservationOutcome), nullable=False) latency_ms = Column(Float, nullable=False) timestamp = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) class OutboxEvent(Base): __tablename__ = 'outbox_events' id = Column(Integer, primary_key=True, autoincrement=True) event_type = Column(String(50), nullable=False) payload = Column(String(1000), nullable=False) processed = Column(Boolean, default=False, nullable=False) timestamp = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) class Restaurant(Base): __tablename__ = 'restaurants' id = Column(String(50), primary_key=True) name = Column(String(100), nullable=False) cuisine = Column(String(100), nullable=False) rating = Column(Float, nullable=False) distance = Column(String(50), nullable=False) time = Column(String(50), nullable=False) slaConfidence = Column(Integer, default=95) isAIPick = Column(Boolean, default=False) isExclusive = Column(Boolean, default=False) image = Column(String(500), nullable=True) class Coupon(Base): __tablename__ = 'coupons' code = Column(String(50), primary_key=True) discount_percentage = Column(Integer, nullable=False) min_cart_value = Column(Float, nullable=False) active = Column(Boolean, default=True) class DineoutReservation(Base): __tablename__ = 'dineout_reservations' id = Column(Integer, primary_key=True, autoincrement=True) customer_name = Column(String(100), nullable=False) restaurant_id = Column(String(50), nullable=False) time_slot = Column(String(50), nullable=False) guests = Column(Integer, nullable=False) class ExpenseLog(Base): __tablename__ = 'expense_logs' id = Column(Integer, primary_key=True, autoincrement=True) category = Column(String(100), nullable=False) amount = Column(Float, nullable=False) description = Column(String(500), nullable=True) timestamp = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) class SystemSetting(Base): __tablename__ = 'system_settings' key = Column(String(100), primary_key=True) value = Column(String(500), nullable=False) class PriceHistory(Base): __tablename__ = 'price_history' id = Column(Integer, primary_key=True, autoincrement=True) product_id = Column(String(100), nullable=False) product_name = Column(String(200), nullable=False) price_inr = Column(Float, nullable=False) source = Column(String(50), default="instamart") captured_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) day_of_week = Column(Integer, nullable=False) hour_of_day = Column(Integer, nullable=False) class RefundPrediction(Base): __tablename__ = 'refund_predictions' id = Column(Integer, primary_key=True, autoincrement=True) order_id = Column(String(100), nullable=False) complaint_type = Column(String(100), nullable=False) predicted_outcome = Column(String(50), nullable=False) fraud_probability = Column(Float, nullable=False) actual_outcome = Column(String(50), nullable=True) created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) class ETAEvent(Base): __tablename__ = 'eta_events' id = Column(Integer, primary_key=True, autoincrement=True) order_id = Column(String(100), nullable=False) raw_eta_min = Column(Integer, nullable=False) smoothed_eta_min = Column(Integer, nullable=True) is_jitter = Column(Boolean, nullable=True) captured_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)