cryogenic22 commited on
Commit
ffee286
·
verified ·
1 Parent(s): 38a2b30

Create services/database_service.py

Browse files
Files changed (1) hide show
  1. src/core/services/database_service.py +196 -0
src/core/services/database_service.py ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Database service for managing application data"""
2
+ import sqlite3
3
+ from contextlib import contextmanager
4
+ from pathlib import Path
5
+ from typing import Dict, List, Any, Optional
6
+ import json
7
+ from datetime import datetime
8
+
9
+ class DatabaseService:
10
+ def __init__(self, db_path: str = "data/robata.db"):
11
+ """Initialize database service"""
12
+ self.db_path = db_path
13
+ Path(db_path).parent.mkdir(parents=True, exist_ok=True)
14
+ self.setup_database()
15
+
16
+ @contextmanager
17
+ def get_db(self):
18
+ """Context manager for database connections"""
19
+ conn = sqlite3.connect(self.db_path)
20
+ try:
21
+ yield conn
22
+ finally:
23
+ conn.close()
24
+
25
+ def setup_database(self):
26
+ """Create database tables if they don't exist"""
27
+ with self.get_db() as conn:
28
+ c = conn.cursor()
29
+ c.executescript('''
30
+ CREATE TABLE IF NOT EXISTS users (
31
+ id TEXT PRIMARY KEY,
32
+ email TEXT UNIQUE,
33
+ name TEXT,
34
+ role TEXT,
35
+ department TEXT,
36
+ title TEXT,
37
+ company TEXT,
38
+ created_at TEXT
39
+ );
40
+
41
+ CREATE TABLE IF NOT EXISTS accounts (
42
+ id TEXT PRIMARY KEY,
43
+ name TEXT,
44
+ industry TEXT,
45
+ status TEXT,
46
+ website TEXT,
47
+ annual_revenue REAL,
48
+ employee_count INTEGER,
49
+ created_at TEXT
50
+ );
51
+
52
+ CREATE TABLE IF NOT EXISTS contacts (
53
+ id TEXT PRIMARY KEY,
54
+ account_id TEXT,
55
+ first_name TEXT,
56
+ last_name TEXT,
57
+ email TEXT,
58
+ title TEXT,
59
+ department TEXT,
60
+ influence_level TEXT,
61
+ created_at TEXT,
62
+ FOREIGN KEY (account_id) REFERENCES accounts (id)
63
+ );
64
+
65
+ CREATE TABLE IF NOT EXISTS interactions (
66
+ id TEXT PRIMARY KEY,
67
+ type TEXT,
68
+ account_id TEXT,
69
+ owner_id TEXT,
70
+ transcript TEXT,
71
+ summary TEXT,
72
+ sentiment_score REAL,
73
+ metadata TEXT,
74
+ created_at TEXT,
75
+ FOREIGN KEY (account_id) REFERENCES accounts (id),
76
+ FOREIGN KEY (owner_id) REFERENCES users (id)
77
+ );
78
+ ''')
79
+
80
+ def get_user_by_email(self, email: str) -> Optional[Dict]:
81
+ """Get user by email address"""
82
+ with self.get_db() as conn:
83
+ cursor = conn.execute(
84
+ "SELECT * FROM users WHERE email = ?",
85
+ (email,)
86
+ )
87
+ row = cursor.fetchone()
88
+ if row:
89
+ return {
90
+ 'id': row[0],
91
+ 'email': row[1],
92
+ 'name': row[2],
93
+ 'role': row[3],
94
+ 'department': row[4],
95
+ 'title': row[5],
96
+ 'company': row[6]
97
+ }
98
+ return None
99
+
100
+ def get_user_accounts(self, user_id: str) -> List[Dict]:
101
+ """Get accounts associated with user"""
102
+ with self.get_db() as conn:
103
+ cursor = conn.execute("""
104
+ SELECT DISTINCT a.*
105
+ FROM accounts a
106
+ JOIN interactions i ON a.id = i.account_id
107
+ WHERE i.owner_id = ?
108
+ ORDER BY a.name
109
+ """, (user_id,))
110
+ return [
111
+ {
112
+ 'id': row[0],
113
+ 'name': row[1],
114
+ 'industry': row[2],
115
+ 'status': row[3],
116
+ 'website': row[4],
117
+ 'annual_revenue': row[5],
118
+ 'employee_count': row[6]
119
+ }
120
+ for row in cursor.fetchall()
121
+ ]
122
+
123
+ def get_account_metrics(self, account_id: str) -> Dict:
124
+ """Get key metrics for an account"""
125
+ with self.get_db() as conn:
126
+ # Get total interactions
127
+ interaction_count = conn.execute(
128
+ "SELECT COUNT(*) FROM interactions WHERE account_id = ?",
129
+ (account_id,)
130
+ ).fetchone()[0]
131
+
132
+ # Get contact count
133
+ contact_count = conn.execute(
134
+ "SELECT COUNT(*) FROM contacts WHERE account_id = ?",
135
+ (account_id,)
136
+ ).fetchone()[0]
137
+
138
+ # Get average sentiment
139
+ avg_sentiment = conn.execute(
140
+ "SELECT AVG(sentiment_score) FROM interactions WHERE account_id = ?",
141
+ (account_id,)
142
+ ).fetchone()[0]
143
+
144
+ return {
145
+ 'interaction_count': interaction_count,
146
+ 'contact_count': contact_count,
147
+ 'avg_sentiment': avg_sentiment or 0
148
+ }
149
+
150
+ def save_interaction(self, interaction_data: Dict) -> str:
151
+ """Save new interaction"""
152
+ with self.get_db() as conn:
153
+ cursor = conn.execute("""
154
+ INSERT INTO interactions (
155
+ id, type, account_id, owner_id, transcript,
156
+ summary, sentiment_score, metadata, created_at
157
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
158
+ """, (
159
+ interaction_data['id'],
160
+ interaction_data['type'],
161
+ interaction_data['account_id'],
162
+ interaction_data['owner_id'],
163
+ interaction_data['transcript'],
164
+ interaction_data.get('summary'),
165
+ interaction_data.get('sentiment_score'),
166
+ json.dumps(interaction_data.get('metadata', {})),
167
+ datetime.now().isoformat()
168
+ ))
169
+ conn.commit()
170
+ return interaction_data['id']
171
+
172
+ def get_recent_interactions(self, user_id: str, limit: int = 10) -> List[Dict]:
173
+ """Get recent interactions for user"""
174
+ with self.get_db() as conn:
175
+ cursor = conn.execute("""
176
+ SELECT i.*, a.name as account_name
177
+ FROM interactions i
178
+ JOIN accounts a ON i.account_id = a.id
179
+ WHERE i.owner_id = ?
180
+ ORDER BY i.created_at DESC
181
+ LIMIT ?
182
+ """, (user_id, limit))
183
+ return [
184
+ {
185
+ 'id': row[0],
186
+ 'type': row[1],
187
+ 'account_id': row[2],
188
+ 'account_name': row[9],
189
+ 'transcript': row[4],
190
+ 'summary': row[5],
191
+ 'sentiment_score': row[6],
192
+ 'metadata': json.loads(row[7]) if row[7] else {},
193
+ 'created_at': row[8]
194
+ }
195
+ for row in cursor.fetchall()
196
+ ]