1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
import { DatabaseSync } from 'node:sqlite';
class AnalyticsCollector {
constructor(dbPath = 'analytics.db') {
this.db = new DatabaseSync(dbPath);
this.init();
}
init() {
this.db.exec(`
CREATE TABLE IF NOT EXISTS events (
id INTEGER PRIMARY KEY AUTOINCREMENT,
event_type TEXT NOT NULL,
user_id TEXT,
session_id TEXT,
properties TEXT,
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP,
INDEX idx_event_type (event_type),
INDEX idx_timestamp (timestamp),
INDEX idx_user_id (user_id)
) STRICT
`);
}
track(eventType, userId = null, sessionId = null, properties = {}) {
const stmt = this.db.prepare(`
INSERT INTO events (event_type, user_id, session_id, properties)
VALUES (?, ?, ?, ?)
`);
stmt.run(eventType, userId, sessionId, JSON.stringify(properties));
}
getEventCounts(startDate, endDate) {
const stmt = this.db.prepare(`
SELECT
event_type,
COUNT(*) as count,
COUNT(DISTINCT user_id) as unique_users
FROM events
WHERE timestamp BETWEEN ? AND ?
GROUP BY event_type
ORDER BY count DESC
`);
return stmt.all(startDate, endDate);
}
getUserActivity(userId, days = 30) {
const stmt = this.db.prepare(`
SELECT
DATE(timestamp) as date,
COUNT(*) as event_count,
COUNT(DISTINCT event_type) as unique_events
FROM events
WHERE user_id = ?
AND timestamp >= datetime('now', '-' || ? || ' days')
GROUP BY DATE(timestamp)
ORDER BY date DESC
`);
return stmt.all(userId, days);
}
getRetentionCohort(startDate, days = 7) {
const stmt = this.db.prepare(`
WITH user_first_seen AS (
SELECT user_id, MIN(DATE(timestamp)) as first_seen
FROM events
WHERE user_id IS NOT NULL
GROUP BY user_id
),
user_activity AS (
SELECT
user_id,
DATE(timestamp) as activity_date,
JULIANDAY(DATE(timestamp)) - JULIANDAY(first_seen) as day_number
FROM events e
JOIN user_first_seen ufs ON e.user_id = ufs.user_id
WHERE user_id IS NOT NULL
)
SELECT
first_seen as cohort_date,
day_number,
COUNT(DISTINCT user_id) as active_users
FROM user_activity ua
JOIN user_first_seen ufs ON ua.user_id = ufs.user_id
WHERE first_seen >= ?
GROUP BY first_seen, day_number
ORDER BY first_seen, day_number
`);
return stmt.all(startDate);
}
}
// Usage
const analytics = new AnalyticsCollector();
// Track various events
analytics.track('page_view', 'user123', 'session456', { page: '/home', referrer: 'google' });
analytics.track('button_click', 'user123', 'session456', { button_id: 'subscribe' });
analytics.track('purchase', 'user123', 'session456', { amount: 29.99, product: 'premium' });
// Generate reports
console.log(analytics.getEventCounts('2024-01-01', '2024-01-31'));
console.log(analytics.getUserActivity('user123'));
|