Add history-based state changes and recompute pipeline
This commit is contained in:
104
migrations/0017_history_core/down.sql
Normal file
104
migrations/0017_history_core/down.sql
Normal file
@@ -0,0 +1,104 @@
|
||||
DROP TABLE IF EXISTS history_admin_audit;
|
||||
DROP TABLE IF EXISTS history_recompute_jobs;
|
||||
DROP TABLE IF EXISTS component_state_snapshots;
|
||||
DROP TABLE IF EXISTS component_change_events;
|
||||
DROP TABLE IF EXISTS asset_state_snapshots;
|
||||
DROP TABLE IF EXISTS asset_change_events;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'timeline_events'
|
||||
AND index_name = 'idx_timeline_subject_deleted_time'
|
||||
),
|
||||
'ALTER TABLE timeline_events DROP INDEX idx_timeline_subject_deleted_time',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'timeline_events'
|
||||
AND index_name = 'idx_timeline_logical_event'
|
||||
),
|
||||
'ALTER TABLE timeline_events DROP INDEX idx_timeline_logical_event',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'timeline_events'
|
||||
AND index_name = 'idx_timeline_correlation'
|
||||
),
|
||||
'ALTER TABLE timeline_events DROP INDEX idx_timeline_correlation',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'timeline_events'
|
||||
AND column_name = 'logical_entity_type'
|
||||
),
|
||||
'ALTER TABLE timeline_events DROP COLUMN logical_entity_type',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'timeline_events'
|
||||
AND column_name = 'logical_event_id'
|
||||
),
|
||||
'ALTER TABLE timeline_events DROP COLUMN logical_event_id',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'timeline_events'
|
||||
AND column_name = 'correlation_id'
|
||||
),
|
||||
'ALTER TABLE timeline_events DROP COLUMN correlation_id',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
SET @sql = (
|
||||
SELECT IF(
|
||||
EXISTS(
|
||||
SELECT 1 FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'timeline_events'
|
||||
AND column_name = 'is_deleted'
|
||||
),
|
||||
'ALTER TABLE timeline_events DROP COLUMN is_deleted',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
159
migrations/0017_history_core/up.sql
Normal file
159
migrations/0017_history_core/up.sql
Normal file
@@ -0,0 +1,159 @@
|
||||
CREATE TABLE IF NOT EXISTS component_change_events (
|
||||
id VARCHAR(16) PRIMARY KEY,
|
||||
part_id VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
effective_at TIMESTAMP NOT NULL,
|
||||
recorded_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
source_type VARCHAR(32) NOT NULL,
|
||||
source_ref VARCHAR(255) NULL,
|
||||
actor_type VARCHAR(32) NOT NULL,
|
||||
actor_id VARCHAR(255) NULL,
|
||||
change_type VARCHAR(64) NOT NULL,
|
||||
correlation_id VARCHAR(64) NULL,
|
||||
idempotency_key VARCHAR(255) NULL,
|
||||
patch_json JSON NOT NULL,
|
||||
before_hash CHAR(64) NULL,
|
||||
after_hash CHAR(64) NOT NULL,
|
||||
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
deleted_by VARCHAR(255) NULL,
|
||||
deleted_reason VARCHAR(255) NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_component_change_events_part
|
||||
FOREIGN KEY (part_id) REFERENCES parts(id)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE KEY uniq_component_change_events_part_version (part_id, version),
|
||||
INDEX idx_component_change_events_part_deleted_version (part_id, is_deleted, version),
|
||||
INDEX idx_component_change_events_part_effective (part_id, effective_at, id),
|
||||
INDEX idx_component_change_events_correlation (correlation_id),
|
||||
INDEX idx_component_change_events_source_idem (part_id, source_type, idempotency_key)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS component_state_snapshots (
|
||||
id VARCHAR(16) PRIMARY KEY,
|
||||
part_id VARCHAR(16) NOT NULL,
|
||||
event_id VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
state_json JSON NOT NULL,
|
||||
state_hash CHAR(64) NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_component_state_snapshots_part
|
||||
FOREIGN KEY (part_id) REFERENCES parts(id)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_component_state_snapshots_event
|
||||
FOREIGN KEY (event_id) REFERENCES component_change_events(id)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE KEY uniq_component_state_snapshots_event (event_id),
|
||||
UNIQUE KEY uniq_component_state_snapshots_part_version (part_id, version),
|
||||
INDEX idx_component_state_snapshots_part_version (part_id, version)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS asset_change_events (
|
||||
id VARCHAR(16) PRIMARY KEY,
|
||||
machine_id VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
effective_at TIMESTAMP NOT NULL,
|
||||
recorded_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
source_type VARCHAR(32) NOT NULL,
|
||||
source_ref VARCHAR(255) NULL,
|
||||
actor_type VARCHAR(32) NOT NULL,
|
||||
actor_id VARCHAR(255) NULL,
|
||||
change_type VARCHAR(64) NOT NULL,
|
||||
correlation_id VARCHAR(64) NULL,
|
||||
idempotency_key VARCHAR(255) NULL,
|
||||
patch_json JSON NOT NULL,
|
||||
before_hash CHAR(64) NULL,
|
||||
after_hash CHAR(64) NOT NULL,
|
||||
is_deleted BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
deleted_at TIMESTAMP NULL,
|
||||
deleted_by VARCHAR(255) NULL,
|
||||
deleted_reason VARCHAR(255) NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_asset_change_events_machine
|
||||
FOREIGN KEY (machine_id) REFERENCES machines(id)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE KEY uniq_asset_change_events_machine_version (machine_id, version),
|
||||
INDEX idx_asset_change_events_machine_deleted_version (machine_id, is_deleted, version),
|
||||
INDEX idx_asset_change_events_machine_effective (machine_id, effective_at, id),
|
||||
INDEX idx_asset_change_events_correlation (correlation_id),
|
||||
INDEX idx_asset_change_events_source_idem (machine_id, source_type, idempotency_key)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS asset_state_snapshots (
|
||||
id VARCHAR(16) PRIMARY KEY,
|
||||
machine_id VARCHAR(16) NOT NULL,
|
||||
event_id VARCHAR(16) NOT NULL,
|
||||
version BIGINT NOT NULL,
|
||||
state_json JSON NOT NULL,
|
||||
state_hash CHAR(64) NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_asset_state_snapshots_machine
|
||||
FOREIGN KEY (machine_id) REFERENCES machines(id)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_asset_state_snapshots_event
|
||||
FOREIGN KEY (event_id) REFERENCES asset_change_events(id)
|
||||
ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
UNIQUE KEY uniq_asset_state_snapshots_event (event_id),
|
||||
UNIQUE KEY uniq_asset_state_snapshots_machine_version (machine_id, version),
|
||||
INDEX idx_asset_state_snapshots_machine_version (machine_id, version)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS history_recompute_jobs (
|
||||
id VARCHAR(32) PRIMARY KEY,
|
||||
job_type VARCHAR(32) NOT NULL,
|
||||
entity_type VARCHAR(16) NOT NULL,
|
||||
entity_id VARCHAR(16) NOT NULL,
|
||||
status VARCHAR(16) NOT NULL,
|
||||
requested_by VARCHAR(255) NULL,
|
||||
payload JSON NOT NULL,
|
||||
result JSON NULL,
|
||||
error TEXT NULL,
|
||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
started_at TIMESTAMP NULL,
|
||||
finished_at TIMESTAMP NULL,
|
||||
locked_at TIMESTAMP NULL,
|
||||
worker_id VARCHAR(64) NULL,
|
||||
attempt_count INT NOT NULL DEFAULT 0,
|
||||
INDEX idx_history_recompute_jobs_status_created (status, created_at),
|
||||
INDEX idx_history_recompute_jobs_entity_created (entity_type, entity_id, created_at)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS history_admin_audit (
|
||||
id VARCHAR(16) PRIMARY KEY,
|
||||
entity_type VARCHAR(16) NOT NULL,
|
||||
entity_id VARCHAR(16) NOT NULL,
|
||||
operation_type VARCHAR(32) NOT NULL,
|
||||
requested_by VARCHAR(255) NULL,
|
||||
requested_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
target_version BIGINT NULL,
|
||||
target_snapshot_id VARCHAR(16) NULL,
|
||||
deleted_future_events_count INT NOT NULL DEFAULT 0,
|
||||
deleted_future_snapshots_count INT NOT NULL DEFAULT 0,
|
||||
job_id VARCHAR(32) NOT NULL,
|
||||
details JSON NULL,
|
||||
INDEX idx_history_admin_audit_entity_requested (entity_type, entity_id, requested_at),
|
||||
INDEX idx_history_admin_audit_job (job_id)
|
||||
);
|
||||
|
||||
ALTER TABLE timeline_events
|
||||
ADD COLUMN logical_entity_type VARCHAR(16) NULL;
|
||||
|
||||
ALTER TABLE timeline_events
|
||||
ADD COLUMN logical_event_id VARCHAR(16) NULL;
|
||||
|
||||
ALTER TABLE timeline_events
|
||||
ADD COLUMN correlation_id VARCHAR(64) NULL;
|
||||
|
||||
ALTER TABLE timeline_events
|
||||
ADD COLUMN is_deleted BOOLEAN NOT NULL DEFAULT FALSE;
|
||||
|
||||
CREATE INDEX idx_timeline_subject_deleted_time ON timeline_events(subject_type, subject_id, is_deleted, event_time, id);
|
||||
CREATE INDEX idx_timeline_logical_event ON timeline_events(logical_entity_type, logical_event_id);
|
||||
CREATE INDEX idx_timeline_correlation ON timeline_events(correlation_id);
|
||||
|
||||
INSERT IGNORE INTO id_sequences (entity_type, next_value) VALUES
|
||||
('component_change_event', 1),
|
||||
('component_snapshot', 1),
|
||||
('asset_change_event', 1),
|
||||
('asset_snapshot', 1),
|
||||
('history_admin_audit', 1);
|
||||
Reference in New Issue
Block a user