from sqlalchemy import ( Column, String, Date, Boolean, ForeignKey, Table, UniqueConstraint, ) from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.orm import relationship import uuid from backend.database import Base # Association table for Item <-> Tag item_tag_table = Table( "item_tag", Base.metadata, Column("item_id", UUID(as_uuid=True), ForeignKey("item.id", ondelete="CASCADE"), primary_key=True), Column("tag_id", UUID(as_uuid=True), ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True), ) # Association tables for Trip <-> Tag trip_selected_tag_table = Table( "trip_selected_tag", Base.metadata, Column("trip_id", UUID(as_uuid=True), ForeignKey("trip.id", ondelete="CASCADE"), primary_key=True), Column("tag_id", UUID(as_uuid=True), ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True), ) trip_marked_tag_table = Table( "trip_marked_tag", Base.metadata, Column("trip_id", UUID(as_uuid=True), ForeignKey("trip.id", ondelete="CASCADE"), primary_key=True), Column("tag_id", UUID(as_uuid=True), ForeignKey("tag.id", ondelete="CASCADE"), primary_key=True), ) class User(Base): __tablename__ = "user" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) name = Column(String, nullable=False) class Tag(Base): __tablename__ = "tag" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id = Column(UUID(as_uuid=True), ForeignKey("user.id", ondelete="CASCADE"), nullable=False) name = Column(String, nullable=False) mandatory = Column(Boolean, nullable=False, default=False) user = relationship("User", backref="tags") __table_args__ = ( UniqueConstraint("user_id", "name", name="uq_tag_user_name"), ) class Item(Base): __tablename__ = "item" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id = Column(UUID(as_uuid=True), ForeignKey("user.id", ondelete="CASCADE"), nullable=False) name = Column(String, nullable=False) user = relationship("User", backref="items") tags = relationship("Tag", secondary=item_tag_table, backref="items") trip_items = relationship("TripItem", back_populates="item", cascade="all, delete-orphan") class Trip(Base): __tablename__ = "trip" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) user_id = Column(UUID(as_uuid=True), ForeignKey("user.id", ondelete="CASCADE"), nullable=False) name = Column(String, nullable=True) start_date = Column(Date, nullable=False) end_date = Column(Date, nullable=False) selected_tags = relationship("Tag", secondary=trip_selected_tag_table, backref="selected_in_trips", cascade="all, delete") marked_tags = relationship("Tag", secondary=trip_marked_tag_table, backref="marked_in_trips", cascade="all, delete") class TripItem(Base): __tablename__ = "trip_item" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) trip_id = Column(UUID(as_uuid=True), ForeignKey("trip.id", ondelete="CASCADE"), nullable=False) item_id = Column(UUID(as_uuid=True), ForeignKey("item.id", ondelete="CASCADE"), nullable=False) name_calculated = Column(String, nullable=False) checked = Column(Boolean, nullable=False, default=False) tag_id = Column(UUID(as_uuid=True), ForeignKey("tag.id"), nullable=True) trip = relationship("Trip", backref="trip_items") item = relationship("Item", back_populates="trip_items") tag = relationship("Tag", backref="trip_items")