integratedhub/utils/QuizDataClient.ts
2026-01-20 09:02:26 -06:00

236 lines
6.5 KiB
TypeScript

import {
cloneObjectExcept as _cloneObjectExcept,
jsonMerge as _jsonMerge,
KvObj,
QuizConfig,
} from "./types.ts";
import { kvStore } from "../modules/KvCacheStore.ts";
/**
* Interface to define the structure of a Quiz document.
* Using an interface provides strong typing for our data.
*/
export interface Quiz {
id: string;
ownerId: string;
questions: unknown[];
[key: string]: unknown;
}
/**
* A client for interacting with quiz data using KvCacheStore.
* Uses the shared KvCacheStore for connection management and operations.
*/
export class QuizDataClient {
// No longer needs Cosmos DB client - using KvCacheStore instead
/**
* Creates an instance of the QuizDataClient.
* No longer requires connection string since using KvCacheStore.
*/
constructor() {
// KvCacheStore is initialized globally, no connection needed
}
/**
* Retrieves all quizzes from KvCacheStore.
* @returns {Promise<Quiz[]>} A promise that resolves to an array of all quiz documents.
*/
async getAllQuizzes(): Promise<Quiz[]> {
const quizzes: Quiz[] = [];
for await (
const entry of kvStore.list<Quiz>({ prefix: ["quiz_configs"] })
) {
quizzes.push(entry.value);
}
return quizzes;
}
/**
* Retrieves all quizzes for a specific owner from KvCacheStore.
* @param {string} ownerId The ID of the owner.
* @returns {Promise<Quiz[]>} A promise that resolves to an array of quiz documents for the specified owner.
*/
async getAllQuizzesForOwner(ownerId: string): Promise<Quiz[]> {
const quizzes: Quiz[] = [];
for await (
const entry of kvStore.list<Quiz>({ prefix: ["quiz_configs", ownerId] })
) {
quizzes.push(entry.value);
}
return quizzes;
}
/**
* Retrieves a single, specific quiz by its ID and owner ID from KvCacheStore.
* @param {string} ownerId The ID of the owner.
* @param {string} quizId The ID of the quiz document.
* @returns {Promise<Quiz | undefined>} A promise that resolves to the quiz document, or undefined if not found.
*/
async getQuiz(ownerId: string, quizId: string): Promise<Quiz | undefined> {
const key = ["quiz_configs", ownerId, quizId];
const result = await kvStore.get<Quiz>(key);
return result || undefined;
}
/**
* Creates a new quiz or updates an existing one in KvCacheStore.
* @param {Quiz} quiz The quiz document to create or update.
* @returns {Promise<Quiz>} A promise that resolves to the state of the quiz document after the upsert operation.
*/
async upsertQuiz(quiz: Quiz): Promise<Quiz> {
const key = ["quiz_configs", quiz.ownerId, quiz.id];
await kvStore.set(key, quiz);
return quiz;
}
/**
* Deletes a specific quiz document from KvCacheStore.
* @param {string} ownerId The ID of the owner.
* @param {string} quizId The ID of the quiz document to delete.
* @returns {Promise<void>} A promise that resolves when the delete operation is complete.
*/
async deleteQuiz(ownerId: string, quizId: string): Promise<void> {
const key = ["quiz_configs", ownerId, quizId];
await kvStore.delete(key);
}
}
export async function initKvQuizAny(
owner_id: string,
quiz_id: string,
quiz: QuizConfig,
): Promise<KvObj<QuizConfig>> {
const key = ["quiz_configs", owner_id, quiz_id];
await kvStore.set(key, quiz);
const objQuizConfig: KvObj<QuizConfig> = {
ok: true,
key: key,
versionstamp: Date.now().toString(),
value: quiz,
};
return objQuizConfig;
}
export async function upsertKvQuizAny(
kvObjQuizConfig: KvObj<QuizConfig>,
): Promise<KvObj<QuizConfig>> {
if (
kvObjQuizConfig.key && kvObjQuizConfig.key[1] && kvObjQuizConfig.key[2] &&
kvObjQuizConfig.value
) {
await kvStore.set(kvObjQuizConfig.key, kvObjQuizConfig.value);
const objQuizConfig: KvObj<QuizConfig> = {
ok: true,
key: kvObjQuizConfig.key,
versionstamp: Date.now().toString(),
value: kvObjQuizConfig.value,
};
return objQuizConfig;
} else {
kvObjQuizConfig.versionstamp += " upsertKvQuizAny: Input parameter bad.";
}
kvObjQuizConfig.ok = false;
console.log("failed", kvObjQuizConfig.value?.quiz_name);
return kvObjQuizConfig;
}
export async function setKvQuizAny(
kvObjQuizConfig: KvObj<QuizConfig>,
): Promise<KvObj<QuizConfig>> {
await kvStore.set(kvObjQuizConfig.key, kvObjQuizConfig.value);
const objQuizConfig: KvObj<QuizConfig> = {
ok: true,
key: kvObjQuizConfig.key,
versionstamp: Date.now().toString(),
value: kvObjQuizConfig.value,
};
return objQuizConfig;
}
export async function getKvQuiz(
owner_id: string,
quiz_id: string,
): Promise<KvObj<QuizConfig>> {
const key = ["quiz_configs", owner_id, quiz_id];
const value = await kvStore.get<QuizConfig>(key);
const kvObjQuizConfig: KvObj<QuizConfig> = {
ok: true,
key: key,
versionstamp: Date.now().toString(),
value: value,
};
return kvObjQuizConfig;
}
export async function getAllKvQuizConfigs(
owner_id?: string,
): Promise<KvObj<QuizConfig>[]> {
const quizs: KvObj<QuizConfig>[] = [];
const prefix = owner_id ? ["quiz_configs", owner_id] : ["quiz_configs"];
for await (const entry of kvStore.list<QuizConfig>({ prefix })) {
const res: KvObj<QuizConfig> = {
key: [...entry.key] as string[],
ok: true,
value: entry.value,
versionstamp: Date.now().toString(),
};
if (!owner_id || res.key[1] === owner_id) {
quizs.push(res);
}
}
return quizs;
}
export async function trasKvQuizAny(
kvObjQuizConfig: KvObj<QuizConfig>,
): Promise<KvObj<QuizConfig>> {
if (
kvObjQuizConfig.key && kvObjQuizConfig.key[1] && kvObjQuizConfig.key[2] &&
kvObjQuizConfig.value
) {
// For trash functionality, we'll delete the quiz from KvCacheStore
await kvStore.delete(kvObjQuizConfig.key);
const objQuizConfig: KvObj<QuizConfig> = {
ok: true,
key: kvObjQuizConfig.key,
versionstamp: Date.now().toString(),
value: kvObjQuizConfig.value,
};
return objQuizConfig;
} else {
kvObjQuizConfig.versionstamp += " trasKvQuizAny: Input parameter bad.";
}
kvObjQuizConfig.ok = false;
console.log("failed", kvObjQuizConfig.value?.quiz_name);
return kvObjQuizConfig;
}
export async function deleteQuizAny(quiz_id: string) {
// Delete all quizzes with the given quiz_id across all owners
const prefix = ["quiz_configs"];
for await (const entry of kvStore.list({ prefix })) {
if (entry.key[2] === quiz_id) {
await kvStore.delete(entry.key);
}
}
console.log("Delete quiz", quiz_id);
}
export const quizDataClient = new QuizDataClient();