feat(api): add in-memory GameSessionStore
Add the session storage infrastructure for tracking correct answers during a game. Designed for easy swap to Valkey in Phase 4. - GameSessionStore interface with create/get/delete methods, all async to match the eventual Valkey implementation - InMemoryGameSessionStore backed by a Map - GameSessionData holds only the answer key (questionId → correctOptionId) - Also fix root build script to build packages in dependency order
This commit is contained in:
parent
f53ac618bb
commit
1940ff3965
6 changed files with 31 additions and 4 deletions
7
apps/api/src/gameSessionStore/GameSessionStore.ts
Normal file
7
apps/api/src/gameSessionStore/GameSessionStore.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
export type GameSessionData = { answers: Map<string, number> };
|
||||||
|
|
||||||
|
export interface GameSessionStore {
|
||||||
|
create(sessionId: string, data: GameSessionData): Promise<void>;
|
||||||
|
get(sessionId: string): Promise<GameSessionData | null>;
|
||||||
|
delete(sessionId: string): Promise<void>;
|
||||||
|
}
|
||||||
17
apps/api/src/gameSessionStore/InMemoryGameSessionStore.ts
Normal file
17
apps/api/src/gameSessionStore/InMemoryGameSessionStore.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import type { GameSessionStore, GameSessionData } from "./GameSessionStore.js";
|
||||||
|
|
||||||
|
export class InMemoryGameSessionStore implements GameSessionStore {
|
||||||
|
private sessions = new Map<string, GameSessionData>();
|
||||||
|
|
||||||
|
async create(sessionId: string, data: GameSessionData): Promise<void> {
|
||||||
|
this.sessions.set(sessionId, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(sessionId: string): Promise<GameSessionData | null> {
|
||||||
|
return this.sessions.get(sessionId) ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async delete(sessionId: string): Promise<void> {
|
||||||
|
this.sessions.delete(sessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
2
apps/api/src/gameSessionStore/index.ts
Normal file
2
apps/api/src/gameSessionStore/index.ts
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
export type { GameSessionStore, GameSessionData } from "./GameSessionStore.js";
|
||||||
|
export { InMemoryGameSessionStore } from "./InMemoryGameSessionStore.js";
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"extends": "../../tsconfig.base.json",
|
"extends": "../../tsconfig.base.json",
|
||||||
"references": [
|
"references": [
|
||||||
{ "path": "../../packages/shared" },
|
{ "path": "../../packages/shared" },
|
||||||
{ "path": "../../packages/db" }
|
{ "path": "../../packages/db" },
|
||||||
],
|
],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "NodeNext",
|
"module": "NodeNext",
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"rootDir": ".",
|
"rootDir": ".",
|
||||||
"types": ["vitest/globals"]
|
"types": ["vitest/globals"],
|
||||||
},
|
},
|
||||||
"include": ["src", "vitest.config.ts", "../../packages/db/src/models"]
|
"include": ["src", "vitest.config.ts"],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
"description": "a vocabulary trainer",
|
"description": "a vocabulary trainer",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"build": "pnpm --filter @glossa/shared build && pnpm --filter @glossa/db build",
|
||||||
"dev": "concurrently --names \"api,web\" -c \"magenta.bold,green.bold\" \"pnpm --filter @glossa/api dev\" \"pnpm --filter @glossa/web dev\"",
|
"dev": "concurrently --names \"api,web\" -c \"magenta.bold,green.bold\" \"pnpm --filter @glossa/api dev\" \"pnpm --filter @glossa/web dev\"",
|
||||||
"test": "vitest",
|
"test": "vitest",
|
||||||
"test:run": "vitest run",
|
"test:run": "vitest run",
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,7 @@ const createDeck = async (tx: DbOrTx, validatedLanguages: string[]) => {
|
||||||
description: config.deckDescription,
|
description: config.deckDescription,
|
||||||
source_language: config.sourceLanguage,
|
source_language: config.sourceLanguage,
|
||||||
validated_languages: validatedLanguages,
|
validated_languages: validatedLanguages,
|
||||||
is_public: false,
|
type: "core",
|
||||||
})
|
})
|
||||||
.returning({ id: decks.id });
|
.returning({ id: decks.id });
|
||||||
const created = result[0];
|
const created = result[0];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue