|
| 1 | +use std::sync::Arc; |
| 2 | + |
| 3 | +use poem::{ |
| 4 | + handler, |
| 5 | + http::StatusCode, |
| 6 | + web::{Data, Json, Path}, |
| 7 | + Error, |
| 8 | +}; |
| 9 | +use sqlx::{query, query_as}; |
| 10 | + |
| 11 | +use crate::{ |
| 12 | + models::{AppState, SpendingRecordResponse, UpdateSpendingRequest}, |
| 13 | + utils::parse_transacted_at, |
| 14 | +}; |
| 15 | + |
| 16 | +#[handler] |
| 17 | +pub async fn update_spending( |
| 18 | + Path(record_id): Path<i64>, |
| 19 | + data: Data<&Arc<AppState>>, |
| 20 | + Json(payload): Json<UpdateSpendingRequest>, |
| 21 | +) -> Result<Json<SpendingRecordResponse>, Error> { |
| 22 | + if payload.amount <= 0 { |
| 23 | + return Err(Error::from_string( |
| 24 | + "amount는 0보다 커야 합니다.", |
| 25 | + StatusCode::BAD_REQUEST, |
| 26 | + )); |
| 27 | + } |
| 28 | + |
| 29 | + let transacted_at = parse_transacted_at(&payload.transacted_at).map_err(|_| { |
| 30 | + Error::from_string( |
| 31 | + "transacted_at 형식이 올바르지 않습니다. 예: 2026-03-03T12:20:00", |
| 32 | + StatusCode::BAD_REQUEST, |
| 33 | + ) |
| 34 | + })?; |
| 35 | + let week_key = crate::utils::iso_week_key_from_datetime(&transacted_at); |
| 36 | + let transacted_at_text = transacted_at.format("%Y-%m-%d %H:%M:%S").to_string(); |
| 37 | + |
| 38 | + let updated = query( |
| 39 | + "UPDATE spending_records |
| 40 | + SET amount = ?, merchant = ?, transacted_at = ?, week_key = ? |
| 41 | + WHERE record_id = ?", |
| 42 | + ) |
| 43 | + .bind(payload.amount) |
| 44 | + .bind(payload.merchant) |
| 45 | + .bind(&transacted_at_text) |
| 46 | + .bind(&week_key) |
| 47 | + .bind(record_id) |
| 48 | + .execute(&data.db) |
| 49 | + .await |
| 50 | + .map_err(|e| { |
| 51 | + Error::from_string( |
| 52 | + format!("소비 기록 수정 실패: {}", e), |
| 53 | + StatusCode::INTERNAL_SERVER_ERROR, |
| 54 | + ) |
| 55 | + })?; |
| 56 | + |
| 57 | + if updated.rows_affected() == 0 { |
| 58 | + return Err(Error::from_string( |
| 59 | + format!("해당 소비 기록(record_id={})을 찾을 수 없습니다.", record_id), |
| 60 | + StatusCode::NOT_FOUND, |
| 61 | + )); |
| 62 | + } |
| 63 | + |
| 64 | + let record = query_as::<_, SpendingRecordResponse>( |
| 65 | + "SELECT record_id, amount, merchant, transacted_at, created_at |
| 66 | + FROM spending_records |
| 67 | + WHERE record_id = ?", |
| 68 | + ) |
| 69 | + .bind(record_id) |
| 70 | + .fetch_one(&data.db) |
| 71 | + .await |
| 72 | + .map_err(|e| { |
| 73 | + Error::from_string( |
| 74 | + format!("수정된 소비 기록 조회 실패: {}", e), |
| 75 | + StatusCode::INTERNAL_SERVER_ERROR, |
| 76 | + ) |
| 77 | + })?; |
| 78 | + |
| 79 | + Ok(Json(record)) |
| 80 | +} |
0 commit comments