feat: implement notes CRUD for SQLite and API backends
Fills in all 7 previously-unimplemented note methods in SqliteInterface and ApiInterface, adds cast/query helpers for notes, and fixes the apirouter (missing updatenote validator, two /user/ → /users/ typos that were also bypassing auth middleware). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit was merged in pull request #3.
This commit is contained in:
@@ -33,6 +33,8 @@ import {
|
||||
selectClientApikeys,
|
||||
selectClientUser,
|
||||
selectClientUsers,
|
||||
selectNote,
|
||||
selectPartialNotes,
|
||||
selectResident,
|
||||
selectResidents,
|
||||
} from "./query.js";
|
||||
@@ -465,24 +467,71 @@ export class SqliteInterface implements BackendDbInterface {
|
||||
}
|
||||
|
||||
async listNotes(): Promise<PartialNote[]> {
|
||||
throw new Error("Unimplemented");
|
||||
return selectPartialNotes(this.#db);
|
||||
}
|
||||
#getNoteById(nid: string): Note {
|
||||
const note = selectNote(this.#db, sql`n."nid" = ${{ uuid: nid }}`);
|
||||
if (!note) throw new NotFoundAbodeError();
|
||||
return note;
|
||||
}
|
||||
async getNoteById(nid: string): Promise<Note> {
|
||||
throw new Error("Unimplemented");
|
||||
return this.#getNoteById(nid);
|
||||
}
|
||||
async deleteNoteById(nid: string): Promise<void> {
|
||||
throw new Error("Unimplemented");
|
||||
this.#checkReadonly();
|
||||
const { changes } = this.#db.run(
|
||||
sql`DELETE FROM "notes" WHERE "nid" = ${{ uuid: nid }}`
|
||||
);
|
||||
if (!changes) throw new NotFoundAbodeError();
|
||||
}
|
||||
async createNote(note: CreateNote, ctx: { uid: string }): Promise<Note> {
|
||||
throw new Error("Unimplemented");
|
||||
this.#checkReadonly();
|
||||
const nid = crypto.randomUUID();
|
||||
return this.#db.rethrow(() =>
|
||||
this.#db.multi(() => {
|
||||
this.#db.run(sql`
|
||||
INSERT INTO "notes"("nid", "aid", "name", "content", "properties", "created_by", "updated_by")
|
||||
VALUES(
|
||||
${{ uuid: nid }},
|
||||
${{ uuid: note.aid }},
|
||||
${{ text: note.name }},
|
||||
${{ text: note.content ?? "" }},
|
||||
${{ jsonb: note.properties }},
|
||||
${{ uuid: ctx.uid }},
|
||||
${{ uuid: ctx.uid }}
|
||||
)
|
||||
`);
|
||||
return this.#getNoteById(nid);
|
||||
})
|
||||
);
|
||||
}
|
||||
async updateNote(note: UpdateNote, ctx: { uid: string }): Promise<Note> {
|
||||
throw new Error("Unimplemented");
|
||||
this.#checkReadonly();
|
||||
const updates = calcUpdates({
|
||||
name: (value: string) => sql`"name" = ${{ text: value }}`,
|
||||
content: (value: string) => sql`"content" = ${{ text: value }}`,
|
||||
properties: (value: object) => sql`"properties" = ${{ jsonb: value }}`,
|
||||
})(note);
|
||||
if (!updates.length) throw new InvalidAbodeError();
|
||||
return this.#db.rethrow(() =>
|
||||
this.#db.multi(() => {
|
||||
const { changes } = this.#db.run(sql`
|
||||
UPDATE "notes"
|
||||
SET
|
||||
"updated_at" = datetime('now', 'localtime', 'subsec'),
|
||||
"updated_by" = ${{ uuid: ctx.uid }},
|
||||
${joinSql(updates, sql`, `)}
|
||||
WHERE "nid" = ${{ uuid: note.nid }}
|
||||
`);
|
||||
if (!changes) throw new NotFoundAbodeError();
|
||||
return this.#getNoteById(note.nid);
|
||||
})
|
||||
);
|
||||
}
|
||||
async listNotesByAbodeId(aid: string): Promise<PartialNote[]> {
|
||||
throw new Error("Unimplemented");
|
||||
return selectPartialNotes(this.#db, sql`n."aid" = ${{ uuid: aid }}`);
|
||||
}
|
||||
async listNotesByUserId(uid: string): Promise<PartialNote[]> {
|
||||
throw new Error("Unimplemented");
|
||||
return selectPartialNotes(this.#db, sql`n."created_by" = ${{ uuid: uid }}`);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user