1use crate::auth::AuthManager;
3use crate::auth_api::*;
4use crate::middleware::{auth_middleware, rate_limit_middleware, AuthState, RateLimitState};
5use crate::rate_limit::RateLimiter;
6use crate::store::EventStore;
7use crate::tenant::TenantManager;
8use crate::tenant_api::*;
9use axum::{
10 middleware,
11 routing::{delete, get, post, put},
12 Router,
13};
14use std::sync::Arc;
15use tower_http::cors::{Any, CorsLayer};
16use tower_http::trace::TraceLayer;
17
18#[derive(Clone)]
20pub struct AppState {
21 pub store: Arc<EventStore>,
22 pub auth_manager: Arc<AuthManager>,
23 pub tenant_manager: Arc<TenantManager>,
24}
25
26impl axum::extract::FromRef<AppState> for Arc<EventStore> {
29 fn from_ref(state: &AppState) -> Self {
30 state.store.clone()
31 }
32}
33
34pub async fn serve_v1(
35 store: Arc<EventStore>,
36 auth_manager: Arc<AuthManager>,
37 tenant_manager: Arc<TenantManager>,
38 rate_limiter: Arc<RateLimiter>,
39 addr: &str,
40) -> anyhow::Result<()> {
41 let app_state = AppState {
42 store,
43 auth_manager: auth_manager.clone(),
44 tenant_manager,
45 };
46
47 let auth_state = AuthState {
48 auth_manager: auth_manager.clone(),
49 };
50
51 let rate_limit_state = RateLimitState { rate_limiter };
52
53 let app = Router::new()
54 .route("/health", get(crate::api::health))
56 .route("/metrics", get(crate::api::prometheus_metrics))
57 .route("/api/v1/auth/register", post(register_handler))
59 .route("/api/v1/auth/login", post(login_handler))
60 .route("/api/v1/auth/me", get(me_handler))
61 .route("/api/v1/auth/api-keys", post(create_api_key_handler))
62 .route("/api/v1/auth/api-keys", get(list_api_keys_handler))
63 .route("/api/v1/auth/api-keys/:id", delete(revoke_api_key_handler))
64 .route("/api/v1/auth/users", get(list_users_handler))
65 .route("/api/v1/auth/users/:id", delete(delete_user_handler))
66 .route("/api/v1/tenants", post(create_tenant_handler))
68 .route("/api/v1/tenants", get(list_tenants_handler))
69 .route("/api/v1/tenants/:id", get(get_tenant_handler))
70 .route("/api/v1/tenants/:id/stats", get(get_tenant_stats_handler))
71 .route("/api/v1/tenants/:id/quotas", put(update_quotas_handler))
72 .route(
73 "/api/v1/tenants/:id/deactivate",
74 post(deactivate_tenant_handler),
75 )
76 .route(
77 "/api/v1/tenants/:id/activate",
78 post(activate_tenant_handler),
79 )
80 .route("/api/v1/tenants/:id", delete(delete_tenant_handler))
81 .route("/api/v1/events", post(crate::api::ingest_event))
83 .route("/api/v1/events/query", get(crate::api::query_events))
84 .route("/api/v1/events/stream", get(crate::api::events_websocket))
85 .route(
86 "/api/v1/entities/:entity_id/state",
87 get(crate::api::get_entity_state),
88 )
89 .route(
90 "/api/v1/entities/:entity_id/snapshot",
91 get(crate::api::get_entity_snapshot),
92 )
93 .route("/api/v1/stats", get(crate::api::get_stats))
94 .route(
96 "/api/v1/analytics/frequency",
97 get(crate::api::analytics_frequency),
98 )
99 .route(
100 "/api/v1/analytics/summary",
101 get(crate::api::analytics_summary),
102 )
103 .route(
104 "/api/v1/analytics/correlation",
105 get(crate::api::analytics_correlation),
106 )
107 .route("/api/v1/snapshots", post(crate::api::create_snapshot))
109 .route("/api/v1/snapshots", get(crate::api::list_snapshots))
110 .route(
111 "/api/v1/snapshots/:entity_id/latest",
112 get(crate::api::get_latest_snapshot),
113 )
114 .route(
116 "/api/v1/compaction/trigger",
117 post(crate::api::trigger_compaction),
118 )
119 .route(
120 "/api/v1/compaction/stats",
121 get(crate::api::compaction_stats),
122 )
123 .route("/api/v1/schemas", post(crate::api::register_schema))
125 .route("/api/v1/schemas", get(crate::api::list_subjects))
126 .route("/api/v1/schemas/:subject", get(crate::api::get_schema))
127 .route(
128 "/api/v1/schemas/:subject/versions",
129 get(crate::api::list_schema_versions),
130 )
131 .route(
132 "/api/v1/schemas/validate",
133 post(crate::api::validate_event_schema),
134 )
135 .route(
136 "/api/v1/schemas/:subject/compatibility",
137 put(crate::api::set_compatibility_mode),
138 )
139 .route("/api/v1/replay", post(crate::api::start_replay))
141 .route("/api/v1/replay", get(crate::api::list_replays))
142 .route(
143 "/api/v1/replay/:replay_id",
144 get(crate::api::get_replay_progress),
145 )
146 .route(
147 "/api/v1/replay/:replay_id/cancel",
148 post(crate::api::cancel_replay),
149 )
150 .route(
151 "/api/v1/replay/:replay_id",
152 delete(crate::api::delete_replay),
153 )
154 .route("/api/v1/pipelines", post(crate::api::register_pipeline))
156 .route("/api/v1/pipelines", get(crate::api::list_pipelines))
157 .route(
158 "/api/v1/pipelines/stats",
159 get(crate::api::all_pipeline_stats),
160 )
161 .route(
162 "/api/v1/pipelines/:pipeline_id",
163 get(crate::api::get_pipeline),
164 )
165 .route(
166 "/api/v1/pipelines/:pipeline_id",
167 delete(crate::api::remove_pipeline),
168 )
169 .route(
170 "/api/v1/pipelines/:pipeline_id/stats",
171 get(crate::api::get_pipeline_stats),
172 )
173 .route(
174 "/api/v1/pipelines/:pipeline_id/reset",
175 put(crate::api::reset_pipeline),
176 )
177 .with_state(app_state)
178 .layer(middleware::from_fn_with_state(auth_state, auth_middleware))
179 .layer(middleware::from_fn_with_state(
180 rate_limit_state,
181 rate_limit_middleware,
182 ))
183 .layer(
184 CorsLayer::new()
185 .allow_origin(Any)
186 .allow_methods(Any)
187 .allow_headers(Any),
188 )
189 .layer(TraceLayer::new_for_http());
190
191 let listener = tokio::net::TcpListener::bind(addr).await?;
192 axum::serve(listener, app).await?;
193
194 Ok(())
195}