aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/server/repositories/review-log.ts
blob: 591c647d980d62c62fafd82b9b2ab682873778a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import { and, eq, gte, sql } from "drizzle-orm";
import { db } from "../db/index.js";
import { CardState, cards, reviewLogs } from "../db/schema.js";
import type { ReviewLog, ReviewLogRepository } from "./types.js";

export const reviewLogRepository: ReviewLogRepository = {
	async create(data: {
		cardId: string;
		userId: string;
		rating: number;
		state: number;
		scheduledDays: number;
		elapsedDays: number;
		durationMs?: number | null;
	}): Promise<ReviewLog> {
		const [reviewLog] = await db
			.insert(reviewLogs)
			.values({
				cardId: data.cardId,
				userId: data.userId,
				rating: data.rating,
				state: data.state,
				scheduledDays: data.scheduledDays,
				elapsedDays: data.elapsedDays,
				durationMs: data.durationMs ?? null,
			})
			.returning();
		if (!reviewLog) {
			throw new Error("Failed to create review log");
		}
		return reviewLog;
	},

	async countTodayNewCardReviews(deckId: string, now: Date): Promise<number> {
		const startOfDay = new Date(now);
		startOfDay.setHours(0, 0, 0, 0);

		const result = await db
			.select({ count: sql<number>`count(distinct ${reviewLogs.cardId})::int` })
			.from(reviewLogs)
			.innerJoin(cards, eq(reviewLogs.cardId, cards.id))
			.where(
				and(
					eq(cards.deckId, deckId),
					eq(reviewLogs.state, CardState.New),
					gte(reviewLogs.reviewedAt, startOfDay),
				),
			);
		return result[0]?.count ?? 0;
	},
};