Coverage for src / local_deep_research / database / models / active_research.py: 94%

17 statements  

« prev     ^ index     » next       coverage.py v7.12.0, created at 2026-01-11 00:51 +0000

1""" 

2Model for tracking active research processes per user. 

3 

4As noted by djpetti: "Is there a reason this isn't in `models.py`?" 

5Response: The codebase follows a domain-driven organization where models are 

6separated into individual files by functionality (auth.py, cache.py, research.py, etc.) 

7rather than a single models.py file. This provides better maintainability and follows 

8the established pattern in the models/ directory. 

9""" 

10 

11from sqlalchemy import JSON, Boolean, Column, Index, Integer, String 

12from sqlalchemy_utc import UtcDateTime, utcnow 

13 

14from .base import Base 

15 

16 

17class UserActiveResearch(Base): 

18 """ 

19 Track active research processes for each user. 

20 Allows multiple concurrent researches per user. 

21 """ 

22 

23 __tablename__ = "user_active_researches" 

24 

25 # Composite primary key: username + research_id 

26 username = Column(String(100), primary_key=True) 

27 research_id = Column(String(36), primary_key=True) # UUID 

28 

29 # Status tracking 

30 status = Column(String(50), default="in_progress") 

31 started_at = Column(UtcDateTime, server_default=utcnow(), nullable=False) 

32 last_heartbeat = Column( 

33 UtcDateTime, server_default=utcnow(), nullable=False 

34 ) 

35 

36 # Process information 

37 thread_id = Column(String(100)) # Thread identifier 

38 pid = Column(Integer) # Process ID if using multiprocessing 

39 

40 # Settings snapshot 

41 settings_snapshot = Column(JSON) # Complete settings used for this research 

42 

43 # Termination flag 

44 termination_requested = Column(Boolean, default=False) 

45 

46 # Indexes for performance 

47 __table_args__ = ( 

48 Index("idx_user_active_research", "username", "status"), 

49 Index("idx_research_heartbeat", "last_heartbeat"), 

50 ) 

51 

52 def __repr__(self): 

53 return f"<UserActiveResearch(user='{self.username}', research='{self.research_id}', status='{self.status}')>"