1use systemprompt_extension::prelude::*;
8
9#[derive(Debug, Clone, Copy, Default)]
10pub struct AnalyticsExtension;
11
12impl Extension for AnalyticsExtension {
13 fn metadata(&self) -> ExtensionMetadata {
14 ExtensionMetadata {
15 id: "analytics",
16 name: "Analytics",
17 version: env!("CARGO_PKG_VERSION"),
18 }
19 }
20
21 fn schemas(&self) -> Vec<SchemaDefinition> {
22 let mut schemas = capture_schemas();
23 schemas.extend(fact_schemas());
24 schemas.extend(snapshot_schemas());
25 schemas.extend(projection_schemas());
26 schemas.extend(behavioral_schemas());
27 schemas
28 }
29
30 fn dependencies(&self) -> Vec<&'static str> {
31 vec!["users"]
32 }
33
34 fn migrations(&self) -> Vec<Migration> {
35 extension_migrations!()
36 }
37
38 fn seeds(&self) -> Vec<Seed> {
39 vec![Seed::new(
40 "analytics_projection_state",
41 crate::projection::REPORTING_STATE_SEED,
42 )]
43 }
44}
45
46register_extension!(AnalyticsExtension);
47
48fn capture_schemas() -> Vec<SchemaDefinition> {
49 vec![SchemaDefinition::sql_only(include_str!(
50 "../schema/reporting_privacy.sql"
51 ))]
52}
53
54fn fact_schemas() -> Vec<SchemaDefinition> {
55 vec![
56 SchemaDefinition::new(
57 "analytics_ingestion_producers",
58 include_str!("../schema/ingestion_producers.sql"),
59 ),
60 SchemaDefinition::new(
61 "analytics_fact_changes",
62 include_str!("../schema/analytics_fact_changes.sql"),
63 ),
64 SchemaDefinition::new(
65 "analytics_normalized_facts",
66 include_str!("../schema/analytics_normalized_facts.sql"),
67 ),
68 SchemaDefinition::new(
69 "analytics_fact_checkpoints",
70 include_str!("../schema/analytics_fact_checkpoints.sql"),
71 ),
72 SchemaDefinition::new(
73 "analytics_fact_deltas",
74 include_str!("../schema/analytics_fact_deltas.sql"),
75 ),
76 SchemaDefinition::new(
77 "analytics_fact_backfills",
78 include_str!("../schema/analytics_fact_backfills.sql"),
79 ),
80 SchemaDefinition::new(
81 "analytics_fact_backfill_pages",
82 include_str!("../schema/analytics_fact_backfill_pages.sql"),
83 ),
84 SchemaDefinition::new(
85 "analytics_fact_consumers",
86 include_str!("../schema/analytics_fact_consumers.sql"),
87 ),
88 ]
89}
90
91fn snapshot_schemas() -> Vec<SchemaDefinition> {
92 vec![
93 SchemaDefinition::new(
94 "analytics_snapshot_dirty",
95 include_str!("../schema/analytics_snapshot_dirty.sql"),
96 ),
97 SchemaDefinition::new(
98 "analytics_snapshot_shadow",
99 include_str!("../schema/analytics_snapshot_shadow.sql"),
100 ),
101 SchemaDefinition::new(
102 "analytics_snapshot_daily",
103 include_str!("../schema/analytics_snapshot_daily.sql"),
104 ),
105 SchemaDefinition::new(
106 "analytics_snapshot_identities",
107 include_str!("../schema/analytics_snapshot_identities.sql"),
108 ),
109 SchemaDefinition::new(
110 "analytics_snapshot_state",
111 include_str!("../schema/analytics_snapshot_state.sql"),
112 ),
113 SchemaDefinition::new(
114 "analytics_snapshot_jobs",
115 include_str!("../schema/analytics_snapshot_jobs.sql"),
116 ),
117 ]
118}
119
120fn projection_schemas() -> Vec<SchemaDefinition> {
121 vec![
122 SchemaDefinition::new(
123 "analytics_projection_state",
124 include_str!("../schema/analytics_projection_state.sql"),
125 )
126 .with_required_columns(vec!["generation".into(), "cutoff_revision".into()]),
127 SchemaDefinition::new(
128 "analytics_projection_revisions",
129 include_str!("../schema/analytics_projection_revisions.sql"),
130 ),
131 SchemaDefinition::new(
132 "analytics_report_users",
133 include_str!("../schema/analytics_report_users.sql"),
134 ),
135 SchemaDefinition::new(
136 "analytics_report_user_sessions",
137 include_str!("../schema/analytics_report_user_sessions.sql"),
138 ),
139 SchemaDefinition::new(
140 "analytics_report_agent_tasks",
141 include_str!("../schema/analytics_report_agent_tasks.sql"),
142 ),
143 SchemaDefinition::new(
144 "analytics_report_task_messages",
145 include_str!("../schema/analytics_report_task_messages.sql"),
146 ),
147 SchemaDefinition::new(
148 "analytics_report_user_contexts",
149 include_str!("../schema/analytics_report_user_contexts.sql"),
150 ),
151 SchemaDefinition::new(
152 "analytics_report_ai_requests",
153 include_str!("../schema/analytics_report_ai_requests.sql"),
154 ),
155 SchemaDefinition::new(
156 "analytics_report_ai_request_messages",
157 include_str!("../schema/analytics_report_ai_request_messages.sql"),
158 ),
159 SchemaDefinition::new(
160 "analytics_report_mcp_tool_executions",
161 include_str!("../schema/analytics_report_mcp_tool_executions.sql"),
162 ),
163 SchemaDefinition::new(
164 "analytics_report_markdown_content",
165 include_str!("../schema/analytics_report_markdown_content.sql"),
166 ),
167 SchemaDefinition::new(
168 "analytics_report_logs",
169 include_str!("../schema/analytics_report_logs.sql"),
170 ),
171 SchemaDefinition::new(
172 "analytics_report_analytics_events",
173 include_str!("../schema/analytics_report_analytics_events.sql"),
174 ),
175 ]
176}
177
178fn behavioral_schemas() -> Vec<SchemaDefinition> {
179 vec![
180 SchemaDefinition::new(
181 "analytics_feedback_snapshots",
182 include_str!("../schema/analytics_feedback_snapshots.sql"),
183 ),
184 SchemaDefinition::new(
185 "engagement_events",
186 include_str!("../schema/engagement_events.sql"),
187 )
188 .with_required_columns(vec!["id".into(), "session_id".into(), "created_at".into()]),
189 SchemaDefinition::new(
190 "anomaly_thresholds",
191 include_str!("../schema/anomaly_thresholds.sql"),
192 )
193 .with_required_columns(vec!["metric_name".into()]),
194 SchemaDefinition::new(
195 "fingerprint_reputation",
196 include_str!("../schema/fingerprint_reputation.sql"),
197 )
198 .with_required_columns(vec!["fingerprint_hash".into()]),
199 SchemaDefinition::new("funnels", include_str!("../schema/funnels.sql"))
200 .with_required_columns(vec!["id".into(), "name".into()]),
201 SchemaDefinition::new("funnel_steps", include_str!("../schema/funnel_steps.sql"))
202 .with_required_columns(vec!["funnel_id".into(), "step_order".into()]),
203 SchemaDefinition::new(
204 "funnel_progress",
205 include_str!("../schema/funnel_progress.sql"),
206 )
207 .with_required_columns(vec!["id".into(), "funnel_id".into(), "session_id".into()]),
208 ]
209}