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
 | 
			
		||||
CREATE TABLE cases (
 | 
			
		||||
  case_id TEXT PRIMARY KEY,
 | 
			
		||||
  title TEXT NOT NULL,
 | 
			
		||||
  case_title TEXT NOT NULL,
 | 
			
		||||
  date_opened TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
			
		||||
  lead_investigator TEXT NOT NULL,
 | 
			
		||||
  investigator TEXT NOT NULL,
 | 
			
		||||
  classification TEXT,
 | 
			
		||||
  summary TEXT,
 | 
			
		||||
  status TEXT DEFAULT 'Active',
 | 
			
		||||
  status TEXT DEFAULT 'active',
 | 
			
		||||
  created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
 | 
			
		||||
  modified_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user