feat(plan): sabit gelir/gider kalemleri ve dönem notları (backend)
- /api/periods/{id}/plan-items: listele, ekle; /api/plan-items/{id}: düzenle, sil
- Önceki dönemden kopyala: göreli gün korunur, dönem sonuna kırpılır, aynı kalem tekrar eklenmez
- /api/periods/{id}/notes (planning | review), /api/notes/{id}: Markdown notlar
- Kapalı dönemde değişiklik yok; silme geri alınabilir şekilde işaretlenir
- Entegrasyon testleri (5): kurallar, kopyalama, salt okunur dönem, hane izolasyonu
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,22 @@ pub async fn get(db: &Database, household_id: Uuid, id: Uuid) -> AppResult<Perio
|
||||
coll(db).find_one(f).await?.ok_or(AppError::NotFound)
|
||||
}
|
||||
|
||||
/// Yazma işlemleri için: dönem bu haneye ait ve **açık** olmalı.
|
||||
/// Plan kalemleri, notlar ve (Faz 5) harcamalar bunu kullanır.
|
||||
pub async fn get_open(db: &Database, household_id: Uuid, id: Uuid) -> AppResult<Period> {
|
||||
let p = get(db, household_id, id).await?;
|
||||
if p.status == PeriodStatus::Closed {
|
||||
return Err(closed());
|
||||
}
|
||||
Ok(p)
|
||||
}
|
||||
|
||||
pub fn closed() -> AppError {
|
||||
AppError::Conflict(
|
||||
"Kapalı dönem değiştirilemez. Düzeltme için hane sahibi dönemi yeniden açmalı.".into(),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn create(db: &Database, household_id: Uuid, p: NewPeriod) -> AppResult<Period> {
|
||||
let (start, end) = validate_range(&p.start_date, &p.end_date)?;
|
||||
let savings_goal = validate_amount(p.savings_goal.unwrap_or(0))?;
|
||||
@@ -135,9 +151,7 @@ pub async fn update(
|
||||
) -> AppResult<Period> {
|
||||
let current = get(db, household_id, id).await?;
|
||||
if current.status == PeriodStatus::Closed {
|
||||
return Err(AppError::Conflict(
|
||||
"Kapalı dönem değiştirilemez. Düzeltme için hane sahibi dönemi yeniden açmalı.".into(),
|
||||
));
|
||||
return Err(closed());
|
||||
}
|
||||
if ch.version.is_some_and(|v| v != current.version) {
|
||||
return Err(stale());
|
||||
@@ -192,7 +206,7 @@ fn validate_range(start: &str, end: &str) -> AppResult<(Date, Date)> {
|
||||
Ok((start, end))
|
||||
}
|
||||
|
||||
fn validate_amount(v: i64) -> AppResult<i64> {
|
||||
pub fn validate_amount(v: i64) -> AppResult<i64> {
|
||||
if !(0..=MAX_AMOUNT).contains(&v) {
|
||||
return Err(AppError::BadRequest("Tutar geçersiz".into()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user