From 7a896c8b7c45c1bd5a52302702acc450b5c0f96e Mon Sep 17 00:00:00 2001 From: Hector van der Aa <103751865+H3ct0r55@users.noreply.github.com> Date: Mon, 1 Dec 2025 00:36:21 +0100 Subject: [PATCH 1/2] Restore startup banner output --- src/backend/AGENTS.md | 1 + src/backend/src/auth/mod.rs | 4 ++-- src/backend/src/core/user_routines.rs | 32 ++++++++++++++++----------- src/backend/src/domain/user.rs | 3 --- src/backend/src/domain/user_prems.rs | 2 +- src/backend/src/infra/db/mod.rs | 5 +++++ src/backend/src/infra/db/perms.rs | 8 ++++++- src/backend/src/infra/db/user.rs | 12 ++++++++++ src/backend/src/main.rs | 18 ++++++++++++++- src/backend/src/router/middleware.rs | 13 ++++++----- src/backend/src/router/mod.rs | 13 ++++++++--- src/backend/src/router/user_routes.rs | 8 ++++++- src/backend/src/state.rs | 12 +++++----- 13 files changed, 96 insertions(+), 35 deletions(-) diff --git a/src/backend/AGENTS.md b/src/backend/AGENTS.md index 5abf3c1..23116eb 100644 --- a/src/backend/AGENTS.md +++ b/src/backend/AGENTS.md @@ -95,6 +95,7 @@ Agents should insert at least: - Improve error messages and error‑mapping logic. - Add missing context fields to logs. - Ensure compliance with this standard. +- Preserve the startup `println!` banner and metadata in `src/backend/src/main.rs` for debug visibility. ### Agents **may not**: - Modify business logic, algorithms, backend behavior, or API responses (other than error messages). diff --git a/src/backend/src/auth/mod.rs b/src/backend/src/auth/mod.rs index 31427f3..b4abc90 100644 --- a/src/backend/src/auth/mod.rs +++ b/src/backend/src/auth/mod.rs @@ -1,6 +1,6 @@ use argon2::{ Argon2, - password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString, rand_core::OsRng}, + password_hash::{PasswordHasher, SaltString, rand_core::OsRng}, }; use tracing::debug; @@ -10,6 +10,6 @@ pub fn hash_password(password: &str) -> Result { let hash = argon2 .hash_password(password.as_bytes(), &salt)? .to_string(); - debug!("Hashed password {}", hash); + debug!("password hashed"); Ok(hash) } diff --git a/src/backend/src/core/user_routines.rs b/src/backend/src/core/user_routines.rs index c683b74..adb64f4 100644 --- a/src/backend/src/core/user_routines.rs +++ b/src/backend/src/core/user_routines.rs @@ -1,18 +1,15 @@ use crate::{ - domain::{ - user::{self, InternalUser}, - user_prems::UserPermissions, - }, + domain::{user::InternalUser, user_prems::UserPermissions}, infra::db, prelude::*, }; use std::sync::Arc; -use axum::{Json, http::StatusCode}; +use axum::http::StatusCode; use uuid::Uuid; use validator::Validate; -use anyhow::{Context, anyhow}; +use anyhow::Context; use crate::{ domain::user::{InternalNewUser, NewUser, User}, @@ -20,29 +17,33 @@ use crate::{ }; pub async fn create(state: Arc, new_user: NewUser) -> Result { + debug!("create user started"); + new_user.validate().map_err(|e| { - error!("User validation failed: {e}"); + error!(error = %e, "user validation failed"); StatusCode::BAD_REQUEST })?; let internal = InternalNewUser::try_from(new_user).map_err(|e| { - error!("Conversion to InternalUser failed: {e}"); + error!(error = %e, "convert to internal user failed"); StatusCode::INTERNAL_SERVER_ERROR })?; let created_user = db::user::create(&state.db_pool, internal) .await .map_err(|e| { - error!("Failed to create new user: {e}"); + error!(error = %e, "create user failed"); StatusCode::INTERNAL_SERVER_ERROR })?; + info!(user_uuid = %created_user.uuid, "user created"); Ok(User::from(created_user)) } pub async fn get_all(state: Arc) -> Result, StatusCode> { + debug!("fetch all users started"); let users = db::user::get_safe_all(&state.db_pool).await.map_err(|e| { - error!("Failed to fetch all users: {e}"); + error!(error = %e, "fetch all users failed"); StatusCode::INTERNAL_SERVER_ERROR })?; @@ -53,16 +54,18 @@ pub async fn get_safe_by_uuid( state: Arc, uuid: Uuid, ) -> Result, StatusCode> { + debug!(user_uuid = %uuid, "fetch user by uuid started"); let user = db::user::get_safe_by_uuid(&state.db_pool, uuid.clone()) .await .map_err(|e| { - error!("Failed to fetch user: {e}"); + error!(error = %e, user_uuid = %uuid, "fetch user failed"); StatusCode::INTERNAL_SERVER_ERROR })?; Ok(user) } pub async fn get_by_uuid(state: Arc, uuid: Uuid) -> anyhow::Result> { + debug!(user_uuid = %uuid, "fetch internal user started"); let mut user = match db::user::get_by_uuid(&state.db_pool, uuid) .await .context("failed to fetch user by uuid")? @@ -93,23 +96,26 @@ pub async fn set_perms( state: Arc, user_perms: UserPermissions, ) -> Result<(), StatusCode> { + debug!(user_uuid = %user_perms.uuid, "assign permissions started"); let exists = db::user::exists_by_uuid(&state.db_pool, user_perms.uuid) .await .map_err(|e| { - error!("Failed to verify user exists: {e}"); + error!(error = %e, user_uuid = %user_perms.uuid, "verify user exists failed"); StatusCode::INTERNAL_SERVER_ERROR })?; if !exists { + warn!(user_uuid = %user_perms.uuid, "assign permissions skipped for missing user"); return Err(StatusCode::BAD_REQUEST); } db::perms::create(&state.db_pool, user_perms) .await .map_err(|e| { - error!("Failed to create user permissions entry: {e}"); + error!(error = %e, "create user permissions entry failed"); StatusCode::INTERNAL_SERVER_ERROR })?; + info!("user permissions assigned"); Ok(()) } diff --git a/src/backend/src/domain/user.rs b/src/backend/src/domain/user.rs index c599d14..5ef34d9 100644 --- a/src/backend/src/domain/user.rs +++ b/src/backend/src/domain/user.rs @@ -1,8 +1,5 @@ use std::fmt::Display; -use axum::response::IntoResponse; -use lazy_static::lazy_static; -use regex::Regex; use serde::{Deserialize, Serialize}; use sqlx::prelude::FromRow; use uuid::Uuid; diff --git a/src/backend/src/domain/user_prems.rs b/src/backend/src/domain/user_prems.rs index 08155b7..098f13e 100644 --- a/src/backend/src/domain/user_prems.rs +++ b/src/backend/src/domain/user_prems.rs @@ -1,4 +1,4 @@ -use serde::{Deserialize, de::value}; +use serde::Deserialize; use sqlx::prelude::FromRow; use uuid::Uuid; diff --git a/src/backend/src/infra/db/mod.rs b/src/backend/src/infra/db/mod.rs index 5948dd7..6a69cff 100644 --- a/src/backend/src/infra/db/mod.rs +++ b/src/backend/src/infra/db/mod.rs @@ -5,19 +5,24 @@ use std::time::Duration; use sqlx::{PgPool, postgres::PgPoolOptions}; +use crate::prelude::*; use anyhow::Result; pub async fn connect(database_url: &str) -> Result { + debug!("open postgres pool started"); let pool = PgPoolOptions::new() .max_connections(10) .acquire_timeout(Duration::from_secs(5)) .connect(database_url) .await?; + debug!("open postgres pool completed"); Ok(pool) } pub async fn migrate(pool: &PgPool) -> Result<()> { + debug!("database migration started"); sqlx::migrate!().run(pool).await?; + debug!("database migration completed"); Ok(()) } diff --git a/src/backend/src/infra/db/perms.rs b/src/backend/src/infra/db/perms.rs index 48bae1f..74a6181 100644 --- a/src/backend/src/infra/db/perms.rs +++ b/src/backend/src/infra/db/perms.rs @@ -2,9 +2,10 @@ use anyhow::Result; use sqlx::PgPool; use uuid::Uuid; -use crate::domain::{user::User, user_prems::UserPermissions}; +use crate::{domain::user_prems::UserPermissions, prelude::*}; pub async fn create(pool: &PgPool, new_perms: UserPermissions) -> Result { + debug!(user_uuid = %new_perms.uuid, "insert user permissions started"); let perms = sqlx::query_as::<_, UserPermissions>( r#" INSERT INTO user_permissions (uuid, root, manage_users, login) @@ -19,10 +20,12 @@ pub async fn create(pool: &PgPool, new_perms: UserPermissions) -> Result Result> { + debug!(user_uuid = %uuid, "fetch user permissions by uuid started"); let perms = sqlx::query_as::<_, UserPermissions>( r#" SELECT uuid, root, manage_users, login @@ -34,10 +37,12 @@ pub async fn get_by_uuid(pool: &PgPool, uuid: Uuid) -> Result Result { + debug!(user_uuid = %uuid, "check user permissions existence started"); let exists = sqlx::query_scalar::<_, bool>( r#" SELECT EXISTS( @@ -51,5 +56,6 @@ pub async fn exists_by_uuid(pool: &PgPool, uuid: Uuid) -> Result { .fetch_one(pool) .await?; + debug!(user_uuid = %uuid, "check user permissions existence completed"); Ok(exists) } diff --git a/src/backend/src/infra/db/user.rs b/src/backend/src/infra/db/user.rs index 64f6557..33caf6b 100644 --- a/src/backend/src/infra/db/user.rs +++ b/src/backend/src/infra/db/user.rs @@ -7,6 +7,7 @@ use sqlx::PgPool; use uuid::Uuid; pub async fn create(pool: &PgPool, new_user: InternalNewUser) -> Result { + debug!(user_uuid = %new_user.uuid, "insert user started"); let user = sqlx::query_as::<_, InternalUser>( r#" INSERT INTO users (uuid, username, email, password_hash, first_name, last_name) @@ -23,10 +24,12 @@ pub async fn create(pool: &PgPool, new_user: InternalNewUser) -> Result Result> { + debug!(user_uuid = %uuid, "fetch user by uuid started"); let user = sqlx::query_as::<_, InternalUser>( r#" SELECT uuid, username, email, password_hash, first_name, last_name FROM users WHERE uuid = $1 @@ -36,10 +39,12 @@ pub async fn get_by_uuid(pool: &PgPool, uuid: Uuid) -> Result Result> { + debug!(user_uuid = %uuid, "fetch safe user by uuid started"); let user = sqlx::query_as::<_, User>( r#" SELECT uuid, username, email, first_name, last_name FROM users WHERE uuid = $1 @@ -49,10 +54,12 @@ pub async fn get_safe_by_uuid(pool: &PgPool, uuid: Uuid) -> Result> .fetch_optional(pool) .await?; + debug!(user_uuid = %uuid, "fetch safe user by uuid completed"); Ok(user) } pub async fn get_all(pool: &PgPool) -> Result> { + debug!("fetch all internal users started"); let users = sqlx::query_as::<_, InternalUser>( r#" SELECT uuid, username, email, password_hash, first_name, last_name @@ -63,10 +70,12 @@ pub async fn get_all(pool: &PgPool) -> Result> { .fetch_all(pool) .await?; + debug!("fetch all internal users completed"); Ok(users) } pub async fn get_safe_all(pool: &PgPool) -> Result> { + debug!("fetch all safe users started"); let users = sqlx::query_as::<_, User>( r#" SELECT uuid, username, email, first_name, last_name @@ -77,10 +86,12 @@ pub async fn get_safe_all(pool: &PgPool) -> Result> { .fetch_all(pool) .await?; + debug!("fetch all safe users completed"); Ok(users) } pub async fn exists_by_uuid(pool: &PgPool, uuid: Uuid) -> Result { + debug!(user_uuid = %uuid, "check user existence started"); let exists = sqlx::query_scalar::<_, bool>( r#" SELECT EXISTS( @@ -94,5 +105,6 @@ pub async fn exists_by_uuid(pool: &PgPool, uuid: Uuid) -> Result { .fetch_one(pool) .await?; + debug!(user_uuid = %uuid, "check user existence completed"); Ok(exists) } diff --git a/src/backend/src/main.rs b/src/backend/src/main.rs index c3018de..749399b 100644 --- a/src/backend/src/main.rs +++ b/src/backend/src/main.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use anyhow::{Ok, Result}; use rustymine_daemon::{config::AppCfg, router, state::AppState}; -use tracing::{Level, debug, error, info, warn}; +use tracing::{Level, debug, info}; pub const APP_NAME: &str = env!("CARGO_PKG_NAME"); pub const APP_VERSION: &str = env!("CARGO_PKG_VERSION"); @@ -38,6 +38,20 @@ async fn main() -> Result<()> { tracing::subscriber::set_global_default(subscriber)?; + debug!(logo = ASCII_LOGO, "render application banner"); + info!( + app = APP_NAME, + version = APP_VERSION, + build_mode = BUILD_MODE, + "starting application" + ); + info!( + git_hash = GIT_HASH, + git_suffix = GIT_SUFFIX, + build_date = BUILD_DATE, + "build metadata" + ); + let db_path: String = "postgres://rustymine:minecraft@localhost:5432/rustymine_dev".to_string(); let config = AppCfg { db_path: db_path.clone(), @@ -48,7 +62,9 @@ async fn main() -> Result<()> { let app_result = router::init_router(state.clone()).await; let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?; + info!(listen_addr = "0.0.0.0:3000", "http server binding started"); axum::serve(listener, app_result).await?; + info!("http server stopped"); Ok(()) } diff --git a/src/backend/src/router/middleware.rs b/src/backend/src/router/middleware.rs index 63d816c..69f73f3 100644 --- a/src/backend/src/router/middleware.rs +++ b/src/backend/src/router/middleware.rs @@ -1,22 +1,25 @@ use axum::{ - Router, extract::Request, http::{Method, header::AUTHORIZATION}, middleware::Next, response::IntoResponse, }; use tower_http::cors::{Any, CorsLayer}; -use tracing::{debug, error, info, warn}; +use tracing::debug; pub async fn auth(request: Request, next: Next) -> impl IntoResponse { - debug!("auth_middleware entry"); + let method = request.method().clone(); + let uri = request.uri().path().to_owned(); + + debug!(%method, uri, "auth middleware started"); let response = next.run(request).await; - debug!("auth_middleware exit"); + let status = response.status(); + debug!(%method, uri, %status, "auth middleware completed"); response } pub fn cors() -> CorsLayer { - debug!("Generating CorsLayer"); + debug!("build cors layer"); CorsLayer::new() .allow_origin(Any) .allow_methods([Method::GET, Method::POST]) diff --git a/src/backend/src/router/mod.rs b/src/backend/src/router/mod.rs index 5006c89..52f705a 100644 --- a/src/backend/src/router/mod.rs +++ b/src/backend/src/router/mod.rs @@ -8,12 +8,15 @@ use axum::{ }; use serde_json::{Value, json}; use std::sync::Arc; -use tower::{Layer, ServiceBuilder}; +use tower::ServiceBuilder; +use crate::prelude::*; use crate::state::AppState; pub async fn init_router(app_state: Arc) -> Router { - Router::new() + info!("router initialization started"); + + let router = Router::new() .route( "/api/ping", get(ping).layer( @@ -33,9 +36,13 @@ pub async fn init_router(app_state: Arc) -> Router { ) .route("/api/users/{uuid}", get(user_routes::get_uuid)) .layer(ServiceBuilder::new().layer(middleware::cors())) - .with_state(app_state.clone()) + .with_state(app_state.clone()); + + info!("router initialization completed"); + router } async fn ping() -> Result, StatusCode> { + debug!("ping request received"); Ok(Json(json!({ "response": "pong"}))) } diff --git a/src/backend/src/router/user_routes.rs b/src/backend/src/router/user_routes.rs index ee41310..07283fa 100644 --- a/src/backend/src/router/user_routes.rs +++ b/src/backend/src/router/user_routes.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use crate::{ core, - domain::user::{InternalNewUser, NewUser, User}, + domain::user::{NewUser, User}, state::AppState, }; use anyhow::Result; @@ -18,12 +18,16 @@ pub async fn create( State(state): State>, Json(new_user): Json, ) -> Result, StatusCode> { + debug!("create user route started"); let user = core::user_routines::create(state, new_user).await?; + info!("create user route completed"); Ok(Json(user)) } pub async fn get_all(State(state): State>) -> Result>, StatusCode> { + debug!("list users route started"); let users = core::user_routines::get_all(state).await?; + debug!(user_count = users.len(), "list users route completed"); Ok(Json(users)) } @@ -31,6 +35,8 @@ pub async fn get_uuid( State(state): State>, Path(uuid): Path, ) -> Result>, StatusCode> { + debug!(user_uuid = %uuid, "get user by uuid route started"); let user = core::user_routines::get_safe_by_uuid(state, uuid).await?; + debug!("get user by uuid route completed"); Ok(Json(user)) } diff --git a/src/backend/src/state.rs b/src/backend/src/state.rs index dc30c14..7921564 100644 --- a/src/backend/src/state.rs +++ b/src/backend/src/state.rs @@ -4,7 +4,7 @@ use crate::prelude::*; use sqlx::PgPool; -use crate::{config::AppCfg, domain::user::InternalNewUser, infra::db}; +use crate::{config::AppCfg, infra::db}; pub struct AppState { pub db_pool: PgPool, @@ -12,23 +12,25 @@ pub struct AppState { impl AppState { pub async fn new(config: &AppCfg) -> Self { - debug!("Initiating new AppState"); + debug!("init app state"); + debug!("establish database connection"); let db_pool = db::connect(&config.db_path) .await .map_err(|e| { - error!("Failed to connect to database: {e}"); + error!(error = %e, "connect to database failed"); exit(20); }) .unwrap(); + debug!("run database migrations"); db::migrate(&db_pool) .await .map_err(|e| { - error!("Failed to migrade database: {e}"); + error!(error = %e, "database migration failed"); exit(22); }) .unwrap(); - info!("DB connect and migrate sucessful"); + info!("database ready after connect and migrate"); Self { db_pool: db_pool } } } From f1581f14dac7d16e8594dd166cea20e67e9e732d Mon Sep 17 00:00:00 2001 From: Hector van der Aa Date: Mon, 1 Dec 2025 00:41:06 +0100 Subject: [PATCH 2/2] Minor main.rs logging fixes --- src/backend/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/src/main.rs b/src/backend/src/main.rs index 749399b..2e160ac 100644 --- a/src/backend/src/main.rs +++ b/src/backend/src/main.rs @@ -38,7 +38,6 @@ async fn main() -> Result<()> { tracing::subscriber::set_global_default(subscriber)?; - debug!(logo = ASCII_LOGO, "render application banner"); info!( app = APP_NAME, version = APP_VERSION,