diff options
Diffstat (limited to 'src/server/repositories')
| -rw-r--r-- | src/server/repositories/deck.ts | 95 | ||||
| -rw-r--r-- | src/server/repositories/index.ts | 1 | ||||
| -rw-r--r-- | src/server/repositories/types.ts | 33 |
3 files changed, 129 insertions, 0 deletions
diff --git a/src/server/repositories/deck.ts b/src/server/repositories/deck.ts new file mode 100644 index 0000000..77985a7 --- /dev/null +++ b/src/server/repositories/deck.ts @@ -0,0 +1,95 @@ +import { and, eq, isNull, sql } from "drizzle-orm"; +import { db } from "../db/index.js"; +import { decks } from "../db/schema.js"; +import type { Deck, DeckRepository } from "./types.js"; + +export const deckRepository: DeckRepository = { + async findByUserId(userId: string): Promise<Deck[]> { + const result = await db + .select() + .from(decks) + .where(and(eq(decks.userId, userId), isNull(decks.deletedAt))); + return result; + }, + + async findById(id: string, userId: string): Promise<Deck | undefined> { + const result = await db + .select() + .from(decks) + .where( + and( + eq(decks.id, id), + eq(decks.userId, userId), + isNull(decks.deletedAt), + ), + ); + return result[0]; + }, + + async create(data: { + userId: string; + name: string; + description?: string | null; + newCardsPerDay?: number; + }): Promise<Deck> { + const [deck] = await db + .insert(decks) + .values({ + userId: data.userId, + name: data.name, + description: data.description ?? null, + newCardsPerDay: data.newCardsPerDay ?? 20, + }) + .returning(); + if (!deck) { + throw new Error("Failed to create deck"); + } + return deck; + }, + + async update( + id: string, + userId: string, + data: { + name?: string; + description?: string | null; + newCardsPerDay?: number; + }, + ): Promise<Deck | undefined> { + const result = await db + .update(decks) + .set({ + ...data, + updatedAt: new Date(), + syncVersion: sql`${decks.syncVersion} + 1`, + }) + .where( + and( + eq(decks.id, id), + eq(decks.userId, userId), + isNull(decks.deletedAt), + ), + ) + .returning(); + return result[0]; + }, + + async softDelete(id: string, userId: string): Promise<boolean> { + const result = await db + .update(decks) + .set({ + deletedAt: new Date(), + updatedAt: new Date(), + syncVersion: sql`${decks.syncVersion} + 1`, + }) + .where( + and( + eq(decks.id, id), + eq(decks.userId, userId), + isNull(decks.deletedAt), + ), + ) + .returning({ id: decks.id }); + return result.length > 0; + }, +}; diff --git a/src/server/repositories/index.ts b/src/server/repositories/index.ts index 04b1f35..9a703ab 100644 --- a/src/server/repositories/index.ts +++ b/src/server/repositories/index.ts @@ -1,3 +1,4 @@ +export { deckRepository } from "./deck.js"; export { refreshTokenRepository } from "./refresh-token.js"; export * from "./types.js"; export { userRepository } from "./user.js"; diff --git a/src/server/repositories/types.ts b/src/server/repositories/types.ts index 1ab4bdc..740fa29 100644 --- a/src/server/repositories/types.ts +++ b/src/server/repositories/types.ts @@ -44,3 +44,36 @@ export interface RefreshTokenRepository { }): Promise<void>; deleteById(id: string): Promise<void>; } + +export interface Deck { + id: string; + userId: string; + name: string; + description: string | null; + newCardsPerDay: number; + createdAt: Date; + updatedAt: Date; + deletedAt: Date | null; + syncVersion: number; +} + +export interface DeckRepository { + findByUserId(userId: string): Promise<Deck[]>; + findById(id: string, userId: string): Promise<Deck | undefined>; + create(data: { + userId: string; + name: string; + description?: string | null; + newCardsPerDay?: number; + }): Promise<Deck>; + update( + id: string, + userId: string, + data: { + name?: string; + description?: string | null; + newCardsPerDay?: number; + }, + ): Promise<Deck | undefined>; + softDelete(id: string, userId: string): Promise<boolean>; +} |
