m4: global API-error surface (no more silent failures)
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 5s
CI & Build / Python tests (push) Successful in 10s
CI & Build / Build & push image (push) Successful in 31s

The api client now catches network failures and non-JSON bodies robustly,
and routes unexpected errors (offline / 5xx) to a global toast — 4xx stay
with the caller so forms keep their inline messages. Toast actions are now
optional (undo toasts keep their button; error toasts are message-only), and
ToastHost moved from AppShell to the app root so toasts show everywhere,
including the login screen.

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:
2026-07-21 00:07:04 -04:00
co-authored by Claude Opus 4.8
parent ecbdd12ba9
commit d3bb091f73
6 changed files with 55 additions and 20 deletions
+3 -2
View File
@@ -106,7 +106,8 @@ export const useNotesStore = defineStore("notes", () => {
const setPinned = (id: string, pinned: boolean) => mutate(id, { pinned });
const setArchived = async (id: string, archived: boolean): Promise<void> => {
await mutate(id, { archived });
if (archived) useUiStore().showToast("Note archived", "Undo", () => void setArchived(id, false));
if (archived)
useUiStore().showToast("Note archived", { label: "Undo", run: () => void setArchived(id, false) });
};
const setColor = (id: string, color: NoteColor) => mutate(id, { color });
const setKind = (id: string, kind: NoteKind) => mutate(id, { kind });
@@ -176,7 +177,7 @@ export const useNotesStore = defineStore("notes", () => {
async function trash(id: string): Promise<void> {
reconcile(await api.post<Note>(`/api/notes/${id}/trash`));
useUiStore().showToast("Note moved to trash", "Undo", () => void restore(id));
useUiStore().showToast("Note moved to trash", { label: "Undo", run: () => void restore(id) });
}
async function restore(id: string): Promise<void> {