diff --git a/geneit_backend/src/controllers/families_controller.rs b/geneit_backend/src/controllers/families_controller.rs index 13f6832..57e751f 100644 --- a/geneit_backend/src/controllers/families_controller.rs +++ b/geneit_backend/src/controllers/families_controller.rs @@ -79,6 +79,13 @@ pub async fn single_info(f: FamilyInPath) -> HttpResult { .json(families_service::get_family_membership(f.family_id(), f.user_id()).await?)) } +/// Attempt to leave a family +pub async fn leave(f: FamilyInPath) -> HttpResult { + families_service::remove_membership(f.family_id(), f.user_id()).await?; + + Ok(HttpResponse::Accepted().finish()) +} + /// Get the list of users who belongs to a family pub async fn users(f: FamilyInPath) -> HttpResult { Ok(HttpResponse::Ok().json(families_service::get_memberships_of_family(f.family_id()).await?)) diff --git a/geneit_backend/src/main.rs b/geneit_backend/src/main.rs index 6460f11..febab2b 100644 --- a/geneit_backend/src/main.rs +++ b/geneit_backend/src/main.rs @@ -97,6 +97,10 @@ async fn main() -> std::io::Result<()> { "/family/{id}/info", web::get().to(families_controller::single_info), ) + .route( + "/family/{id}/leave", + web::post().to(families_controller::leave), + ) .route( "/family/{id}/users", web::get().to(families_controller::users), diff --git a/geneit_backend/src/models.rs b/geneit_backend/src/models.rs index 2067307..4c24ead 100644 --- a/geneit_backend/src/models.rs +++ b/geneit_backend/src/models.rs @@ -111,8 +111,8 @@ pub struct FamilyMembership { family_id: i32, name: String, time_create: i64, - is_admin: bool, + pub is_admin: bool, invitation_code: String, - count_members: i64, - count_admins: i64, + pub count_members: i64, + pub count_admins: i64, } diff --git a/geneit_backend/src/services/families_service.rs b/geneit_backend/src/services/families_service.rs index 8e2afca..171d905 100644 --- a/geneit_backend/src/services/families_service.rs +++ b/geneit_backend/src/services/families_service.rs @@ -132,9 +132,49 @@ pub async fn get_family_membership( }) } +/// Delete a family +pub async fn delete_family(family_id: FamilyID) -> anyhow::Result<()> { + // TODO : delete members and couples + + // Remove all memberships + db_connection::execute(|conn| { + diesel::delete( + memberships::dsl::memberships.filter(memberships::dsl::family_id.eq(family_id.0)), + ) + .execute(conn) + })?; + + // Remove the family itself + db_connection::execute(|conn| { + diesel::delete(families::dsl::families.filter(families::dsl::id.eq(family_id.0))) + .execute(conn) + })?; + + Ok(()) +} + /// Remove a membership to a family -pub async fn remove_membership(_family_id: FamilyID, _user_id: UserID) { - todo!() +pub async fn remove_membership(family_id: FamilyID, user_id: UserID) -> anyhow::Result<()> { + let family = get_family_membership(family_id, user_id).await?; + + if family.is_admin && family.count_admins == 1 { + // We need to delete the whole family + delete_family(family_id).await + } else { + // Remove the single membership + db_connection::execute(|conn| { + diesel::delete( + memberships::dsl::memberships.filter( + memberships::dsl::user_id + .eq(user_id.0) + .and(memberships::dsl::family_id.eq(family_id.0)), + ), + ) + .execute(conn) + })?; + + Ok(()) + } } /// Remove all memberships of user diff --git a/geneit_backend/src/services/users_service.rs b/geneit_backend/src/services/users_service.rs index c726e8c..e208a59 100644 --- a/geneit_backend/src/services/users_service.rs +++ b/geneit_backend/src/services/users_service.rs @@ -177,9 +177,10 @@ pub async fn delete_account(user: &User) -> anyhow::Result<()> { login_token_service::disconnect_user_from_all_devices(user.id()).await?; db_connection::execute(|conn| { - diesel::delete(users::dsl::users.filter(users::dsl::id.eq(user.id().0))).execute(conn)?; - Ok(()) - }) + diesel::delete(users::dsl::users.filter(users::dsl::id.eq(user.id().0))).execute(conn) + })?; + + Ok(()) } /// Mark account as validated