Coverage for src/couchers/models/mod_note.py: 95%
22 statements
« prev ^ index » next coverage.py v7.11.0, created at 2025-12-25 10:58 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2025-12-25 10:58 +0000
1from datetime import datetime
2from typing import TYPE_CHECKING
4from sqlalchemy import BigInteger, DateTime, ForeignKey, Index, String, func
5from sqlalchemy.ext.hybrid import hybrid_property
6from sqlalchemy.orm import Mapped, backref, mapped_column, relationship
8from couchers.models.base import Base
10if TYPE_CHECKING:
11 from couchers.models.users import User
14class ModNote(Base):
15 """
16 A moderator note to a user. This could be a warning, just a note "hey, we did X", or any other similar message.
18 The user has to read and "acknowledge" the note before continuing onto the platform, and being un-jailed.
19 """
21 __tablename__ = "mod_notes"
23 id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
24 user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True)
26 created: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now())
27 acknowledged: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
29 # this is an internal ID to allow the mods to track different types of notes
30 internal_id: Mapped[str] = mapped_column(String)
31 # the admin that left this note
32 creator_user_id: Mapped[int] = mapped_column(ForeignKey("users.id"))
34 note_content: Mapped[str] = mapped_column(String) # CommonMark without images
36 user: Mapped["User"] = relationship(
37 "User", foreign_keys="ModNote.user_id", backref=backref("mod_notes", lazy="dynamic")
38 )
40 def __repr__(self) -> str:
41 return f"ModeNote(id={self.id}, user={self.user}, created={self.created}, ack'd={self.acknowledged})"
43 @hybrid_property
44 def is_pending(self) -> bool:
45 return self.acknowledged == None
47 __table_args__ = (
48 # used to look up pending notes
49 Index(
50 "ix_mod_notes_unacknowledged",
51 user_id,
52 postgresql_where=acknowledged == None,
53 ),
54 )