Spaces:
Sleeping
Sleeping
File size: 9,773 Bytes
5ff3858 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | 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")
@property
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")
@property
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()
|