Coverage for app / backend / src / couchers / models / mod_note.py: 95%

22 statements  

« prev     ^ index     » next       coverage.py v7.13.2, created at 2026-02-03 06:18 +0000

1from datetime import datetime 

2from typing import TYPE_CHECKING 

3 

4from sqlalchemy import BigInteger, DateTime, ForeignKey, Index, String, func 

5from sqlalchemy.ext.hybrid import hybrid_property 

6from sqlalchemy.orm import Mapped, mapped_column, relationship 

7 

8from couchers.models.base import Base 

9 

10if TYPE_CHECKING: 

11 from couchers.models.users import User 

12 

13 

14class ModNote(Base, kw_only=True): 

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. 

17 

18 The user has to read and "acknowledge" the note before continuing onto the platform, and being un-jailed. 

19 """ 

20 

21 __tablename__ = "mod_notes" 

22 

23 id: Mapped[int] = mapped_column(BigInteger, primary_key=True, init=False) 

24 user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), index=True) 

25 

26 created: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now(), init=False) 

27 acknowledged: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), default=None) 

28 

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")) 

33 

34 note_content: Mapped[str] = mapped_column(String) # CommonMark without images 

35 

36 user: Mapped[User] = relationship(init=False, foreign_keys="ModNote.user_id", back_populates="mod_notes") 

37 

38 def __repr__(self) -> str: 

39 return f"ModeNote(id={self.id}, user={self.user}, created={self.created}, ack'd={self.acknowledged})" 

40 

41 @hybrid_property 

42 def is_pending(self) -> bool: 

43 return self.acknowledged == None 

44 

45 __table_args__ = ( 

46 # used to look up pending notes 

47 Index( 

48 "ix_mod_notes_unacknowledged", 

49 user_id, 

50 postgresql_where=acknowledged == None, 

51 ), 

52 )