diff --git a/src/api/db_vendo_navigator.rs b/src/api/db_vendo_navigator.rs index 89ef122..68fcf04 100644 --- a/src/api/db_vendo_navigator.rs +++ b/src/api/db_vendo_navigator.rs @@ -17,6 +17,7 @@ pub async fn get_railcar_identifier_by_journey( } fn find_railcar_identifier(train_ordering: TrainOrdering) -> Result { + //TODO: refactor - trainsets can consist out of several trains let trainset = train_ordering.train_sets.first() .ok_or(ResolveTripNumberError::Api("No items in field 'fahrzeuggruppe'".to_string()))?; let identifier_str = trainset.identifier.to_owned(); diff --git a/src/api/handlers/webhook.rs b/src/api/handlers/webhook.rs index aeca59f..71d3c41 100644 --- a/src/api/handlers/webhook.rs +++ b/src/api/handlers/webhook.rs @@ -7,7 +7,7 @@ use axum::{ use axum_core::response::IntoResponse; use chrono::DateTime; use serde::Deserialize; -use sqlx::PgPool; +use sqlx::{Error, PgPool}; use sqlx::postgres::PgQueryResult; use crate::api::db_vendo_navigator::get_railcar_identifier_by_journey; use crate::error::train_order_api_error::{CheckInError, ResolveTripNumberError}; @@ -46,14 +46,20 @@ async fn receive_travelynx_checkin( ) .await .map_err(|e| CheckInError::from(e))?; - let train = get_train_by_identifier(railcar_identifier as i32, db.clone()) - .await - .map_err(|e| ResolveTripNumberError::from(e)) - .map_err(|e| CheckInError::from(e))?; + let train_result = get_train_by_identifier(railcar_identifier as i32, db.clone()) + .await; + let train = train_result + .map_err(|e| { + match e { + Error::RowNotFound => CheckInError::TrainNotFound, + e => CheckInError::from(ResolveTripNumberError::from(e)) + } + })?; println!("Train: {:?}", train); - record_journey(user, train, check_in.status.from_station.scheduled_time.unwrap(), db) + let result = record_journey(user, train, check_in.status.from_station.scheduled_time.unwrap(), db) .await - .expect("Failed to check in!"); + .map_err(|e| CheckInError::from(ResolveTripNumberError::from(e)))?; + println!("Journey recorded: {:?}", result); let message = format!( "Successfully checked into {} {} ({}), departing from station {} at {}", check_in.status.train.train_type.unwrap(), @@ -63,7 +69,7 @@ async fn receive_travelynx_checkin( check_in.status.from_station.scheduled_time.unwrap() ); Ok::<_, CheckInError>(( - StatusCode::OK, + StatusCode::CREATED, message ).into_response()) }, diff --git a/src/error/train_order_api_error.rs b/src/error/train_order_api_error.rs index 246277d..65e4012 100644 --- a/src/error/train_order_api_error.rs +++ b/src/error/train_order_api_error.rs @@ -54,6 +54,7 @@ impl From for ResolveTripNumberError { #[derive(Debug)] pub enum CheckInError { ResolveError(ResolveTripNumberError), + TrainNotFound, } impl From for CheckInError { @@ -65,6 +66,7 @@ impl Display for CheckInError { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { match self { CheckInError::ResolveError(e) => f.write_str(e.to_string().as_str()), + CheckInError::TrainNotFound => f.write_str("Train not found"), } } } @@ -73,9 +75,9 @@ pub type ApiResult = Result; impl IntoResponse for CheckInError { fn into_response(self) -> axum_core::response::Response { - ( - StatusCode::INTERNAL_SERVER_ERROR, - format!("Error processing checkin: {}", self) - ).into_response() + match self { + CheckInError::TrainNotFound => (StatusCode::OK, format!("Train not found")), + _ => (StatusCode::INTERNAL_SERVER_ERROR, format!("Error processing checkin: {}", self)), + }.into_response() } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index a676e22..e36f6a4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -20,7 +20,7 @@ async fn main() { .await.expect("Unable to load config"); let state: AppState = AppState::new(config.clone()).await.unwrap(); - //migrate(state.clone()).await.expect("Database migration failed"); + migrate(state.clone()).await.expect("Database migration failed"); let router = build_router(state); let listener = listen(config).await; diff --git a/src/sql/migrations/2025051101_triebzuege.sql b/src/sql/migrations/2025051101_triebzuege.sql new file mode 100644 index 0000000..4c91b4c --- /dev/null +++ b/src/sql/migrations/2025051101_triebzuege.sql @@ -0,0 +1,123 @@ +INSERT INTO triebzug (uuid, tz_id, name) +VALUES (gen_random_uuid(), 101, 'Gießen'), + (gen_random_uuid(), 102, 'Jever'), + (gen_random_uuid(), 103, 'Neu-Isenburg'), + (gen_random_uuid(), 104, 'Fulda'), + (gen_random_uuid(), 105, 'Offenbach am Main'), + (gen_random_uuid(), 106, 'Itzehoe'), + (gen_random_uuid(), 107, 'Plattling'), + (gen_random_uuid(), 108, 'Lichtenfels'), + (gen_random_uuid(), 109, 'Lüneburg'), + (gen_random_uuid(), 110, 'Gelsenkirchen'), + (gen_random_uuid(), 111, 'Nürnberg'), + (gen_random_uuid(), 112, 'Memmingen'), + (gen_random_uuid(), 113, 'Frankenthal/Pfalz'), + (gen_random_uuid(), 114, 'Friedrichshafen'), + (gen_random_uuid(), 115, 'Regensburg'), + (gen_random_uuid(), 116, 'Pforzheim'), + (gen_random_uuid(), 117, 'Hof'), + (gen_random_uuid(), 119, 'Osnabrück'), + (gen_random_uuid(), 152, 'Hanau'), + (gen_random_uuid(), 153, 'Neumünster'), + (gen_random_uuid(), 154, 'Flensburg'), + (gen_random_uuid(), 155, 'Rosenheim'), + (gen_random_uuid(), 156, 'Heppenheim/Bergstraße'), + (gen_random_uuid(), 157, 'Landshut'), + (gen_random_uuid(), 158, 'Gütersloh'), + (gen_random_uuid(), 159, 'Bad Oldesloe'), + (gen_random_uuid(), 160, 'Mülheim an der Ruhr'), + (gen_random_uuid(), 161, 'Bebra'), + (gen_random_uuid(), 162, 'Geisenheim/Rheingau'), + (gen_random_uuid(), 166, 'Gelnhausen'), + (gen_random_uuid(), 167, 'Garmisch-Partenkirchen'), + (gen_random_uuid(), 168, 'Crailsheim'), + (gen_random_uuid(), 169, 'Worms'), + (gen_random_uuid(), 171, 'Heusenstamm'), + (gen_random_uuid(), 172, 'Aschaffenburg'), + (gen_random_uuid(), 173, 'Basel'), + (gen_random_uuid(), 174, 'Zürich'), + (gen_random_uuid(), 175, 'Nürnberg'), + (gen_random_uuid(), 176, 'Bremen'), + (gen_random_uuid(), 177, 'Rendsburg'), + (gen_random_uuid(), 178, 'Bremerhaven'), + (gen_random_uuid(), 179, 'Chur'), + (gen_random_uuid(), 180, 'Castrop-Rauxel'), + (gen_random_uuid(), 181, 'Interlaken'), + (gen_random_uuid(), 182, 'Rüdesheim am Rhein'), + (gen_random_uuid(), 183, 'Timmendorfer Strand'), + (gen_random_uuid(), 184, 'Bruchsal'), + (gen_random_uuid(), 185, 'Freilassing'), + (gen_random_uuid(), 186, 'Chur'), + (gen_random_uuid(), 187, 'Mühldorf a. Inn'), + (gen_random_uuid(), 188, 'Hildesheim'), + (gen_random_uuid(), 189, 'Castrop-Rauxel'), + (gen_random_uuid(), 190, 'Ludwigshafen am Rhein'), + (gen_random_uuid(), 301, 'Freiburg im Breisgau'), + (gen_random_uuid(), 302, 'Hansestadt Lübeck'), + (gen_random_uuid(), 303, 'Dortmund'), + (gen_random_uuid(), 304, 'München'), + (gen_random_uuid(), 305, 'Baden-Baden'), + (gen_random_uuid(), 306, 'Nördlingen'), + (gen_random_uuid(), 307, 'Oberhausen'), + (gen_random_uuid(), 308, 'Murnau am Staffelsee'), + (gen_random_uuid(), 309, 'Aalen'), + (gen_random_uuid(), 310, 'Wolfsburg'), + (gen_random_uuid(), 311, 'Wiesbaden'), + (gen_random_uuid(), 312, 'Montabaur'), + (gen_random_uuid(), 313, 'Treuchtlingen'), + (gen_random_uuid(), 314, 'Bergisch Gladbach'), + (gen_random_uuid(), 315, 'Singen (Hohentwiel)'), + (gen_random_uuid(), 316, 'Siegburg'), + (gen_random_uuid(), 317, 'Recklinghausen'), + (gen_random_uuid(), 318, 'Münster (Westf.)'), + (gen_random_uuid(), 319, 'Duisburg'), + (gen_random_uuid(), 320, 'Weil am Rhein'), + (gen_random_uuid(), 321, 'Krefeld'), + (gen_random_uuid(), 322, 'Solingen'), + (gen_random_uuid(), 323, 'Schaffhausen'), + (gen_random_uuid(), 324, 'Fürth'), + (gen_random_uuid(), 325, 'Ravensburg'), + (gen_random_uuid(), 326, 'Neunkirchen'), + (gen_random_uuid(), 327, 'Siegen'), + (gen_random_uuid(), 328, 'Aachen'), + (gen_random_uuid(), 330, 'Göttingen'), + (gen_random_uuid(), 331, 'Westerland/Sylt'), + (gen_random_uuid(), 332, 'Augsburg'), + (gen_random_uuid(), 333, 'Goslar'), + (gen_random_uuid(), 334, 'Offenburg'), + (gen_random_uuid(), 335, 'Konstanz'), + (gen_random_uuid(), 336, 'Ingolstadt'), + (gen_random_uuid(), 337, 'Stuttgart'), + (gen_random_uuid(), 351, 'Herford'), + (gen_random_uuid(), 352, 'Mönchengladbach'), + (gen_random_uuid(), 353, 'Neu-Ulm'), + (gen_random_uuid(), 354, 'Mittenwald'), + (gen_random_uuid(), 355, 'Tuttlingen'), + (gen_random_uuid(), 357, 'Esslingen am Neckar'), + (gen_random_uuid(), 358, 'St. Ingbert'), + (gen_random_uuid(), 359, 'Leverkusen'), + (gen_random_uuid(), 360, 'Linz am Rhein'), + (gen_random_uuid(), 361, 'Celle'), + (gen_random_uuid(), 362, 'Schwerte (Ruhr)'), + (gen_random_uuid(), 363, 'Weilheim i. OB'), + (gen_random_uuid(), 710, 'Ansbach'), + (gen_random_uuid(), 712, 'Dillingen a.d. Donau'), + (gen_random_uuid(), 717, 'Paris'), + (gen_random_uuid(), 8007, 'Rheinland'), + (gen_random_uuid(), 8019, 'Düsseldorf'), + (gen_random_uuid(), 8020, 'Amsterdam'), + (gen_random_uuid(), 8022, 'Waldecker Land'), + (gen_random_uuid(), 8029, 'Europa/Europe'), + (gen_random_uuid(), 9006, 'Martin Luther'), + (gen_random_uuid(), 9018, 'Freistaat Bayern'), + (gen_random_uuid(), 9025, 'Nordrhein-Westfalen'), + (gen_random_uuid(), 9026, 'Zürichsee'), + (gen_random_uuid(), 9028, 'Freistaat Sachsen'), + (gen_random_uuid(), 9041, 'Baden-Württemberg'), + (gen_random_uuid(), 9050, 'Metropole Ruhr'), + (gen_random_uuid(), 9202, 'Schleswig-Holstein'), + (gen_random_uuid(), 9208, 'Nationalpark Bayerischer Wald'), + (gen_random_uuid(), 9234, 'Ruhr'), + (gen_random_uuid(), 9237, 'Spree'), + (gen_random_uuid(), 9457, 'Bundesrepublik Deutschland'), + (gen_random_uuid(), 9481, 'Rheinland-Pfalz'); \ No newline at end of file