delete the batch practice-problems module (superseded by practice sessions)
Owner ruling 2026-10-04: the module is a sunk cost, retrievable from history if ever revisited. Removed: core practice contracts + pipeline helpers, the PracticeStore port + adapter + data dir path, server service + API routes (sets, clusters picker, practice aborts), the practice pages + dialog/exam/list UI, chain-table's Generate handoff, sidebar nav, activity-dock practice rows, and the partitioner/ problemGenerator/grader model roles (BACKGROUND_MODEL_ROLES 8 → 5). Survivors, moved to core/chains.ts (pure + browser-safe): ReasoningChain, chainsForSelection, formatChainLine — the chain table and graph emission still consume them.
This commit is contained in:
@@ -17,7 +17,7 @@
|
||||
* Extraction abort is idempotent by design (aborting with nothing in
|
||||
* flight is success — the blob is gone either way) -> 200.
|
||||
*/
|
||||
import { abortExtraction, abortJob, abortTurn, practice } from "@/src/server";
|
||||
import { abortExtraction, abortJob, abortTurn } from "@/src/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
let body: unknown;
|
||||
@@ -27,11 +27,9 @@ export async function POST(req: Request) {
|
||||
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
||||
}
|
||||
const { kind, id } = (body ?? {}) as { kind?: string; id?: string };
|
||||
if ((kind !== "job" && kind !== "extraction" && kind !== "turn" && kind !== "practice") || typeof id !== "string" || id === "") {
|
||||
return Response.json({ error: 'Body must be {kind: "job"|"extraction"|"turn"|"practice", id: string}' }, { status: 400 });
|
||||
if ((kind !== "job" && kind !== "extraction" && kind !== "turn") || typeof id !== "string" || id === "") {
|
||||
return Response.json({ error: 'Body must be {kind: "job"|"extraction"|"turn", id: string}' }, { status: 400 });
|
||||
}
|
||||
// Practice row keys carry ":" (setId:gen:problemId) — the charset
|
||||
// admits it for every kind (job/turn/extraction ids never use it).
|
||||
if (!/^[A-Za-z0-9:_-]+$/.test(id)) {
|
||||
return Response.json({ error: "Invalid id" }, { status: 400 });
|
||||
}
|
||||
@@ -51,14 +49,6 @@ export async function POST(req: Request) {
|
||||
}
|
||||
// kind === "extraction": true cancellation; idempotent (nothing in
|
||||
// flight is success — same dock outcome)
|
||||
if (kind === "practice") {
|
||||
// practice restructure (owner, 2026-09-29): id is the ROW key —
|
||||
// abort routes by shape (a gen row kills THAT problem only; the
|
||||
// partition row ends the run; a grade row drops that grade).
|
||||
// Idempotent like extraction (nothing in flight is success).
|
||||
practice.abortPracticeRow(id);
|
||||
return Response.json({ ok: true });
|
||||
}
|
||||
abortExtraction(id);
|
||||
return Response.json({ ok: true });
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
/**
|
||||
* GET /api/graph/clusters — the birth-session groups for the practice
|
||||
* creation picker (owner ruling 2026-09-29: sets are created from graph
|
||||
* clusters, node ids only). Thin transport; the grouping is the graph
|
||||
* view's own (server/graph.ts → graphSnapshot's clusters).
|
||||
*/
|
||||
import { graphClusters } from "@/src/server";
|
||||
|
||||
export async function GET() {
|
||||
return Response.json({ clusters: graphClusters() }, { headers: { "cache-control": "no-store" } });
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* POST /api/practice/sets/[id]/answers — submit answers for grading
|
||||
* (202; one grading job per answered problem runs in the background).
|
||||
* Body: {answers: [{problemId, text}]}. Set must be ready; answers must
|
||||
* be non-empty text on known, not-yet-answered problems (400/409 via the
|
||||
* service's typed-error mapping). ONE ATTEMPT (owner 2026-09-29): once a
|
||||
* problem carries an answer it is done — re-submission is refused.
|
||||
*/
|
||||
import { submitPracticeAnswersResponse } from "@/src/server";
|
||||
|
||||
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
|
||||
const { id } = await params;
|
||||
let body: unknown;
|
||||
try {
|
||||
body = await req.json();
|
||||
} catch {
|
||||
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
||||
}
|
||||
return submitPracticeAnswersResponse(id, body);
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* GET /api/practice/sets/[id] — one problem set (the exam page polls
|
||||
* this while status ≠ ready; graph-view's reveal-poll idiom).
|
||||
* DELETE — abort the set's live jobs, then drop the record (the unified
|
||||
* delete doctrine: no orphans, no zombies). 404 when never existed.
|
||||
*/
|
||||
import { getPracticeSet, practice, practiceErrorResponse } from "@/src/server";
|
||||
|
||||
export async function GET(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
||||
const { id } = await params;
|
||||
try {
|
||||
const set = getPracticeSet(id);
|
||||
if (!set) return Response.json({ error: "no practice set", code: "not_found" }, { status: 404 });
|
||||
return Response.json({ set });
|
||||
} catch (err) {
|
||||
return practiceErrorResponse(err);
|
||||
}
|
||||
}
|
||||
|
||||
export async function DELETE(_req: Request, { params }: { params: Promise<{ id: string }> }) {
|
||||
const { id } = await params;
|
||||
try {
|
||||
const existed = await practice.deleteProblemSet(id);
|
||||
if (!existed) return Response.json({ error: "no practice set", code: "not_found" }, { status: 404 });
|
||||
return Response.json({ ok: true });
|
||||
} catch (err) {
|
||||
return practiceErrorResponse(err);
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* POST /api/practice/sets — create a problem set (202 {id}; generation
|
||||
* runs in the background — the fire-and-forget pipeline). Body:
|
||||
* {nodeIds, params, title?, note?} — a node selection, the cluster's
|
||||
* label, and the learner's optional
|
||||
* free-form note
|
||||
* Validation + typed-error mapping live in the service (server/practice).
|
||||
* GET — the set list (createdAt desc, the store's order).
|
||||
*/
|
||||
import { createPracticeSetResponse, listPracticeSets, practiceErrorResponse } from "@/src/server";
|
||||
|
||||
export async function POST(req: Request) {
|
||||
let body: unknown;
|
||||
try {
|
||||
body = await req.json();
|
||||
} catch {
|
||||
return Response.json({ error: "Invalid JSON body" }, { status: 400 });
|
||||
}
|
||||
return createPracticeSetResponse(body);
|
||||
}
|
||||
|
||||
export async function GET() {
|
||||
try {
|
||||
return Response.json({ sets: listPracticeSets() });
|
||||
} catch (err) {
|
||||
return practiceErrorResponse(err);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user