systemprompt_users/
extension.rs1use systemprompt_extension::prelude::*;
7
8#[derive(Debug, Clone, Copy, Default)]
9pub struct UsersExtension;
10
11impl Extension for UsersExtension {
12 fn metadata(&self) -> ExtensionMetadata {
13 ExtensionMetadata {
14 id: "users",
15 name: "Users",
16 version: env!("CARGO_PKG_VERSION"),
17 }
18 }
19
20 fn is_required(&self) -> bool {
21 true
22 }
23
24 fn schemas(&self) -> Vec<SchemaDefinition> {
25 vec![
26 SchemaDefinition::new("users", include_str!("../schema/users.sql"))
27 .with_required_columns(vec![
28 "id".into(),
29 "name".into(),
30 "email".into(),
31 "created_at".into(),
32 ]),
33 SchemaDefinition::new("user_sessions", include_str!("../schema/user_sessions.sql"))
34 .with_required_columns(vec![
35 "session_id".into(),
36 "started_at".into(),
37 "bot_type".into(),
38 ]),
39 SchemaDefinition::sql_only(include_str!("../schema/session_bot_type.sql")),
40 SchemaDefinition::new(
41 "session_traffic_rollup_hourly",
42 include_str!("../schema/session_traffic_rollup_hourly.sql"),
43 )
44 .with_required_columns(vec![
45 "bucket".into(),
46 "traffic_class".into(),
47 "sessions".into(),
48 ]),
49 SchemaDefinition::new("banned_ips", include_str!("../schema/banned_ips.sql"))
50 .with_required_columns(vec![
51 "ip_address".into(),
52 "reason".into(),
53 "banned_at".into(),
54 ]),
55 SchemaDefinition::new("user_api_keys", include_str!("../schema/user_api_keys.sql"))
56 .with_required_columns(vec![
57 "id".into(),
58 "user_id".into(),
59 "key_prefix".into(),
60 "key_hash".into(),
61 "model_allowlist".into(),
62 "request_window_seconds".into(),
63 ]),
64 SchemaDefinition::new(
65 "user_api_key_scopes",
66 include_str!("../schema/user_api_key_scopes.sql"),
67 )
68 .with_required_columns(vec![
69 "key_id".into(),
70 "dimension".into(),
71 "value".into(),
72 ]),
73 SchemaDefinition::new(
74 "user_device_certs",
75 include_str!("../schema/user_device_certs.sql"),
76 )
77 .with_required_columns(vec![
78 "id".into(),
79 "user_id".into(),
80 "fingerprint".into(),
81 "label".into(),
82 ]),
83 SchemaDefinition::new(
84 "user_rate_limit_buckets",
85 include_str!("../schema/user_rate_limit_buckets.sql"),
86 )
87 .with_required_columns(vec![
88 "user_id".into(),
89 "scope".into(),
90 "window_start".into(),
91 "hits".into(),
92 ]),
93 ]
94 .into_iter()
95 .chain(std::iter::once(api_key_session_schema()))
96 .chain(federation_schemas())
97 .collect()
98 }
99
100 fn dependencies(&self) -> Vec<&'static str> {
101 vec!["events"]
102 }
103
104 fn migrations(&self) -> Vec<Migration> {
105 extension_migrations!()
106 }
107}
108
109register_extension!(UsersExtension);
110
111fn federation_schemas() -> [SchemaDefinition; 2] {
112 [
113 SchemaDefinition::new(
114 "federated_identities",
115 include_str!("../schema/federated_identities.sql"),
116 )
117 .with_required_columns(vec![
118 "issuer".into(),
119 "external_sub".into(),
120 "user_id".into(),
121 ]),
122 SchemaDefinition::new(
123 "sso_login_events",
124 include_str!("../schema/sso_login_events.sql"),
125 )
126 .with_required_columns(vec![
127 "provider_id".into(),
128 "outcome".into(),
129 "occurred_at".into(),
130 ]),
131 ]
132}
133
134fn api_key_session_schema() -> SchemaDefinition {
135 SchemaDefinition::new(
136 "api_key_sessions",
137 include_str!("../schema/api_key_sessions.sql"),
138 )
139 .with_required_columns(vec!["api_key_id".into(), "session_id".into()])
140}