schema update and case manager addition
This commit is contained in:
		
							parent
							
								
									172de21f55
								
							
						
					
					
						commit
						c6d0192fa8
					
				
							
								
								
									
										107
									
								
								src/forensictrails/core/case_manager.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								src/forensictrails/core/case_manager.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,107 @@
 | 
				
			|||||||
 | 
					import config
 | 
				
			||||||
 | 
					from db.database import get_db_connection
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					import datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class CaseManager(case_id=None, case_title=None, investigator=None, classification=None, summary=None):
 | 
				
			||||||
 | 
					    def __init__(self, db_path=None, case_id=None, case_title=None, investigator=None, classification=None, summary=None):
 | 
				
			||||||
 | 
					        if db_path is None:
 | 
				
			||||||
 | 
					            db_path = config.database_path
 | 
				
			||||||
 | 
					        self.db_path = db_path
 | 
				
			||||||
 | 
					        self.conn = get_db_connection(self.db_path)
 | 
				
			||||||
 | 
					        self.cursor = self.conn.cursor()
 | 
				
			||||||
 | 
					        logging.debug(f"Connected to database at {self.db_path}")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        self.case_id = case_id
 | 
				
			||||||
 | 
					        self.case_title = case_title
 | 
				
			||||||
 | 
					        self.investigator = investigator
 | 
				
			||||||
 | 
					        self.classification = classification
 | 
				
			||||||
 | 
					        self.summary = summary
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    def create_case(self, case_id, case_title, investigator, classification=None, summary=None):
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            self.cursor.execute("""
 | 
				
			||||||
 | 
					                INSERT INTO cases (case_id, case_title, investigator, classification, summary, status)
 | 
				
			||||||
 | 
					                VALUES (?, ?, ?, ?, ?, 'active')
 | 
				
			||||||
 | 
					            """, (case_id, case_title, investigator, classification, summary))
 | 
				
			||||||
 | 
					            logging.info(f"Created new case with ID: {case_id}")
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def list_cases(self, status=None, search_term=None):
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            query = "SELECT * FROM cases WHERE 1=1"
 | 
				
			||||||
 | 
					            params = []
 | 
				
			||||||
 | 
					            conditions = []
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            if status:
 | 
				
			||||||
 | 
					                query += " AND status = ?"
 | 
				
			||||||
 | 
					                params.append(status)
 | 
				
			||||||
 | 
					            if search_term:
 | 
				
			||||||
 | 
					                query += " AND (case_id LIKE ? OR case_title LIKE ? OR investigator LIKE ?)"
 | 
				
			||||||
 | 
					                like_term = f"%{search_term}%"
 | 
				
			||||||
 | 
					                params.extend([like_term, like_term, like_term])
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					            query += " ORDER BY created_at DESC"
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            self.cursor.execute(query, params)
 | 
				
			||||||
 | 
					            return [dict(row) for row in self.cursor.fetchall()]
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def update_case(self, case_id, **kwargs):
 | 
				
			||||||
 | 
					        allowed_fields = ['case_title', 'investigator', 'classification', 'summary', 'status']
 | 
				
			||||||
 | 
					        updates = {k: v for k, v in kwargs.items() if k in allowed_fields}
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if not updates:
 | 
				
			||||||
 | 
					            logging.warning("No valid fields provided for update.")
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        updates['modified_at'] = datetime.utcnow().isoformat()
 | 
				
			||||||
 | 
					        set_clause = ", ".join([f"{k} = ?" for k in updates.keys()])
 | 
				
			||||||
 | 
					        values = list(updates.values()) + [case_id]
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            self.cursor.execute(f"""
 | 
				
			||||||
 | 
					                UPDATE cases
 | 
				
			||||||
 | 
					                SET {set_clause}
 | 
				
			||||||
 | 
					                WHERE case_id = ?
 | 
				
			||||||
 | 
					            """, values)
 | 
				
			||||||
 | 
					            logging.info(f"Updated case with ID: {case_id}")
 | 
				
			||||||
 | 
					            return self.cursor.rowcount > 0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def close_case(self, case_id):
 | 
				
			||||||
 | 
					        return self.update_case(case_id, status='closed')
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def delete_case(self, case_id):
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            self.cursor.execute("DELETE FROM cases WHERE case_id = ?", (case_id,))
 | 
				
			||||||
 | 
					            logging.info(f"Deleted case with ID: {case_id}")
 | 
				
			||||||
 | 
					            return self.cursor.rowcount > 0
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def archive_case(self, case_id):
 | 
				
			||||||
 | 
					        return self.update_case(case_id, status='archived')
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def export_case_db(self, case_id, export_path):
 | 
				
			||||||
 | 
					        with self.conn:
 | 
				
			||||||
 | 
					            self.cursor.execute("SELECT * FROM cases WHERE case_id = ?", (case_id,))
 | 
				
			||||||
 | 
					            case = self.cursor.fetchone()
 | 
				
			||||||
 | 
					            if not case:
 | 
				
			||||||
 | 
					                logging.error(f"No case found with ID: {case_id}")
 | 
				
			||||||
 | 
					                return False
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            with open(export_path, 'w') as f:
 | 
				
			||||||
 | 
					                for key in case.keys():
 | 
				
			||||||
 | 
					                    f.write(f"{key}: {case[key]}\n")
 | 
				
			||||||
 | 
					            logging.info(f"Exported case {case_id} to {export_path}")
 | 
				
			||||||
 | 
					            return True
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def import_case_db(self, import_path):
 | 
				
			||||||
 | 
					        with open(import_path, 'r') as f:
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                with open(config.database_path, 'w') as db_file:
 | 
				
			||||||
 | 
					                    db_file.write(f.read())
 | 
				
			||||||
 | 
					                    get_db_connection(config.database_path)
 | 
				
			||||||
 | 
					                logging.info(f"Imported case database from {import_path}")
 | 
				
			||||||
 | 
					                return True
 | 
				
			||||||
 | 
					            except Exception as e:
 | 
				
			||||||
 | 
					                logging.error(f"Failed to import case database: {e}")
 | 
				
			||||||
 | 
					                return False
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
@ -1,12 +1,12 @@
 | 
				
			|||||||
-- Cases table
 | 
					-- Cases table
 | 
				
			||||||
CREATE TABLE cases (
 | 
					CREATE TABLE cases (
 | 
				
			||||||
  case_id TEXT PRIMARY KEY,
 | 
					  case_id TEXT PRIMARY KEY,
 | 
				
			||||||
  title TEXT NOT NULL,
 | 
					  case_title TEXT NOT NULL,
 | 
				
			||||||
  date_opened TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
					  date_opened TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
				
			||||||
  lead_investigator TEXT NOT NULL,
 | 
					  investigator TEXT NOT NULL,
 | 
				
			||||||
  classification TEXT,
 | 
					  classification TEXT,
 | 
				
			||||||
  summary TEXT,
 | 
					  summary TEXT,
 | 
				
			||||||
  status TEXT DEFAULT 'Active',
 | 
					  status TEXT DEFAULT 'active',
 | 
				
			||||||
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
					  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
				
			||||||
  modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
 | 
					  modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user