# services/tenant/app/models/tenants.py - FIXED VERSION """ Tenant models for bakery management - FIXED Removed cross-service User relationship to eliminate circular dependencies """ from sqlalchemy import Column, String, Boolean, DateTime, Float, ForeignKey, Text, Integer, JSON from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship from datetime import datetime, timezone import uuid from shared.database.base import Base class Tenant(Base): """Tenant/Bakery model""" __tablename__ = "tenants" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column(String(200), nullable=False) subdomain = Column(String(100), unique=True) business_type = Column(String(100), default="bakery") business_model = Column(String(100), default="individual_bakery") # individual_bakery, central_baker_satellite, retail_bakery, hybrid_bakery # Location info address = Column(Text, nullable=False) city = Column(String(100), default="Madrid") postal_code = Column(String(10), nullable=False) latitude = Column(Float) longitude = Column(Float) # Contact info phone = Column(String(20)) email = Column(String(255)) # Status is_active = Column(Boolean, default=True) subscription_tier = Column(String(50), default="starter") # ML status ml_model_trained = Column(Boolean, default=False) last_training_date = Column(DateTime(timezone=True)) # Ownership (user_id without FK - cross-service reference) owner_id = Column(UUID(as_uuid=True), nullable=False, index=True) # Timestamps created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) # Relationships - only within tenant service members = relationship("TenantMember", back_populates="tenant", cascade="all, delete-orphan") # REMOVED: users relationship - no cross-service SQLAlchemy relationships def __repr__(self): return f"" class TenantMember(Base): """Tenant membership model for team access""" __tablename__ = "tenant_members" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False) user_id = Column(UUID(as_uuid=True), nullable=False, index=True) # No FK - cross-service reference # Role and permissions specific to this tenant role = Column(String(50), default="member") # owner, admin, member, viewer permissions = Column(Text) # JSON string of permissions # Status is_active = Column(Boolean, default=True) invited_by = Column(UUID(as_uuid=True)) # No FK - cross-service reference invited_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) joined_at = Column(DateTime(timezone=True)) created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) # Relationships - only within tenant service tenant = relationship("Tenant", back_populates="members") # REMOVED: user relationship - no cross-service SQLAlchemy relationships def __repr__(self): return f"" # Additional models for subscriptions, plans, etc. class Subscription(Base): """Subscription model for tenant billing""" __tablename__ = "subscriptions" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) tenant_id = Column(UUID(as_uuid=True), ForeignKey("tenants.id", ondelete="CASCADE"), nullable=False) plan = Column(String(50), default="starter") # starter, professional, enterprise status = Column(String(50), default="active") # active, suspended, cancelled # Billing monthly_price = Column(Float, default=0.0) billing_cycle = Column(String(20), default="monthly") # monthly, yearly next_billing_date = Column(DateTime(timezone=True)) trial_ends_at = Column(DateTime(timezone=True)) # Limits max_users = Column(Integer, default=5) max_locations = Column(Integer, default=1) max_products = Column(Integer, default=50) # Features - Store plan features as JSON features = Column(JSON) # Timestamps created_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc)) updated_at = Column(DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), onupdate=lambda: datetime.now(timezone.utc)) # Relationships tenant = relationship("Tenant") def __repr__(self): return f""