systemprompt_analytics/
extension.rs1use systemprompt_extension::prelude::*;
2
3const MIGRATION_001_EVENT_TYPE: &str = r"
4ALTER TABLE engagement_events ADD COLUMN IF NOT EXISTS event_type VARCHAR(50) NOT NULL DEFAULT 'page_exit';
5CREATE INDEX IF NOT EXISTS idx_engagement_events_event_type ON engagement_events(event_type);
6";
7
8#[derive(Debug, Clone, Copy, Default)]
9pub struct AnalyticsExtension;
10
11impl Extension for AnalyticsExtension {
12 fn metadata(&self) -> ExtensionMetadata {
13 ExtensionMetadata {
14 id: "analytics",
15 name: "Analytics",
16 version: env!("CARGO_PKG_VERSION"),
17 }
18 }
19
20 fn migration_weight(&self) -> u32 {
21 20
22 }
23
24 fn schemas(&self) -> Vec<SchemaDefinition> {
25 vec![
26 SchemaDefinition::inline(
27 "engagement_events",
28 include_str!("../schema/engagement_events.sql"),
29 )
30 .with_required_columns(vec![
31 "id".into(),
32 "session_id".into(),
33 "created_at".into(),
34 ]),
35 SchemaDefinition::inline(
36 "anomaly_thresholds",
37 include_str!("../schema/anomaly_thresholds.sql"),
38 )
39 .with_required_columns(vec!["metric_name".into()]),
40 SchemaDefinition::inline(
41 "fingerprint_reputation",
42 include_str!("../schema/fingerprint_reputation.sql"),
43 )
44 .with_required_columns(vec!["fingerprint_hash".into()]),
45 SchemaDefinition::inline("funnels", include_str!("../schema/funnels.sql"))
46 .with_required_columns(vec!["id".into(), "name".into()]),
47 SchemaDefinition::inline(
48 "funnel_progress",
49 include_str!("../schema/funnel_progress.sql"),
50 )
51 .with_required_columns(vec![
52 "id".into(),
53 "funnel_id".into(),
54 "session_id".into(),
55 ]),
56 ]
57 }
58
59 fn dependencies(&self) -> Vec<&'static str> {
60 vec!["users"]
61 }
62
63 fn migrations(&self) -> Vec<Migration> {
64 vec![Migration::new(
65 1,
66 "add_engagement_event_type",
67 MIGRATION_001_EVENT_TYPE,
68 )]
69 }
70}
71
72register_extension!(AnalyticsExtension);