// src/auth/handlers/register.rs use bcrypt::{hash, DEFAULT_COST}; use tonic::{Response, Status}; use common::proto::multieko2::auth::{RegisterRequest, AuthResponse}; use crate::db::PgPool; use crate::auth::models::AuthError; pub async fn register( pool: &PgPool, payload: RegisterRequest, ) -> Result, Status> { // Validate passwords match if payload.password != payload.password_confirmation { return Err(Status::invalid_argument(AuthError::PasswordMismatch.to_string())); } // Hash password let password_hash = hash(payload.password, DEFAULT_COST) .map_err(|e| Status::internal(AuthError::HashingError(e.to_string()).to_string()))?; // Insert user let user = sqlx::query!( r#" INSERT INTO users (username, email, password_hash, role) VALUES ($1, $2, $3, 'accountant') RETURNING id, username, email, role "#, payload.username, payload.email, password_hash ) .fetch_one(pool) .await .map_err(|e| { if e.to_string().contains("duplicate key") { Status::already_exists(AuthError::UserExists.to_string()) } else { Status::internal(AuthError::DatabaseError(e.to_string()).to_string()) } })?; Ok(Response::new(AuthResponse { id: user.id.to_string(), username: user.username, email: user.email.unwrap_or_default(), role: user.role, })) }