feat(housekeeping): unify complete rebuild in gated preview
CI / check (pull_request) Failing after 10s
CI / deploy (pull_request) Skipped
CI / release (pull_request) Skipped

This commit is contained in:
Simo committed 2026-08-31 20:37:51 +02:00
1 parent 4ad007d241
commit 43470ebf82
402 files changed
+78313 -1663

No files matched your search

@@ -0,0 +1,225 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
import { PERMS } from "@/lib/permission-slugs";
import { dispatchHousekeepingCommand } from "../../../foundation/commands/dispatcher";
import {
type HousekeepingCommand,
registerHousekeepingCommand,
} from "../../../foundation/commands/registry";
import type { HousekeepingCapabilityContext } from "../../../foundation/contracts";
const doubles = vi.hoisted(() => ({
createEmulatorRank: vi.fn(),
dbExecute: vi.fn(),
dbInsert: vi.fn(),
dbSelect: vi.fn(),
dbTransaction: vi.fn(),
dbUpdate: vi.fn(),
deleteEmulatorRank: vi.fn(),
logStaffActivity: vi.fn(),
rconSend: vi.fn(),
rconSetRank: vi.fn(),
updateEmulatorRank: vi.fn(),
}));
vi.mock("@/lib/db", async (importOriginal) => {
const actual = await importOriginal<typeof import("@/lib/db")>();
return {
...actual,
db: {
...actual.db,
execute: doubles.dbExecute,
insert: doubles.dbInsert,
select: doubles.dbSelect,
transaction: doubles.dbTransaction,
update: doubles.dbUpdate,
},
};
});
vi.mock("@/lib/services/permission-ranks", () => ({
createEmulatorRank: doubles.createEmulatorRank,
deleteEmulatorRank: doubles.deleteEmulatorRank,
updateEmulatorRank: doubles.updateEmulatorRank,
}));
vi.mock("@/lib/services/rcon", () => ({
rcon: { send: doubles.rconSend, setRank: doubles.rconSetRank },
}));
vi.mock("@/lib/services/staff-activity", () => ({
logStaffActivity: doubles.logStaffActivity,
}));
import { createSystemCommands } from "../commands/system-commands";
import {
type SystemMutationOperation,
systemMutationService,
} from "./mutations";
function capabilityContext(
granted: readonly string[],
): HousekeepingCapabilityContext {
const permissions = new Set(granted);
return {
actor: { id: 42, username: "operator", rank: 500 },
isSuperAdmin: false,
has: (slug) => permissions.has(slug),
hasAny: (...slugs) => slugs.some((slug) => permissions.has(slug)),
hasAll: (...slugs) => slugs.every((slug) => permissions.has(slug)),
};
}
function serviceContext(permission: string) {
return {
capability: capabilityContext([permission]),
correlationId: "rank-mutation-correlation",
};
}
function insertChain() {
return {
values: () => ({
onDuplicateKeyUpdate: vi.fn().mockResolvedValue(undefined),
}),
};
}
function limitedSelection(rows: readonly unknown[]) {
return {
from: () => ({
where: () => ({ limit: () => Promise.resolve(rows) }),
}),
};
}
function plainSelection(rows: readonly unknown[]) {
return {
from: () => ({ where: () => Promise.resolve(rows) }),
};
}
beforeEach(() => {
for (const mock of Object.values(doubles)) mock.mockReset();
doubles.createEmulatorRank.mockResolvedValue(7);
doubles.deleteEmulatorRank.mockResolvedValue(undefined);
doubles.updateEmulatorRank.mockResolvedValue(undefined);
doubles.logStaffActivity.mockResolvedValue(undefined);
doubles.dbInsert.mockImplementation(insertChain);
});
describe("rank synchronization failures", () => {
it("returns failure and audits failure when create committed but updatepermissions returned false", async () => {
doubles.rconSend.mockResolvedValue(false);
const command = createSystemCommands(systemMutationService).find(
(entry) => entry.id === "system.access.rank.create",
) as
| HousekeepingCommand<{ name: string; level: number }, unknown>
| undefined;
if (!command) throw new Error("rank create command missing");
registerHousekeepingCommand(command);
const outcomes: string[] = [];
const result = await dispatchHousekeepingCommand(
{
commandId: command.id,
input: { name: "Administrator", level: 7 },
reason: "Create the administrator rank",
},
{
context: capabilityContext([PERMS.PERMISSIONS_MANAGE]),
ipAddress: "198.51.100.8",
audit: {
write: async (entry) => {
if (entry.outcome) outcomes.push(entry.outcome);
},
},
rateLimit: async () => true,
},
);
expect(result).toMatchObject({
ok: false,
error: {
code: "DEPENDENCY_UNAVAILABLE",
messageKey: "errors.housekeeping.system.rankSynchronizationIncomplete",
fieldErrors: {
operation: ["access.rank.create"],
completed: ["database", "audit"],
pending: ["emulator-permission-cache"],
},
},
});
expect(outcomes).toEqual(["intent", "failure"]);
});
it.each([
[
"access.rank.delete",
{ id: 7 },
() => {
doubles.dbSelect
.mockImplementationOnce(() => plainSelection([{ total: 0 }]))
.mockImplementationOnce(() => limitedSelection([]));
},
],
["access.rank.update", { id: 7, fields: { badge: "ADM" } }, () => {}],
] as const)(
"returns failure when %s committed but updatepermissions returned false",
async (operation, input, prepare) => {
prepare();
doubles.rconSend.mockResolvedValue(false);
const result = await systemMutationService.execute(
serviceContext(PERMS.PERMISSIONS_MANAGE),
operation as SystemMutationOperation,
input,
);
expect(result).toMatchObject({
ok: false,
error: {
code: "DEPENDENCY_UNAVAILABLE",
messageKey:
"errors.housekeeping.system.rankSynchronizationIncomplete",
fieldErrors: {
operation: [operation],
completed: ["database", "audit"],
pending: ["emulator-permission-cache"],
},
},
});
},
);
it("reports external completion when set-rank RCON succeeded but DB persistence failed", async () => {
doubles.dbSelect.mockImplementationOnce(() =>
limitedSelection([{ rank: 3 }]),
);
doubles.dbExecute.mockResolvedValue([[{ id: 4 }]]);
doubles.rconSetRank.mockResolvedValue(true);
doubles.dbUpdate.mockReturnValue({
set: () => ({
where: () => Promise.reject(new Error("users update unavailable")),
}),
});
const result = await systemMutationService.execute(
serviceContext(PERMS.RCON_EXECUTE),
"rcon.set-rank",
{ userId: 8, rank: 4 },
);
expect(result).toMatchObject({
ok: false,
error: {
code: "DEPENDENCY_UNAVAILABLE",
messageKey: "errors.housekeeping.system.rankPersistenceIncomplete",
fieldErrors: {
operation: ["rcon.set-rank"],
completed: ["emulator"],
pending: ["database"],
},
},
});
});
});