fix: make command constraint replay restart-safe

This commit is contained in:
DCCONSTRUCTIONS
2026-08-21 18:51:08 +03:00
parent 68800b773d
commit 1d3ed5e16e
5 changed files with 64 additions and 4 deletions
@@ -16,6 +16,6 @@ alter table device_management_command_receipts
'edge.ensure',
'route.ensure',
'enrollment_intent.ensure'
));
)) not valid;
commit;
@@ -20,6 +20,6 @@ alter table device_management_command_receipts
'device.transfer',
'discovery.reject',
'discovery.expire'
));
)) not valid;
commit;
@@ -22,6 +22,6 @@ alter table device_management_command_receipts
'discovery.expire',
'device_credential_binding.upsert',
'device_credential_binding.revoke'
));
)) not valid;
commit;
@@ -26,6 +26,6 @@ alter table device_management_command_receipts
'device_binding.revoke',
'device_configuration_revision.create',
'device_configuration_desired.set'
));
)) not valid;
commit;
@@ -2,6 +2,36 @@ import assert from "node:assert/strict";
import { readFile } from "node:fs/promises";
import test from "node:test";
const replayedIntermediateConstraintMigrations = Object.freeze([
"005_device_registry_commands.sql",
"007_device_lifecycle_commands.sql",
"009_device_sensitive_reference_commands.sql",
"011_device_control_resource_commands.sql",
]);
const finalCommandKindMigration = "014_device_registry_profile_commands.sql";
const finalCommandKinds = Object.freeze([
"owner_scope.ensure",
"project.ensure",
"collection.ensure",
"project_grant.upsert",
"adapter_package.ensure",
"adapter_version.register",
"model_profile.register",
"edge.ensure",
"route.ensure",
"enrollment_intent.ensure",
"device.claim",
"device.update",
"device.transfer",
"discovery.reject",
"discovery.expire",
"device_credential_binding.upsert",
"device_credential_binding.revoke",
"device_binding.ensure",
"device_binding.revoke",
"device_configuration_revision.create",
"device_configuration_desired.set",
]);
const migrationUrl = new URL(
"../migrations/003_device_management_commands.sql",
import.meta.url,
@@ -37,3 +67,33 @@ test("repository applies management migration after project access", async () =>
assert.notEqual(managementIndex, -1);
assert.ok(projectAccessIndex < managementIndex);
});
test("replayed intermediate command constraints do not revalidate historical receipts", async () => {
for (const migrationFile of replayedIntermediateConstraintMigrations) {
const sql = await readFile(
new URL(`../migrations/${migrationFile}`, import.meta.url),
"utf8",
);
assert.match(
sql,
/add constraint device_management_command_receipts_command_kind_check[\s\S]+not valid;/,
`${migrationFile} must not reject receipts introduced by a later migration`,
);
}
});
test("final replayed command constraint validates every current command kind", async () => {
const sql = await readFile(
new URL(`../migrations/${finalCommandKindMigration}`, import.meta.url),
"utf8",
);
assert.doesNotMatch(sql, /not valid;/);
for (const commandKind of finalCommandKinds) {
assert.ok(
sql.includes(`'${commandKind}'`),
`${finalCommandKindMigration} must validate ${commandKind}`,
);
}
});