refactor(harness): route workflow persistence through repositories
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const cp = require("node:child_process");
|
||||
const { createRequire } = require("node:module");
|
||||
const path = require("node:path");
|
||||
|
||||
const GATE = path.join(__dirname, "..", "..", "tht-gate.js");
|
||||
if (typeof globalThis.require === "undefined") globalThis.require = createRequire(GATE);
|
||||
|
||||
test("repository write tools persist CTE and final SQL through deterministic tht commands", async () => {
|
||||
const calls = [];
|
||||
const original = cp.execFileSync;
|
||||
cp.execFileSync = (file, args, options) => {
|
||||
calls.push({ args, input: options?.input });
|
||||
return "";
|
||||
};
|
||||
try {
|
||||
const gate = require(GATE);
|
||||
const { createFakePi } = require("./fake_pi_runtime.js");
|
||||
const { pi, ctx, tools } = createFakePi();
|
||||
ctx.cwd = "/nonexistent-thothii-test-cwd";
|
||||
gate.default(pi);
|
||||
|
||||
const cte = tools.get("write_cte_sql");
|
||||
const final = tools.get("write_final_sql");
|
||||
assert.ok(cte, "write_cte_sql must be registered");
|
||||
assert.ok(final, "write_final_sql must be registered");
|
||||
|
||||
await cte.def.execute("cte", { session: "s1", name: "base", sql: "WITH base AS (SELECT 1)" }, null, null, ctx);
|
||||
await final.def.execute("sql", { session: "s1", sql: "SELECT * FROM base" }, null, null, ctx);
|
||||
|
||||
assert.deepEqual(calls.map((call) => call.args), [
|
||||
["cte", "save", "--session", "s1", "--name", "base", "--file", "-"],
|
||||
["sql", "set-final", "--session", "s1", "--file", "-"],
|
||||
]);
|
||||
assert.deepEqual(calls.map((call) => call.input), ["WITH base AS (SELECT 1)", "SELECT * FROM base"]);
|
||||
assert.equal(JSON.stringify(calls).includes("sessions/s1"), false);
|
||||
} finally {
|
||||
cp.execFileSync = original;
|
||||
}
|
||||
});
|
||||
@@ -1401,6 +1401,38 @@ export default function (pi) {
|
||||
},
|
||||
});
|
||||
|
||||
pi.registerTool({
|
||||
name: "write_cte_sql",
|
||||
label: "Scrittura CTE SQL",
|
||||
description: "Persiste un blocco CTE tramite tht cte save; non scrivere mai file di sessione direttamente.",
|
||||
parameters: Type.Object({ session: Type.String(), name: Type.String(), sql: Type.String() }),
|
||||
async execute(_id, params, _signal, _onUpdate, ctx) {
|
||||
const err = relayIfThtFails(
|
||||
ctx,
|
||||
["cte", "save", "--session", params.session, "--name", params.name, "--file", "-"],
|
||||
"Correggi il blocco CTE e riprova.",
|
||||
params.sql,
|
||||
);
|
||||
return err || textResult(`CTE ${params.name} salvato per la sessione ${params.session}.`);
|
||||
},
|
||||
});
|
||||
|
||||
pi.registerTool({
|
||||
name: "write_final_sql",
|
||||
label: "Scrittura SQL finale",
|
||||
description: "Persiste il SQL finale tramite tht sql set-final; non scrivere mai file di sessione direttamente.",
|
||||
parameters: Type.Object({ session: Type.String(), sql: Type.String() }),
|
||||
async execute(_id, params, _signal, _onUpdate, ctx) {
|
||||
const err = relayIfThtFails(
|
||||
ctx,
|
||||
["sql", "set-final", "--session", params.session, "--file", "-"],
|
||||
"Correggi il SQL finale e riprova.",
|
||||
params.sql,
|
||||
);
|
||||
return err || textResult(`SQL finale salvato per la sessione ${params.session}.`);
|
||||
},
|
||||
});
|
||||
|
||||
// --- slash command: /torna [session_id] [N] (rollback to a previous phase) --
|
||||
pi.registerCommand("torna", {
|
||||
description:
|
||||
|
||||
@@ -353,7 +353,9 @@ Prerequisite: Phase 5 closed.
|
||||
"output_columns":["cod_paz","data_ricovero"]}
|
||||
]}
|
||||
```
|
||||
3. For each CTE (in plan order): write `sessions/<id>/ctes/<name>.sql` (ONLY the
|
||||
3. For each CTE (in plan order): call `write_cte_sql` with the session id, CTE name,
|
||||
and SQL block (the tool invokes `tht cte save --session <id> --name <name> --file -`).
|
||||
Persist ONLY the
|
||||
`WITH ... AS (...)` block, NO trailing SELECT), test with `tht cte test --session
|
||||
<id> <name>` (with an **ok** outcome), then present it with
|
||||
`reviewer_confirm kind:"cte_result"`. Pass ONLY the thin v2 data
|
||||
@@ -385,7 +387,8 @@ Prerequisite: Phase 6 closed.
|
||||
columns (`dt.year`, `dt.month`, …), NEVER arithmetic on the key.
|
||||
3. `tht sql validate` + `tht sql preview` (max 10 rows). On errors / suspicious
|
||||
results, apply the `sql-generation.md` checklist and correct with the reviewer.
|
||||
4. `tht sql save` writes `sessions/<id>/sql_final.sql` (ONLY clean SQL, no comments).
|
||||
4. Call `write_final_sql` with the session id and clean SQL; it invokes
|
||||
`tht sql set-final --session <id> --file -` (ONLY clean SQL, no comments).
|
||||
Approve with `reviewer_confirm kind:"sql"` (records `sql_approved`), then advance to
|
||||
Phase 8 with `reviewer_confirm kind:"phase"` — `kind:"sql"` alone does NOT advance F7.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user