aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/server/repositories
diff options
context:
space:
mode:
authorClaude <noreply@anthropic.com>2026-02-12 14:54:18 +0000
committerClaude <noreply@anthropic.com>2026-02-12 14:54:18 +0000
commit1afb825860cd293b8065d51746f4b23e4e8dab5d (patch)
tree1fe3a43f1c7ab469bb0154a1495028cc42b414a0 /src/server/repositories
parent9a52e7ad3b2d46c523caf079794fdb7757375b91 (diff)
downloadkioku-1afb825860cd293b8065d51746f4b23e4e8dab5d.tar.gz
kioku-1afb825860cd293b8065d51746f4b23e4e8dab5d.tar.zst
kioku-1afb825860cd293b8065d51746f4b23e4e8dab5d.zip
feat: 学習カード数の上限を撤廃
REVIEW_CARDS_LIMIT(復習カード80枚制限)とnewCardsPerDay(1日の新規カード制限) を削除し、期日が来たすべてのカードを制限なく返すように変更。 削除した主な要素: - REVIEW_CARDS_LIMIT定数とカード取得時のlimitパラメータ - newCardsPerDayフィールド(DB schema, 型定義, Zod schema, sync, CRDT) - countDueNewCards, countDueReviewCards, findDueNewCardsForStudy, findDueReviewCardsForStudy(CardRepository) - countTodayNewCardReviews(ReviewLogRepository) - デッキルートからのReviewLogRepository依存 https://claude.ai/code/session_018hrEJ9vg3RPoeAPyEc17gS
Diffstat (limited to 'src/server/repositories')
-rw-r--r--src/server/repositories/card.test.ts4
-rw-r--r--src/server/repositories/card.ts93
-rw-r--r--src/server/repositories/deck.test.ts5
-rw-r--r--src/server/repositories/deck.ts3
-rw-r--r--src/server/repositories/review-log.ts21
-rw-r--r--src/server/repositories/sync.test.ts1
-rw-r--r--src/server/repositories/sync.ts3
-rw-r--r--src/server/repositories/types.ts25
8 files changed, 8 insertions, 147 deletions
diff --git a/src/server/repositories/card.test.ts b/src/server/repositories/card.test.ts
index 21e5485..b492fd7 100644
--- a/src/server/repositories/card.test.ts
+++ b/src/server/repositories/card.test.ts
@@ -112,12 +112,8 @@ function createMockCardRepo(): CardRepository {
softDeleteByNoteId: vi.fn(),
findDueCards: vi.fn(),
countDueCards: vi.fn(),
- countDueNewCards: vi.fn(),
- countDueReviewCards: vi.fn(),
findDueCardsWithNoteData: vi.fn(),
findDueCardsForStudy: vi.fn(),
- findDueNewCardsForStudy: vi.fn(),
- findDueReviewCardsForStudy: vi.fn(),
updateFSRSFields: vi.fn(),
};
}
diff --git a/src/server/repositories/card.ts b/src/server/repositories/card.ts
index d382f4d..0f1ef79 100644
--- a/src/server/repositories/card.ts
+++ b/src/server/repositories/card.ts
@@ -1,4 +1,4 @@
-import { and, eq, isNull, lt, ne, sql } from "drizzle-orm";
+import { and, eq, isNull, lt, sql } from "drizzle-orm";
import { getEndOfStudyDayBoundary } from "../../shared/date.js";
import { db } from "../db/index.js";
import {
@@ -185,11 +185,7 @@ export const cardRepository: CardRepository = {
return result.length > 0;
},
- async findDueCards(
- deckId: string,
- now: Date,
- limit: number,
- ): Promise<Card[]> {
+ async findDueCards(deckId: string, now: Date): Promise<Card[]> {
const boundary = getEndOfStudyDayBoundary(now);
const result = await db
.select()
@@ -201,8 +197,7 @@ export const cardRepository: CardRepository = {
lt(cards.due, boundary),
),
)
- .orderBy(cards.due)
- .limit(limit);
+ .orderBy(cards.due);
return result;
},
@@ -221,44 +216,11 @@ export const cardRepository: CardRepository = {
return result[0]?.count ?? 0;
},
- async countDueNewCards(deckId: string, now: Date): Promise<number> {
- const boundary = getEndOfStudyDayBoundary(now);
- const result = await db
- .select({ count: sql<number>`count(*)::int` })
- .from(cards)
- .where(
- and(
- eq(cards.deckId, deckId),
- isNull(cards.deletedAt),
- lt(cards.due, boundary),
- eq(cards.state, CardState.New),
- ),
- );
- return result[0]?.count ?? 0;
- },
-
- async countDueReviewCards(deckId: string, now: Date): Promise<number> {
- const boundary = getEndOfStudyDayBoundary(now);
- const result = await db
- .select({ count: sql<number>`count(*)::int` })
- .from(cards)
- .where(
- and(
- eq(cards.deckId, deckId),
- isNull(cards.deletedAt),
- lt(cards.due, boundary),
- ne(cards.state, CardState.New),
- ),
- );
- return result[0]?.count ?? 0;
- },
-
async findDueCardsWithNoteData(
deckId: string,
now: Date,
- limit: number,
): Promise<CardWithNoteData[]> {
- const dueCards = await this.findDueCards(deckId, now, limit);
+ const dueCards = await this.findDueCards(deckId, now);
const cardsWithNoteData: CardWithNoteData[] = [];
@@ -292,56 +254,11 @@ export const cardRepository: CardRepository = {
async findDueCardsForStudy(
deckId: string,
now: Date,
- limit: number,
): Promise<CardForStudy[]> {
- const dueCards = await this.findDueCards(deckId, now, limit);
+ const dueCards = await this.findDueCards(deckId, now);
return enrichCardsForStudy(dueCards);
},
- async findDueNewCardsForStudy(
- deckId: string,
- now: Date,
- limit: number,
- ): Promise<CardForStudy[]> {
- const boundary = getEndOfStudyDayBoundary(now);
- const result = await db
- .select()
- .from(cards)
- .where(
- and(
- eq(cards.deckId, deckId),
- isNull(cards.deletedAt),
- lt(cards.due, boundary),
- eq(cards.state, CardState.New),
- ),
- )
- .orderBy(cards.due)
- .limit(limit);
- return enrichCardsForStudy(result);
- },
-
- async findDueReviewCardsForStudy(
- deckId: string,
- now: Date,
- limit: number,
- ): Promise<CardForStudy[]> {
- const boundary = getEndOfStudyDayBoundary(now);
- const result = await db
- .select()
- .from(cards)
- .where(
- and(
- eq(cards.deckId, deckId),
- isNull(cards.deletedAt),
- lt(cards.due, boundary),
- ne(cards.state, CardState.New),
- ),
- )
- .orderBy(cards.due)
- .limit(limit);
- return enrichCardsForStudy(result);
- },
-
async updateFSRSFields(
id: string,
deckId: string,
diff --git a/src/server/repositories/deck.test.ts b/src/server/repositories/deck.test.ts
index 945f844..ab6e2fc 100644
--- a/src/server/repositories/deck.test.ts
+++ b/src/server/repositories/deck.test.ts
@@ -7,7 +7,6 @@ function createMockDeck(overrides: Partial<Deck> = {}): Deck {
userId: "user-uuid-123",
name: "Test Deck",
description: null,
- newCardsPerDay: 20,
createdAt: new Date("2024-01-01"),
updatedAt: new Date("2024-01-01"),
deletedAt: null,
@@ -35,7 +34,6 @@ describe("DeckRepository mock factory", () => {
expect(deck.userId).toBe("user-uuid-123");
expect(deck.name).toBe("Test Deck");
expect(deck.description).toBeNull();
- expect(deck.newCardsPerDay).toBe(20);
expect(deck.deletedAt).toBeNull();
expect(deck.syncVersion).toBe(0);
});
@@ -45,13 +43,11 @@ describe("DeckRepository mock factory", () => {
id: "custom-id",
name: "Custom Deck",
description: "A description",
- newCardsPerDay: 50,
});
expect(deck.id).toBe("custom-id");
expect(deck.name).toBe("Custom Deck");
expect(deck.description).toBe("A description");
- expect(deck.newCardsPerDay).toBe(50);
});
});
@@ -130,7 +126,6 @@ describe("Deck interface contracts", () => {
expect(deck).toHaveProperty("name");
expect(deck).toHaveProperty("description");
- expect(deck).toHaveProperty("newCardsPerDay");
});
});
diff --git a/src/server/repositories/deck.ts b/src/server/repositories/deck.ts
index 647c5cb..97af5f7 100644
--- a/src/server/repositories/deck.ts
+++ b/src/server/repositories/deck.ts
@@ -31,7 +31,6 @@ export const deckRepository: DeckRepository = {
userId: string;
name: string;
description?: string | null;
- newCardsPerDay?: number;
}): Promise<Deck> {
const [deck] = await db
.insert(decks)
@@ -39,7 +38,6 @@ export const deckRepository: DeckRepository = {
userId: data.userId,
name: data.name,
description: data.description ?? null,
- newCardsPerDay: data.newCardsPerDay ?? 20,
})
.returning();
if (!deck) {
@@ -54,7 +52,6 @@ export const deckRepository: DeckRepository = {
data: {
name?: string;
description?: string | null;
- newCardsPerDay?: number;
},
): Promise<Deck | undefined> {
const result = await db
diff --git a/src/server/repositories/review-log.ts b/src/server/repositories/review-log.ts
index 97488d2..c8950d6 100644
--- a/src/server/repositories/review-log.ts
+++ b/src/server/repositories/review-log.ts
@@ -1,7 +1,5 @@
-import { and, eq, gte, sql } from "drizzle-orm";
-import { getStartOfStudyDayBoundary } from "../../shared/date.js";
import { db } from "../db/index.js";
-import { CardState, cards, reviewLogs } from "../db/schema.js";
+import { reviewLogs } from "../db/schema.js";
import type { ReviewLog, ReviewLogRepository } from "./types.js";
export const reviewLogRepository: ReviewLogRepository = {
@@ -31,21 +29,4 @@ export const reviewLogRepository: ReviewLogRepository = {
}
return reviewLog;
},
-
- async countTodayNewCardReviews(deckId: string, now: Date): Promise<number> {
- const startOfDay = getStartOfStudyDayBoundary(now);
-
- 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;
- },
};
diff --git a/src/server/repositories/sync.test.ts b/src/server/repositories/sync.test.ts
index ce59cb5..8425839 100644
--- a/src/server/repositories/sync.test.ts
+++ b/src/server/repositories/sync.test.ts
@@ -16,7 +16,6 @@ function createMockDeck(overrides: Partial<Deck> = {}): Deck {
userId: "user-uuid-123",
name: "Test Deck",
description: null,
- newCardsPerDay: 20,
createdAt: new Date("2024-01-01"),
updatedAt: new Date("2024-01-01"),
deletedAt: null,
diff --git a/src/server/repositories/sync.ts b/src/server/repositories/sync.ts
index ca4c208..e197d37 100644
--- a/src/server/repositories/sync.ts
+++ b/src/server/repositories/sync.ts
@@ -53,7 +53,6 @@ export interface SyncDeckData {
id: string;
name: string;
description: string | null;
- newCardsPerDay: number;
createdAt: string;
updatedAt: string;
deletedAt: string | null;
@@ -224,7 +223,6 @@ export const syncRepository: SyncRepository = {
userId,
name: deckData.name,
description: deckData.description,
- newCardsPerDay: deckData.newCardsPerDay,
createdAt: new Date(deckData.createdAt),
updatedAt: clientUpdatedAt,
deletedAt: deckData.deletedAt ? new Date(deckData.deletedAt) : null,
@@ -248,7 +246,6 @@ export const syncRepository: SyncRepository = {
.set({
name: deckData.name,
description: deckData.description,
- newCardsPerDay: deckData.newCardsPerDay,
updatedAt: clientUpdatedAt,
deletedAt: deckData.deletedAt
? new Date(deckData.deletedAt)
diff --git a/src/server/repositories/types.ts b/src/server/repositories/types.ts
index 4042daf..71cb811 100644
--- a/src/server/repositories/types.ts
+++ b/src/server/repositories/types.ts
@@ -50,7 +50,6 @@ export interface Deck {
userId: string;
name: string;
description: string | null;
- newCardsPerDay: number;
createdAt: Date;
updatedAt: Date;
deletedAt: Date | null;
@@ -64,7 +63,6 @@ export interface DeckRepository {
userId: string;
name: string;
description?: string | null;
- newCardsPerDay?: number;
}): Promise<Deck>;
update(
id: string,
@@ -72,7 +70,6 @@ export interface DeckRepository {
data: {
name?: string;
description?: string | null;
- newCardsPerDay?: number;
},
): Promise<Deck | undefined>;
softDelete(id: string, userId: string): Promise<boolean>;
@@ -146,30 +143,13 @@ export interface CardRepository {
): Promise<Card | undefined>;
softDelete(id: string, deckId: string): Promise<boolean>;
softDeleteByNoteId(noteId: string): Promise<boolean>;
- findDueCards(deckId: string, now: Date, limit: number): Promise<Card[]>;
+ findDueCards(deckId: string, now: Date): Promise<Card[]>;
countDueCards(deckId: string, now: Date): Promise<number>;
findDueCardsWithNoteData(
deckId: string,
now: Date,
- limit: number,
): Promise<CardWithNoteData[]>;
- findDueCardsForStudy(
- deckId: string,
- now: Date,
- limit: number,
- ): Promise<CardForStudy[]>;
- findDueNewCardsForStudy(
- deckId: string,
- now: Date,
- limit: number,
- ): Promise<CardForStudy[]>;
- findDueReviewCardsForStudy(
- deckId: string,
- now: Date,
- limit: number,
- ): Promise<CardForStudy[]>;
- countDueNewCards(deckId: string, now: Date): Promise<number>;
- countDueReviewCards(deckId: string, now: Date): Promise<number>;
+ findDueCardsForStudy(deckId: string, now: Date): Promise<CardForStudy[]>;
updateFSRSFields(
id: string,
deckId: string,
@@ -210,7 +190,6 @@ export interface ReviewLogRepository {
elapsedDays: number;
durationMs?: number | null;
}): Promise<ReviewLog>;
- countTodayNewCardReviews(deckId: string, now: Date): Promise<number>;
}
export interface NoteType {