Skip to main content

sentrystr_api/
handlers.rs

1use axum::{Json, extract::Query};
2use chrono::Utc;
3use nostr::PublicKey;
4use sentrystr::Level;
5use sentrystr_collector::{EventCollector, EventFilter};
6
7use crate::models::{EventQuery, EventResponse, EventsResponse, HealthResponse};
8use crate::{ApiError, Result};
9
10pub async fn health() -> Json<HealthResponse> {
11    Json(HealthResponse {
12        status: "ok".to_string(),
13        timestamp: Utc::now(),
14    })
15}
16
17pub async fn get_events(Query(params): Query<EventQuery>) -> Result<Json<EventsResponse>> {
18    let relays = vec!["wss://relay.damus.io".to_string()];
19
20    let collector = EventCollector::new(relays)
21        .await
22        .map_err(|e| ApiError::Collection(e.to_string()))?;
23
24    let mut filter = EventFilter::new();
25
26    if let Some(limit) = params.limit {
27        filter = filter.with_limit(limit);
28    } else {
29        filter = filter.with_limit(100);
30    }
31
32    if let Some(author_str) = params.author {
33        let author = PublicKey::parse(&author_str)
34            .map_err(|e| ApiError::BadRequest(format!("Invalid public key: {}", e)))?;
35        filter = filter.with_author(author);
36    }
37
38    if let Some(level_str) = params.level {
39        let level = match level_str.to_lowercase().as_str() {
40            "debug" => Level::Debug,
41            "info" => Level::Info,
42            "warning" => Level::Warning,
43            "error" => Level::Error,
44            "fatal" => Level::Fatal,
45            _ => return Err(ApiError::BadRequest("Invalid level".to_string())),
46        };
47        filter = filter.with_level(level);
48    }
49
50    if let Some(service) = params.service {
51        filter = filter.with_service_filter(service);
52    }
53
54    if let Some(environment) = params.environment {
55        filter = filter.with_environment_filter(environment);
56    }
57
58    if let Some(component) = params.component {
59        filter = filter.with_component_filter(component);
60    }
61
62    if let Some(severity) = params.severity {
63        filter = filter.with_severity_filter(severity);
64    }
65
66    if let Some(since) = params.since {
67        filter = filter.with_since(since);
68    }
69
70    if let Some(until) = params.until {
71        filter = filter.with_until(until);
72    }
73
74    let events = collector
75        .collect_events(filter)
76        .await
77        .map_err(|e| ApiError::Collection(e.to_string()))?;
78
79    collector
80        .disconnect()
81        .await
82        .map_err(|e| ApiError::Internal(e.to_string()))?;
83
84    let response_events: Vec<EventResponse> = events
85        .into_iter()
86        .map(|event| EventResponse {
87            nostr_event_id: event.nostr_event_id.to_string(),
88            author: event.author.to_string(),
89            received_at: event.received_at,
90            event: crate::models::EventData {
91                event_id: event.event.event_id,
92                timestamp: event.event.timestamp,
93                platform: event.event.platform,
94                level: event.event.level,
95                logger: event.event.logger,
96                transaction: event.event.transaction,
97                server_name: event.event.server_name,
98                release: event.event.release,
99                environment: event.event.environment,
100                message: event.event.message,
101                tags: event.event.tags,
102                extra: event.event.extra,
103            },
104        })
105        .collect();
106
107    let total = response_events.len();
108
109    Ok(Json(EventsResponse {
110        events: response_events,
111        total,
112    }))
113}