promote: dev → main (location bookmarks) #119
1 changed files with 28 additions and 0 deletions
|
|
@ -195,3 +195,31 @@ class PendingDigest(Base):
|
|||
# duplicating, which is what makes the form idempotent.
|
||||
UniqueConstraint("email", name="uq_pending_digest_email"),
|
||||
)
|
||||
|
||||
|
||||
class Bookmark(Base):
|
||||
"""A saved location, owned by a user — the "bookmarked locations" feature.
|
||||
|
||||
Keyed like ``Subscription`` on ``grid.snap(lat, lon)["id"]``: one bookmark per
|
||||
(user, cell), so re-bookmarking the same cell is an upsert of the label rather
|
||||
than a duplicate row (see ``create_bookmark`` / ``import_bookmarks`` in
|
||||
api_accounts.py, which enforce this at the application layer too).
|
||||
"""
|
||||
__tablename__ = "bookmark"
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
user_id: Mapped[uuid.UUID] = mapped_column(
|
||||
GUID, ForeignKey("user.id", ondelete="CASCADE"), nullable=False
|
||||
)
|
||||
# grid.snap(lat, lon)["id"] — the stable per-location key used across the app.
|
||||
cell_id: Mapped[str] = mapped_column(String(40), nullable=False)
|
||||
label: Mapped[str] = mapped_column(String(80), nullable=False)
|
||||
lat: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
lon: Mapped[float] = mapped_column(Float, nullable=False)
|
||||
created_at: Mapped[float] = mapped_column(Float, nullable=False, default=time.time)
|
||||
|
||||
__table_args__ = (
|
||||
# One bookmark per location per user — re-bookmarking upserts the label.
|
||||
UniqueConstraint("user_id", "cell_id", name="uq_bookmark_user_cell"),
|
||||
Index("idx_bookmark_user", "user_id"),
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue