2026-02-23 09:57:22 -05:00
|
|
|
use std::error::Error;
|
|
|
|
|
|
2026-02-23 19:45:19 -05:00
|
|
|
use axum::{Json, Router, extract::Path, http::StatusCode, routing::get};
|
2026-02-23 09:57:22 -05:00
|
|
|
use log::{debug, error, info};
|
2026-02-17 09:34:22 -05:00
|
|
|
use tower_http::services::ServeDir;
|
|
|
|
|
|
2026-02-19 11:24:23 -05:00
|
|
|
use crate::{
|
|
|
|
|
db,
|
|
|
|
|
model::{devices::Device, notifications::Notification},
|
|
|
|
|
};
|
2026-02-17 12:15:46 -05:00
|
|
|
|
2026-02-23 09:57:22 -05:00
|
|
|
pub async fn serve() -> Result<(), Box<dyn Error>> {
|
2026-02-17 09:34:22 -05:00
|
|
|
info!("Starting web server");
|
|
|
|
|
let static_files = ServeDir::new("./web");
|
|
|
|
|
|
|
|
|
|
let router = Router::new()
|
|
|
|
|
.route("/", get(|| async { "hello" }))
|
2026-02-23 19:45:19 -05:00
|
|
|
.route("/api/devices", get(get_devices))
|
|
|
|
|
.route("/api/notifications", get(list_notifications))
|
|
|
|
|
.route("/api/notifications/{id}", get(read_notification))
|
|
|
|
|
.route(
|
|
|
|
|
"/api/notifications/{id}/read_without_flagging",
|
|
|
|
|
get(read_notification_without_flagging),
|
|
|
|
|
)
|
2026-02-17 09:34:22 -05:00
|
|
|
.nest_service("/web", static_files);
|
2026-02-23 09:57:22 -05:00
|
|
|
info!("Web server starting at http://0.0.0.0:3000");
|
2026-02-17 09:34:22 -05:00
|
|
|
// Start the server
|
2026-02-23 09:57:22 -05:00
|
|
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
|
|
|
|
|
|
|
|
|
|
debug!("Web server bound to IP and port");
|
|
|
|
|
|
|
|
|
|
axum::serve(listener, router).await?;
|
2026-02-17 09:34:22 -05:00
|
|
|
Ok(())
|
|
|
|
|
}
|
2026-02-17 12:15:46 -05:00
|
|
|
|
|
|
|
|
async fn get_devices() -> Result<Json<Vec<Device>>, StatusCode> {
|
2026-02-23 19:45:19 -05:00
|
|
|
unimplemented!();
|
|
|
|
|
}
|
2026-02-17 12:15:46 -05:00
|
|
|
|
2026-02-23 19:45:19 -05:00
|
|
|
async fn read_notification(Path(id): Path<i64>) -> Result<Json<Notification>, StatusCode> {
|
|
|
|
|
match db::notifications::mark_as_old(id) {
|
|
|
|
|
Ok(_) => {}
|
|
|
|
|
Err(err) => {
|
|
|
|
|
error!("Error marking notification (id={id}) as old: {}", err);
|
|
|
|
|
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
|
|
|
|
}
|
|
|
|
|
};
|
2026-02-17 12:15:46 -05:00
|
|
|
|
2026-02-23 19:45:19 -05:00
|
|
|
match db::notifications::read(id) {
|
|
|
|
|
Some(value) => Ok(Json(value)),
|
|
|
|
|
None => Err(StatusCode::NOT_FOUND),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn read_notification_without_flagging(
|
|
|
|
|
Path(id): Path<i64>,
|
|
|
|
|
) -> Result<Json<Notification>, StatusCode> {
|
|
|
|
|
match db::notifications::read(id) {
|
|
|
|
|
Some(value) => Ok(Json(value)),
|
|
|
|
|
None => Err(StatusCode::NOT_FOUND),
|
|
|
|
|
}
|
2026-02-17 12:15:46 -05:00
|
|
|
}
|
2026-02-19 11:24:23 -05:00
|
|
|
|
|
|
|
|
async fn list_notifications() -> Result<Json<Vec<Notification>>, StatusCode> {
|
|
|
|
|
match db::notifications::list() {
|
|
|
|
|
Ok(value) => Ok(Json(value)),
|
|
|
|
|
Err(err) => {
|
|
|
|
|
error!("Error listing notifications: {}", err);
|
|
|
|
|
Err(StatusCode::INTERNAL_SERVER_ERROR)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|