heldar_kernel/routes/
discovery.rs1use axum::extract::State;
2use axum::routing::post;
3use axum::{Json, Router};
4use serde_json::{json, Value};
5
6use crate::error::{AppError, AppResult};
7use crate::services::discovery::{self, DiscoverOptions};
8use crate::state::AppState;
9
10pub fn router() -> Router<AppState> {
11 Router::new().route("/api/v1/discover", post(discover_handler))
12}
13
14async fn discover_handler(
16 State(st): State<AppState>,
17 Json(opts): Json<DiscoverOptions>,
18) -> AppResult<Json<Value>> {
19 let devices = discovery::discover(&st.pool, &st.cfg, &st.http, &opts)
20 .await
21 .map_err(AppError::BadRequest)?;
22
23 let mut added: Vec<String> = Vec::new();
24 if opts.auto_add {
25 for d in devices
26 .iter()
27 .filter(|d| d.verified && !d.already_registered)
28 {
29 match discovery::add_device(&st.pool, d).await {
30 Ok(id) => {
31 st.recorder.reconcile(&id).await;
32 added.push(id);
33 }
34 Err(e) => {
35 tracing::error!(addr = %d.address, error = %e, "discover: auto-add failed")
36 }
37 }
38 }
39 }
40
41 Ok(Json(json!({
42 "scanned": opts.targets,
43 "found": devices.len(),
44 "verified": devices.iter().filter(|d| d.verified).count(),
45 "added": added,
46 "devices": devices,
47 })))
48}