feat: Introduce note version history with dedicated UI, API, and database schema.

This commit is contained in:
2025-12-23 03:08:14 +01:00
parent 7aad3b7d84
commit c441f14bfa
12 changed files with 408 additions and 10 deletions

View File

@@ -146,3 +146,25 @@ pub struct UserResponse {
pub email: String,
pub created_at: DateTime<Utc>,
}
/// Note Version response DTO
#[derive(Debug, Serialize)]
pub struct NoteVersionResponse {
pub id: Uuid,
pub note_id: Uuid,
pub title: String,
pub content: String,
pub created_at: DateTime<Utc>,
}
impl From<notes_domain::NoteVersion> for NoteVersionResponse {
fn from(version: notes_domain::NoteVersion) -> Self {
Self {
id: version.id,
note_id: version.note_id,
title: version.title,
content: version.content,
created_at: version.created_at,
}
}
}

View File

@@ -28,6 +28,7 @@ pub fn api_v1_router() -> Router<AppState> {
.patch(notes::update_note)
.delete(notes::delete_note),
)
.route("/notes/{id}/versions", get(notes::list_note_versions))
// Search route
.route("/search", get(notes::search_notes))
// Import/Export routes

View File

@@ -177,3 +177,28 @@ pub async fn search_notes(
Ok(Json(response))
}
/// List versions of a note
/// GET /api/v1/notes/:id/versions
pub async fn list_note_versions(
State(state): State<AppState>,
auth: AuthSession<AuthBackend>,
Path(id): Path<Uuid>,
) -> ApiResult<Json<Vec<crate::dto::NoteVersionResponse>>> {
let user = auth
.user
.ok_or(ApiError::Domain(notes_domain::DomainError::Unauthorized(
"Login required".to_string(),
)))?;
let user_id = user.id();
let service = NoteService::new(state.note_repo, state.tag_repo);
let versions = service.list_note_versions(id, user_id).await?;
let response: Vec<crate::dto::NoteVersionResponse> = versions
.into_iter()
.map(crate::dto::NoteVersionResponse::from)
.collect();
Ok(Json(response))
}