Files
Jyotisha/frontend/tests/database-rectification-block-scan.test.ts
T
Jesse_Chen 814c924e4a
Independent Staging Quality Gate / validate (push) Successful in 9m20s
Independent Staging Quality Gate / publish (push) Successful in 6m51s
fix(rectification): exhaustion exit, explain layer, range reading, unknown-time scan (BUG-565–568)
Keep askable cards after exhaustion, explain each probe, read the adopted credible range in reports and chat, and compare declared periods before the minute grid when the clock is unknown.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-07 09:10:37 +08:00

194 lines
7.2 KiB
TypeScript

import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { fileURLToPath } from "node:url";
import test from "node:test";
import { closeLocalPostgresDataPool, createLocalPostgresDataClient } from "../src/lib/db/local-postgres-client-core.ts";
import { startPostgresFixture } from "./helpers/postgres-fixture.ts";
const runnerPath = fileURLToPath(
new URL("../scripts/db-migrate.mjs", import.meta.url),
);
function dockerAvailable(): boolean {
const probe = spawnSync("docker", ["version", "--format", "{{.Server.Version}}"], {
encoding: "utf8",
stdio: "ignore",
});
return probe.status === 0;
}
const skipWithoutDocker = dockerAvailable() ? false : "docker unavailable on this host";
function rpcError(error: unknown): string {
if (!error || typeof error !== "object") return "";
const value = error as { message?: unknown };
return typeof value.message === "string" ? value.message : "";
}
const snapshot = {
birth_date: "1998-03-15",
birth_place_label: "北京市",
latitude: 39.9042,
longitude: 116.4074,
timezone_id: "Asia/Shanghai",
timezone_offset: 8,
birth_time_source: "unknown",
reported_birth_time: null,
active_birth_time: null,
birth_time_period: null,
uncertainty_before_minutes: null,
uncertainty_after_minutes: null,
};
const fingerprint = "b".repeat(64);
const fullDay = { start_time: "00:00", end_time: "23:59" };
const skillName = "jyotish-birth-time-rectification";
const skillVersion = "9.0.0";
const blocks = {
blocks: [
{ period: "early_morning", start_time: "04:00", end_time: "07:59", relative_support: 12 },
{ period: "morning", start_time: "08:00", end_time: "11:59", relative_support: 41 },
{ period: "afternoon", start_time: "12:00", end_time: "17:59", relative_support: 28 },
{ period: "evening", start_time: "18:00", end_time: "22:59", relative_support: 11 },
{ period: "late_night", start_time: "23:00", end_time: "03:59", relative_support: 8 },
],
};
test("block_scan RPCs are service_role-only and advance a declared period", { skip: skipWithoutDocker }, async () => {
const fixture = startPostgresFixture();
const schemaUrl = fixture.connectionUrl("schema_owner", "schema-owner-test-password");
try {
const migration = spawnSync(process.execPath, [runnerPath], {
encoding: "utf8",
env: { ...process.env, SCHEMA_DATABASE_URL: schemaUrl },
});
assert.equal(migration.status, 0, migration.stderr);
fixture.psqlAs(
"identity_runtime",
"identity-runtime-test-password",
`
insert into identity.users (name, email, email_verified, email_verified_at)
values ('Unknown', 'unknown-time@example.com', true, now());
`,
);
const userId = fixture.psql(
"select id from identity.users where email = 'unknown-time@example.com'",
);
fixture.psql(`
update public.profiles
set birth_date = '1998-03-15',
reported_birth_time = null,
birth_time_source = 'unknown',
latitude = 39.9042, longitude = 116.4074, timezone_offset = 8,
birth_time_status = 'reported'
where id = '${userId}';
`);
fixture.psql(`
with provider as (
insert into public.model_providers (code, name, provider_type, encrypted_api_key, enabled)
values ('block-scan-test', 'Block Scan Test', 'openai', 'test-ciphertext', true)
returning id
), config as (
insert into public.model_configs (model_id)
values ('block-scan-default-model')
returning id
)
insert into public.model_config_versions (
config_id, version, provider_id, label, provider_model, enabled, is_default, status, published_at
)
select config.id, 1, provider.id, 'Default', 'gpt-test', true, true, 'published', now()
from config cross join provider;
`);
const service = createLocalPostgresDataClient(
fixture.connectionUrl("service_runtime", "service-runtime-test-password"),
null,
"service_role",
);
const opened = await service.rpc("open_agentic_rectification_case", {
p_user_id: userId,
p_request_id: "aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa",
p_intent: "homepage",
p_session_id: null,
p_skill_name: skillName,
p_skill_version: skillVersion,
p_baseline_profile_fingerprint: fingerprint,
p_baseline_birth_snapshot: snapshot,
p_candidate_range: fullDay,
});
assert.equal(opened.error, null, rpcError(opened.error));
const caseId = String((opened.data as Record<string, unknown>).case_id);
const staged = await service.rpc("set_agentic_rectification_case_stage", {
p_user_id: userId,
p_case_id: caseId,
p_stage: "block_scan",
});
assert.equal(staged.error, null, rpcError(staged.error));
const written = await service.rpc("write_agentic_rectification_block_scan", {
p_user_id: userId,
p_case_id: caseId,
p_block_scan: blocks,
});
assert.equal(written.error, null, rpcError(written.error));
const dossier = await service.rpc("get_agentic_rectification_case_dossier", {
p_user_id: userId,
p_case_id: caseId,
});
assert.equal(dossier.error, null, rpcError(dossier.error));
const caseRow = (dossier.data as { case?: { stage?: string; block_scan?: unknown } }).case;
assert.equal(caseRow?.stage, "block_scan");
assert.ok(caseRow?.block_scan);
const advanced = await service.rpc("advance_agentic_rectification_case_from_block_scan", {
p_user_id: userId,
p_case_id: caseId,
p_start_time: "08:00",
p_end_time: "11:59",
});
assert.equal(advanced.error, null, rpcError(advanced.error));
assert.equal((advanced.data as { stage?: string }).stage, "minute");
assert.deepEqual((advanced.data as { candidate_range?: unknown }).candidate_range, {
start_time: "08:00",
end_time: "11:59",
});
assert.equal(
fixture.psql(`select stage from public.agentic_rectification_cases where id = '${caseId}'`),
"minute",
);
assert.equal(
fixture.psql(`select block_scan is null from public.agentic_rectification_cases where id = '${caseId}'`),
"t",
);
const invalidPeriod = await service.rpc("advance_agentic_rectification_case_from_block_scan", {
p_user_id: userId,
p_case_id: caseId,
p_start_time: "04:50",
p_end_time: "05:10",
});
assert.match(rpcError(invalidPeriod.error), /agentic_rectification_not_block_scan|agentic_rectification_invalid_block_period/);
const privileges = fixture.psql(`
select concat_ws(':',
has_function_privilege('service_role', 'public.set_agentic_rectification_case_stage(uuid,uuid,text)', 'EXECUTE'),
has_function_privilege('anon', 'public.set_agentic_rectification_case_stage(uuid,uuid,text)', 'EXECUTE'),
has_function_privilege('authenticated', 'public.write_agentic_rectification_block_scan(uuid,uuid,jsonb)', 'EXECUTE'),
has_function_privilege('service_role', 'public.advance_agentic_rectification_case_from_block_scan(uuid,uuid,text,text)', 'EXECUTE')
)
`);
assert.equal(privileges, "t:f:f:t");
} finally {
try {
await closeLocalPostgresDataPool(
fixture.connectionUrl("service_runtime", "service-runtime-test-password"),
);
} finally {
fixture.stop();
}
}
});