M6: version history — note revisions + restore
A note's title+body is snapshotted on each edit that changes either, so an accidental overwrite can be viewed and restored (task 1906). Underwrites 'dump freely, nothing is lost'. Backend: note_revisions table (migration 0014) + NoteRevision model; update_note records a revision of the PRE-edit state whenever title/body changes; GET /api/notes/<id>/revisions (newest 50) and POST /api/notes/<id>/revisions/<rev_id>/restore (snapshots the current state first so restore is itself undoable, then applies the revision with the usual title/body ripple — display name, links, #tags, backlinks). Title+body only in v1. Frontend: a History toggle in the modal editor opens a panel of past versions (timestamp + preview) with per-row Restore. Store gains fetchRevisions/restoreRevision. Migration 0014 runs on deploy; DB behavior operator-verified (no Postgres CI lane). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FRgehjoz7Yv8LkUfADxACm
This commit is contained in:
@@ -29,6 +29,14 @@ export interface Attachment {
|
||||
mime: string;
|
||||
}
|
||||
|
||||
// A past version of a note's title+body (version history).
|
||||
export interface NoteRevision {
|
||||
id: string;
|
||||
title: string | null;
|
||||
body: string;
|
||||
created_at: string | null;
|
||||
}
|
||||
|
||||
export interface Note {
|
||||
id: string;
|
||||
title: string | null;
|
||||
@@ -204,6 +212,17 @@ export const useNotesStore = defineStore("notes", () => {
|
||||
if (idx >= 0) items.value.splice(idx, 1);
|
||||
}
|
||||
|
||||
async function fetchRevisions(id: string): Promise<NoteRevision[]> {
|
||||
const res = await api.get<{ revisions: NoteRevision[] }>(`/api/notes/${id}/revisions`);
|
||||
return res.revisions;
|
||||
}
|
||||
|
||||
async function restoreRevision(id: string, revId: string): Promise<Note> {
|
||||
const note = await api.post<Note>(`/api/notes/${id}/revisions/${revId}/restore`);
|
||||
reconcile(note);
|
||||
return note;
|
||||
}
|
||||
|
||||
return {
|
||||
items,
|
||||
loading,
|
||||
@@ -229,5 +248,7 @@ export const useNotesStore = defineStore("notes", () => {
|
||||
trash,
|
||||
restore,
|
||||
deleteForever,
|
||||
fetchRevisions,
|
||||
restoreRevision,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user