60 lines
2.0 KiB
TypeScript
60 lines
2.0 KiB
TypeScript
import { and, desc, eq } from 'drizzle-orm'
|
|
import type { drizzle } from 'drizzle-orm/postgres-js'
|
|
import { notes, type Note } from '@/entities/note/model/schema'
|
|
import type { NoteInput } from '@/entities/note/model/input'
|
|
|
|
/** The handle the shared `db()` returns (`@/shared/api/db/server`). */
|
|
export type NoteDb = ReturnType<typeof drizzle>
|
|
|
|
/**
|
|
* Note persistence over one database handle. The handle is a parameter so a test
|
|
* can run the same code against its own Postgres.
|
|
*
|
|
* Every write names its author in the `where`: a visitor can change only the
|
|
* notes they wrote (tenancy, D16).
|
|
*/
|
|
export function noteRepository(db: NoteDb) {
|
|
return {
|
|
async create(input: NoteInput & { authorId: string }): Promise<Note> {
|
|
const [row] = await db.insert(notes).values(input).returning()
|
|
if (!row) throw new Error('the insert returned no row')
|
|
return row
|
|
},
|
|
|
|
async get(id: string): Promise<Note | undefined> {
|
|
const [row] = await db.select().from(notes).where(eq(notes.id, id)).limit(1)
|
|
return row
|
|
},
|
|
|
|
async listByAuthor(authorId: string, limit = 50): Promise<Note[]> {
|
|
return db
|
|
.select()
|
|
.from(notes)
|
|
.where(eq(notes.authorId, authorId))
|
|
.orderBy(desc(notes.createdAt))
|
|
.limit(limit)
|
|
},
|
|
|
|
/** The updated note, or `undefined` when `authorId` did not write it. */
|
|
async update(id: string, authorId: string, input: NoteInput): Promise<Note | undefined> {
|
|
const [row] = await db
|
|
.update(notes)
|
|
.set({ ...input, updatedAt: new Date() })
|
|
.where(and(eq(notes.id, id), eq(notes.authorId, authorId)))
|
|
.returning()
|
|
return row
|
|
},
|
|
|
|
/** `true` when the note existed and `authorId` wrote it. */
|
|
async remove(id: string, authorId: string): Promise<boolean> {
|
|
const rows = await db
|
|
.delete(notes)
|
|
.where(and(eq(notes.id, id), eq(notes.authorId, authorId)))
|
|
.returning({ id: notes.id })
|
|
return rows.length > 0
|
|
},
|
|
}
|
|
}
|
|
|
|
export type NoteRepository = ReturnType<typeof noteRepository>
|