Coverage for app / backend / src / couchers / models / public_trips.py: 100%
23 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-22 07:30 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-22 07:30 +0000
1import enum
2from datetime import date, datetime
3from typing import TYPE_CHECKING
5from sqlalchemy import BigInteger, CheckConstraint, Date, DateTime, Enum, ForeignKey, Index, String, func
6from sqlalchemy.orm import Mapped, mapped_column, relationship
8from couchers.models.base import Base
10if TYPE_CHECKING:
11 from couchers.models import Node, User
12 from couchers.models.host_requests import HostRequest
15class PublicTripStatus(enum.Enum):
16 searching_for_host = enum.auto()
17 closed = enum.auto()
20class PublicTrip(Base, kw_only=True):
21 """
22 A public trip posted by a traveler looking for a host in a community.
23 """
25 __tablename__ = "public_trips"
27 id: Mapped[int] = mapped_column(BigInteger, primary_key=True, init=False)
29 # The traveler posting the trip
30 user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True)
32 # The community/location (city-level node)
33 node_id: Mapped[int] = mapped_column(ForeignKey("nodes.id"), index=True)
35 # Trip dates
36 from_date: Mapped[date] = mapped_column(Date)
37 to_date: Mapped[date] = mapped_column(Date)
39 # User's message about their trip
40 description: Mapped[str] = mapped_column(String)
42 # Current status
43 status: Mapped[PublicTripStatus] = mapped_column(
44 Enum(PublicTripStatus), default=PublicTripStatus.searching_for_host
45 )
47 # Timestamps
48 created: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), init=False)
50 # Relationships
51 user: Mapped[User] = relationship(init=False, back_populates="public_trips")
52 node: Mapped[Node] = relationship(init=False, back_populates="public_trips")
53 host_requests: Mapped[list[HostRequest]] = relationship(init=False, back_populates="public_trip")
55 __table_args__ = (
56 # Ensure from_date is not after to_date
57 CheckConstraint("from_date <= to_date", name="valid_date_range"),
58 # Index for querying active trips in a community
59 # Using partial index since we mostly query for active trips
60 Index(
61 "ix_public_trips_node_from_date_active",
62 node_id,
63 from_date,
64 postgresql_where=status == PublicTripStatus.searching_for_host,
65 ),
66 )