Skip to content

Commit 7e8ab2b

Browse files
committed
추가 소비 기록 수정 엔드포인트 만들기
1 parent d6fb9f8 commit 7e8ab2b

4 files changed

Lines changed: 93 additions & 1 deletion

File tree

src/main.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use crate::routes::set_budget::set_budget;
2626
use crate::routes::update_budget::update_budget;
2727
use crate::routes::update_portfolio::update_portfolio;
2828
use crate::routes::update_post::update_post;
29+
use crate::routes::update_spending::update_spending;
2930
use crate::routes::upload_image::upload_image;
3031
use crate::{models::AppState, routes::add_user::add_user};
3132
use db::init_db;
@@ -101,7 +102,10 @@ async fn main() -> Result<(), std::io::Error> {
101102
"/budget/spending",
102103
get(get_spending).post(create_spending.with(ApiKeyAuth)),
103104
)
104-
.at("/budget/spending/:record_id", delete(delete_spending))
105+
.at(
106+
"/budget/spending/:record_id",
107+
put(update_spending).delete(delete_spending),
108+
)
105109
.at("/budget/weekly", get(get_weekly_summary))
106110
.at("/budget/weekly/:week_key", get(get_weekly_summary_by_key))
107111
.nest("/images", StaticFilesEndpoint::new(upload_base_path))

src/models.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,13 @@ pub struct CreateSpendingRequest {
187187
pub transacted_at: String,
188188
}
189189

190+
#[derive(Debug, Deserialize)]
191+
pub struct UpdateSpendingRequest {
192+
pub amount: i64,
193+
pub merchant: Option<String>,
194+
pub transacted_at: String,
195+
}
196+
190197
#[derive(Debug, Serialize)]
191198
pub struct CreateSpendingResponse {
192199
pub record_id: i64,

src/routes.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ pub mod get_spending;
1212
pub mod login;
1313
pub mod update_portfolio;
1414
pub mod update_post;
15+
pub mod update_spending;
1516
pub mod upload_image;
1617
pub mod upload_post;
1718
pub mod get_posts_with_tags;

src/routes/update_spending.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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

Comments
 (0)