This commit is contained in:
arrelin
2026-01-17 10:15:44 +03:00
parent 564adac629
commit a4b06fb057
26 changed files with 1542 additions and 346 deletions

View File

@@ -3,12 +3,15 @@ use axum::{
http::StatusCode,
Json,
};
use sea_orm::DatabaseConnection;
use axum_login::AuthSession;
use sea_orm::{DatabaseConnection, EntityTrait, ActiveModelTrait, Set};
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
use tower_sessions::Session;
use crate::auth::AuthBackend;
use crate::models::family::Model as FamilyModel;
use crate::models::{user, User};
use crate::services::FamilyService;
#[derive(Debug, Deserialize, ToSchema)]
@@ -18,6 +21,14 @@ pub struct CreateFamilyRequest {
pub password: String,
}
#[derive(Debug, Deserialize, ToSchema)]
#[schema(example = json!({"name": "Smith Family", "password": "secret123"}))]
pub struct CreateMyFamilyRequest {
pub name: String,
#[serde(default)]
pub password: Option<String>,
}
#[derive(Debug, Deserialize, ToSchema)]
#[schema(example = json!({"password": "secret123"}))]
pub struct VerifyFamilyPasswordRequest {
@@ -188,3 +199,57 @@ pub async fn verify_family_password(
Err(StatusCode::UNAUTHORIZED)
}
}
#[derive(Debug, Serialize, ToSchema)]
pub struct CreateMyFamilyResponse {
pub family: FamilyModel,
pub user_id: i32,
pub family_id: i32,
}
#[utoipa::path(
post,
path = "/my-family",
tag = "families",
request_body = CreateMyFamilyRequest,
responses(
(status = 200, description = "Family created and linked to user", body = CreateMyFamilyResponse),
(status = 401, description = "Not authenticated"),
(status = 409, description = "User already has a family"),
(status = 500, description = "Internal server error")
)
)]
pub async fn create_my_family(
auth_session: AuthSession<AuthBackend>,
State(db): State<DatabaseConnection>,
Json(payload): Json<CreateMyFamilyRequest>,
) -> Result<Json<CreateMyFamilyResponse>, StatusCode> {
let current_user = auth_session.user.ok_or(StatusCode::UNAUTHORIZED)?;
if current_user.family_id.is_some() {
return Err(StatusCode::CONFLICT);
}
let password = payload.password.unwrap_or_default();
let family = FamilyService::create(&db, payload.name, password)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
let mut active_user: user::ActiveModel = User::find_by_id(current_user.id)
.one(&db)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
.ok_or(StatusCode::NOT_FOUND)?
.into();
active_user.family_id = Set(Some(family.id));
active_user.update(&db)
.await
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
Ok(Json(CreateMyFamilyResponse {
family_id: family.id,
user_id: current_user.id,
family,
}))
}