Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| from datetime import date, datetime | |
| from typing import Any | |
| from sqlalchemy import ( | |
| JSON, | |
| Boolean, | |
| Date, | |
| DateTime, | |
| Float, | |
| ForeignKey, | |
| Integer, | |
| String, | |
| Text, | |
| ) | |
| from sqlalchemy.orm import Mapped, mapped_column, relationship | |
| from app.database import Base | |
| class User(Base): | |
| __tablename__ = "users" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| name: Mapped[str] = mapped_column(String(120), nullable=False) | |
| email: Mapped[str] = mapped_column(String(255), unique=True, index=True, nullable=False) | |
| password: Mapped[str] = mapped_column(String(120), nullable=False) | |
| is_host: Mapped[bool] = mapped_column(Boolean, default=False, nullable=False) | |
| hometown: Mapped[str] = mapped_column(String(120), default="", nullable=False) | |
| bio: Mapped[str] = mapped_column(Text, default="", nullable=False) | |
| avatar_url: Mapped[str] = mapped_column(String(500), default="", nullable=False) | |
| listings: Mapped[list["Listing"]] = relationship(back_populates="host") | |
| bookings: Mapped[list["Booking"]] = relationship(back_populates="guest") | |
| wishlist_items: Mapped[list["WishlistItem"]] = relationship(back_populates="user") | |
| reviews: Mapped[list["Review"]] = relationship(back_populates="user") | |
| sent_messages: Mapped[list["Message"]] = relationship(back_populates="sender") | |
| class Listing(Base): | |
| __tablename__ = "listings" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| slug: Mapped[str] = mapped_column(String(150), unique=True, index=True, nullable=False) | |
| host_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| title: Mapped[str] = mapped_column(String(200), nullable=False) | |
| city: Mapped[str] = mapped_column(String(120), index=True, nullable=False) | |
| country: Mapped[str] = mapped_column(String(120), nullable=False) | |
| neighborhood: Mapped[str] = mapped_column(String(120), nullable=False) | |
| price_per_night: Mapped[float] = mapped_column(Float, nullable=False) | |
| cleaning_fee: Mapped[float] = mapped_column(Float, default=0, nullable=False) | |
| service_fee: Mapped[float] = mapped_column(Float, default=0, nullable=False) | |
| bedrooms: Mapped[int] = mapped_column(Integer, default=1, nullable=False) | |
| beds: Mapped[int] = mapped_column(Integer, default=1, nullable=False) | |
| baths: Mapped[float] = mapped_column(Float, default=1, nullable=False) | |
| max_guests: Mapped[int] = mapped_column(Integer, default=2, nullable=False) | |
| rating: Mapped[float] = mapped_column(Float, default=5.0, nullable=False) | |
| review_count: Mapped[int] = mapped_column(Integer, default=0, nullable=False) | |
| description: Mapped[str] = mapped_column(Text, default="", nullable=False) | |
| amenities: Mapped[list[str]] = mapped_column(JSON, default=list, nullable=False) | |
| house_rules: Mapped[list[str]] = mapped_column(JSON, default=list, nullable=False) | |
| blocked_ranges: Mapped[list[dict[str, str]]] = mapped_column(JSON, default=list, nullable=False) | |
| host: Mapped[User] = relationship(back_populates="listings") | |
| images: Mapped[list["ListingImage"]] = relationship( | |
| back_populates="listing", | |
| cascade="all, delete-orphan", | |
| order_by="ListingImage.display_order", | |
| ) | |
| reviews: Mapped[list["Review"]] = relationship( | |
| back_populates="listing", | |
| cascade="all, delete-orphan", | |
| order_by="desc(Review.created_at)", | |
| ) | |
| bookings: Mapped[list["Booking"]] = relationship(back_populates="listing") | |
| availability_entries: Mapped[list["Availability"]] = relationship( | |
| back_populates="listing", | |
| cascade="all, delete-orphan", | |
| ) | |
| wishlist_items: Mapped[list["WishlistItem"]] = relationship(back_populates="listing") | |
| threads: Mapped[list["MessageThread"]] = relationship(back_populates="listing") | |
| def primary_image(self) -> str: | |
| if self.images: | |
| return self.images[0].url | |
| return "https://images.unsplash.com/photo-1505693416388-ac5ce068fe85?auto=format&fit=crop&w=1200&q=80" | |
| class ListingImage(Base): | |
| __tablename__ = "listing_images" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| listing_id: Mapped[int] = mapped_column(ForeignKey("listings.id"), nullable=False) | |
| url: Mapped[str] = mapped_column(String(500), nullable=False) | |
| alt_text: Mapped[str] = mapped_column(String(255), default="", nullable=False) | |
| display_order: Mapped[int] = mapped_column(Integer, default=0, nullable=False) | |
| listing: Mapped[Listing] = relationship(back_populates="images") | |
| class Availability(Base): | |
| __tablename__ = "availability" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| listing_id: Mapped[int] = mapped_column(ForeignKey("listings.id"), index=True, nullable=False) | |
| date: Mapped[date] = mapped_column(Date, index=True, nullable=False) | |
| is_available: Mapped[bool] = mapped_column(Boolean, default=True, nullable=False) | |
| listing: Mapped[Listing] = relationship(back_populates="availability_entries") | |
| class Review(Base): | |
| __tablename__ = "reviews" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| listing_id: Mapped[int] = mapped_column(ForeignKey("listings.id"), nullable=False) | |
| user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| rating: Mapped[float] = mapped_column(Float, nullable=False) | |
| comment: Mapped[str] = mapped_column(Text, nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| listing: Mapped[Listing] = relationship(back_populates="reviews") | |
| user: Mapped[User] = relationship(back_populates="reviews") | |
| class Booking(Base): | |
| __tablename__ = "bookings" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| confirmation_code: Mapped[str] = mapped_column(String(50), unique=True, nullable=False) | |
| listing_id: Mapped[int] = mapped_column(ForeignKey("listings.id"), nullable=False) | |
| guest_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| check_in: Mapped[date] = mapped_column(Date, nullable=False) | |
| check_out: Mapped[date] = mapped_column(Date, nullable=False) | |
| guests: Mapped[int] = mapped_column(Integer, nullable=False) | |
| total_price: Mapped[float] = mapped_column(Float, nullable=False) | |
| status: Mapped[str] = mapped_column(String(40), default="confirmed", nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| listing: Mapped[Listing] = relationship(back_populates="bookings") | |
| guest: Mapped[User] = relationship(back_populates="bookings") | |
| def nights(self) -> int: | |
| return (self.check_out - self.check_in).days | |
| class WishlistItem(Base): | |
| __tablename__ = "wishlist_items" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| listing_id: Mapped[int] = mapped_column(ForeignKey("listings.id"), nullable=False) | |
| notes: Mapped[str] = mapped_column(Text, default="", nullable=False) | |
| user: Mapped[User] = relationship(back_populates="wishlist_items") | |
| listing: Mapped[Listing] = relationship(back_populates="wishlist_items") | |
| class MessageThread(Base): | |
| __tablename__ = "message_threads" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| listing_id: Mapped[int] = mapped_column(ForeignKey("listings.id"), nullable=False) | |
| guest_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| host_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| subject: Mapped[str] = mapped_column(String(200), nullable=False) | |
| last_message_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| listing: Mapped[Listing] = relationship(back_populates="threads") | |
| guest: Mapped[User] = relationship(foreign_keys=[guest_id]) | |
| host: Mapped[User] = relationship(foreign_keys=[host_id]) | |
| messages: Mapped[list["Message"]] = relationship( | |
| back_populates="thread", | |
| cascade="all, delete-orphan", | |
| order_by="Message.created_at", | |
| ) | |
| class Message(Base): | |
| __tablename__ = "messages" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| thread_id: Mapped[int] = mapped_column(ForeignKey("message_threads.id"), nullable=False) | |
| sender_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| body: Mapped[str] = mapped_column(Text, nullable=False) | |
| created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, nullable=False) | |
| thread: Mapped[MessageThread] = relationship(back_populates="messages") | |
| sender: Mapped[User] = relationship(back_populates="sent_messages") | |
| class TaskDefinition(Base): | |
| __tablename__ = "task_definitions" | |
| id: Mapped[int] = mapped_column(Integer, primary_key=True) | |
| slug: Mapped[str] = mapped_column(String(120), unique=True, nullable=False) | |
| title: Mapped[str] = mapped_column(String(200), nullable=False) | |
| category: Mapped[str] = mapped_column(String(120), nullable=False) | |
| difficulty: Mapped[str] = mapped_column(String(50), nullable=False) | |
| start_path: Mapped[str] = mapped_column(String(255), default="/", nullable=False) | |
| persona_user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False) | |
| intent: Mapped[str] = mapped_column(Text, nullable=False) | |
| success_criteria: Mapped[str] = mapped_column(Text, nullable=False) | |
| validator_key: Mapped[str] = mapped_column(String(80), nullable=False) | |
| validation_target: Mapped[dict[str, Any]] = mapped_column(JSON, default=dict, nullable=False) | |
| persona: Mapped[User] = relationship() | |