Compare commits

...

4 Commits

Author SHA1 Message Date
spinline
3e9a042444 fix(setup): align dependencies to Axum 0.8 and fix server function handler trait bounds
All checks were successful
Build MIPS Binary / build (push) Successful in 5m23s
2026-02-11 22:15:33 +03:00
spinline
09a4c69282 fix(auth): fix MsgPack serialization by adding missing feature in backend and reverting to individual arguments
All checks were successful
Build MIPS Binary / build (push) Successful in 5m15s
2026-02-11 22:03:46 +03:00
spinline
a877e0c393 chore: remove db files from git and update gitignore
All checks were successful
Build MIPS Binary / build (push) Successful in 5m13s
2026-02-11 21:54:15 +03:00
spinline
fd65df2962 fix(setup): add logging and error details for setup debugging
Some checks failed
Build MIPS Binary / build (push) Has been cancelled
2026-02-11 21:53:53 +03:00
9 changed files with 256 additions and 63 deletions

6
.gitignore vendored
View File

@@ -8,3 +8,9 @@ backend.log
.runner .runner
.env .env
backend/.env backend/.env
*.db
*.db-shm
*.db-wal
*.sqlite
*.sqlite-shm
*.sqlite-wal

197
Cargo.lock generated
View File

@@ -323,6 +323,7 @@ dependencies = [
"jsonwebtoken", "jsonwebtoken",
"leptos", "leptos",
"leptos_axum", "leptos_axum",
"leptos_router",
"mime_guess", "mime_guess",
"openssl", "openssl",
"quick-xml", "quick-xml",
@@ -520,9 +521,9 @@ dependencies = [
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.57" version = "4.5.58"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6899ea499e3fb9305a65d5ebf6e3d2248c5fab291f300ad0a704fbe142eae31a" checksum = "63be97961acde393029492ce0be7a1af7e323e6bae9511ebfac33751be5e6806"
dependencies = [ dependencies = [
"clap_builder", "clap_builder",
"clap_derive", "clap_derive",
@@ -530,9 +531,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_builder" name = "clap_builder"
version = "4.5.57" version = "4.5.58"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b12c8b680195a62a8364d16b8447b01b6c2c8f9aaf68bee653be34d4245e238" checksum = "7f13174bda5dfd69d7e947827e5af4b0f2f94a4a3ee92912fba07a66150f21e2"
dependencies = [ dependencies = [
"anstream", "anstream",
"anstyle", "anstyle",
@@ -554,9 +555,9 @@ dependencies = [
[[package]] [[package]]
name = "clap_lex" name = "clap_lex"
version = "0.7.7" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
[[package]] [[package]]
name = "coarsetime" name = "coarsetime"
@@ -940,9 +941,9 @@ dependencies = [
[[package]] [[package]]
name = "deranged" name = "deranged"
version = "0.5.5" version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" checksum = "cc3dc5ad92c2e2d1c193bbbbdf2ea477cb81331de4f3103f267ca18368b988c4"
dependencies = [ dependencies = [
"powerfmt", "powerfmt",
"serde_core", "serde_core",
@@ -1426,6 +1427,19 @@ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]]
name = "getrandom"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasip2",
"wasip3",
]
[[package]] [[package]]
name = "gloo-console" name = "gloo-console"
version = "0.3.0" version = "0.3.0"
@@ -1634,9 +1648,9 @@ dependencies = [
[[package]] [[package]]
name = "hmac-sha512" name = "hmac-sha512"
version = "1.1.10" version = "1.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "425aae4cbcd7250fdcc9665de9cbec21348dd4b6c6a7321b2f5eaf41a3e97dcd" checksum = "5075d41b75a022af043a5bbf49b89abf17665d5aebf6f6ec64ffff207d87654d"
dependencies = [ dependencies = [
"digest", "digest",
] ]
@@ -1945,6 +1959,12 @@ dependencies = [
"zerovec", "zerovec",
] ]
[[package]]
name = "id-arena"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
[[package]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@@ -2113,6 +2133,12 @@ dependencies = [
"spin", "spin",
] ]
[[package]]
name = "leb128fmt"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
[[package]] [[package]]
name = "leptos" name = "leptos"
version = "0.8.15" version = "0.8.15"
@@ -2373,9 +2399,9 @@ dependencies = [
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.180" version = "0.2.181"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" checksum = "459427e2af2b9c839b132acb702a1c654d95e10f8c326bfc2ad11310e458b1c5"
[[package]] [[package]]
name = "libm" name = "libm"
@@ -2391,7 +2417,7 @@ checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"libc", "libc",
"redox_syscall 0.7.0", "redox_syscall 0.7.1",
] ]
[[package]] [[package]]
@@ -3250,9 +3276,9 @@ dependencies = [
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.7.0" version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" checksum = "35985aa610addc02e24fc232012c86fd11f14111180f902b67e2d5331f8ebf2b"
dependencies = [ dependencies = [
"bitflags", "bitflags",
] ]
@@ -3757,10 +3783,12 @@ dependencies = [
"quick-xml", "quick-xml",
"rmp-serde", "rmp-serde",
"serde", "serde",
"serde_json",
"sqlx", "sqlx",
"struct-patch", "struct-patch",
"thiserror 2.0.18", "thiserror 2.0.18",
"tokio", "tokio",
"tracing",
"utoipa", "utoipa",
] ]
@@ -4267,12 +4295,12 @@ dependencies = [
[[package]] [[package]]
name = "tempfile" name = "tempfile"
version = "3.24.0" version = "3.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" checksum = "0136791f7c95b1f6dd99f9cc786b91bb81c3800b639b3478e561ddb7be95e5f1"
dependencies = [ dependencies = [
"fastrand", "fastrand",
"getrandom 0.3.4", "getrandom 0.4.1",
"once_cell", "once_cell",
"rustix", "rustix",
"windows-sys 0.61.2", "windows-sys 0.61.2",
@@ -4469,9 +4497,9 @@ dependencies = [
[[package]] [[package]]
name = "toml" name = "toml"
version = "0.9.11+spec-1.1.0" version = "0.9.12+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" checksum = "cf92845e79fc2e2def6a5d828f0801e29a2f8acc037becc5ab08595c7d5e9863"
dependencies = [ dependencies = [
"serde_core", "serde_core",
"serde_spanned", "serde_spanned",
@@ -4491,9 +4519,9 @@ dependencies = [
[[package]] [[package]]
name = "toml_parser" name = "toml_parser"
version = "1.0.6+spec-1.1.0" version = "1.0.7+spec-1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" checksum = "247eaa3197818b831697600aadf81514e577e0cba5eab10f7e064e78ae154df1"
dependencies = [ dependencies = [
"winnow", "winnow",
] ]
@@ -4965,6 +4993,15 @@ dependencies = [
"wit-bindgen", "wit-bindgen",
] ]
[[package]]
name = "wasip3"
version = "0.4.0+wasi-0.3.0-rc-2026-01-06"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5"
dependencies = [
"wit-bindgen",
]
[[package]] [[package]]
name = "wasite" name = "wasite"
version = "0.1.0" version = "0.1.0"
@@ -5039,6 +5076,28 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "wasm-encoder"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319"
dependencies = [
"leb128fmt",
"wasmparser",
]
[[package]]
name = "wasm-metadata"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909"
dependencies = [
"anyhow",
"indexmap",
"wasm-encoder",
"wasmparser",
]
[[package]] [[package]]
name = "wasm-streams" name = "wasm-streams"
version = "0.4.2" version = "0.4.2"
@@ -5074,6 +5133,18 @@ dependencies = [
"syn 2.0.114", "syn 2.0.114",
] ]
[[package]]
name = "wasmparser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe"
dependencies = [
"bitflags",
"hashbrown 0.15.5",
"indexmap",
"semver",
]
[[package]] [[package]]
name = "web-push" name = "web-push"
version = "0.10.4" version = "0.10.4"
@@ -5452,6 +5523,88 @@ name = "wit-bindgen"
version = "0.51.0" version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5"
dependencies = [
"wit-bindgen-rust-macro",
]
[[package]]
name = "wit-bindgen-core"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc"
dependencies = [
"anyhow",
"heck",
"wit-parser",
]
[[package]]
name = "wit-bindgen-rust"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21"
dependencies = [
"anyhow",
"heck",
"indexmap",
"prettyplease",
"syn 2.0.114",
"wasm-metadata",
"wit-bindgen-core",
"wit-component",
]
[[package]]
name = "wit-bindgen-rust-macro"
version = "0.51.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a"
dependencies = [
"anyhow",
"prettyplease",
"proc-macro2",
"quote",
"syn 2.0.114",
"wit-bindgen-core",
"wit-bindgen-rust",
]
[[package]]
name = "wit-component"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2"
dependencies = [
"anyhow",
"bitflags",
"indexmap",
"log",
"serde",
"serde_derive",
"serde_json",
"wasm-encoder",
"wasm-metadata",
"wasmparser",
"wit-parser",
]
[[package]]
name = "wit-parser"
version = "0.244.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736"
dependencies = [
"anyhow",
"id-arena",
"indexmap",
"log",
"semver",
"serde",
"serde_derive",
"serde_json",
"unicode-xid",
"wasmparser",
]
[[package]] [[package]]
name = "writeable" name = "writeable"

View File

@@ -4,7 +4,7 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[features] [features]
default = ["swagger"] # push-notifications kaldırıldı default = ["swagger"]
push-notifications = ["web-push", "openssl"] push-notifications = ["web-push", "openssl"]
swagger = ["utoipa-swagger-ui"] swagger = ["utoipa-swagger-ui"]
@@ -28,7 +28,7 @@ clap = { version = "4.4", features = ["derive", "env"] }
rust-embed = "8.2" rust-embed = "8.2"
mime_guess = "2.0" mime_guess = "2.0"
shared = { path = "../shared", features = ["ssr"] } shared = { path = "../shared", features = ["ssr"] }
thiserror = "2.0.18" thiserror = "2.0"
dotenvy = "0.15.7" dotenvy = "0.15.7"
utoipa = { version = "5.4.0", features = ["axum_extras"] } utoipa = { version = "5.4.0", features = ["axum_extras"] }
utoipa-swagger-ui = { version = "9.0", features = ["axum"], optional = true } utoipa-swagger-ui = { version = "9.0", features = ["axum"], optional = true }
@@ -38,12 +38,13 @@ openssl = { version = "0.10", features = ["vendored"], optional = true }
bcrypt = "0.17.0" bcrypt = "0.17.0"
axum-extra = { version = "0.10", features = ["cookie"] } axum-extra = { version = "0.10", features = ["cookie"] }
rand = "0.8" rand = "0.8"
anyhow = "1.0.101" anyhow = "1.0"
time = { version = "0.3.47", features = ["serde", "formatting", "parsing"] } time = { version = "0.3", features = ["serde", "formatting", "parsing"] }
tower_governor = "0.8.0" tower_governor = "0.8.0"
governor = "0.10.4" governor = "0.10.4"
# Leptos # Leptos
leptos = { version = "0.8.15", features = ["nightly"] } leptos = { version = "0.8.15", features = ["nightly", "msgpack"] }
leptos_axum = { version = "0.8.7" } leptos_axum = { version = "0.8.7" }
leptos_router = { version = "0.8.11" }
jsonwebtoken = "9" jsonwebtoken = "9"

View File

@@ -26,7 +26,7 @@ use std::time::Duration;
use tokio::sync::{broadcast, watch}; use tokio::sync::{broadcast, watch};
use tower::ServiceBuilder; use tower::ServiceBuilder;
use tower_http::{ use tower_http::{
compression::{CompressionLayer, CompressionLevel}, compression::CompressionLayer,
cors::CorsLayer, cors::CorsLayer,
trace::TraceLayer, trace::TraceLayer,
}; };
@@ -407,37 +407,37 @@ async fn main() {
} }
}); });
async fn server_fn_handler(
axum::extract::State(state): axum::extract::State<AppState>,
req: Request<Body>,
) -> impl axum::response::IntoResponse {
let scgi_path = state.scgi_socket_path.clone();
let db = state.db.clone();
leptos_axum::handle_server_fns_with_context(
move || {
leptos::context::provide_context(shared::ServerContext {
scgi_socket_path: scgi_path.clone(),
});
leptos::context::provide_context(shared::DbContext {
db: db.clone(),
});
},
req,
).await
}
let app = Router::new(); let app = Router::new();
#[cfg(feature = "swagger")] #[cfg(feature = "swagger")]
let app = app.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi())); let app = app.merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()));
// Setup & Auth Routes (cookie-based, stay as REST) // Setup & Auth Routes (cookie-based, stay as REST)
// Setup & Auth Routes (cookie-based, stay as REST)
let scgi_path_for_ctx = args.socket.clone();
let db_for_ctx = db.clone();
let app = app let app = app
.route("/api/events", get(sse::sse_handler)) .route("/api/events", get(sse::sse_handler))
.route("/api/server_fns/{*fn_name}", post({ .route("/api/server_fns/{*fn_name}", post(server_fn_handler))
let scgi_path = scgi_path_for_ctx.clone(); .fallback(handlers::static_handler)
let db = db_for_ctx.clone(); .with_state(app_state.clone());
move |req: Request<Body>| {
let scgi_path = scgi_path.clone();
let db = db.clone();
leptos_axum::handle_server_fns_with_context(
move || {
leptos::context::provide_context(shared::ServerContext {
scgi_socket_path: scgi_path.clone(),
});
leptos::context::provide_context(shared::DbContext {
db: db.clone(),
});
},
req,
)
}
}))
.fallback(handlers::static_handler);
let app = app let app = app
.layer(middleware::from_fn_with_state(app_state.clone(), auth_middleware)) .layer(middleware::from_fn_with_state(app_state.clone(), auth_middleware))
@@ -445,8 +445,7 @@ async fn main() {
.layer( .layer(
CompressionLayer::new() CompressionLayer::new()
.br(false) .br(false)
.gzip(true) .gzip(true),
.quality(CompressionLevel::Fastest),
) )
.layer( .layer(
ServiceBuilder::new() ServiceBuilder::new()

View File

@@ -41,7 +41,8 @@ pub fn Setup() -> impl IntoView {
} }
Err(e) => { Err(e) => {
log::error!("Setup failed: {:?}", e); log::error!("Setup failed: {:?}", e);
error.1.set(Some("Kurulum sırasında bir hata oluştu".to_string())); // Hatanın sadece mesaj kısmını almaya çalışalım, yoksa full struct basılabilir
error.1.set(Some(format!("Hata: {}", e)));
loading.1.set(false); loading.1.set(false);
} }
} }

View File

@@ -6,14 +6,16 @@ edition = "2021"
[dependencies] [dependencies]
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
utoipa = { version = "5.4.0", features = ["axum_extras"] } utoipa = { version = "5.4.0", features = ["axum_extras"] }
serde_json = "1"
struct-patch = "0.5" struct-patch = "0.5"
rmp-serde = "1.3" rmp-serde = "1.3"
bytes = "1" bytes = "1"
http = "1" http = "1"
tracing = "0.1"
# Leptos 0.8.7 # Leptos 0.8
leptos = { version = "0.8.15", features = ["nightly", "msgpack"] } leptos = { version = "0.8.15", features = ["nightly", "msgpack"] }
leptos_router = { version = "0.8.7", features = ["nightly"] } leptos_router = { version = "0.8.11", features = ["nightly"] }
leptos_axum = { version = "0.8.7", optional = true } leptos_axum = { version = "0.8.7", optional = true }
axum = { version = "0.8", features = ["macros"], optional = true } axum = { version = "0.8", features = ["macros"], optional = true }

View File

@@ -28,8 +28,17 @@ impl Db {
} }
async fn run_migrations(&self) -> Result<()> { async fn run_migrations(&self) -> Result<()> {
sqlx::migrate!("./migrations").run(&self.pool).await?; tracing::info!("Starting database migrations...");
Ok(()) match sqlx::migrate!("./migrations").run(&self.pool).await {
Ok(_) => {
tracing::info!("Database migrations completed successfully.");
Ok(())
}
Err(e) => {
tracing::error!("Database migration failed: {}", e);
Err(e.into())
}
}
} }
// --- User Operations --- // --- User Operations ---

View File

@@ -24,9 +24,19 @@ pub struct SetupStatus {
pub async fn get_setup_status() -> Result<SetupStatus, ServerFnError> { pub async fn get_setup_status() -> Result<SetupStatus, ServerFnError> {
use crate::DbContext; use crate::DbContext;
let db_context = use_context::<DbContext>().ok_or_else(|| ServerFnError::new("DB Context missing"))?; tracing::info!("Checking setup status...");
let db_context = use_context::<DbContext>().ok_or_else(|| {
tracing::error!("DB Context missing in GetSetupStatus");
ServerFnError::new("DB Context missing")
})?;
let has_users = db_context.db.has_users().await let has_users = db_context.db.has_users().await
.map_err(|e| ServerFnError::new(format!("DB error: {}", e)))?; .map_err(|e| {
tracing::error!("DB error in GetSetupStatus: {}", e);
ServerFnError::new(format!("DB error: {}", e))
})?;
tracing::info!("Setup status: completed={}", has_users);
Ok(SetupStatus { Ok(SetupStatus {
completed: has_users, completed: has_users,
@@ -37,21 +47,33 @@ pub async fn get_setup_status() -> Result<SetupStatus, ServerFnError> {
pub async fn setup(username: String, password: String) -> Result<(), ServerFnError> { pub async fn setup(username: String, password: String) -> Result<(), ServerFnError> {
use crate::DbContext; use crate::DbContext;
let db_context = use_context::<DbContext>().ok_or_else(|| ServerFnError::new("DB Context missing"))?; tracing::info!("Attempting setup for user: {}", username);
let db_context = use_context::<DbContext>().ok_or_else(|| {
tracing::error!("DB Context missing in Setup");
ServerFnError::new("DB Context missing")
})?;
// Check if setup is already done // Check if setup is already done
let has_users = db_context.db.has_users().await.unwrap_or(false); let has_users = db_context.db.has_users().await.unwrap_or(false);
if has_users { if has_users {
tracing::warn!("Setup attempt blocked: Setup already completed");
return Err(ServerFnError::new("Setup already completed")); return Err(ServerFnError::new("Setup already completed"));
} }
// Hash password (low cost for MIPS) // Hash password (low cost for MIPS)
let password_hash = bcrypt::hash(&password, 6) let password_hash = bcrypt::hash(&password, 6)
.map_err(|_| ServerFnError::new("Hashing error"))?; .map_err(|e| {
tracing::error!("Hashing error: {}", e);
ServerFnError::new("Hashing error")
})?;
db_context.db.create_user(&username, &password_hash).await db_context.db.create_user(&username, &password_hash).await
.map_err(|e| ServerFnError::new(format!("DB error: {}", e)))?; .map_err(|e| {
tracing::error!("Failed to create user: {}", e);
ServerFnError::new(format!("DB error: {}", e))
})?;
tracing::info!("Setup completed successfully for user: {}", username);
Ok(()) Ok(())
} }

Binary file not shown.