Release Healer Man 0.1.46

This commit is contained in:
phenom committed 2026-09-16 14:30:58 -04:00
1 parent f82daf1c13
commit 9ff574ac0b
73 files changed
+33486 -174

No files matched your search

+100 -1
View File
@@ -1,11 +1,13 @@
import assert from "node:assert/strict";
import { mkdtempSync, rmSync } from "node:fs";
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
import os from "node:os";
import path from "node:path";
import test from "node:test";
import { DatabaseSync } from "node:sqlite";
import { GameDatabaseError, openGameDatabase } from "./database.mjs";
const routeCatalog = JSON.parse(readFileSync(new URL("../src/game/generated/dungeonRouteCatalog.generated.json", import.meta.url), "utf8"));
function withDatabase(run) {
const directory = mkdtempSync(path.join(os.tmpdir(), "healer-man-db-test-"));
const database = openGameDatabase({ dataDir: directory, sessionTtlDays: 1 });
@@ -137,6 +139,103 @@ test("persists revisioned Manastorm GM configuration and rejects stale or unauth
}), (error) => error instanceof GameDatabaseError && error.status === 400);
}));
test("stores GM simulation replays and gates exact-hash route approval", () => withDatabase(async (database) => {
const gmAuth = await database.register("Phenom", "storm-admin");
const playerAuth = await database.register("RoutePlayer", "route-player");
const gm = database.authenticate(gmAuth.token);
const player = database.authenticate(playerAuth.token);
const routeHash = routeCatalog.routes.find((route) => route.dungeonId === "deadmines").hash;
const replay = {
schemaVersion: 1,
dungeonId: "deadmines",
routeId: "primary",
routeHash,
mode: "navigation-only",
seed: "deadmines:primary",
result: "completed",
startedAt: 1_700_000_000_000,
durationMs: 42_000,
report: { schemaVersion: 1, findings: [] },
frames: [{ atMs: 0, actors: [] }],
events: [],
};
assert.throws(() => database.saveDungeonSimulationReplay(player, replay), (error) => (
error instanceof GameDatabaseError && error.status === 403
));
assert.throws(() => database.putDungeonRouteReview(gm, "deadmines", "primary", {
routeHash, status: "Approved", expectedRevision: 0,
}), (error) => error instanceof GameDatabaseError && error.code === "route_run_required");
const saved = database.saveDungeonSimulationReplay(gm, replay);
assert.equal(saved.criticalFindings, 0);
assert.equal(database.getDungeonSimulationReplay(gm, saved.id).frames.length, 1);
assert.equal(database.getDungeonSimulationReport(gm, saved.id).schemaVersion, 1);
const review = database.putDungeonRouteReview(gm, "deadmines", "primary", {
routeHash, status: "Approved", expectedRevision: 0, note: "Clean navigation-only pass.",
});
assert.equal(review.revision, 1);
assert.deepEqual(database.listDungeonRouteApprovals().approvals.map(({ reviewedAt: _reviewedAt, ...entry }) => entry), [{
dungeonId: "deadmines", routeId: "primary", routeHash,
}]);
assert.throws(() => database.putDungeonRouteReview(gm, "deadmines", "primary", {
routeHash, status: "NeedsWork", expectedRevision: 0,
}), (error) => error instanceof GameDatabaseError && error.status === 409);
assert.equal(database.deleteDungeonSimulationReplay(gm, saved.id).ok, true);
}));
test("requires an override note when the latest exact-hash route run has critical findings", () => withDatabase(async (database) => {
const gmAuth = await database.register("Phenom", "storm-admin");
const gm = database.authenticate(gmAuth.token);
const routeHash = routeCatalog.routes.find((route) => route.dungeonId === "blackfathom-deeps").hash;
database.saveDungeonSimulationReplay(gm, {
schemaVersion: 1,
dungeonId: "blackfathom-deeps",
routeId: "primary",
routeHash,
mode: "navigation-only",
seed: "route-seed",
result: "completed",
startedAt: 1_700_000_000_000,
durationMs: 10_000,
report: { schemaVersion: 1, findings: [{ severity: "critical", code: "no-path" }] },
frames: [],
events: [],
});
assert.throws(() => database.putDungeonRouteReview(gm, "blackfathom-deeps", "primary", {
routeHash, status: "Approved", expectedRevision: 0,
}), (error) => error instanceof GameDatabaseError && error.code === "route_override_required");
const review = database.putDungeonRouteReview(gm, "blackfathom-deeps", "primary", {
routeHash, status: "Approved", expectedRevision: 0, criticalOverrideNote: "Known scripted lift gap.",
});
assert.equal(review.status, "Approved");
assert.equal(review.criticalOverrideNote, "Known scripted lift gap.");
}));
test("requires the latest exact-hash route run to be completed before approval", () => withDatabase(async (database) => {
const gmAuth = await database.register("Phenom", "storm-admin");
const gm = database.authenticate(gmAuth.token);
const routeHash = routeCatalog.routes.find((route) => route.dungeonId === "razorfen-downs").hash;
database.saveDungeonSimulationReplay(gm, {
schemaVersion: 1,
dungeonId: "razorfen-downs",
routeId: "primary",
routeHash,
mode: "full-combat",
seed: "incomplete-route-seed",
result: "stopped",
startedAt: 1_700_000_000_000,
durationMs: 10_000,
report: { schemaVersion: 1, findings: [] },
frames: [],
events: [],
});
assert.throws(() => database.putDungeonRouteReview(gm, "razorfen-downs", "primary", {
routeHash, status: "Approved", expectedRevision: 0,
}), (error) => error instanceof GameDatabaseError && error.code === "route_completed_run_required");
}));
test("creates online groups through invitations and transfers leadership when the leader leaves", () => withDatabase(async (database) => {
const leaderAuth = await database.register("GroupLeader", "group-pass");
const healerAuth = await database.register("GroupHealer", "healer-pass");