feat(arayüz): API istemcisi, TanStack Query, ts-rs tip üretimi ve oturum durumu
- Backend: ts-rs ile DTO'lardan TypeScript tipleri (frontend/src/types, npm run types) - Hata ve health yanıtları tipli yapılara çevrildi - lib/api.ts: tek API istemcisi, Türkçe ApiError, ağ hatası mesajı - lib/query.ts: QueryClient (4xx tekrar denenmez, 401 → oturum kapanır) - lib/auth.ts: useMe, useLogin, useRegister, useLogout - Vitest: 7 API istemcisi testi (toplam 29) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+25
-6
@@ -6,7 +6,24 @@ use axum::{
|
||||
http::StatusCode,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use serde_json::json;
|
||||
use serde::Serialize;
|
||||
use ts_rs::TS;
|
||||
|
||||
/// Tüm hata yanıtlarının gövdesi: `{ "error": { "code": "...", "message": "..." } }`
|
||||
#[derive(Serialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct ApiErrorBody {
|
||||
pub error: ApiErrorDetail,
|
||||
}
|
||||
|
||||
#[derive(Serialize, TS)]
|
||||
#[ts(export)]
|
||||
pub struct ApiErrorDetail {
|
||||
/// Makine için: `unauthorized`, `bad_request`, `conflict`, `not_found`, ...
|
||||
pub code: String,
|
||||
/// Kullanıcıya gösterilecek Türkçe mesaj
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AppError {
|
||||
@@ -59,11 +76,13 @@ impl IntoResponse for AppError {
|
||||
self.to_string()
|
||||
};
|
||||
|
||||
(
|
||||
status,
|
||||
Json(json!({ "error": { "code": code, "message": message } })),
|
||||
)
|
||||
.into_response()
|
||||
let body = ApiErrorBody {
|
||||
error: ApiErrorDetail {
|
||||
code: code.into(),
|
||||
message,
|
||||
},
|
||||
};
|
||||
(status, Json(body)).into_response()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user