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

20 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-11-08 00:20 +0000

1from sqlalchemy import BigInteger, Column, DateTime, ForeignKey, Index, String, func 

2from sqlalchemy.ext.hybrid import hybrid_property 

3from sqlalchemy.orm import backref, relationship 

4 

5from couchers.models.base import Base 

6 

7 

8class ModNote(Base): 

9 """ 

10 A moderator note to a user. This could be a warning, just a note "hey, we did X", or any other similar message. 

11 

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

13 """ 

14 

15 __tablename__ = "mod_notes" 

16 id = Column(BigInteger, primary_key=True) 

17 

18 user_id = Column(ForeignKey("users.id"), nullable=False, index=True) 

19 

20 created = Column(DateTime(timezone=True), nullable=False, server_default=func.now()) 

21 acknowledged = Column(DateTime(timezone=True), nullable=True) 

22 

23 # this is an internal ID to allow the mods to track different types of notes 

24 internal_id = Column(String, nullable=False) 

25 # the admin that left this note 

26 creator_user_id = Column(ForeignKey("users.id"), nullable=False) 

27 

28 note_content = Column(String, nullable=False) # CommonMark without images 

29 

30 user = relationship("User", backref=backref("mod_notes", lazy="dynamic"), foreign_keys="ModNote.user_id") 

31 

32 def __repr__(self): 

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

34 

35 @hybrid_property 

36 def is_pending(self): 

37 return self.acknowledged == None 

38 

39 __table_args__ = ( 

40 # used to look up pending notes 

41 Index( 

42 "ix_mod_notes_unacknowledged", 

43 user_id, 

44 postgresql_where=acknowledged == None, 

45 ), 

46 )