1use serde::{Deserialize, Serialize};
9use std::collections::HashMap;
10
11use crate::amalgamation;
12use crate::common::ApiState;
13use crate::common::{ApiError, ApiResult, Json, State};
14
15#[allow(non_snake_case)] #[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
21pub struct FatigueInfo {
22 pub fatigue_index: Option<u8>,
24 pub fatigue_active: Option<bool>,
26 pub regular_neuron_util: Option<u8>,
28 pub memory_neuron_util: Option<u8>,
30 pub synapse_util: Option<u8>,
32}
33
34#[allow(non_snake_case)] #[derive(Debug, Serialize, Deserialize, utoipa::ToSchema)]
36pub struct HealthCheckResponse {
37 pub burst_engine: bool,
38 pub connected_agents: Option<i32>,
39 pub influxdb_availability: bool,
40 pub neuron_count_max: i64,
41 pub synapse_count_max: i64,
42 pub latest_changes_saved_externally: bool,
43 pub genome_availability: bool,
44 pub genome_validity: Option<bool>,
45 pub brain_readiness: bool,
46 pub feagi_session: Option<i64>,
47 pub fitness: Option<f64>,
48 pub cortical_area_count: Option<i32>,
49 pub neuron_count: Option<i64>,
50 pub memory_neuron_count: Option<i64>,
51 pub regular_neuron_count: Option<i64>,
52 pub synapse_count: Option<i64>,
53 pub estimated_brain_size_in_MB: Option<f64>,
54 pub genome_num: Option<i32>,
55 pub genome_timestamp: Option<i64>,
56 pub simulation_timestep: Option<f64>,
57 pub memory_area_stats: Option<HashMap<String, HashMap<String, serde_json::Value>>>,
58 pub amalgamation_pending: Option<HashMap<String, serde_json::Value>>,
59 #[serde(skip_serializing_if = "Option::is_none")]
61 pub brain_regions_hash: Option<u64>,
62 #[serde(skip_serializing_if = "Option::is_none")]
64 pub cortical_areas_hash: Option<u64>,
65 #[serde(skip_serializing_if = "Option::is_none")]
67 pub brain_geometry_hash: Option<u64>,
68 #[serde(skip_serializing_if = "Option::is_none")]
70 pub morphologies_hash: Option<u64>,
71 #[serde(skip_serializing_if = "Option::is_none")]
73 pub cortical_mappings_hash: Option<u64>,
74 #[serde(skip_serializing_if = "Option::is_none")]
76 pub brain_regions_root: Option<String>,
77 #[serde(skip_serializing_if = "Option::is_none")]
79 pub fatigue: Option<FatigueInfo>,
80}
81
82#[utoipa::path(
88 get,
89 path = "/v1/system/health_check",
90 responses(
91 (status = 200, description = "System health retrieved successfully", body = HealthCheckResponse),
92 (status = 500, description = "Internal server error")
93 ),
94 tag = "system"
95)]
96pub async fn get_health_check(
97 State(state): State<ApiState>,
98) -> ApiResult<Json<HealthCheckResponse>> {
99 let analytics_service = state.analytics_service.as_ref();
100
101 let health = analytics_service
103 .get_system_health()
104 .await
105 .map_err(|e| ApiError::internal(format!("Failed to get system health: {}", e)))?;
106
107 let runtime_status = state.runtime_service.get_status().await.ok();
109 let burst_engine_active = runtime_status
110 .as_ref()
111 .map(|status| status.is_running)
112 .unwrap_or(false);
113
114 let _burst_count = state.runtime_service.get_burst_count().await.ok();
115
116 let connected_agents = if let Some(agent_service) = state.agent_service.as_ref() {
118 agent_service
119 .list_agents()
120 .await
121 .ok()
122 .map(|agents| agents.len() as i32)
123 } else {
124 None
125 };
126
127 let synapse_count = analytics_service
129 .get_total_synapse_count()
130 .await
131 .ok()
132 .map(|count| count as i64);
133
134 let regular_neuron_count = analytics_service
136 .get_regular_neuron_count()
137 .await
138 .ok()
139 .map(|count| count as i64);
140
141 let memory_neuron_count = analytics_service
142 .get_memory_neuron_count()
143 .await
144 .ok()
145 .map(|count| count as i64);
146
147 let genome_info = state.genome_service.get_genome_info().await.ok();
149
150 let runtime_timestep = runtime_status.as_ref().map(|status| {
152 if status.frequency_hz > 0.0 {
153 1.0 / status.frequency_hz
154 } else {
155 0.0
156 }
157 });
158 let simulation_timestep =
159 runtime_timestep.or_else(|| genome_info.as_ref().map(|info| info.simulation_timestep));
160 let genome_num = genome_info.as_ref().and_then(|info| info.genome_num);
161 let genome_timestamp = genome_info.as_ref().and_then(|info| info.genome_timestamp);
162
163 #[allow(non_snake_case)] let estimated_brain_size_in_MB = {
167 let neuron_bytes = health.neuron_count * 64;
168 let synapse_bytes = synapse_count.unwrap_or(0) as usize * 16;
169 let metadata_bytes = health.cortical_area_count * 512; let total_bytes = neuron_bytes + synapse_bytes + metadata_bytes;
171 Some((total_bytes as f64) / (1024.0 * 1024.0))
172 };
173
174 let neuron_count_max = health.neuron_capacity as i64;
176 let synapse_count_max = health.synapse_capacity as i64;
177
178 let influxdb_availability = false; let latest_changes_saved_externally = false; let genome_availability = health.cortical_area_count > 0;
182 let genome_validity = Some(health.brain_readiness);
183
184 let feagi_session = Some(state.feagi_session_timestamp);
186
187 let fitness = None; let (memory_area_stats, memory_neuron_count_from_cache) = state
196 .memory_stats_cache
197 .as_ref()
198 .map(|cache| {
199 let snapshot = feagi_npu_plasticity::memory_stats_cache::get_stats_snapshot(cache);
200 let total = snapshot
201 .values()
202 .map(|s| s.neuron_count as i64)
203 .sum::<i64>();
204 let per_area = snapshot
205 .into_iter()
206 .map(|(name, stats)| {
207 let mut inner_map = HashMap::new();
208 inner_map.insert(
209 "neuron_count".to_string(),
210 serde_json::json!(stats.neuron_count),
211 );
212 inner_map.insert(
213 "created_total".to_string(),
214 serde_json::json!(stats.created_total),
215 );
216 inner_map.insert(
217 "deleted_total".to_string(),
218 serde_json::json!(stats.deleted_total),
219 );
220 inner_map.insert(
221 "last_updated".to_string(),
222 serde_json::json!(stats.last_updated),
223 );
224 (name, inner_map)
225 })
226 .collect::<HashMap<String, HashMap<String, serde_json::Value>>>();
227 (Some(per_area), Some(total))
228 })
229 .unwrap_or((None, None));
230
231 let memory_neuron_count = memory_neuron_count_from_cache.or(memory_neuron_count);
233
234 let amalgamation_pending = state.amalgamation_state.read().pending.as_ref().map(|p| {
239 let v = amalgamation::pending_summary_to_health_json(&p.summary);
240 v.as_object()
241 .cloned()
242 .unwrap_or_default()
243 .into_iter()
244 .collect::<HashMap<String, serde_json::Value>>()
245 });
246
247 #[cfg(feature = "services")]
249 let brain_regions_root = feagi_brain_development::ConnectomeManager::instance()
250 .read()
251 .get_root_region_id();
252 #[cfg(not(feature = "services"))]
253 let brain_regions_root = None; #[cfg(feature = "services")]
258 let fatigue = {
259 use feagi_state_manager::StateManager;
260 match StateManager::instance().try_read() {
262 Some(state_manager) => {
263 let core_state = state_manager.get_core_state();
264 Some(FatigueInfo {
265 fatigue_index: Some(core_state.get_fatigue_index()),
266 fatigue_active: Some(core_state.is_fatigue_active()),
267 regular_neuron_util: Some(core_state.get_regular_neuron_util()),
268 memory_neuron_util: Some(core_state.get_memory_neuron_util()),
269 synapse_util: Some(core_state.get_synapse_util()),
270 })
271 }
272 None => {
273 tracing::warn!(target: "feagi-api", "StateManager is locked, cannot read fatigue data");
275 None
276 }
277 }
278 };
279 #[cfg(not(feature = "services"))]
280 let fatigue = {
281 tracing::debug!(target: "feagi-api", "Services feature not enabled, fatigue data unavailable");
282 None
283 };
284
285 let (
286 brain_regions_hash,
287 cortical_areas_hash,
288 brain_geometry_hash,
289 morphologies_hash,
290 cortical_mappings_hash,
291 ) = {
292 let state_manager = feagi_state_manager::StateManager::instance();
293 let state_manager = state_manager.read();
294 (
295 Some(state_manager.get_brain_regions_hash()),
296 Some(state_manager.get_cortical_areas_hash()),
297 Some(state_manager.get_brain_geometry_hash()),
298 Some(state_manager.get_morphologies_hash()),
299 Some(state_manager.get_cortical_mappings_hash()),
300 )
301 };
302
303 Ok(Json(HealthCheckResponse {
304 burst_engine: burst_engine_active,
305 connected_agents,
306 influxdb_availability,
307 neuron_count_max,
308 synapse_count_max,
309 latest_changes_saved_externally,
310 genome_availability,
311 genome_validity,
312 brain_readiness: health.brain_readiness,
313 feagi_session,
314 fitness,
315 cortical_area_count: Some(health.cortical_area_count as i32),
316 neuron_count: Some(health.neuron_count as i64),
317 memory_neuron_count,
318 regular_neuron_count,
319 synapse_count,
320 estimated_brain_size_in_MB,
321 genome_num,
322 genome_timestamp,
323 simulation_timestep,
324 memory_area_stats,
325 amalgamation_pending,
326 brain_regions_hash,
327 cortical_areas_hash,
328 brain_geometry_hash,
329 morphologies_hash,
330 cortical_mappings_hash,
331 brain_regions_root, fatigue,
333 }))
334}
335
336#[utoipa::path(
338 get,
339 path = "/v1/system/cortical_area_visualization_skip_rate",
340 responses(
341 (status = 200, description = "Skip rate retrieved successfully", body = i32),
342 (status = 500, description = "Internal server error")
343 ),
344 tag = "system"
345)]
346pub async fn get_cortical_area_visualization_skip_rate(
347 State(_state): State<ApiState>,
348) -> ApiResult<Json<i32>> {
349 Ok(Json(1))
352}
353
354#[utoipa::path(
356 put,
357 path = "/v1/system/cortical_area_visualization_skip_rate",
358 request_body = i32,
359 responses(
360 (status = 200, description = "Skip rate updated successfully"),
361 (status = 500, description = "Internal server error")
362 ),
363 tag = "system"
364)]
365pub async fn set_cortical_area_visualization_skip_rate(
366 State(_state): State<ApiState>,
367 Json(skip_rate): Json<i32>,
368) -> ApiResult<Json<serde_json::Value>> {
369 Ok(Json(serde_json::json!({
371 "message": format!("Skip rate set to {}", skip_rate)
372 })))
373}
374
375#[utoipa::path(
377 get,
378 path = "/v1/system/cortical_area_visualization_suppression_threshold",
379 responses(
380 (status = 200, description = "Threshold retrieved successfully", body = i32),
381 (status = 500, description = "Internal server error")
382 ),
383 tag = "system"
384)]
385pub async fn get_cortical_area_visualization_suppression_threshold(
386 State(_state): State<ApiState>,
387) -> ApiResult<Json<i32>> {
388 Ok(Json(0))
391}
392
393#[utoipa::path(
395 put,
396 path = "/v1/system/cortical_area_visualization_suppression_threshold",
397 request_body = i32,
398 responses(
399 (status = 200, description = "Threshold updated successfully"),
400 (status = 500, description = "Internal server error")
401 ),
402 tag = "system"
403)]
404pub async fn set_cortical_area_visualization_suppression_threshold(
405 State(_state): State<ApiState>,
406 Json(threshold): Json<i32>,
407) -> ApiResult<Json<serde_json::Value>> {
408 Ok(Json(serde_json::json!({
410 "message": format!("Suppression threshold set to {}", threshold)
411 })))
412}
413
414#[utoipa::path(
420 get,
421 path = "/v1/system/version",
422 tag = "system",
423 responses(
424 (status = 200, description = "Version string", body = String)
425 )
426)]
427pub async fn get_version(State(_state): State<ApiState>) -> ApiResult<Json<String>> {
428 Ok(Json(env!("CARGO_PKG_VERSION").to_string()))
429}
430
431#[utoipa::path(
433 get,
434 path = "/v1/system/versions",
435 tag = "system",
436 responses(
437 (status = 200, description = "Version information", body = HashMap<String, String>)
438 )
439)]
440pub async fn get_versions(
441 State(state): State<ApiState>,
442) -> ApiResult<Json<HashMap<String, String>>> {
443 match state.system_service.get_version().await {
446 Ok(version_info) => {
447 let mut versions = version_info.crates.clone();
448
449 versions.insert("rust".to_string(), version_info.rust_version);
451 versions.insert("build_timestamp".to_string(), version_info.build_timestamp);
452
453 Ok(Json(versions))
454 }
455 Err(e) => {
456 tracing::warn!(
458 "Failed to get version from system service: {}, using fallback",
459 e
460 );
461 let mut versions = HashMap::new();
462 versions.insert(
463 "error".to_string(),
464 "system service unavailable".to_string(),
465 );
466 Ok(Json(versions))
467 }
468 }
469}
470
471#[utoipa::path(
473 get,
474 path = "/v1/system/configuration",
475 tag = "system",
476 responses(
477 (status = 200, description = "System configuration", body = HashMap<String, serde_json::Value>)
478 )
479)]
480pub async fn get_configuration(
481 State(state): State<ApiState>,
482) -> ApiResult<Json<HashMap<String, serde_json::Value>>> {
483 let health = state
485 .analytics_service
486 .get_system_health()
487 .await
488 .map_err(|e| ApiError::internal(format!("Failed to get system health: {}", e)))?;
489
490 let mut config = HashMap::new();
491 config.insert("api_host".to_string(), serde_json::json!("0.0.0.0"));
492 config.insert("api_port".to_string(), serde_json::json!(8000));
493 config.insert(
495 "max_neurons".to_string(),
496 serde_json::json!(health.neuron_capacity),
497 );
498 config.insert(
499 "max_synapses".to_string(),
500 serde_json::json!(health.synapse_capacity),
501 );
502
503 Ok(Json(config))
504}
505
506#[utoipa::path(
508 get,
509 path = "/v1/system/user_preferences",
510 tag = "system",
511 responses(
512 (status = 200, description = "User preferences", body = HashMap<String, serde_json::Value>)
513 )
514)]
515pub async fn get_user_preferences(
516 State(_state): State<ApiState>,
517) -> ApiResult<Json<HashMap<String, serde_json::Value>>> {
518 let mut prefs = HashMap::new();
519 prefs.insert("adv_mode".to_string(), serde_json::json!(false));
520 prefs.insert("ui_magnification".to_string(), serde_json::json!(1.0));
521 prefs.insert(
522 "auto_pns_area_creation".to_string(),
523 serde_json::json!(true),
524 );
525
526 Ok(Json(prefs))
527}
528
529#[utoipa::path(
531 put,
532 path = "/v1/system/user_preferences",
533 tag = "system",
534 responses(
535 (status = 200, description = "Preferences updated", body = HashMap<String, String>)
536 )
537)]
538pub async fn put_user_preferences(
539 State(_state): State<ApiState>,
540 Json(_prefs): Json<HashMap<String, serde_json::Value>>,
541) -> ApiResult<Json<HashMap<String, String>>> {
542 Ok(Json(HashMap::from([(
543 "message".to_string(),
544 "User preferences updated successfully".to_string(),
545 )])))
546}
547
548#[utoipa::path(
550 get,
551 path = "/v1/system/cortical_area_types",
552 tag = "system",
553 responses(
554 (status = 200, description = "Cortical area types", body = Vec<String>)
555 )
556)]
557pub async fn get_cortical_area_types_list(
558 State(_state): State<ApiState>,
559) -> ApiResult<Json<Vec<String>>> {
560 Ok(Json(vec![
561 "Sensory".to_string(),
562 "Motor".to_string(),
563 "Custom".to_string(),
564 "Memory".to_string(),
565 "Core".to_string(),
566 ]))
567}
568
569#[utoipa::path(
571 post,
572 path = "/v1/system/enable_visualization_fq_sampler",
573 tag = "system",
574 responses(
575 (status = 200, description = "FQ sampler enabled", body = HashMap<String, String>)
576 )
577)]
578pub async fn post_enable_visualization_fq_sampler(
579 State(state): State<ApiState>,
580) -> ApiResult<Json<HashMap<String, String>>> {
581 let runtime_service = state.runtime_service.as_ref();
582
583 runtime_service
584 .set_fcl_sampler_config(None, Some(1))
585 .await
586 .map_err(|e| ApiError::internal(format!("Failed to enable FQ sampler: {}", e)))?;
587
588 Ok(Json(HashMap::from([(
589 "message".to_string(),
590 "Visualization FQ sampler enabled".to_string(),
591 )])))
592}
593
594#[utoipa::path(
596 post,
597 path = "/v1/system/disable_visualization_fq_sampler",
598 tag = "system",
599 responses(
600 (status = 200, description = "FQ sampler disabled", body = HashMap<String, String>)
601 )
602)]
603pub async fn post_disable_visualization_fq_sampler(
604 State(state): State<ApiState>,
605) -> ApiResult<Json<HashMap<String, String>>> {
606 let runtime_service = state.runtime_service.as_ref();
607
608 runtime_service
609 .set_fcl_sampler_config(None, Some(0))
610 .await
611 .map_err(|e| ApiError::internal(format!("Failed to disable FQ sampler: {}", e)))?;
612
613 Ok(Json(HashMap::from([(
614 "message".to_string(),
615 "Visualization FQ sampler disabled".to_string(),
616 )])))
617}
618
619#[utoipa::path(
621 get,
622 path = "/v1/system/fcl_status",
623 tag = "system",
624 responses(
625 (status = 200, description = "FCL status", body = HashMap<String, serde_json::Value>)
626 )
627)]
628pub async fn get_fcl_status_system(
629 State(state): State<ApiState>,
630) -> ApiResult<Json<HashMap<String, serde_json::Value>>> {
631 let runtime_service = state.runtime_service.as_ref();
632
633 let (frequency, consumer) = runtime_service
634 .get_fcl_sampler_config()
635 .await
636 .map_err(|e| ApiError::internal(format!("Failed to get FCL status: {}", e)))?;
637
638 let mut response = HashMap::new();
639 response.insert("available".to_string(), serde_json::json!(true));
640 response.insert("frequency".to_string(), serde_json::json!(frequency));
641 response.insert("consumer".to_string(), serde_json::json!(consumer));
642 response.insert("enabled".to_string(), serde_json::json!(consumer > 0));
643
644 Ok(Json(response))
645}
646
647#[utoipa::path(
649 post,
650 path = "/v1/system/fcl_reset",
651 tag = "system",
652 responses(
653 (status = 200, description = "FCL reset", body = HashMap<String, String>)
654 )
655)]
656pub async fn post_fcl_reset_system(
657 State(_state): State<ApiState>,
658) -> ApiResult<Json<HashMap<String, String>>> {
659 tracing::info!(target: "feagi-api", "FCL reset requested");
660
661 Ok(Json(HashMap::from([(
662 "message".to_string(),
663 "FCL reset successfully".to_string(),
664 )])))
665}
666
667#[utoipa::path(
669 get,
670 path = "/v1/system/processes",
671 tag = "system",
672 responses(
673 (status = 200, description = "Active processes", body = HashMap<String, serde_json::Value>)
674 )
675)]
676pub async fn get_processes(
677 State(state): State<ApiState>,
678) -> ApiResult<Json<HashMap<String, serde_json::Value>>> {
679 let runtime_service = state.runtime_service.as_ref();
680
681 let status = runtime_service
682 .get_status()
683 .await
684 .map_err(|e| ApiError::internal(format!("Failed to get processes: {}", e)))?;
685
686 let mut processes = HashMap::new();
687 processes.insert(
688 "burst_engine".to_string(),
689 serde_json::json!({
690 "active": status.is_running,
691 "paused": status.is_paused
692 }),
693 );
694 processes.insert(
695 "api_server".to_string(),
696 serde_json::json!({"active": true}),
697 );
698
699 Ok(Json(processes))
700}
701
702#[utoipa::path(
704 get,
705 path = "/v1/system/unique_logs",
706 tag = "system",
707 responses(
708 (status = 200, description = "Unique logs", body = HashMap<String, Vec<String>>)
709 )
710)]
711pub async fn get_unique_logs(
712 State(_state): State<ApiState>,
713) -> ApiResult<Json<HashMap<String, Vec<String>>>> {
714 let mut response = HashMap::new();
715 response.insert("logs".to_string(), Vec::new());
716
717 Ok(Json(response))
718}
719
720#[utoipa::path(
722 post,
723 path = "/v1/system/logs",
724 tag = "system",
725 responses(
726 (status = 200, description = "Log config updated", body = HashMap<String, String>)
727 )
728)]
729pub async fn post_logs(
730 State(_state): State<ApiState>,
731 Json(_config): Json<HashMap<String, serde_json::Value>>,
732) -> ApiResult<Json<HashMap<String, String>>> {
733 Ok(Json(HashMap::from([(
734 "message".to_string(),
735 "Log configuration updated".to_string(),
736 )])))
737}
738
739#[utoipa::path(
741 get,
742 path = "/v1/system/beacon/subscribers",
743 tag = "system",
744 responses(
745 (status = 200, description = "Beacon subscribers", body = Vec<String>)
746 )
747)]
748pub async fn get_beacon_subscribers(
749 State(_state): State<ApiState>,
750) -> ApiResult<Json<Vec<String>>> {
751 Ok(Json(Vec::new()))
752}
753
754#[utoipa::path(
756 post,
757 path = "/v1/system/beacon/subscribe",
758 tag = "system",
759 responses(
760 (status = 200, description = "Subscribed", body = HashMap<String, String>)
761 )
762)]
763pub async fn post_beacon_subscribe(
764 State(_state): State<ApiState>,
765 Json(_request): Json<HashMap<String, String>>,
766) -> ApiResult<Json<HashMap<String, String>>> {
767 Ok(Json(HashMap::from([(
768 "message".to_string(),
769 "Subscribed to beacon".to_string(),
770 )])))
771}
772
773#[utoipa::path(
775 delete,
776 path = "/v1/system/beacon/unsubscribe",
777 tag = "system",
778 responses(
779 (status = 200, description = "Unsubscribed", body = HashMap<String, String>)
780 )
781)]
782pub async fn delete_beacon_unsubscribe(
783 State(_state): State<ApiState>,
784 Json(_request): Json<HashMap<String, String>>,
785) -> ApiResult<Json<HashMap<String, String>>> {
786 Ok(Json(HashMap::from([(
787 "message".to_string(),
788 "Unsubscribed from beacon".to_string(),
789 )])))
790}
791
792#[utoipa::path(
794 get,
795 path = "/v1/system/global_activity_visualization",
796 tag = "system",
797 responses(
798 (status = 200, description = "Global activity viz status", body = HashMap<String, serde_json::Value>)
799 )
800)]
801pub async fn get_global_activity_visualization(
802 State(_state): State<ApiState>,
803) -> ApiResult<Json<HashMap<String, serde_json::Value>>> {
804 let mut response = HashMap::new();
805 response.insert("enabled".to_string(), serde_json::json!(false));
806 response.insert("frequency_hz".to_string(), serde_json::json!(30.0));
807
808 Ok(Json(response))
809}
810
811#[utoipa::path(
813 put,
814 path = "/v1/system/global_activity_visualization",
815 tag = "system",
816 responses(
817 (status = 200, description = "Configured", body = HashMap<String, String>)
818 )
819)]
820pub async fn put_global_activity_visualization(
821 State(_state): State<ApiState>,
822 Json(_config): Json<HashMap<String, serde_json::Value>>,
823) -> ApiResult<Json<HashMap<String, String>>> {
824 Ok(Json(HashMap::from([(
825 "message".to_string(),
826 "Global activity visualization configured".to_string(),
827 )])))
828}
829
830#[utoipa::path(
832 post,
833 path = "/v1/system/circuit_library_path",
834 tag = "system",
835 responses(
836 (status = 200, description = "Path set", body = HashMap<String, String>)
837 )
838)]
839pub async fn post_circuit_library_path(
840 State(_state): State<ApiState>,
841 Json(_request): Json<HashMap<String, String>>,
842) -> ApiResult<Json<HashMap<String, String>>> {
843 Ok(Json(HashMap::from([(
844 "message".to_string(),
845 "Circuit library path updated".to_string(),
846 )])))
847}
848
849#[utoipa::path(
851 get,
852 path = "/v1/system/db/influxdb/test",
853 tag = "system",
854 responses(
855 (status = 200, description = "Test result", body = HashMap<String, bool>)
856 )
857)]
858pub async fn get_influxdb_test(
859 State(_state): State<ApiState>,
860) -> ApiResult<Json<HashMap<String, bool>>> {
861 let mut response = HashMap::new();
862 response.insert("connected".to_string(), false);
863 response.insert("available".to_string(), false);
864
865 Ok(Json(response))
866}
867
868#[utoipa::path(
870 post,
871 path = "/v1/system/register",
872 tag = "system",
873 responses(
874 (status = 200, description = "Registered", body = HashMap<String, String>)
875 )
876)]
877pub async fn post_register_system(
878 State(_state): State<ApiState>,
879 Json(_request): Json<HashMap<String, serde_json::Value>>,
880) -> ApiResult<Json<HashMap<String, String>>> {
881 Ok(Json(HashMap::from([(
882 "message".to_string(),
883 "System component registered".to_string(),
884 )])))
885}