formatting

This commit is contained in:
lila 2026-04-28 13:18:18 +02:00
parent 2ff7d1759e
commit 4f59f3bc14
23 changed files with 994 additions and 3338 deletions

View file

@ -61,10 +61,12 @@ export const evaluateAnswer = async (
store: GameSessionStore,
): Promise<AnswerResult> => {
const session = await store.get(submission.sessionId);
if (!session) throw new NotFoundError(`Game session not found: ${submission.sessionId}`);
if (!session)
throw new NotFoundError(`Game session not found: ${submission.sessionId}`);
const correctOptionId = session.answers.get(submission.questionId);
if (correctOptionId === undefined) throw new NotFoundError(`Question not found: ${submission.questionId}`);
if (correctOptionId === undefined)
throw new NotFoundError(`Question not found: ${submission.questionId}`);
// delete answered question; delete session when all questions are answered
session.answers.delete(submission.questionId);
@ -84,10 +86,14 @@ export const evaluateAnswer = async (
```ts
// ✅ option B — TTL in InMemoryGameSessionStore
export class InMemoryGameSessionStore implements GameSessionStore {
private sessions = new Map<string, { data: GameSessionData; expiresAt: number }>();
private sessions = new Map<
string,
{ data: GameSessionData; expiresAt: number }
>();
private readonly ttlMs: number;
constructor(ttlMs = 30 * 60 * 1000) { // 30 minutes default
constructor(ttlMs = 30 * 60 * 1000) {
// 30 minutes default
this.ttlMs = ttlMs;
}
@ -115,15 +121,13 @@ export class InMemoryGameSessionStore implements GameSessionStore {
---
**Problem**
`GameRequest.rounds` is typed as `string` in `@lila/shared`, forcing the service to cast it every time:
```ts
// ❌ why is a round count a string?
Number(request.rounds)
Number(request.rounds);
```
**Fix — fix the schema in `@lila/shared`**
@ -204,7 +208,10 @@ it("correct answer appears exactly once in options even if distractor matches",
// simulate getDistractors returning the correct answer as one of the distractors
mockGetDistractors.mockResolvedValueOnce(["cane", "wrong2", "wrong3"]);
const session = await createGameSession(validRequest, new InMemoryGameSessionStore());
const session = await createGameSession(
validRequest,
new InMemoryGameSessionStore(),
);
const question = session.questions[0]!;
const optionTexts = question.options.map((o) => o.text);
@ -285,16 +292,14 @@ his `sessionId`.
```ts
// GameSessionStore.ts
export type GameSessionData = {
answers: Map<string, number>;
userId: string;
};
export type GameSessionData = { answers: Map<string, number>; userId: string };
// evaluateAnswer
const session = await store.get(submission.sessionId);
if (!session) throw new NotFoundError(`Game session not found`);
if (session.userId !== requestingUserId) throw new NotFoundError(`Game session not found`);
if (session.userId !== requestingUserId)
throw new NotFoundError(`Game session not found`);
// ^^^ same error — don't confirm the session exists to the wrong user
```
@ -326,8 +331,9 @@ if (terms.length === 0) {
it("throws when getGameTerms returns no terms", async () => {
mockGetGameTerms.mockResolvedValue([]);
await expect(createGameSession(validRequest, new InMemoryGameSessionStore()))
.rejects.toThrow("No terms found");
await expect(
createGameSession(validRequest, new InMemoryGameSessionStore()),
).rejects.toThrow("No terms found");
});
```
@ -349,8 +355,9 @@ it("throws when getGameTerms returns no terms", async () => {
it("propagates getDistractors failure", async () => {
mockGetDistractors.mockRejectedValue(new Error("db timeout"));
await expect(createGameSession(validRequest, new InMemoryGameSessionStore()))
.rejects.toThrow("db timeout");
await expect(
createGameSession(validRequest, new InMemoryGameSessionStore()),
).rejects.toThrow("db timeout");
});
```