-- Make client request IDs idempotent within an account, not globally. ALTER TABLE usage_records DROP FOREIGN KEY fk_usage_records_provider_request, DROP INDEX uq_usage_records_request_meter, ADD COLUMN account_id VARCHAR(36) CHARACTER SET ascii COLLATE ascii_bin NULL AFTER id; UPDATE usage_records ur JOIN provider_requests pr ON pr.request_id = ur.request_id SET ur.account_id = pr.account_id; ALTER TABLE usage_records MODIFY account_id VARCHAR(36) CHARACTER SET ascii COLLATE ascii_bin NOT NULL; -- Normalize every legacy value before installing the binary status column and -- stricter CHECK. Unknown historical states are held for manual review rather -- than making a non-transactional MySQL migration fail halfway through. UPDATE provider_requests SET status = CASE UPPER(status) WHEN 'SUCCEEDED' THEN 'SETTLED' WHEN 'FAILED' THEN 'MANUAL_REVIEW' WHEN 'CLAIMED' THEN 'CLAIMED' WHEN 'STARTED' THEN 'STARTED' WHEN 'SETTLEMENT_PENDING' THEN 'SETTLEMENT_PENDING' WHEN 'SETTLED' THEN 'SETTLED' WHEN 'RELEASED' THEN 'RELEASED' WHEN 'MANUAL_REVIEW' THEN 'MANUAL_REVIEW' ELSE 'MANUAL_REVIEW' END; ALTER TABLE provider_requests ADD COLUMN reservation_id CHAR(36) NULL AFTER account_id, ADD COLUMN usage_meter VARCHAR(32) NULL AFTER provider_request_id, ADD COLUMN usage_units BIGINT UNSIGNED NULL AFTER usage_meter, ADD COLUMN usage_input_units BIGINT UNSIGNED NULL AFTER usage_units, ADD COLUMN usage_output_units BIGINT UNSIGNED NULL AFTER usage_input_units, MODIFY COLUMN status VARCHAR(24) CHARACTER SET ascii COLLATE ascii_bin NOT NULL, DROP PRIMARY KEY, ADD PRIMARY KEY (account_id, request_id), ADD UNIQUE KEY uq_provider_requests_reservation (reservation_id), ADD INDEX idx_provider_requests_status_created (status, created_at), ADD CONSTRAINT chk_provider_request_status CHECK ( status IN ( 'CLAIMED', 'STARTED', 'SETTLEMENT_PENDING', 'SETTLED', 'RELEASED', 'MANUAL_REVIEW' ) ); ALTER TABLE usage_records ADD UNIQUE KEY uq_usage_records_account_request_meter (account_id, request_id, meter), ADD CONSTRAINT fk_usage_records_provider_request FOREIGN KEY (account_id, request_id) REFERENCES provider_requests (account_id, request_id) ON DELETE CASCADE; -- A rotated refresh row points to its replacement. RESTRICT can block the -- account -> grant -> refresh cascade when an account is deleted. ALTER TABLE gateway_refresh_tokens DROP FOREIGN KEY fk_gateway_refresh_replacement, ADD CONSTRAINT fk_gateway_refresh_replacement FOREIGN KEY (replaced_by_id) REFERENCES gateway_refresh_tokens (id) ON DELETE SET NULL;