2026-01-20 09:02:26 -06:00

102 lines
3.4 KiB
TypeScript

// routes/api/brain/debug.ts
// Debug endpoint to verify brain progress persistence across restarts
import { define, State } from "../../../utils.ts";
import { SessionCookie } from "../../auth/callback.ts";
import { brainDataClient } from "../../../utils/BrainDataClient.ts";
import {
sqlGetAllBrainProgress,
sqlGetBrainProgressByUser,
} from "../../../db/sqlUserRepository.ts";
export const handler = define.handlers({
// GET: Debug info about brain progress persistence
async GET(ctx) {
const state = ctx.state as State;
const stateData: SessionCookie = state.data ?? {
started_on: 0,
user_name: "",
user_id: "",
role: "",
user_encrypted: false,
};
if (!state.stateId || !stateData.user_id) {
return new Response(
JSON.stringify({ error: "Unauthorized" }),
{ status: 401, headers: { "Content-Type": "application/json" } },
);
}
try {
// Get progress from BrainDataClient (uses KV + SQL via KvCacheStore)
const kvProgress = await brainDataClient.getUserProgress(
stateData.user_id,
);
// Get progress directly from SQL (bypasses KV cache)
const sqlProgress = await sqlGetBrainProgressByUser(stateData.user_id);
// Get all SQL progress (for admin debugging)
const allSqlProgress = await sqlGetAllBrainProgress();
// Count records with is_review_only = true
const kvMasteredCount = kvProgress.filter((p) => p.is_review_only).length;
const sqlMasteredCount = sqlProgress.filter((p) =>
p.is_review_only
).length;
return new Response(
JSON.stringify({
success: true,
user_id: stateData.user_id,
persistence_status: {
kv_record_count: kvProgress.length,
sql_record_count: sqlProgress.length,
all_sql_record_count: allSqlProgress.length,
kv_mastered_count: kvMasteredCount,
sql_mastered_count: sqlMasteredCount,
records_match: kvProgress.length === sqlProgress.length,
},
// Include first few records for debugging
kv_sample: kvProgress.slice(0, 3).map((p) => ({
id: p.id,
question_id: p.question_id,
current_mode: p.current_mode,
mode_index: p.mode_index,
is_review_only: p.is_review_only,
attempts: p.attempts,
})),
sql_sample: sqlProgress.slice(0, 3).map((p) => ({
id: p.id,
question_id: p.question_id,
current_mode: p.current_mode,
mode_index: p.mode_index,
is_review_only: p.is_review_only,
attempts: p.attempts,
})),
// Diagnostic info
diagnostics: {
kv_mastered_ids: kvProgress
.filter((p) => p.is_review_only)
.map((p) => p.question_id),
sql_mastered_ids: sqlProgress
.filter((p) => p.is_review_only)
.map((p) => p.question_id),
},
}),
{ status: 200, headers: { "Content-Type": "application/json" } },
);
} catch (error) {
console.error("Error in brain debug endpoint:", error);
return new Response(
JSON.stringify({
error: "Failed to fetch debug info",
details: error instanceof Error ? error.message : String(error),
}),
{ status: 500, headers: { "Content-Type": "application/json" } },
);
}
},
});