Skip to content

Commit 197d2ae

Browse files
committed
delete hospital softly
1 parent fbc2c32 commit 197d2ae

6 files changed

Lines changed: 91 additions & 8 deletions

File tree

src/auth/service.rs

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,26 @@ pub fn verify_jwt(token: &str, secret: &str) -> Result<TokenData<Claims>> {
267267
pub fn soft_delete_account(
268268
conn: &mut PgConnection,
269269
user_id: &Uuid,
270-
) -> Result<(), diesel::result::Error> {
270+
) -> Result<(), AppError> {
271271
use crate::schema::users::dsl::*;
272272
use diesel::prelude::*;
273273
use chrono::Utc;
274-
275-
diesel::update(users.filter(id.eq(user_id)))
276-
.set(deleted_at.eq(Some(Utc::now())))
277-
.execute(conn)?;
274+
use crate::utils::enums::Role;
275+
276+
let affected = diesel::update(
277+
users
278+
.filter(id.eq(user_id))
279+
.filter(role.ne(Role::Admin))
280+
.filter(deleted_at.is_null()),
281+
)
282+
.set(deleted_at.eq(Some(Utc::now())))
283+
.execute(conn)?;
284+
285+
if affected == 0 {
286+
return Err(AppError::Unauthorized(
287+
"This account cannot be deleted".into(),
288+
));
289+
}
278290

279291
Ok(())
280292
}

src/docs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ use crate::handlers::{auth, hospitals, patients, appointments, specialists, admi
2424
hospitals::update_blood_request,
2525
hospitals::get_hospital_settings,
2626
hospitals::update_hospital_settings,
27+
hospitals::delete_hospital,
2728
specialists::create_specialist,
2829
specialists::get_specialist,
2930
specialists::get_specialists,

src/handlers/auth.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -414,7 +414,6 @@ pub async fn verify_email(
414414
#[utoipa::path(
415415
post,
416416
path = "/api/auth/delete-account",
417-
request_body = DeleteAccountRequest,
418417
responses(
419418
(status = 200, description = "Account deleted successfully"),
420419
(status = 401, description = "Unauthorized"),

src/handlers/hospitals.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ use crate::{
1414
self,
1515
blood_requests::{BloodRequestQuery, BloodRequestResponse, CreateBloodRequest, UpdateBloodRequest}, settings},
1616
models::{BloodRequest, Hospital, HospitalSettings, User},
17-
utils::{enums::{HospitalTypeEnum, RequestStatusTypeEnum}, response::ApiResponse},
17+
utils::{
18+
enums::{HospitalTypeEnum, RequestStatusTypeEnum},
19+
response::{ApiResponse, EmptyData}
20+
},
1821
};
1922

2023
/// Create hospital profile
@@ -304,3 +307,31 @@ pub async fn update_hospital_settings(
304307
settings::update_hospital_settings(&mut conn, hospital_id, payload)?;
305308
Ok(ApiResponse::success_with_message("Hospital settings updated successfully", settings))
306309
}
310+
311+
#[utoipa::path(
312+
delete,
313+
path = "/api/hospitals/{hospital_id}",
314+
responses(
315+
(status = 200, description = "Hospital deleted successfully"),
316+
(status = 401),
317+
(status = 404),
318+
(status = 500)
319+
),
320+
tag = "hospitals",
321+
security(("bearer_auth" = []))
322+
)]
323+
pub async fn delete_hospital(
324+
State(state): State<AppState>,
325+
Extension(user): Extension<User>,
326+
Path(hospital_id): Path<Uuid>,
327+
) -> Result<ApiResponse<EmptyData>, AppError> {
328+
let mut conn = state.pool.get()?;
329+
330+
hospitals::service::delete_hospital(&mut conn, hospital_id, &user)?;
331+
332+
Ok(ApiResponse::message_only(
333+
axum::http::StatusCode::OK,
334+
"Hospital deleted successfully",
335+
))
336+
}
337+

src/hospitals/service.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use diesel::prelude::*;
22
use diesel::pg::PgConnection;
3+
use uuid::Uuid;
34

45
use crate::services::mail::MailService;
56
use crate::{
@@ -118,4 +119,42 @@ pub fn update_hospital(
118119
}
119120
}
120121

122+
pub fn delete_hospital(
123+
conn: &mut PgConnection,
124+
hospital_id: Uuid,
125+
user: &User,
126+
) -> Result<(), AppError> {
127+
use crate::schema::hospitals::dsl::*;
128+
use crate::utils::enums::Role;
129+
use diesel::prelude::*;
130+
use chrono::Utc;
131+
132+
let affected = if user.role == Role::Admin {
133+
// Admin can delete any hospital
134+
diesel::update(
135+
hospitals
136+
.filter(id.eq(hospital_id))
137+
.filter(deleted_at.is_null()),
138+
)
139+
.set(deleted_at.eq(Some(Utc::now())))
140+
.execute(conn)?
141+
} else {
142+
// Hospital can only delete their own
143+
diesel::update(
144+
hospitals
145+
.filter(id.eq(hospital_id))
146+
.filter(user_id.eq(user.id))
147+
.filter(deleted_at.is_null()),
148+
)
149+
.set(deleted_at.eq(Some(Utc::now())))
150+
.execute(conn)?
151+
};
152+
153+
if affected == 0 {
154+
return Err(AppError::NotFound(
155+
"Hospital not found or not authorized to delete".into(),
156+
));
157+
}
121158

159+
Ok(())
160+
}

src/routes/hospitals.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
use axum::{Router, routing::{get, post, put, patch}};
1+
use axum::{Router, routing::{get, post, put, patch, delete}};
22
use crate::{AppState, handlers::hospitals};
33

44
pub fn router() -> Router<AppState> {
55
Router::new()
6+
.route("/{hospital_id}", delete(hospitals::delete_hospital))
67
.route("/create", post(hospitals::create_hospital))
78
.route("/update/{hospital_id}", put(hospitals::update_hospital))
89
.route("/blood-request", get(hospitals::get_blood_requests))

0 commit comments

Comments
 (0)