From a047cdd517efe7693ccd41162f9267f48cd67955 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 4 Feb 2026 22:31:13 +0900 Subject: feat(study): enforce newCardsPerDay limit in study API Split due card fetching into new cards and review cards, applying the deck's newCardsPerDay limit to new cards while leaving review cards unrestricted. New cards are placed before review cards in the response. Co-Authored-By: Claude Opus 4.5 --- src/server/repositories/review-log.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/server/repositories/review-log.ts') diff --git a/src/server/repositories/review-log.ts b/src/server/repositories/review-log.ts index c8950d6..591c647 100644 --- a/src/server/repositories/review-log.ts +++ b/src/server/repositories/review-log.ts @@ -1,5 +1,6 @@ +import { and, eq, gte, sql } from "drizzle-orm"; import { db } from "../db/index.js"; -import { reviewLogs } from "../db/schema.js"; +import { CardState, cards, reviewLogs } from "../db/schema.js"; import type { ReviewLog, ReviewLogRepository } from "./types.js"; export const reviewLogRepository: ReviewLogRepository = { @@ -29,4 +30,22 @@ export const reviewLogRepository: ReviewLogRepository = { } return reviewLog; }, + + async countTodayNewCardReviews(deckId: string, now: Date): Promise { + const startOfDay = new Date(now); + startOfDay.setHours(0, 0, 0, 0); + + const result = await db + .select({ count: sql`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; + }, }; -- cgit v1.3-1-g0d28