feat(wcs): persist and query execution recovery state

This commit is contained in:
zgw
2026-08-11 11:27:31 +08:00
parent 9782800b0b
commit 434cbe57b9
10 changed files with 858 additions and 0 deletions

View File

@@ -0,0 +1,341 @@
SET XACT_ABORT ON;
BEGIN TRANSACTION;
IF OBJECT_ID('dbo.wcs_control_lease', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_control_lease (
lease_name varchar(64) NOT NULL PRIMARY KEY,
owner_id varchar(128) NULL,
fencing_token bigint NOT NULL,
lease_until datetime2(3) NULL,
state_version bigint NOT NULL,
CONSTRAINT ck_wcs_control_lease_fencing CHECK (fencing_token >= 0),
CONSTRAINT ck_wcs_control_lease_version CHECK (state_version >= 0)
);
END;
IF OBJECT_ID('dbo.wcs_device_command', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_device_command (
command_id varchar(128) NOT NULL PRIMARY KEY,
command_key varchar(128) NOT NULL,
order_id varchar(64) NULL,
step_id varchar(128) NULL,
device_id varchar(64) NOT NULL,
command_type varchar(64) NOT NULL,
payload_json nvarchar(max) NOT NULL,
transport_attempt int NOT NULL,
command_state varchar(32) NOT NULL,
send_receipt_id varchar(128) NULL,
acknowledge_evidence_id varchar(128) NULL,
completion_evidence_id varchar(128) NULL,
status_reason nvarchar(512) NULL,
created_time datetime2(3) NOT NULL,
updated_time datetime2(3) NOT NULL,
state_version bigint NOT NULL,
CONSTRAINT uk_wcs_device_command_key UNIQUE (command_key),
CONSTRAINT ck_wcs_device_command_attempt CHECK (transport_attempt >= 0),
CONSTRAINT ck_wcs_device_command_version CHECK (state_version >= 0)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_device_command')
AND name = 'ix_wcs_device_command_device_state')
BEGIN
CREATE INDEX ix_wcs_device_command_device_state
ON dbo.wcs_device_command(device_id, command_state);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_device_command')
AND name = 'ix_wcs_device_command_order_step')
BEGIN
CREATE INDEX ix_wcs_device_command_order_step
ON dbo.wcs_device_command(order_id, step_id);
END;
IF OBJECT_ID('dbo.wcs_device_execution', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_device_execution (
command_id varchar(128) NOT NULL PRIMARY KEY,
command_key varchar(128) NOT NULL,
device_id varchar(64) NOT NULL,
task_number varchar(128) NOT NULL,
route_nodes_json nvarchar(max) NOT NULL,
route_resources_json nvarchar(max) NOT NULL,
topology_version bigint NOT NULL,
fencing_token bigint NOT NULL,
expected_boot_id varchar(128) NOT NULL,
current_node_index int NOT NULL,
released_resource_count int NOT NULL,
last_device_sequence bigint NOT NULL,
active_flag bit NOT NULL
CONSTRAINT df_wcs_device_execution_active DEFAULT (1),
updated_time datetime2(3) NOT NULL,
state_version bigint NOT NULL,
CONSTRAINT fk_wcs_device_execution_command FOREIGN KEY (command_id)
REFERENCES dbo.wcs_device_command(command_id),
CONSTRAINT uk_wcs_device_execution_key UNIQUE (command_key),
CONSTRAINT ck_wcs_device_execution_topology CHECK (topology_version > 0),
CONSTRAINT ck_wcs_device_execution_fencing CHECK (fencing_token > 0),
CONSTRAINT ck_wcs_device_execution_indexes CHECK (
current_node_index >= 0 AND released_resource_count >= 0),
CONSTRAINT ck_wcs_device_execution_version CHECK (state_version >= 0)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_device_execution')
AND name = 'uk_wcs_device_execution_active_device')
BEGIN
CREATE UNIQUE INDEX uk_wcs_device_execution_active_device
ON dbo.wcs_device_execution(device_id)
WHERE active_flag = 1;
END;
IF OBJECT_ID('dbo.wcs_command_outbox', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_command_outbox (
command_id varchar(128) NOT NULL PRIMARY KEY,
command_key varchar(128) NOT NULL,
payload_json nvarchar(max) NOT NULL,
topology_version bigint NOT NULL,
fencing_token bigint NOT NULL,
delivery_state varchar(32) NOT NULL,
attempt_count int NOT NULL,
next_attempt_time datetime2(3) NOT NULL,
claimed_by varchar(128) NULL,
claimed_time datetime2(3) NULL,
last_error nvarchar(1024) NULL,
delivered_time datetime2(3) NULL,
state_version bigint NOT NULL,
CONSTRAINT fk_wcs_command_outbox_command FOREIGN KEY (command_id)
REFERENCES dbo.wcs_device_command(command_id),
CONSTRAINT uk_wcs_command_outbox_key UNIQUE (command_key),
CONSTRAINT ck_wcs_command_outbox_attempt CHECK (attempt_count >= 0),
CONSTRAINT ck_wcs_command_outbox_topology CHECK (topology_version > 0),
CONSTRAINT ck_wcs_command_outbox_fencing CHECK (fencing_token > 0),
CONSTRAINT ck_wcs_command_outbox_version CHECK (state_version >= 0)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_command_outbox')
AND name = 'ix_wcs_command_outbox_due')
BEGIN
CREATE INDEX ix_wcs_command_outbox_due
ON dbo.wcs_command_outbox(delivery_state, next_attempt_time);
END;
IF OBJECT_ID('dbo.wcs_wms_notification_outbox', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_wms_notification_outbox (
outbox_id bigint IDENTITY(1,1) NOT NULL PRIMARY KEY,
event_id varchar(128) NOT NULL,
notification_type varchar(64) NOT NULL,
payload_json nvarchar(max) NOT NULL,
delivery_state varchar(32) NOT NULL,
attempt_count int NOT NULL,
next_attempt_time datetime2(3) NOT NULL,
claimed_by varchar(128) NULL,
claimed_time datetime2(3) NULL,
external_receipt varchar(256) NULL,
last_error nvarchar(1024) NULL,
created_time datetime2(3) NOT NULL,
delivered_time datetime2(3) NULL,
state_version bigint NOT NULL,
CONSTRAINT uk_wcs_wms_outbox_event UNIQUE (event_id),
CONSTRAINT ck_wcs_wms_outbox_attempt CHECK (attempt_count >= 0),
CONSTRAINT ck_wcs_wms_outbox_version CHECK (state_version >= 0)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_wms_notification_outbox')
AND name = 'ix_wcs_wms_outbox_due')
BEGIN
CREATE INDEX ix_wcs_wms_outbox_due
ON dbo.wcs_wms_notification_outbox(
delivery_state, next_attempt_time);
END;
IF OBJECT_ID('dbo.wcs_device_snapshot', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_device_snapshot (
snapshot_id varchar(128) NOT NULL PRIMARY KEY,
device_id varchar(64) NOT NULL,
command_key varchar(128) NOT NULL,
task_number varchar(128) NOT NULL,
device_sequence bigint NOT NULL,
observed_time datetime2(3) NOT NULL,
connected_flag bit NOT NULL,
device_boot_id varchar(128) NOT NULL,
topology_version bigint NOT NULL,
fencing_token bigint NOT NULL,
current_node_id varchar(128) NOT NULL,
remaining_route_json nvarchar(max) NOT NULL,
command_completed_flag bit NOT NULL,
facts_json nvarchar(max) NULL,
received_time datetime2(3) NOT NULL,
CONSTRAINT ck_wcs_device_snapshot_sequence CHECK (device_sequence >= 0),
CONSTRAINT ck_wcs_device_snapshot_topology CHECK (topology_version > 0),
CONSTRAINT ck_wcs_device_snapshot_fencing CHECK (fencing_token > 0)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_device_snapshot')
AND name = 'ix_wcs_device_snapshot_device_time')
BEGIN
CREATE INDEX ix_wcs_device_snapshot_device_time
ON dbo.wcs_device_snapshot(device_id, observed_time DESC);
END;
IF OBJECT_ID('dbo.wcs_device_event', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_device_event (
event_id varchar(128) NOT NULL PRIMARY KEY,
device_id varchar(64) NOT NULL,
command_key varchar(128) NOT NULL,
task_number varchar(128) NOT NULL,
device_sequence bigint NOT NULL,
event_type varchar(32) NOT NULL,
current_node_id varchar(128) NULL,
remaining_route_json nvarchar(max) NULL,
facts_json nvarchar(max) NULL,
device_time datetime2(3) NOT NULL,
received_time datetime2(3) NOT NULL,
CONSTRAINT ck_wcs_device_event_sequence CHECK (device_sequence >= 0)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_device_event')
AND name = 'ix_wcs_device_event_device_sequence')
BEGIN
CREATE INDEX ix_wcs_device_event_device_sequence
ON dbo.wcs_device_event(device_id, device_sequence);
END;
IF OBJECT_ID('dbo.wcs_alarm', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_alarm (
alarm_id varchar(128) NOT NULL PRIMARY KEY,
device_id varchar(64) NULL,
command_key varchar(128) NULL,
recovery_case_id varchar(128) NULL,
alarm_code varchar(128) NOT NULL,
severity varchar(16) NOT NULL,
alarm_state varchar(32) NOT NULL,
detail nvarchar(1024) NULL,
source_event_id varchar(128) NULL,
opened_time datetime2(3) NOT NULL,
acknowledged_by varchar(128) NULL,
acknowledged_time datetime2(3) NULL,
closed_time datetime2(3) NULL,
state_version bigint NOT NULL,
CONSTRAINT ck_wcs_alarm_version CHECK (state_version >= 0)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_alarm')
AND name = 'ix_wcs_alarm_device_state')
BEGIN
CREATE INDEX ix_wcs_alarm_device_state
ON dbo.wcs_alarm(device_id, alarm_state, opened_time DESC);
END;
IF OBJECT_ID('dbo.wcs_recovery_case', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_recovery_case (
case_id varchar(128) NOT NULL PRIMARY KEY,
device_id varchar(64) NOT NULL,
command_key varchar(128) NOT NULL,
reason_code varchar(128) NOT NULL,
evidence_ids_json nvarchar(max) NOT NULL,
expected_task_number varchar(128) NULL,
expected_site varchar(128) NULL,
expected_load_state varchar(32) NULL,
recovery_state varchar(32) NOT NULL,
created_time datetime2(3) NOT NULL,
resolved_by varchar(128) NULL,
resolved_time datetime2(3) NULL,
resolution_evidence_json nvarchar(max) NULL,
resolution_reason nvarchar(512) NULL,
state_version bigint NOT NULL,
CONSTRAINT ck_wcs_recovery_case_version CHECK (state_version >= 0),
CONSTRAINT ck_wcs_recovery_case_expected_facts CHECK (
(expected_task_number IS NULL AND expected_site IS NULL
AND expected_load_state IS NULL)
OR
(expected_task_number IS NOT NULL AND expected_site IS NOT NULL
AND expected_load_state IS NOT NULL))
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_recovery_case')
AND name = 'uk_wcs_recovery_case_open')
BEGIN
CREATE UNIQUE INDEX uk_wcs_recovery_case_open
ON dbo.wcs_recovery_case(device_id, command_key)
WHERE recovery_state = 'OPEN';
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_recovery_case')
AND name = 'ix_wcs_recovery_case_state_created')
BEGIN
CREATE INDEX ix_wcs_recovery_case_state_created
ON dbo.wcs_recovery_case(recovery_state, created_time);
END;
IF OBJECT_ID('dbo.wcs_manual_action_audit', 'U') IS NULL
BEGIN
CREATE TABLE dbo.wcs_manual_action_audit (
audit_id varchar(128) NOT NULL PRIMARY KEY,
case_id varchar(128) NOT NULL,
action_type varchar(32) NOT NULL,
operator_id varchar(128) NOT NULL,
action_reason nvarchar(512) NOT NULL,
before_state varchar(32) NOT NULL,
after_state varchar(32) NOT NULL,
evidence_json nvarchar(max) NULL,
occurred_time datetime2(3) NOT NULL,
CONSTRAINT fk_wcs_manual_action_case FOREIGN KEY (case_id)
REFERENCES dbo.wcs_recovery_case(case_id)
);
END;
IF NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_manual_action_audit')
AND name = 'ix_wcs_manual_action_case_time')
BEGIN
CREATE INDEX ix_wcs_manual_action_case_time
ON dbo.wcs_manual_action_audit(case_id, occurred_time);
END;
IF OBJECT_ID('dbo.wcs_resource_reservation', 'U') IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM sys.indexes
WHERE object_id = OBJECT_ID('dbo.wcs_resource_reservation')
AND name = 'ix_wcs_resource_reservation_resource_state')
BEGIN
CREATE INDEX ix_wcs_resource_reservation_resource_state
ON dbo.wcs_resource_reservation(resource_key, reservation_state);
END;
COMMIT TRANSACTION;