Working on email templating, updating with swagger

This commit is contained in:
2025-05-14 20:33:13 -04:00
parent 1e3c75624a
commit e46e8ab9b4
41 changed files with 1124 additions and 189 deletions

View File

@@ -1,5 +1,5 @@
mod model;
mod routes;
pub mod model;
pub mod routes;
pub use model::*;
pub use routes::init_routes;

View File

@@ -1,20 +1,22 @@
use std::collections::HashMap;
use std::str::FromStr;
use crate::airports::{
AirportCategory, Communication, CommunicationRow, Runway, RunwayRow, UpdateCommunication,
UpdateRunway,
};
use crate::db;
use crate::error::{ApiResult, Error};
use crate::metars::Metar;
use chrono::{DateTime, Utc};
use futures_util::try_join;
use reqwest::Client;
use serde::{Deserialize, Serialize};
use sqlx::{Postgres, QueryBuilder};
use crate::airports::{
AirportCategory, Communication, CommunicationRow, Runway, RunwayRow, UpdateCommunication, UpdateRunway,
};
use crate::db;
use crate::error::{ApiResult, Error};
use crate::metars::Metar;
use std::collections::HashMap;
use std::str::FromStr;
use utoipa::{IntoParams, ToSchema};
const TABLE_NAME: &str = "airports";
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct Airport {
pub icao: String,
#[serde(skip_serializing_if = "Option::is_none")]
@@ -40,7 +42,8 @@ pub struct Airport {
pub latest_metar: Option<Metar>,
}
#[derive(Debug, Deserialize)]
#[derive(Debug, Deserialize, ToSchema, IntoParams)]
#[into_params(parameter_in = Query)]
pub struct AirportQuery {
pub page: Option<u32>,
pub limit: Option<u32>,
@@ -75,7 +78,7 @@ impl Default for AirportQuery {
}
}
#[derive(Debug, Deserialize)]
#[derive(Debug, Deserialize, ToSchema)]
pub struct Bounds {
pub north_east_lat: f32,
pub north_east_lon: f32,
@@ -125,7 +128,7 @@ struct AirportRow {
pub metar_observation_time: Option<DateTime<Utc>>,
}
#[derive(Debug, Deserialize)]
#[derive(Debug, Deserialize, ToSchema)]
pub struct UpdateAirport {
pub icao: Option<String>,
pub iata: Option<String>,

View File

@@ -1,8 +1,9 @@
use serde::{Deserialize, Serialize};
use std::fmt::Display;
use std::str::FromStr;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub enum AirportCategory {
#[serde(rename = "small_airport")]
Small,

View File

@@ -1,13 +1,14 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use sqlx::{Postgres, QueryBuilder};
use uuid::Uuid;
use crate::db;
use crate::error::ApiResult;
use serde::{Deserialize, Serialize};
use sqlx::{Postgres, QueryBuilder};
use std::collections::HashMap;
use utoipa::ToSchema;
use uuid::Uuid;
const TABLE_NAME: &str = "communications";
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Communication {
pub id: String,
#[serde(skip_serializing_if = "Option::is_none")]
@@ -27,7 +28,7 @@ pub struct CommunicationRow {
pub phone: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct UpdateCommunication {
#[serde(skip_serializing_if = "Option::is_none")]
pub icao: Option<String>,

View File

@@ -1,13 +1,14 @@
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
use sqlx::{Postgres, QueryBuilder};
use uuid::Uuid;
use crate::db;
use crate::error::ApiResult;
use serde::{Deserialize, Serialize};
use sqlx::{Postgres, QueryBuilder};
use std::collections::HashMap;
use utoipa::ToSchema;
use uuid::Uuid;
const TABLE_NAME: &str = "runways";
#[derive(Debug, Clone, Serialize, Deserialize)]
#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
pub struct Runway {
#[serde(rename = "id")]
pub runway_id: String,
@@ -26,7 +27,7 @@ pub struct RunwayRow {
pub surface: String,
}
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, ToSchema)]
pub struct UpdateRunway {
#[serde(skip_serializing_if = "Option::is_none")]
pub icao: Option<String>,

View File

@@ -1,16 +1,39 @@
use futures_util::stream::StreamExt as _;
use crate::{
airports::Airport,
db::Paged,
account::{Auth, verify_role},
AppState,
};
use actix_multipart::Multipart;
use actix_web::{delete, get, post, put, web, HttpResponse, HttpRequest, ResponseError};
use crate::airports::{AirportQuery, UpdateAirport};
use crate::users::ADMIN_ROLE;
use crate::{
AppState,
account::{Auth, verify_role},
airports::Airport,
db::Paged,
};
use actix_multipart::Multipart;
use actix_web::{HttpRequest, HttpResponse, ResponseError, delete, get, post, put, web};
use utoipa::ToSchema;
use utoipa_actix_web::scope;
use utoipa_actix_web::service_config::ServiceConfig;
#[derive(ToSchema)]
#[allow(unused)]
struct UploadedFile {
#[schema(value_type = String, format = Binary)]
file: Vec<u8>,
}
#[utoipa::path(
tag = "Airports",
request_body(
content = UploadedFile, content_type = "multipart/form-data"
),
responses(
(status = 200, description = "Successful import"),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[post("/import")]
async fn import_airports(mut payload: Multipart, auth: Auth) -> HttpResponse {
if let Err(err) = verify_role(&auth, ADMIN_ROLE) {
@@ -53,6 +76,15 @@ async fn import_airports(mut payload: Multipart, auth: Auth) -> HttpResponse {
HttpResponse::Ok().finish()
}
#[utoipa::path(
tag = "Airports",
params(
AirportQuery
),
responses(
(status = 200, description = "", body = [Airport]),
),
)]
#[get("")]
async fn get_airports(data: web::Data<AppState>, req: HttpRequest) -> HttpResponse {
let mut query = match web::Query::<AirportQuery>::from_query(req.query_string()) {
@@ -87,6 +119,13 @@ async fn get_airports(data: web::Data<AppState>, req: HttpRequest) -> HttpRespon
}
}
#[utoipa::path(
tag = "Airports",
responses(
(status = 200, description = "", body = Airport),
(status = 404, description = ""),
),
)]
#[get("/{icao}")]
async fn get_airport(
data: web::Data<AppState>,
@@ -108,6 +147,17 @@ async fn get_airport(
}
}
#[utoipa::path(
tag = "Airports",
responses(
(status = 200, description = "", body = Airport),
(status = 401, description = ""),
(status = 409, description = ""),
),
security(
("session_auth" = [])
)
)]
#[post("")]
async fn insert_airport(airport: web::Json<Airport>, auth: Auth) -> HttpResponse {
let _ = match verify_role(&auth, ADMIN_ROLE) {
@@ -123,6 +173,16 @@ async fn insert_airport(airport: web::Json<Airport>, auth: Auth) -> HttpResponse
}
}
#[utoipa::path(
tag = "Airports",
responses(
(status = 200, description = "", body = Airport),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[put("/{icao}")]
async fn update_airport(
icao: web::Path<String>,
@@ -142,6 +202,16 @@ async fn update_airport(
}
}
#[utoipa::path(
tag = "Airports",
responses(
(status = 201, description = ""),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[delete("")]
async fn delete_airports(auth: Auth) -> HttpResponse {
let _ = match verify_role(&auth, ADMIN_ROLE) {
@@ -157,6 +227,16 @@ async fn delete_airports(auth: Auth) -> HttpResponse {
}
}
#[utoipa::path(
tag = "Airports",
responses(
(status = 201, description = ""),
(status = 401, description = ""),
),
security(
("session_auth" = [])
)
)]
#[delete("/{icao}")]
async fn delete_airport(icao: web::Path<String>, auth: Auth) -> HttpResponse {
let _ = match verify_role(&auth, ADMIN_ROLE) {
@@ -172,9 +252,9 @@ async fn delete_airport(icao: web::Path<String>, auth: Auth) -> HttpResponse {
}
}
pub fn init_routes(config: &mut web::ServiceConfig) {
pub fn init_routes(config: &mut ServiceConfig) {
config.service(
web::scope("airports")
scope::scope("/airports")
.service(import_airports)
.service(get_airports)
.service(get_airport)