[
  {
    "type": "raw_sql",
    "description": "Add the payroll export idempotency key when it is missing",
    "database": "{{store}}",
    "check_query": "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'scheduleTimesheetExports' AND COLUMN_NAME = 'idempotencyKey'",
    "sql": "ALTER TABLE `scheduleTimesheetExports` ADD COLUMN `idempotencyKey` VARCHAR(128) DEFAULT NULL COMMENT 'Client/generated payroll export idempotency key; null only for legacy or quarantined duplicate rows'"
  },
  {
    "type": "raw_sql",
    "description": "Add the payroll export request fingerprint when it is missing",
    "database": "{{store}}",
    "check_query": "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'scheduleTimesheetExports' AND COLUMN_NAME = 'requestHash'",
    "sql": "ALTER TABLE `scheduleTimesheetExports` ADD COLUMN `requestHash` CHAR(64) DEFAULT NULL COMMENT 'SHA-256 of canonical store+request metadata'"
  },
  {
    "type": "raw_sql",
    "description": "Add the emitted payroll CSV fingerprint when it is missing",
    "database": "{{store}}",
    "check_query": "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'scheduleTimesheetExports' AND COLUMN_NAME = 'csvHash'",
    "sql": "ALTER TABLE `scheduleTimesheetExports` ADD COLUMN `csvHash` CHAR(64) DEFAULT NULL COMMENT 'SHA-256 of emitted CSV; CSV body is never persisted'"
  },
  {
    "type": "raw_sql",
    "description": "Add immutable payroll export row snapshots when they are missing",
    "database": "{{store}}",
    "check_query": "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'scheduleTimesheetExports' AND COLUMN_NAME = 'exportDetails'",
    "sql": "ALTER TABLE `scheduleTimesheetExports` ADD COLUMN `exportDetails` LONGTEXT DEFAULT NULL COMMENT 'Immutable JSON row snapshots: emitted hours/pay plus effective rate and overtime rule identity/multipliers'"
  },
  {
    "type": "raw_sql",
    "description": "Add an audit-preserving quarantine field for duplicate payroll idempotency keys when it is missing",
    "database": "{{store}}",
    "check_query": "SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'scheduleTimesheetExports' AND COLUMN_NAME = 'idempotencyConflictKey'",
    "sql": "ALTER TABLE `scheduleTimesheetExports` ADD COLUMN `idempotencyConflictKey` VARCHAR(128) DEFAULT NULL COMMENT 'Original idempotency key quarantined during uniqueness migration; never used for replay'"
  },
  {
    "type": "raw_sql",
    "description": "Quarantine duplicate non-null payroll idempotency keys before enforcing uniqueness, preserving the oldest export as keeper and retaining every audit row",
    "database": "{{store}}",
    "always_check": true,
    "sql": "UPDATE `scheduleTimesheetExports` AS duplicateExport INNER JOIN `scheduleTimesheetExports` AS keeper ON keeper.idempotencyKey = duplicateExport.idempotencyKey AND keeper.exportId < duplicateExport.exportId SET duplicateExport.idempotencyConflictKey = duplicateExport.idempotencyKey, duplicateExport.idempotencyKey = NULL WHERE duplicateExport.idempotencyKey IS NOT NULL"
  },
  {
    "type": "raw_sql",
    "description": "Enforce one durable payroll export audit per non-null idempotency key",
    "database": "{{store}}",
    "check_query": "SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'scheduleTimesheetExports' AND INDEX_NAME = 'uq_timesheet_export_idempotency' AND NON_UNIQUE = 0 GROUP BY INDEX_NAME HAVING GROUP_CONCAT(COLUMN_NAME ORDER BY SEQ_IN_INDEX) = 'idempotencyKey'",
    "sql": "ALTER TABLE `scheduleTimesheetExports` ADD UNIQUE INDEX `uq_timesheet_export_idempotency` (`idempotencyKey`)"
  }
]
