init push
This commit is contained in:
150
migrations/20260313_contacts_profiles.sql
Normal file
150
migrations/20260313_contacts_profiles.sql
Normal file
@@ -0,0 +1,150 @@
|
||||
-- +goose Up
|
||||
-- HEMS contacts/users module schema extension
|
||||
|
||||
ALTER TABLE roles
|
||||
ADD COLUMN IF NOT EXISTS code VARCHAR(64) NULL,
|
||||
ADD UNIQUE KEY IF NOT EXISTS uq_roles_code (code);
|
||||
|
||||
ALTER TABLE users
|
||||
ADD COLUMN IF NOT EXISTS username VARCHAR(100) NULL,
|
||||
ADD UNIQUE KEY IF NOT EXISTS uq_users_username (username),
|
||||
ADD COLUMN IF NOT EXISTS is_active TINYINT(1) NOT NULL DEFAULT 1;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS pilot_profiles (
|
||||
user_id BINARY(16) NOT NULL,
|
||||
pilot_category ENUM('regular','freelance','dry_lease') NOT NULL,
|
||||
short_name VARCHAR(120) NULL,
|
||||
license_no VARCHAR(120) NULL,
|
||||
license_issued_at DATETIME NULL,
|
||||
license_expired_at DATETIME NULL,
|
||||
technician_license_no VARCHAR(120) NULL,
|
||||
has_ifr_qualification TINYINT(1) NOT NULL DEFAULT 0,
|
||||
is_chief_pilot TINYINT(1) NOT NULL DEFAULT 0,
|
||||
is_dul TINYINT(1) NOT NULL DEFAULT 0,
|
||||
total_flight_minutes INT NOT NULL DEFAULT 0,
|
||||
responsible_pilot_minutes INT NOT NULL DEFAULT 0,
|
||||
second_pilot_minutes INT NOT NULL DEFAULT 0,
|
||||
double_command_minutes INT NOT NULL DEFAULT 0,
|
||||
flight_instructor_minutes INT NOT NULL DEFAULT 0,
|
||||
night_flight_minutes INT NOT NULL DEFAULT 0,
|
||||
ifr_flight_minutes INT NOT NULL DEFAULT 0,
|
||||
location VARCHAR(255) NULL,
|
||||
postcode VARCHAR(32) NULL,
|
||||
street_line VARCHAR(255) NULL,
|
||||
weight_kg DECIMAL(8,2) NULL,
|
||||
photo_file_id VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (user_id),
|
||||
KEY idx_pilot_profiles_category (pilot_category),
|
||||
KEY idx_pilot_profiles_license (license_no),
|
||||
CONSTRAINT fk_pilot_profiles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS doctor_profiles (
|
||||
user_id BINARY(16) NOT NULL,
|
||||
short_name VARCHAR(120) NULL,
|
||||
medical_license_no VARCHAR(120) NULL,
|
||||
license_issued_at DATETIME NULL,
|
||||
license_expired_at DATETIME NULL,
|
||||
specialization VARCHAR(120) NULL,
|
||||
sub_specialization VARCHAR(120) NULL,
|
||||
is_chief_physician TINYINT(1) NOT NULL DEFAULT 0,
|
||||
location VARCHAR(255) NULL,
|
||||
postcode VARCHAR(32) NULL,
|
||||
street_line VARCHAR(255) NULL,
|
||||
photo_file_id VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (user_id),
|
||||
KEY idx_doctor_profiles_medical_license (medical_license_no),
|
||||
CONSTRAINT fk_doctor_profiles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS air_rescuer_profiles (
|
||||
user_id BINARY(16) NOT NULL,
|
||||
short_name VARCHAR(120) NULL,
|
||||
is_chief_physician_in_charge TINYINT(1) NOT NULL DEFAULT 0,
|
||||
responsible_flight_rescuer TINYINT(1) NOT NULL DEFAULT 0,
|
||||
location VARCHAR(255) NULL,
|
||||
postcode VARCHAR(32) NULL,
|
||||
street_line VARCHAR(255) NULL,
|
||||
photo_file_id VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (user_id),
|
||||
CONSTRAINT fk_air_rescuer_profiles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS technician_profiles (
|
||||
user_id BINARY(16) NOT NULL,
|
||||
short_name VARCHAR(120) NULL,
|
||||
license_no VARCHAR(120) NULL,
|
||||
is_chief_technician TINYINT(1) NOT NULL DEFAULT 0,
|
||||
is_responsible_complaints TINYINT(1) NOT NULL DEFAULT 0,
|
||||
location VARCHAR(255) NULL,
|
||||
postcode VARCHAR(32) NULL,
|
||||
street_line VARCHAR(255) NULL,
|
||||
photo_file_id VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (user_id),
|
||||
KEY idx_technician_profiles_license (license_no),
|
||||
CONSTRAINT fk_technician_profiles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS flight_assistant_profiles (
|
||||
user_id BINARY(16) NOT NULL,
|
||||
short_name VARCHAR(120) NULL,
|
||||
location VARCHAR(255) NULL,
|
||||
postcode VARCHAR(32) NULL,
|
||||
street_line VARCHAR(255) NULL,
|
||||
photo_file_id VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (user_id),
|
||||
CONSTRAINT fk_flight_assistant_profiles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS staff_profiles (
|
||||
user_id BINARY(16) NOT NULL,
|
||||
short_name VARCHAR(120) NULL,
|
||||
role_label VARCHAR(120) NULL,
|
||||
location VARCHAR(255) NULL,
|
||||
postcode VARCHAR(32) NULL,
|
||||
street_line VARCHAR(255) NULL,
|
||||
photo_file_id VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (user_id),
|
||||
CONSTRAINT fk_staff_profiles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS staff_profiles;
|
||||
DROP TABLE IF EXISTS flight_assistant_profiles;
|
||||
DROP TABLE IF EXISTS technician_profiles;
|
||||
DROP TABLE IF EXISTS air_rescuer_profiles;
|
||||
DROP TABLE IF EXISTS doctor_profiles;
|
||||
DROP TABLE IF EXISTS pilot_profiles;
|
||||
|
||||
ALTER TABLE users
|
||||
DROP COLUMN IF EXISTS is_active,
|
||||
DROP INDEX IF EXISTS uq_users_username,
|
||||
DROP COLUMN IF EXISTS username;
|
||||
|
||||
ALTER TABLE roles
|
||||
DROP INDEX IF EXISTS uq_roles_code,
|
||||
DROP COLUMN IF EXISTS code;
|
||||
@@ -0,0 +1,21 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE air_rescuer_profiles
|
||||
ADD COLUMN IF NOT EXISTS responsible_flight_rescuer TINYINT(1) NOT NULL DEFAULT 0 AFTER is_chief_physician_in_charge;
|
||||
|
||||
UPDATE air_rescuer_profiles arp
|
||||
JOIN pilot_profiles pp ON pp.user_id = arp.user_id
|
||||
SET arp.responsible_flight_rescuer = pp.responsible_flight_rescuer;
|
||||
|
||||
ALTER TABLE pilot_profiles
|
||||
DROP COLUMN IF EXISTS responsible_flight_rescuer;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE pilot_profiles
|
||||
ADD COLUMN IF NOT EXISTS responsible_flight_rescuer TINYINT(1) NOT NULL DEFAULT 0 AFTER is_dul;
|
||||
|
||||
UPDATE pilot_profiles pp
|
||||
JOIN air_rescuer_profiles arp ON arp.user_id = pp.user_id
|
||||
SET pp.responsible_flight_rescuer = arp.responsible_flight_rescuer;
|
||||
|
||||
ALTER TABLE air_rescuer_profiles
|
||||
DROP COLUMN IF EXISTS responsible_flight_rescuer;
|
||||
66
migrations/20260331_file_manager_tables.sql
Normal file
66
migrations/20260331_file_manager_tables.sql
Normal file
@@ -0,0 +1,66 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS file_folders (
|
||||
id BINARY(16) NOT NULL,
|
||||
parent_id BINARY(16) NULL,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
name_normalized VARCHAR(128) NOT NULL,
|
||||
depth SMALLINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
path_cache VARCHAR(2048) NULL,
|
||||
name_slot CHAR(36) NOT NULL DEFAULT 'live',
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME(6) NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
purge_at DATETIME(6) NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk_file_folders_parent
|
||||
FOREIGN KEY (parent_id) REFERENCES file_folders(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT,
|
||||
UNIQUE KEY uq_file_folders_parent_name_slot (parent_id, name_normalized, name_slot),
|
||||
KEY idx_file_folders_parent_active (parent_id, deleted_at),
|
||||
KEY idx_file_folders_deleted_at (deleted_at),
|
||||
KEY idx_file_folders_purge_at (purge_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS file_files (
|
||||
id BINARY(16) NOT NULL,
|
||||
folder_id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
name_normalized VARCHAR(255) NOT NULL,
|
||||
extension VARCHAR(32) NULL,
|
||||
size_bytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
mime_type VARCHAR(255) NOT NULL,
|
||||
bucket VARCHAR(128) NOT NULL,
|
||||
object_key VARCHAR(512) NOT NULL,
|
||||
object_version VARCHAR(128) NULL,
|
||||
etag VARCHAR(128) NULL,
|
||||
checksum_sha256 CHAR(64) NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
upload_error TEXT NULL,
|
||||
name_slot CHAR(36) NOT NULL DEFAULT 'live',
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME(6) NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
trashed_at DATETIME(6) NULL,
|
||||
purge_at DATETIME(6) NULL,
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk_file_files_folder
|
||||
FOREIGN KEY (folder_id) REFERENCES file_folders(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE RESTRICT,
|
||||
UNIQUE KEY uq_file_files_object_key (object_key),
|
||||
UNIQUE KEY uq_file_files_folder_name_slot (folder_id, name_normalized, name_slot),
|
||||
KEY idx_file_files_folder_active (folder_id, deleted_at),
|
||||
KEY idx_file_files_status_updated (status, updated_at),
|
||||
KEY idx_file_files_purge_at (purge_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS file_files;
|
||||
DROP TABLE IF EXISTS file_folders;
|
||||
42
migrations/20260403_file_manager_file_lifecycle_phase1.sql
Normal file
42
migrations/20260403_file_manager_file_lifecycle_phase1.sql
Normal file
@@ -0,0 +1,42 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE file_files
|
||||
MODIFY COLUMN status VARCHAR(32) NOT NULL DEFAULT 'uploaded',
|
||||
ADD COLUMN processing_started_at DATETIME(6) NULL AFTER status,
|
||||
ADD COLUMN processed_at DATETIME(6) NULL AFTER processing_started_at,
|
||||
ADD COLUMN validated_at DATETIME(6) NULL AFTER processed_at,
|
||||
ADD COLUMN failed_at DATETIME(6) NULL AFTER validated_at,
|
||||
ADD COLUMN failure_reason TEXT NULL AFTER failed_at;
|
||||
|
||||
UPDATE file_files
|
||||
SET status = 'validated',
|
||||
processed_at = COALESCE(processed_at, updated_at),
|
||||
validated_at = COALESCE(validated_at, updated_at)
|
||||
WHERE status = 'pending';
|
||||
|
||||
UPDATE file_files
|
||||
SET status = 'processing',
|
||||
processing_started_at = COALESCE(processing_started_at, updated_at)
|
||||
WHERE status = 'uploading';
|
||||
|
||||
UPDATE file_files
|
||||
SET failure_reason = NULLIF(TRIM(upload_error), '')
|
||||
WHERE (failure_reason IS NULL OR failure_reason = '')
|
||||
AND upload_error IS NOT NULL
|
||||
AND TRIM(upload_error) <> '';
|
||||
|
||||
-- +goose Down
|
||||
UPDATE file_files
|
||||
SET status = 'pending'
|
||||
WHERE status IN ('uploaded', 'validated');
|
||||
|
||||
UPDATE file_files
|
||||
SET status = 'uploading'
|
||||
WHERE status = 'processing';
|
||||
|
||||
ALTER TABLE file_files
|
||||
DROP COLUMN failure_reason,
|
||||
DROP COLUMN failed_at,
|
||||
DROP COLUMN validated_at,
|
||||
DROP COLUMN processed_at,
|
||||
DROP COLUMN processing_started_at,
|
||||
MODIFY COLUMN status VARCHAR(32) NOT NULL DEFAULT 'pending';
|
||||
33
migrations/20260405_file_processing_outbox.sql
Normal file
33
migrations/20260405_file_processing_outbox.sql
Normal file
@@ -0,0 +1,33 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS file_processing_outbox_messages (
|
||||
id BINARY(16) NOT NULL,
|
||||
message_id VARCHAR(64) NOT NULL,
|
||||
kind VARCHAR(64) NOT NULL,
|
||||
job_type VARCHAR(64) NOT NULL,
|
||||
body LONGBLOB NOT NULL,
|
||||
attributes LONGBLOB NULL,
|
||||
message_group_id VARCHAR(128) NULL,
|
||||
deduplication_id VARCHAR(128) NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
attempts INT NOT NULL DEFAULT 0,
|
||||
available_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
locked_at DATETIME(6) NULL,
|
||||
locked_by VARCHAR(64) NULL,
|
||||
published_at DATETIME(6) NULL,
|
||||
last_error TEXT NULL,
|
||||
correlation_id VARCHAR(64) NULL,
|
||||
trace_id VARCHAR(64) NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_file_processing_outbox_message_id (message_id),
|
||||
KEY idx_file_processing_outbox_status_available (status, available_at),
|
||||
KEY idx_file_processing_outbox_locked_at (locked_at),
|
||||
KEY idx_file_processing_outbox_kind (kind),
|
||||
KEY idx_file_processing_outbox_job_type (job_type),
|
||||
KEY idx_file_processing_outbox_correlation (correlation_id),
|
||||
KEY idx_file_processing_outbox_trace (trace_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS file_processing_outbox_messages;
|
||||
22
migrations/20260406_file_status_realtime_events.sql
Normal file
22
migrations/20260406_file_status_realtime_events.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS file_status_realtime_events (
|
||||
id BINARY(16) NOT NULL,
|
||||
file_id BINARY(16) NOT NULL,
|
||||
user_id BINARY(16) NOT NULL,
|
||||
status VARCHAR(32) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
failure_reason TEXT NULL,
|
||||
occurred_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
delivered_at DATETIME(6) NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_file_status_realtime_events_file (file_id),
|
||||
KEY idx_file_status_realtime_events_user (user_id),
|
||||
KEY idx_file_status_realtime_events_status (status),
|
||||
KEY idx_file_status_realtime_events_occurred (occurred_at),
|
||||
KEY idx_file_status_realtime_events_delivered (delivered_at)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS file_status_realtime_events;
|
||||
27
migrations/20260406_file_upload_intents.sql
Normal file
27
migrations/20260406_file_upload_intents.sql
Normal file
@@ -0,0 +1,27 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS file_upload_intents (
|
||||
id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
name_normalized VARCHAR(255) NOT NULL,
|
||||
extension VARCHAR(32) NULL,
|
||||
size_bytes BIGINT UNSIGNED NOT NULL DEFAULT 0,
|
||||
mime_type VARCHAR(255) NOT NULL,
|
||||
bucket VARCHAR(128) NOT NULL,
|
||||
object_key VARCHAR(512) NOT NULL,
|
||||
status VARCHAR(32) NOT NULL DEFAULT 'pending',
|
||||
expires_at DATETIME(6) NOT NULL,
|
||||
completed_at DATETIME(6) NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_file_upload_intents_object_key (object_key),
|
||||
KEY idx_file_upload_intents_status (status),
|
||||
KEY idx_file_upload_intents_expires_at (expires_at),
|
||||
KEY idx_file_upload_intents_completed_at (completed_at),
|
||||
KEY idx_file_upload_intents_created_by (created_by)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS file_upload_intents;
|
||||
35
migrations/20260406_user_roles.sql
Normal file
35
migrations/20260406_user_roles.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
id BINARY(16) NOT NULL,
|
||||
user_id BINARY(16) NOT NULL,
|
||||
role_id BINARY(16) NOT NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY ux_user_role (user_id, role_id),
|
||||
KEY idx_user_roles_user_id (user_id),
|
||||
KEY idx_user_roles_role_id (role_id),
|
||||
CONSTRAINT fk_user_roles_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_user_roles_role FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO user_roles (id, user_id, role_id, created_at, updated_at)
|
||||
SELECT
|
||||
UNHEX(REPLACE(UUID(), '-', '')),
|
||||
users.id,
|
||||
users.role_id,
|
||||
CURRENT_TIMESTAMP(6),
|
||||
CURRENT_TIMESTAMP(6)
|
||||
FROM users
|
||||
WHERE users.role_id IS NOT NULL
|
||||
AND NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM user_roles
|
||||
WHERE user_roles.user_id = users.id
|
||||
AND user_roles.role_id = users.role_id
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS user_roles;
|
||||
@@ -0,0 +1,265 @@
|
||||
-- +goose Up
|
||||
SET @col_default_shift_start_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'default_shift_start'
|
||||
);
|
||||
SET @add_default_shift_start_sql := IF(
|
||||
@col_default_shift_start_exists = 0,
|
||||
'ALTER TABLE bases ADD COLUMN default_shift_start TIME NULL AFTER leg_time',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_default_shift_start FROM @add_default_shift_start_sql;
|
||||
EXECUTE stmt_add_default_shift_start;
|
||||
DEALLOCATE PREPARE stmt_add_default_shift_start;
|
||||
|
||||
SET @col_default_shift_end_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'default_shift_end'
|
||||
);
|
||||
SET @add_default_shift_end_sql := IF(
|
||||
@col_default_shift_end_exists = 0,
|
||||
'ALTER TABLE bases ADD COLUMN default_shift_end TIME NULL AFTER default_shift_start',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_default_shift_end FROM @add_default_shift_end_sql;
|
||||
EXECUTE stmt_add_default_shift_end;
|
||||
DEALLOCATE PREPARE stmt_add_default_shift_end;
|
||||
|
||||
SET @col_foto_attachment_id_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'foto_attachment_id'
|
||||
);
|
||||
SET @add_foto_attachment_id_sql := IF(
|
||||
@col_foto_attachment_id_exists = 0,
|
||||
'ALTER TABLE bases ADD COLUMN foto_attachment_id BINARY(16) NULL AFTER foto',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_foto_attachment_id FROM @add_foto_attachment_id_sql;
|
||||
EXECUTE stmt_add_foto_attachment_id;
|
||||
DEALLOCATE PREPARE stmt_add_foto_attachment_id;
|
||||
|
||||
SET @col_deleted_at_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'deleted_at'
|
||||
);
|
||||
SET @add_deleted_at_sql := IF(
|
||||
@col_deleted_at_exists = 0,
|
||||
'ALTER TABLE bases ADD COLUMN deleted_at DATETIME(3) NULL AFTER updated_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_deleted_at FROM @add_deleted_at_sql;
|
||||
EXECUTE stmt_add_deleted_at;
|
||||
DEALLOCATE PREPARE stmt_add_deleted_at;
|
||||
|
||||
SET @col_deleted_by_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'deleted_by'
|
||||
);
|
||||
SET @add_deleted_by_sql := IF(
|
||||
@col_deleted_by_exists = 0,
|
||||
'ALTER TABLE bases ADD COLUMN deleted_by BINARY(16) NULL AFTER deleted_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_deleted_by FROM @add_deleted_by_sql;
|
||||
EXECUTE stmt_add_deleted_by;
|
||||
DEALLOCATE PREPARE stmt_add_deleted_by;
|
||||
|
||||
SET @idx_bases_deleted_at_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND index_name = 'idx_bases_deleted_at'
|
||||
);
|
||||
SET @add_idx_bases_deleted_at_sql := IF(
|
||||
@idx_bases_deleted_at_exists = 0,
|
||||
'ALTER TABLE bases ADD INDEX idx_bases_deleted_at (deleted_at)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_idx_bases_deleted_at FROM @add_idx_bases_deleted_at_sql;
|
||||
EXECUTE stmt_add_idx_bases_deleted_at;
|
||||
DEALLOCATE PREPARE stmt_add_idx_bases_deleted_at;
|
||||
|
||||
SET @idx_bases_foto_attachment_id_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND index_name = 'idx_bases_foto_attachment_id'
|
||||
);
|
||||
SET @add_idx_bases_foto_attachment_id_sql := IF(
|
||||
@idx_bases_foto_attachment_id_exists = 0,
|
||||
'ALTER TABLE bases ADD INDEX idx_bases_foto_attachment_id (foto_attachment_id)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_idx_bases_foto_attachment_id FROM @add_idx_bases_foto_attachment_id_sql;
|
||||
EXECUTE stmt_add_idx_bases_foto_attachment_id;
|
||||
DEALLOCATE PREPARE stmt_add_idx_bases_foto_attachment_id;
|
||||
|
||||
SET @attachments_table_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'attachments'
|
||||
);
|
||||
SET @fk_bases_foto_attachment_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.table_constraints
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND constraint_name = 'fk_bases_foto_attachment'
|
||||
AND constraint_type = 'FOREIGN KEY'
|
||||
);
|
||||
SET @add_fk_bases_foto_attachment_sql := IF(
|
||||
@attachments_table_exists > 0 AND @fk_bases_foto_attachment_exists = 0,
|
||||
'ALTER TABLE bases ADD CONSTRAINT fk_bases_foto_attachment FOREIGN KEY (foto_attachment_id) REFERENCES attachments(id) ON UPDATE CASCADE ON DELETE SET NULL',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_fk_bases_foto_attachment FROM @add_fk_bases_foto_attachment_sql;
|
||||
EXECUTE stmt_add_fk_bases_foto_attachment;
|
||||
DEALLOCATE PREPARE stmt_add_fk_bases_foto_attachment;
|
||||
|
||||
-- +goose Down
|
||||
SET @fk_bases_foto_attachment_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.table_constraints
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND constraint_name = 'fk_bases_foto_attachment'
|
||||
AND constraint_type = 'FOREIGN KEY'
|
||||
);
|
||||
SET @drop_fk_bases_foto_attachment_sql := IF(
|
||||
@fk_bases_foto_attachment_exists > 0,
|
||||
'ALTER TABLE bases DROP FOREIGN KEY fk_bases_foto_attachment',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_fk_bases_foto_attachment FROM @drop_fk_bases_foto_attachment_sql;
|
||||
EXECUTE stmt_drop_fk_bases_foto_attachment;
|
||||
DEALLOCATE PREPARE stmt_drop_fk_bases_foto_attachment;
|
||||
|
||||
SET @idx_bases_foto_attachment_id_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND index_name = 'idx_bases_foto_attachment_id'
|
||||
);
|
||||
SET @drop_idx_bases_foto_attachment_id_sql := IF(
|
||||
@idx_bases_foto_attachment_id_exists > 0,
|
||||
'ALTER TABLE bases DROP INDEX idx_bases_foto_attachment_id',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_idx_bases_foto_attachment_id FROM @drop_idx_bases_foto_attachment_id_sql;
|
||||
EXECUTE stmt_drop_idx_bases_foto_attachment_id;
|
||||
DEALLOCATE PREPARE stmt_drop_idx_bases_foto_attachment_id;
|
||||
|
||||
SET @idx_bases_deleted_at_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND index_name = 'idx_bases_deleted_at'
|
||||
);
|
||||
SET @drop_idx_bases_deleted_at_sql := IF(
|
||||
@idx_bases_deleted_at_exists > 0,
|
||||
'ALTER TABLE bases DROP INDEX idx_bases_deleted_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_idx_bases_deleted_at FROM @drop_idx_bases_deleted_at_sql;
|
||||
EXECUTE stmt_drop_idx_bases_deleted_at;
|
||||
DEALLOCATE PREPARE stmt_drop_idx_bases_deleted_at;
|
||||
|
||||
SET @col_deleted_by_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'deleted_by'
|
||||
);
|
||||
SET @drop_deleted_by_sql := IF(
|
||||
@col_deleted_by_exists > 0,
|
||||
'ALTER TABLE bases DROP COLUMN deleted_by',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_deleted_by FROM @drop_deleted_by_sql;
|
||||
EXECUTE stmt_drop_deleted_by;
|
||||
DEALLOCATE PREPARE stmt_drop_deleted_by;
|
||||
|
||||
SET @col_deleted_at_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'deleted_at'
|
||||
);
|
||||
SET @drop_deleted_at_sql := IF(
|
||||
@col_deleted_at_exists > 0,
|
||||
'ALTER TABLE bases DROP COLUMN deleted_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_deleted_at FROM @drop_deleted_at_sql;
|
||||
EXECUTE stmt_drop_deleted_at;
|
||||
DEALLOCATE PREPARE stmt_drop_deleted_at;
|
||||
|
||||
SET @col_foto_attachment_id_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'foto_attachment_id'
|
||||
);
|
||||
SET @drop_foto_attachment_id_sql := IF(
|
||||
@col_foto_attachment_id_exists > 0,
|
||||
'ALTER TABLE bases DROP COLUMN foto_attachment_id',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_foto_attachment_id FROM @drop_foto_attachment_id_sql;
|
||||
EXECUTE stmt_drop_foto_attachment_id;
|
||||
DEALLOCATE PREPARE stmt_drop_foto_attachment_id;
|
||||
|
||||
SET @col_default_shift_end_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'default_shift_end'
|
||||
);
|
||||
SET @drop_default_shift_end_sql := IF(
|
||||
@col_default_shift_end_exists > 0,
|
||||
'ALTER TABLE bases DROP COLUMN default_shift_end',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_default_shift_end FROM @drop_default_shift_end_sql;
|
||||
EXECUTE stmt_drop_default_shift_end;
|
||||
DEALLOCATE PREPARE stmt_drop_default_shift_end;
|
||||
|
||||
SET @col_default_shift_start_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'default_shift_start'
|
||||
);
|
||||
SET @drop_default_shift_start_sql := IF(
|
||||
@col_default_shift_start_exists > 0,
|
||||
'ALTER TABLE bases DROP COLUMN default_shift_start',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_default_shift_start FROM @drop_default_shift_start_sql;
|
||||
EXECUTE stmt_drop_default_shift_start;
|
||||
DEALLOCATE PREPARE stmt_drop_default_shift_start;
|
||||
81
migrations/20260407_permissions_requires_pin.sql
Normal file
81
migrations/20260407_permissions_requires_pin.sql
Normal file
@@ -0,0 +1,81 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE permissions
|
||||
ADD COLUMN requires_pin TINYINT(1) NOT NULL DEFAULT 0 AFTER description;
|
||||
|
||||
UPDATE permissions
|
||||
SET requires_pin = 1
|
||||
WHERE (updated_by IS NULL OR LENGTH(updated_by) = 0)
|
||||
AND `key` IN (
|
||||
'user.create',
|
||||
'user.update',
|
||||
'user.delete',
|
||||
'role.create',
|
||||
'role.update',
|
||||
'role.delete',
|
||||
'role.permission.assign',
|
||||
'role.permission.remove',
|
||||
'role.permission.update',
|
||||
'helicopter.create',
|
||||
'helicopter.report.generate',
|
||||
'helicopter.update',
|
||||
'helicopter.delete',
|
||||
'facility.create',
|
||||
'facility.update',
|
||||
'facility.delete',
|
||||
'base.create',
|
||||
'base.update',
|
||||
'base.delete',
|
||||
'hems_base.create',
|
||||
'hems_base.update',
|
||||
'hems_base.delete',
|
||||
'bmd.create',
|
||||
'bmd.update',
|
||||
'bmd.delete',
|
||||
'medicine.create',
|
||||
'medicine.update',
|
||||
'medicine.delete',
|
||||
'vocation.create',
|
||||
'vocation.update',
|
||||
'vocation.delete',
|
||||
'opc.create',
|
||||
'opc.update',
|
||||
'opc.delete',
|
||||
'forces_present.create',
|
||||
'forces_present.update',
|
||||
'forces_present.delete',
|
||||
'hospital.create',
|
||||
'hospital.update',
|
||||
'hospital.delete',
|
||||
'health_insurance_companies.create',
|
||||
'health_insurance_companies.update',
|
||||
'health_insurance_companies.delete',
|
||||
'federal_state.create',
|
||||
'federal_state.update',
|
||||
'federal_state.delete',
|
||||
'nationality.create',
|
||||
'nationality.update',
|
||||
'nationality.delete',
|
||||
'icao.create',
|
||||
'icao.update',
|
||||
'icao.delete',
|
||||
'land.create',
|
||||
'land.update',
|
||||
'land.delete',
|
||||
'master_settings.create',
|
||||
'master_settings.update',
|
||||
'master_settings.delete',
|
||||
'file_manager.create',
|
||||
'file_manager.update',
|
||||
'file_manager.delete',
|
||||
'hems_duty_roster.create',
|
||||
'hems_duty_roster.update',
|
||||
'hems_duty_roster.delete',
|
||||
'air_rescuer_checklist.create',
|
||||
'air_rescuer_checklist.update',
|
||||
'air_rescuer_checklist.delete',
|
||||
'audit.read'
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE permissions
|
||||
DROP COLUMN requires_pin;
|
||||
85
migrations/20260408_crew_related_tables.sql
Normal file
85
migrations/20260408_crew_related_tables.sql
Normal file
@@ -0,0 +1,85 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS crews (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
crew_type VARCHAR(32) NOT NULL,
|
||||
user_id BINARY(16) NOT NULL,
|
||||
start_date DATETIME NOT NULL,
|
||||
end_date DATETIME NOT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
CONSTRAINT chk_crews_crew_type CHECK (crew_type IN ('main', 'additional')),
|
||||
CONSTRAINT chk_crews_date_range CHECK (start_date <= end_date),
|
||||
CONSTRAINT fk_crews_user FOREIGN KEY (user_id) REFERENCES users(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_crews_user_id ON crews(user_id);
|
||||
CREATE INDEX idx_crews_crew_type ON crews(crew_type);
|
||||
CREATE INDEX idx_crews_start_date ON crews(start_date);
|
||||
CREATE INDEX idx_crews_end_date ON crews(end_date);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS roster_crews (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
roster_id BINARY(16) NOT NULL,
|
||||
crew_id BINARY(16) NOT NULL,
|
||||
confirm_at DATETIME NULL,
|
||||
role VARCHAR(32) NOT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
CONSTRAINT chk_roster_crews_role CHECK (role IN ('Pilot', 'Copilot', 'Doctor', 'AirRescuer')),
|
||||
CONSTRAINT fk_roster_crews_roster FOREIGN KEY (roster_id) REFERENCES hems_duty_rosters(id),
|
||||
CONSTRAINT fk_roster_crews_crew FOREIGN KEY (crew_id) REFERENCES crews(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_roster_crews_roster_id ON roster_crews(roster_id);
|
||||
CREATE INDEX idx_roster_crews_role ON roster_crews(role);
|
||||
CREATE UNIQUE INDEX idx_roster_crews_roster_crew ON roster_crews(roster_id, crew_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS duty_roster_other_persons (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
roster_id BINARY(16) NOT NULL,
|
||||
name VARCHAR(191) NOT NULL,
|
||||
mobile_phone VARCHAR(64) NULL,
|
||||
email VARCHAR(191) NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_duty_roster_other_persons_roster FOREIGN KEY (roster_id) REFERENCES hems_duty_rosters(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_duty_roster_other_persons_roster_id ON duty_roster_other_persons(roster_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS duty_roster_crew_pilot_additionals (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
crew_id BINARY(16) NOT NULL,
|
||||
flight_instructor TINYINT(1) NOT NULL DEFAULT 0,
|
||||
line_checker TINYINT(1) NOT NULL DEFAULT 0,
|
||||
supervisor TINYINT(1) NOT NULL DEFAULT 0,
|
||||
examiner TINYINT(1) NOT NULL DEFAULT 0,
|
||||
copilot TINYINT(1) NOT NULL DEFAULT 0,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_duty_roster_crew_pilot_additionals_crew FOREIGN KEY (crew_id) REFERENCES crews(id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_duty_roster_crew_pilot_additionals_crew_id ON duty_roster_crew_pilot_additionals(crew_id);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS duty_roster_crew_pilot_additionals;
|
||||
DROP TABLE IF EXISTS duty_roster_other_persons;
|
||||
DROP TABLE IF EXISTS roster_crews;
|
||||
DROP TABLE IF EXISTS crews;
|
||||
25
migrations/20260408_file_manager_attachments.sql
Normal file
25
migrations/20260408_file_manager_attachments.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS attachments (
|
||||
id BINARY(16) NOT NULL,
|
||||
file_id BINARY(16) NOT NULL,
|
||||
ref_type VARCHAR(64) NOT NULL,
|
||||
ref_id VARCHAR(191) NOT NULL,
|
||||
category VARCHAR(64) NULL,
|
||||
sort_order INT NOT NULL DEFAULT 0,
|
||||
is_primary TINYINT(1) NOT NULL DEFAULT 0,
|
||||
attached_by BINARY(16) NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (id),
|
||||
CONSTRAINT fk_attachments_file
|
||||
FOREIGN KEY (file_id) REFERENCES file_files(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE,
|
||||
UNIQUE KEY uq_attachments_ref_file (ref_type, ref_id, file_id),
|
||||
KEY idx_attachments_file_id (file_id),
|
||||
KEY idx_attachments_ref_sort (ref_type, ref_id, sort_order, created_at),
|
||||
KEY idx_attachments_ref_category (ref_type, ref_id, category)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS attachments;
|
||||
@@ -0,0 +1,7 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE hems_duty_roster_crews
|
||||
ADD COLUMN IF NOT EXISTS confirm_at DATETIME NULL AFTER email;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE hems_duty_roster_crews
|
||||
DROP COLUMN IF EXISTS confirm_at;
|
||||
25
migrations/20260409_after_flight_inspections.sql
Normal file
25
migrations/20260409_after_flight_inspections.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS after_flight_inspections (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
flight_inspection_id BINARY(16) NOT NULL,
|
||||
ac_oil_upload_liter DECIMAL(10,2) NULL,
|
||||
oil_engine_nr1_checked TINYINT(1) NULL,
|
||||
oil_engine_nr2_checked TINYINT(1) NULL,
|
||||
hydraulic_lh_checked TINYINT(1) NULL,
|
||||
hydraulic_rh_checked TINYINT(1) NULL,
|
||||
oil_transmission_mgb_checked TINYINT(1) NULL,
|
||||
oil_transmission_igb_checked TINYINT(1) NULL,
|
||||
oil_transmission_tgb_checked TINYINT(1) NULL,
|
||||
note TEXT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_after_flight_inspections_flight_inspection FOREIGN KEY (flight_inspection_id) REFERENCES flight_inspections(id),
|
||||
CONSTRAINT chk_after_flight_ac_oil_upload_liter CHECK (ac_oil_upload_liter IS NULL OR ac_oil_upload_liter >= 0)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_after_flight_inspections_flight_inspection_id ON after_flight_inspections(flight_inspection_id);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS after_flight_inspections;
|
||||
27
migrations/20260409_before_flight_inspections.sql
Normal file
27
migrations/20260409_before_flight_inspections.sql
Normal file
@@ -0,0 +1,27 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS before_flight_inspections (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
flight_inspection_id BINARY(16) NOT NULL,
|
||||
oil_engine_nr1_checked TINYINT(1) NULL,
|
||||
oil_engine_nr2_checked TINYINT(1) NULL,
|
||||
hydraulic_lh_checked TINYINT(1) NULL,
|
||||
hydraulic_rh_checked TINYINT(1) NULL,
|
||||
oil_transmission_mgb_checked TINYINT(1) NULL,
|
||||
oil_transmission_igb_checked TINYINT(1) NULL,
|
||||
oil_transmission_tgb_checked TINYINT(1) NULL,
|
||||
fuel_amount DECIMAL(10,2) NULL,
|
||||
fuel_unit VARCHAR(10) NULL,
|
||||
fuel_added_amount DECIMAL(10,2) NULL,
|
||||
note TEXT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_before_flight_inspections_flight_inspection FOREIGN KEY (flight_inspection_id) REFERENCES flight_inspections(id),
|
||||
CONSTRAINT chk_before_flight_fuel_unit CHECK (fuel_unit IS NULL OR fuel_unit IN ('LT', 'KG', 'POUND'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX idx_before_flight_inspections_flight_inspection_id ON before_flight_inspections(flight_inspection_id);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS before_flight_inspections;
|
||||
30
migrations/20260409_flight_inspections.sql
Normal file
30
migrations/20260409_flight_inspections.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS flight_inspections (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
helicopter_id BINARY(16) NOT NULL,
|
||||
inspection_date DATE NOT NULL,
|
||||
operation_id BINARY(16) NULL,
|
||||
status ENUM('Draft', 'InProgress', 'Completed') NOT NULL DEFAULT 'Draft',
|
||||
before_flight_completed_at DATETIME NULL,
|
||||
before_flight_completed_by BINARY(16) NULL,
|
||||
flight_prep_completed_at DATETIME NULL,
|
||||
flight_prep_completed_by BINARY(16) NULL,
|
||||
after_flight_completed_at DATETIME NULL,
|
||||
after_flight_completed_by BINARY(16) NULL,
|
||||
final_completed_at DATETIME NULL,
|
||||
final_completed_by BINARY(16) NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_flight_inspections_helicopter FOREIGN KEY (helicopter_id) REFERENCES helicopters(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_flight_inspections_helicopter_id ON flight_inspections(helicopter_id);
|
||||
CREATE INDEX idx_flight_inspections_inspection_date ON flight_inspections(inspection_date);
|
||||
CREATE INDEX idx_flight_inspections_status ON flight_inspections(status);
|
||||
CREATE INDEX idx_flight_inspections_operation_id ON flight_inspections(operation_id);
|
||||
CREATE INDEX idx_flight_inspections_helicopter_date ON flight_inspections(helicopter_id, inspection_date);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS flight_inspections;
|
||||
26
migrations/20260409_flight_prep_checks.sql
Normal file
26
migrations/20260409_flight_prep_checks.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
-- +goose Up
|
||||
-- Migration: Create flight_prep_checks table
|
||||
-- Date: 2026-04-09
|
||||
-- Description: Per-inspection execution data for flight preparation checklist items
|
||||
|
||||
CREATE TABLE flight_prep_checks (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
flight_inspection_id BINARY(16) NOT NULL,
|
||||
flight_prep_item_id BINARY(16) NOT NULL,
|
||||
is_done TINYINT(1) NOT NULL DEFAULT 0,
|
||||
note TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16),
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16),
|
||||
|
||||
CONSTRAINT fk_flight_prep_checks_flight_inspection FOREIGN KEY (flight_inspection_id) REFERENCES flight_inspections(id) ON DELETE CASCADE,
|
||||
CONSTRAINT fk_flight_prep_checks_flight_prep_item FOREIGN KEY (flight_prep_item_id) REFERENCES flight_prep_items(id) ON DELETE RESTRICT,
|
||||
|
||||
INDEX idx_flight_prep_checks_flight_inspection (flight_inspection_id),
|
||||
INDEX idx_flight_prep_checks_flight_inspection_sorted (flight_inspection_id, is_done),
|
||||
UNIQUE KEY uk_flight_prep_checks_inspection_item (flight_inspection_id, flight_prep_item_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS flight_prep_checks;
|
||||
25
migrations/20260409_flight_prep_items.sql
Normal file
25
migrations/20260409_flight_prep_items.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- +goose Up
|
||||
-- Migration: Create flight_prep_items table
|
||||
-- Date: 2026-04-09
|
||||
-- Description: Master data table for flight preparation checklist items
|
||||
|
||||
CREATE TABLE flight_prep_items (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
title VARCHAR(255) NOT NULL,
|
||||
section ENUM('FLIGHT_PREPARATION', 'WEIGHT_AND_BALANCE') NOT NULL,
|
||||
sort_order INT NOT NULL DEFAULT 0 CHECK (sort_order >= 0),
|
||||
is_required TINYINT(1) NOT NULL,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16),
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16),
|
||||
|
||||
INDEX idx_flight_prep_items_section_active (section, is_active),
|
||||
INDEX idx_flight_prep_items_sort_order (sort_order),
|
||||
INDEX idx_flight_prep_items_created_at (created_at),
|
||||
UNIQUE KEY uk_flight_prep_items_title_section_active (title, section, is_active)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS flight_prep_items;
|
||||
20
migrations/20260410_opcs.sql
Normal file
20
migrations/20260410_opcs.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- Create opcs table for OPC (Operation Planning Center) master data
|
||||
|
||||
CREATE TABLE IF NOT EXISTS opcs (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
name VARCHAR(64) NOT NULL UNIQUE,
|
||||
description VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
|
||||
KEY idx_opcs_name (name),
|
||||
KEY idx_opcs_deleted_at (deleted_at)
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS opcs;
|
||||
57
migrations/20260410_patient_data.sql
Normal file
57
migrations/20260410_patient_data.sql
Normal file
@@ -0,0 +1,57 @@
|
||||
-- +goose Up
|
||||
-- Create insurance_patient_data table
|
||||
|
||||
CREATE TABLE IF NOT EXISTS insurance_patient_data (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
health_insurance_companies_id BINARY(16) NULL,
|
||||
federal_state_id BINARY(16) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
|
||||
KEY idx_insurance_patient_data_health_insurance_companies_id (health_insurance_companies_id),
|
||||
KEY idx_insurance_patient_data_federal_state_id (federal_state_id),
|
||||
KEY idx_insurance_patient_data_deleted_at (deleted_at)
|
||||
);
|
||||
|
||||
-- Create patient_data table
|
||||
|
||||
CREATE TABLE IF NOT EXISTS patient_data (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
family_name VARCHAR(128) NOT NULL,
|
||||
first_name VARCHAR(128) NOT NULL,
|
||||
opc_id BINARY(16) NULL,
|
||||
birth_date DATE NULL,
|
||||
gender ENUM('male','female') NOT NULL,
|
||||
street VARCHAR(255) NULL,
|
||||
svnr VARCHAR(64) NULL,
|
||||
email VARCHAR(191) NULL,
|
||||
phone VARCHAR(64) NULL,
|
||||
co_insured TINYINT(1) NOT NULL DEFAULT 0,
|
||||
place_id BINARY(16) NULL,
|
||||
nationality_id BINARY(16) NULL,
|
||||
insurance_patient_data_id BINARY(16) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
|
||||
KEY idx_patient_data_opc_id (opc_id),
|
||||
KEY idx_patient_data_place_id (place_id),
|
||||
KEY idx_patient_data_nationality_id (nationality_id),
|
||||
KEY idx_patient_data_insurance_patient_data_id (insurance_patient_data_id),
|
||||
KEY idx_patient_data_deleted_at (deleted_at),
|
||||
|
||||
CONSTRAINT fk_patient_data_insurance_patient_data
|
||||
FOREIGN KEY (insurance_patient_data_id) REFERENCES insurance_patient_data (id)
|
||||
ON UPDATE CASCADE ON DELETE SET NULL
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS patient_data;
|
||||
DROP TABLE IF EXISTS insurance_patient_data;
|
||||
28
migrations/20260410_places.sql
Normal file
28
migrations/20260410_places.sql
Normal file
@@ -0,0 +1,28 @@
|
||||
-- +goose Up
|
||||
-- Create places table
|
||||
|
||||
CREATE TABLE IF NOT EXISTS places (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
state VARCHAR(255) NULL,
|
||||
post_code VARCHAR(32) NULL,
|
||||
location VARCHAR(255) NOT NULL,
|
||||
street VARCHAR(255) NULL,
|
||||
no VARCHAR(50) NULL,
|
||||
country_code VARCHAR(10) NULL,
|
||||
country_name VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
|
||||
KEY idx_places_location (location),
|
||||
KEY idx_places_state (state),
|
||||
KEY idx_places_post_code (post_code),
|
||||
KEY idx_places_country_code (country_code),
|
||||
KEY idx_places_deleted_at (deleted_at)
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS places;
|
||||
@@ -0,0 +1,26 @@
|
||||
CREATE TABLE IF NOT EXISTS reserve_acs (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
status VARCHAR(20) NOT NULL DEFAULT 'pending',
|
||||
helicopter_id BINARY(16) NOT NULL,
|
||||
inspection_id BINARY(16) NOT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
CONSTRAINT chk_reserve_ac_status CHECK (status IN ('pending', 'approved', 'onprogress')),
|
||||
CONSTRAINT fk_reserve_acs_helicopter FOREIGN KEY (helicopter_id) REFERENCES helicopters(id),
|
||||
CONSTRAINT fk_reserve_acs_inspection FOREIGN KEY (inspection_id) REFERENCES flight_inspections(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_reserve_acs_helicopter_id ON reserve_acs(helicopter_id);
|
||||
CREATE INDEX idx_reserve_acs_inspection_id ON reserve_acs(inspection_id);
|
||||
CREATE INDEX idx_reserve_acs_deleted_at ON reserve_acs(deleted_at);
|
||||
|
||||
ALTER TABLE flight_inspections DROP FOREIGN KEY fk_flight_inspections_helicopter;
|
||||
DROP INDEX idx_flight_inspections_helicopter_id ON flight_inspections;
|
||||
DROP INDEX idx_flight_inspections_operation_id ON flight_inspections;
|
||||
DROP INDEX idx_flight_inspections_helicopter_date ON flight_inspections;
|
||||
ALTER TABLE flight_inspections DROP COLUMN helicopter_id;
|
||||
ALTER TABLE flight_inspections DROP COLUMN operation_id;
|
||||
23
migrations/20260414_flights.sql
Normal file
23
migrations/20260414_flights.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
CREATE TABLE IF NOT EXISTS flights (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
mission_code VARCHAR(64) NOT NULL,
|
||||
mission_type VARCHAR(32) NOT NULL,
|
||||
date DATE NOT NULL,
|
||||
duty_roster_id BINARY(16) NULL,
|
||||
reserve_ac_id BINARY(16) NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_flights_reserve_ac FOREIGN KEY (reserve_ac_id) REFERENCES reserve_acs(id),
|
||||
CONSTRAINT chk_flights_mission_type CHECK (mission_type IN ('hems', 'cat', 'spo', 'nco'))
|
||||
);
|
||||
|
||||
CREATE INDEX idx_flights_mission_code ON flights(mission_code);
|
||||
CREATE INDEX idx_flights_mission_type ON flights(mission_type);
|
||||
CREATE INDEX idx_flights_date ON flights(date);
|
||||
CREATE INDEX idx_flights_duty_roster_id ON flights(duty_roster_id);
|
||||
CREATE INDEX idx_flights_reserve_ac_id ON flights(reserve_ac_id);
|
||||
CREATE INDEX idx_flights_deleted_at ON flights(deleted_at);
|
||||
@@ -0,0 +1,41 @@
|
||||
CREATE TABLE IF NOT EXISTS helicopter_files (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
section VARCHAR(64) NOT NULL,
|
||||
helicopter_id BINARY(16) NOT NULL,
|
||||
file_attachment_id BINARY(16) NOT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
CONSTRAINT chk_helicopter_files_section CHECK (
|
||||
section IN (
|
||||
'before_first_flight_inspection',
|
||||
'flight_preparation_and_wb',
|
||||
'after_last_flight_inspection'
|
||||
)
|
||||
),
|
||||
CONSTRAINT fk_helicopter_files_helicopter FOREIGN KEY (helicopter_id) REFERENCES helicopters(id),
|
||||
CONSTRAINT fk_helicopter_files_attachment FOREIGN KEY (file_attachment_id) REFERENCES attachments(id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_helicopter_files_section ON helicopter_files(section);
|
||||
CREATE INDEX idx_helicopter_files_helicopter_id ON helicopter_files(helicopter_id);
|
||||
CREATE INDEX idx_helicopter_files_attachment_id ON helicopter_files(file_attachment_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS flight_inspection_file_checklists (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
is_done TINYINT(1) NOT NULL DEFAULT 0,
|
||||
helicopter_file_id BINARY(16) NOT NULL,
|
||||
flight_inspection_id BINARY(16) NOT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_flight_inspection_file_checklists_helicopter_file FOREIGN KEY (helicopter_file_id) REFERENCES helicopter_files(id),
|
||||
CONSTRAINT fk_flight_inspection_file_checklists_inspection FOREIGN KEY (flight_inspection_id) REFERENCES flight_inspections(id),
|
||||
CONSTRAINT uq_flight_inspection_file_checklists_inspection_file UNIQUE (flight_inspection_id, helicopter_file_id)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_flight_inspection_file_checklists_file_id ON flight_inspection_file_checklists(helicopter_file_id);
|
||||
CREATE INDEX idx_flight_inspection_file_checklists_inspection_id ON flight_inspection_file_checklists(flight_inspection_id);
|
||||
CREATE INDEX idx_flight_inspection_file_checklists_inspection_sorted ON flight_inspection_file_checklists(flight_inspection_id, is_done);
|
||||
35
migrations/20260414_hems_operations_mission_link.sql
Normal file
35
migrations/20260414_hems_operations_mission_link.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
ALTER TABLE hems_operations
|
||||
ADD COLUMN IF NOT EXISTS mission_id BINARY(16) NULL;
|
||||
|
||||
SET @fk_exists := (
|
||||
SELECT COUNT(1)
|
||||
FROM information_schema.table_constraints
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hems_operations'
|
||||
AND constraint_type = 'FOREIGN KEY'
|
||||
AND constraint_name = 'fk_hems_operations_mission'
|
||||
);
|
||||
SET @fk_sql := IF(
|
||||
@fk_exists = 0,
|
||||
'ALTER TABLE hems_operations ADD CONSTRAINT fk_hems_operations_mission FOREIGN KEY (mission_id) REFERENCES missions(id) ON UPDATE CASCADE ON DELETE SET NULL',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_fk FROM @fk_sql;
|
||||
EXECUTE stmt_fk;
|
||||
DEALLOCATE PREPARE stmt_fk;
|
||||
|
||||
SET @idx_exists := (
|
||||
SELECT COUNT(1)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hems_operations'
|
||||
AND index_name = 'uidx_hems_operations_mission_id'
|
||||
);
|
||||
SET @idx_sql := IF(
|
||||
@idx_exists = 0,
|
||||
'ALTER TABLE hems_operations ADD UNIQUE INDEX uidx_hems_operations_mission_id (mission_id)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_idx FROM @idx_sql;
|
||||
EXECUTE stmt_idx;
|
||||
DEALLOCATE PREPARE stmt_idx;
|
||||
17
migrations/20260414_missions.sql
Normal file
17
migrations/20260414_missions.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
CREATE TABLE IF NOT EXISTS missions (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
flight_id BINARY(16) NOT NULL,
|
||||
type VARCHAR(20) NOT NULL,
|
||||
created_at DATETIME NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
CONSTRAINT fk_missions_flight FOREIGN KEY (flight_id) REFERENCES flights(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT chk_missions_type CHECK (type IN ('CAT', 'SPO', 'NCO', 'HEMS'))
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX uidx_missions_flight_id ON missions(flight_id);
|
||||
CREATE INDEX idx_missions_type ON missions(type);
|
||||
CREATE INDEX idx_missions_deleted_at ON missions(deleted_at);
|
||||
2
migrations/20260414_reserve_acs_unique_inspection_id.sql
Normal file
2
migrations/20260414_reserve_acs_unique_inspection_id.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE reserve_acs DROP INDEX idx_reserve_acs_inspection_id;
|
||||
ALTER TABLE reserve_acs ADD UNIQUE INDEX uidx_reserve_acs_inspection_id (inspection_id);
|
||||
17
migrations/20260415_helicopter_files_section_short_codes.sql
Normal file
17
migrations/20260415_helicopter_files_section_short_codes.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
ALTER TABLE helicopter_files DROP CHECK chk_helicopter_files_section;
|
||||
|
||||
UPDATE helicopter_files
|
||||
SET section = 'bfi'
|
||||
WHERE section = 'before_first_flight_inspection';
|
||||
|
||||
UPDATE helicopter_files
|
||||
SET section = 'fpwb'
|
||||
WHERE section = 'flight_preparation_and_wb';
|
||||
|
||||
UPDATE helicopter_files
|
||||
SET section = 'afi'
|
||||
WHERE section = 'after_last_flight_inspection';
|
||||
|
||||
ALTER TABLE helicopter_files
|
||||
ADD CONSTRAINT chk_helicopter_files_section
|
||||
CHECK (section IN ('bfi', 'fpwb', 'afi'));
|
||||
1
migrations/20260416_drop_flight_prep_items.sql
Normal file
1
migrations/20260416_drop_flight_prep_items.sql
Normal file
@@ -0,0 +1 @@
|
||||
DROP TABLE IF EXISTS flight_prep_items;
|
||||
14
migrations/20260416_flight_prep_checks_static_fields.sql
Normal file
14
migrations/20260416_flight_prep_checks_static_fields.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
ALTER TABLE flight_prep_checks DROP FOREIGN KEY fk_flight_prep_checks_flight_prep_item;
|
||||
ALTER TABLE flight_prep_checks DROP INDEX uk_flight_prep_checks_inspection_item;
|
||||
ALTER TABLE flight_prep_checks DROP COLUMN flight_prep_item_id;
|
||||
ALTER TABLE flight_prep_checks DROP COLUMN is_done;
|
||||
ALTER TABLE flight_prep_checks DROP COLUMN note;
|
||||
ALTER TABLE flight_prep_checks DROP INDEX idx_flight_prep_checks_flight_inspection_sorted;
|
||||
|
||||
ALTER TABLE flight_prep_checks
|
||||
ADD COLUMN notam_briefing TINYINT(1) NOT NULL DEFAULT 0 AFTER id,
|
||||
ADD COLUMN weather_briefing TINYINT(1) NOT NULL DEFAULT 0 AFTER notam_briefing,
|
||||
ADD COLUMN operational_flight_plan TINYINT(1) NOT NULL DEFAULT 0 AFTER weather_briefing;
|
||||
|
||||
ALTER TABLE flight_prep_checks
|
||||
ADD UNIQUE KEY uk_flight_prep_checks_inspection (flight_inspection_id);
|
||||
14
migrations/20260416_helicopters_foto_attachment.sql
Normal file
14
migrations/20260416_helicopters_foto_attachment.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE helicopters
|
||||
ADD COLUMN foto_attachment_id BINARY(16) NULL,
|
||||
ADD KEY idx_helicopters_foto_attachment_id (foto_attachment_id),
|
||||
ADD CONSTRAINT fk_helicopters_foto_attachment
|
||||
FOREIGN KEY (foto_attachment_id) REFERENCES attachments(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE SET NULL;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE helicopters
|
||||
DROP FOREIGN KEY fk_helicopters_foto_attachment,
|
||||
DROP KEY idx_helicopters_foto_attachment_id,
|
||||
DROP COLUMN foto_attachment_id;
|
||||
16
migrations/20260416_master_setting_values.sql
Normal file
16
migrations/20260416_master_setting_values.sql
Normal file
@@ -0,0 +1,16 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS master_setting_values (
|
||||
setting_key VARCHAR(120) NOT NULL PRIMARY KEY,
|
||||
value TEXT NOT NULL,
|
||||
is_encrypted TINYINT(1) NOT NULL DEFAULT 0,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
|
||||
KEY idx_master_setting_values_updated_at (updated_at),
|
||||
KEY idx_master_setting_values_is_encrypted (is_encrypted)
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS master_setting_values;
|
||||
14
migrations/20260416_users_profile_picture_attachment.sql
Normal file
14
migrations/20260416_users_profile_picture_attachment.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE users
|
||||
ADD COLUMN image_attachment_id BINARY(16) NULL,
|
||||
ADD KEY idx_users_image_attachment_id (image_attachment_id),
|
||||
ADD CONSTRAINT fk_users_image_attachment
|
||||
FOREIGN KEY (image_attachment_id) REFERENCES attachments(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE SET NULL;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE users
|
||||
DROP FOREIGN KEY fk_users_image_attachment,
|
||||
DROP KEY idx_users_image_attachment_id,
|
||||
DROP COLUMN image_attachment_id;
|
||||
8
migrations/20260421_file_thumbnail_metadata.sql
Normal file
8
migrations/20260421_file_thumbnail_metadata.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
ALTER TABLE file_files
|
||||
ADD COLUMN thumbnail_mime_type VARCHAR(255) NULL AFTER etag,
|
||||
ADD COLUMN thumbnail_size_bytes BIGINT UNSIGNED NULL AFTER thumbnail_mime_type,
|
||||
ADD COLUMN thumbnail_bucket VARCHAR(128) NULL AFTER thumbnail_size_bytes,
|
||||
ADD COLUMN thumbnail_object_key VARCHAR(512) NULL AFTER thumbnail_bucket,
|
||||
ADD COLUMN thumbnail_object_version VARCHAR(128) NULL AFTER thumbnail_object_key,
|
||||
ADD COLUMN thumbnail_etag VARCHAR(128) NULL AFTER thumbnail_object_version,
|
||||
ADD UNIQUE KEY uq_file_files_thumbnail_object_key (thumbnail_object_key);
|
||||
13
migrations/20260421_file_thumbnail_metadata_null_cleanup.sql
Normal file
13
migrations/20260421_file_thumbnail_metadata_null_cleanup.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
UPDATE file_files
|
||||
SET
|
||||
thumbnail_mime_type = NULLIF(TRIM(thumbnail_mime_type), ''),
|
||||
thumbnail_bucket = NULLIF(TRIM(thumbnail_bucket), ''),
|
||||
thumbnail_object_key = NULLIF(TRIM(thumbnail_object_key), ''),
|
||||
thumbnail_object_version = NULLIF(TRIM(thumbnail_object_version), ''),
|
||||
thumbnail_etag = NULLIF(TRIM(thumbnail_etag), '')
|
||||
WHERE
|
||||
COALESCE(TRIM(thumbnail_mime_type), '') = ''
|
||||
OR COALESCE(TRIM(thumbnail_bucket), '') = ''
|
||||
OR COALESCE(TRIM(thumbnail_object_key), '') = ''
|
||||
OR COALESCE(TRIM(thumbnail_object_version), '') = ''
|
||||
OR COALESCE(TRIM(thumbnail_etag), '') = '';
|
||||
7
migrations/20260422_helicopters_aog_reason.sql
Normal file
7
migrations/20260422_helicopters_aog_reason.sql
Normal file
@@ -0,0 +1,7 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE helicopters
|
||||
ADD COLUMN aog_reason TEXT NULL AFTER air_on_ground;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE helicopters
|
||||
DROP COLUMN aog_reason;
|
||||
@@ -0,0 +1,31 @@
|
||||
-- Backfill checklist rows for existing reserve AC records.
|
||||
-- This fixes historical gaps where checklist rows were not inserted.
|
||||
|
||||
INSERT INTO flight_inspection_file_checklists (
|
||||
id,
|
||||
is_done,
|
||||
helicopter_file_id,
|
||||
flight_inspection_id,
|
||||
created_at,
|
||||
created_by,
|
||||
updated_at,
|
||||
updated_by
|
||||
)
|
||||
SELECT
|
||||
UUID_TO_BIN(UUID()) AS id,
|
||||
0 AS is_done,
|
||||
hf.id AS helicopter_file_id,
|
||||
ra.inspection_id AS flight_inspection_id,
|
||||
UTC_TIMESTAMP(3) AS created_at,
|
||||
ra.created_by AS created_by,
|
||||
UTC_TIMESTAMP(3) AS updated_at,
|
||||
ra.updated_by AS updated_by
|
||||
FROM reserve_acs ra
|
||||
JOIN helicopter_files hf
|
||||
ON hf.helicopter_id = ra.helicopter_id
|
||||
AND hf.section IN ('bfi', 'fpwb')
|
||||
LEFT JOIN flight_inspection_file_checklists fck
|
||||
ON fck.flight_inspection_id = ra.inspection_id
|
||||
AND fck.helicopter_file_id = hf.id
|
||||
WHERE ra.deleted_at IS NULL
|
||||
AND fck.id IS NULL;
|
||||
@@ -0,0 +1,52 @@
|
||||
-- Remove legacy aircraft_file_id from flight_inspection_file_checklists.
|
||||
-- Current app writes helicopter_file_id; keeping aircraft_file_id as NOT NULL
|
||||
-- causes inserts to fail with:
|
||||
-- Error 1364 (HY000): Field 'aircraft_file_id' doesn't have a default value
|
||||
|
||||
SET @schema_name := DATABASE();
|
||||
|
||||
SELECT COUNT(*) INTO @has_legacy_fk
|
||||
FROM information_schema.TABLE_CONSTRAINTS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspection_file_checklists'
|
||||
AND CONSTRAINT_TYPE = 'FOREIGN KEY'
|
||||
AND CONSTRAINT_NAME = 'fk_flight_inspection_file_checklists_aircraft_file';
|
||||
|
||||
SET @drop_legacy_fk_sql := IF(
|
||||
@has_legacy_fk > 0,
|
||||
'ALTER TABLE flight_inspection_file_checklists DROP FOREIGN KEY fk_flight_inspection_file_checklists_aircraft_file',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_legacy_fk FROM @drop_legacy_fk_sql;
|
||||
EXECUTE stmt_drop_legacy_fk;
|
||||
DEALLOCATE PREPARE stmt_drop_legacy_fk;
|
||||
|
||||
SELECT COUNT(*) INTO @has_legacy_index
|
||||
FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspection_file_checklists'
|
||||
AND INDEX_NAME = 'fk_flight_inspection_file_checklists_aircraft_file';
|
||||
|
||||
SET @drop_legacy_index_sql := IF(
|
||||
@has_legacy_index > 0,
|
||||
'ALTER TABLE flight_inspection_file_checklists DROP INDEX fk_flight_inspection_file_checklists_aircraft_file',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_legacy_index FROM @drop_legacy_index_sql;
|
||||
EXECUTE stmt_drop_legacy_index;
|
||||
DEALLOCATE PREPARE stmt_drop_legacy_index;
|
||||
|
||||
SELECT COUNT(*) INTO @has_legacy_column
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspection_file_checklists'
|
||||
AND COLUMN_NAME = 'aircraft_file_id';
|
||||
|
||||
SET @drop_legacy_column_sql := IF(
|
||||
@has_legacy_column > 0,
|
||||
'ALTER TABLE flight_inspection_file_checklists DROP COLUMN aircraft_file_id',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_legacy_column FROM @drop_legacy_column_sql;
|
||||
EXECUTE stmt_drop_legacy_column;
|
||||
DEALLOCATE PREPARE stmt_drop_legacy_column;
|
||||
9
migrations/20260424_bases_sortkey.sql
Normal file
9
migrations/20260424_bases_sortkey.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE bases
|
||||
ADD COLUMN sortkey INT NULL AFTER position,
|
||||
ADD KEY idx_bases_sortkey (sortkey);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE bases
|
||||
DROP KEY idx_bases_sortkey,
|
||||
DROP COLUMN sortkey;
|
||||
15
migrations/20260424_bmds_note_sortkey_is_active.sql
Normal file
15
migrations/20260424_bmds_note_sortkey_is_active.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE bmds
|
||||
ADD COLUMN note VARCHAR(255) NULL AFTER country_name,
|
||||
ADD COLUMN sortkey INT NULL AFTER country_name,
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER sortkey,
|
||||
ADD KEY idx_bmds_sortkey (sortkey),
|
||||
ADD KEY idx_bmds_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE bmds
|
||||
DROP KEY idx_bmds_sortkey,
|
||||
DROP KEY idx_bmds_is_active,
|
||||
DROP COLUMN sortkey,
|
||||
DROP COLUMN note,
|
||||
DROP COLUMN is_active;
|
||||
51
migrations/20260424_drop_bases_default_shift_time.sql
Normal file
51
migrations/20260424_drop_bases_default_shift_time.sql
Normal file
@@ -0,0 +1,51 @@
|
||||
-- +goose Up
|
||||
SET @bases_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
);
|
||||
|
||||
SET @col_default_shift_time_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'default_shift_time'
|
||||
);
|
||||
|
||||
SET @drop_default_shift_time_sql := IF(
|
||||
@bases_exists > 0 AND @col_default_shift_time_exists > 0,
|
||||
'ALTER TABLE bases DROP COLUMN default_shift_time',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt_drop_default_shift_time FROM @drop_default_shift_time_sql;
|
||||
EXECUTE stmt_drop_default_shift_time;
|
||||
DEALLOCATE PREPARE stmt_drop_default_shift_time;
|
||||
|
||||
-- +goose Down
|
||||
SET @bases_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
);
|
||||
|
||||
SET @col_default_shift_time_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'bases'
|
||||
AND column_name = 'default_shift_time'
|
||||
);
|
||||
|
||||
SET @add_default_shift_time_sql := IF(
|
||||
@bases_exists > 0 AND @col_default_shift_time_exists = 0,
|
||||
'ALTER TABLE bases ADD COLUMN default_shift_time VARCHAR(64) NULL AFTER default_shift_end',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt_add_default_shift_time FROM @add_default_shift_time_sql;
|
||||
EXECUTE stmt_add_default_shift_time;
|
||||
DEALLOCATE PREPARE stmt_add_default_shift_time;
|
||||
9
migrations/20260424_facilities_sortkey.sql
Normal file
9
migrations/20260424_facilities_sortkey.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE facilities
|
||||
ADD COLUMN sortkey INT NULL AFTER type,
|
||||
ADD KEY idx_facilities_sortkey (sortkey);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE facilities
|
||||
DROP KEY idx_facilities_sortkey,
|
||||
DROP COLUMN sortkey;
|
||||
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE forces_present
|
||||
ADD COLUMN note VARCHAR(255) NULL AFTER description,
|
||||
ADD COLUMN sortkey INT NULL AFTER name,
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER sortkey,
|
||||
ADD KEY idx_forces_present_sortkey (sortkey),
|
||||
ADD KEY idx_forces_present_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE forces_present
|
||||
DROP KEY idx_forces_present_sortkey,
|
||||
DROP KEY idx_forces_present_is_active,
|
||||
DROP COLUMN sortkey,
|
||||
DROP COLUMN note,
|
||||
DROP COLUMN is_active;
|
||||
@@ -0,0 +1,13 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE health_insurance_companies
|
||||
ADD COLUMN sortkey INT NULL AFTER name,
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER sortkey,
|
||||
ADD KEY idx_health_insurance_companies_sortkey (sortkey),
|
||||
ADD KEY idx_health_insurance_companies_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE health_insurance_companies
|
||||
DROP KEY idx_health_insurance_companies_sortkey,
|
||||
DROP KEY idx_health_insurance_companies_is_active,
|
||||
DROP COLUMN sortkey,
|
||||
DROP COLUMN is_active;
|
||||
9
migrations/20260424_helicopters_sortkey.sql
Normal file
9
migrations/20260424_helicopters_sortkey.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE helicopters
|
||||
ADD COLUMN sortkey INT NULL AFTER type,
|
||||
ADD KEY idx_helicopters_sortkey (sortkey);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE helicopters
|
||||
DROP KEY idx_helicopters_sortkey,
|
||||
DROP COLUMN sortkey;
|
||||
73
migrations/20260424_hospital_contacts_notes.sql
Normal file
73
migrations/20260424_hospital_contacts_notes.sql
Normal file
@@ -0,0 +1,73 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE hospitals
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE icaos
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE health_insurance_companies
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE federal_states
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE lands
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE nationalities
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE pilot_profiles
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE doctor_profiles
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE air_rescuer_profiles
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE technician_profiles
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE flight_assistant_profiles
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
ALTER TABLE staff_profiles
|
||||
ADD COLUMN IF NOT EXISTS note TEXT NULL;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE hospitals
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE icaos
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE health_insurance_companies
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE federal_states
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE lands
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE nationalities
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE pilot_profiles
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE doctor_profiles
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE air_rescuer_profiles
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE technician_profiles
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE flight_assistant_profiles
|
||||
DROP COLUMN IF EXISTS note;
|
||||
|
||||
ALTER TABLE staff_profiles
|
||||
DROP COLUMN IF EXISTS note;
|
||||
80
migrations/20260424_hospitals_is_active.sql
Normal file
80
migrations/20260424_hospitals_is_active.sql
Normal file
@@ -0,0 +1,80 @@
|
||||
-- +goose Up
|
||||
SET @table_hospitals_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hospitals'
|
||||
);
|
||||
|
||||
SET @col_hospitals_is_active_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hospitals'
|
||||
AND column_name = 'is_active'
|
||||
);
|
||||
|
||||
SET @add_hospitals_is_active_sql := IF(
|
||||
@table_hospitals_exists > 0 AND @col_hospitals_is_active_exists = 0,
|
||||
'ALTER TABLE hospitals ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER note',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt_add_hospitals_is_active FROM @add_hospitals_is_active_sql;
|
||||
EXECUTE stmt_add_hospitals_is_active;
|
||||
DEALLOCATE PREPARE stmt_add_hospitals_is_active;
|
||||
|
||||
SET @idx_hospitals_is_active_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hospitals'
|
||||
AND index_name = 'idx_hospitals_is_active'
|
||||
);
|
||||
|
||||
SET @add_idx_hospitals_is_active_sql := IF(
|
||||
@table_hospitals_exists > 0 AND @idx_hospitals_is_active_exists = 0,
|
||||
'ALTER TABLE hospitals ADD INDEX idx_hospitals_is_active (is_active)',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt_add_idx_hospitals_is_active FROM @add_idx_hospitals_is_active_sql;
|
||||
EXECUTE stmt_add_idx_hospitals_is_active;
|
||||
DEALLOCATE PREPARE stmt_add_idx_hospitals_is_active;
|
||||
|
||||
-- +goose Down
|
||||
SET @idx_hospitals_is_active_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hospitals'
|
||||
AND index_name = 'idx_hospitals_is_active'
|
||||
);
|
||||
|
||||
SET @drop_idx_hospitals_is_active_sql := IF(
|
||||
@idx_hospitals_is_active_exists > 0,
|
||||
'ALTER TABLE hospitals DROP INDEX idx_hospitals_is_active',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt_drop_idx_hospitals_is_active FROM @drop_idx_hospitals_is_active_sql;
|
||||
EXECUTE stmt_drop_idx_hospitals_is_active;
|
||||
DEALLOCATE PREPARE stmt_drop_idx_hospitals_is_active;
|
||||
|
||||
SET @col_hospitals_is_active_exists := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hospitals'
|
||||
AND column_name = 'is_active'
|
||||
);
|
||||
|
||||
SET @drop_hospitals_is_active_sql := IF(
|
||||
@col_hospitals_is_active_exists > 0,
|
||||
'ALTER TABLE hospitals DROP COLUMN is_active',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt_drop_hospitals_is_active FROM @drop_hospitals_is_active_sql;
|
||||
EXECUTE stmt_drop_hospitals_is_active;
|
||||
DEALLOCATE PREPARE stmt_drop_hospitals_is_active;
|
||||
13
migrations/20260424_icaos_sortkey_is_active.sql
Normal file
13
migrations/20260424_icaos_sortkey_is_active.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE icaos
|
||||
ADD COLUMN sortkey INT NULL AFTER icao_code,
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER sortkey,
|
||||
ADD KEY idx_icaos_sortkey (sortkey),
|
||||
ADD KEY idx_icaos_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE icaos
|
||||
DROP KEY idx_icaos_sortkey,
|
||||
DROP KEY idx_icaos_is_active,
|
||||
DROP COLUMN sortkey,
|
||||
DROP COLUMN is_active;
|
||||
17
migrations/20260424_lands_opcs_is_active.sql
Normal file
17
migrations/20260424_lands_opcs_is_active.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE lands
|
||||
ADD COLUMN IF NOT EXISTS is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
ADD KEY idx_lands_is_active (is_active);
|
||||
|
||||
ALTER TABLE opcs
|
||||
ADD COLUMN IF NOT EXISTS is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
ADD KEY idx_opcs_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE lands
|
||||
DROP KEY idx_lands_is_active,
|
||||
DROP COLUMN IF EXISTS is_active;
|
||||
|
||||
ALTER TABLE opcs
|
||||
DROP KEY idx_opcs_is_active,
|
||||
DROP COLUMN IF EXISTS is_active;
|
||||
15
migrations/20260424_medicines_note_sortkey_is_active.sql
Normal file
15
migrations/20260424_medicines_note_sortkey_is_active.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE medicines
|
||||
ADD COLUMN note VARCHAR(255) NULL AFTER name,
|
||||
ADD COLUMN sortkey INT NULL AFTER name,
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER sortkey,
|
||||
ADD KEY idx_medicines_sortkey (sortkey),
|
||||
ADD KEY idx_medicines_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE medicines
|
||||
DROP KEY idx_medicines_sortkey,
|
||||
DROP KEY idx_medicines_is_active,
|
||||
DROP COLUMN sortkey,
|
||||
DROP COLUMN note,
|
||||
DROP COLUMN is_active;
|
||||
11
migrations/20260424_opcs_note_sortkey.sql
Normal file
11
migrations/20260424_opcs_note_sortkey.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE opcs
|
||||
ADD COLUMN note VARCHAR(255) NULL AFTER description,
|
||||
ADD COLUMN sortkey INT NULL AFTER name,
|
||||
ADD KEY idx_opcs_sortkey (sortkey);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE opcs
|
||||
DROP KEY idx_opcs_sortkey,
|
||||
DROP COLUMN sortkey,
|
||||
DROP COLUMN note;
|
||||
@@ -0,0 +1,43 @@
|
||||
-- +goose Up
|
||||
-- Remove deprecated places table and patient_data.place_id relation.
|
||||
|
||||
ALTER TABLE patient_data
|
||||
DROP FOREIGN KEY fk_patient_data_place;
|
||||
|
||||
ALTER TABLE patient_data
|
||||
DROP COLUMN place_id;
|
||||
|
||||
DROP TABLE IF EXISTS places;
|
||||
|
||||
-- +goose Down
|
||||
-- Recreate places table and patient_data.place_id column.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS places (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
state VARCHAR(255) NULL,
|
||||
post_code VARCHAR(32) NULL,
|
||||
location VARCHAR(255) NOT NULL,
|
||||
street VARCHAR(255) NULL,
|
||||
no VARCHAR(50) NULL,
|
||||
country_code VARCHAR(10) NULL,
|
||||
country_name VARCHAR(255) NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
|
||||
KEY idx_places_location (location),
|
||||
KEY idx_places_state (state),
|
||||
KEY idx_places_post_code (post_code),
|
||||
KEY idx_places_country_code (country_code),
|
||||
KEY idx_places_deleted_at (deleted_at)
|
||||
);
|
||||
|
||||
ALTER TABLE patient_data
|
||||
ADD COLUMN place_id BINARY(16) NULL AFTER co_insured,
|
||||
ADD KEY idx_patient_data_place_id (place_id),
|
||||
ADD CONSTRAINT fk_patient_data_place
|
||||
FOREIGN KEY (place_id) REFERENCES places (id)
|
||||
ON UPDATE CASCADE ON DELETE SET NULL;
|
||||
9
migrations/20260424_users_sortkey_for_contacts.sql
Normal file
9
migrations/20260424_users_sortkey_for_contacts.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE users
|
||||
ADD COLUMN sortkey INT NULL AFTER timezone,
|
||||
ADD KEY idx_users_sortkey (sortkey);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE users
|
||||
DROP KEY idx_users_sortkey,
|
||||
DROP COLUMN sortkey;
|
||||
15
migrations/20260424_vocations_note_sortkey_is_active.sql
Normal file
15
migrations/20260424_vocations_note_sortkey_is_active.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE vocations
|
||||
ADD COLUMN note VARCHAR(255) NULL AFTER description,
|
||||
ADD COLUMN sortkey INT NULL AFTER name,
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER sortkey,
|
||||
ADD KEY idx_vocations_sortkey (sortkey),
|
||||
ADD KEY idx_vocations_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE vocations
|
||||
DROP KEY idx_vocations_sortkey,
|
||||
DROP KEY idx_vocations_is_active,
|
||||
DROP COLUMN sortkey,
|
||||
DROP COLUMN note,
|
||||
DROP COLUMN is_active;
|
||||
13
migrations/20260425_federal_states_sortkey_is_active.sql
Normal file
13
migrations/20260425_federal_states_sortkey_is_active.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE federal_states
|
||||
ADD COLUMN IF NOT EXISTS sortkey INT NULL AFTER name,
|
||||
ADD COLUMN IF NOT EXISTS is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER note,
|
||||
ADD KEY idx_federal_states_sortkey (sortkey),
|
||||
ADD KEY idx_federal_states_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE federal_states
|
||||
DROP KEY idx_federal_states_sortkey,
|
||||
DROP KEY idx_federal_states_is_active,
|
||||
DROP COLUMN IF EXISTS sortkey,
|
||||
DROP COLUMN IF EXISTS is_active;
|
||||
9
migrations/20260425_hospitals_sortkey.sql
Normal file
9
migrations/20260425_hospitals_sortkey.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE hospitals
|
||||
ADD COLUMN sortkey INT NULL AFTER hospital_name,
|
||||
ADD KEY idx_hospitals_sortkey (sortkey);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE hospitals
|
||||
DROP KEY idx_hospitals_sortkey,
|
||||
DROP COLUMN sortkey;
|
||||
9
migrations/20260425_lands_sortkey.sql
Normal file
9
migrations/20260425_lands_sortkey.sql
Normal file
@@ -0,0 +1,9 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE lands
|
||||
ADD COLUMN sortkey INT NULL AFTER name,
|
||||
ADD KEY idx_lands_sortkey (sortkey);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE lands
|
||||
DROP KEY idx_lands_sortkey,
|
||||
DROP COLUMN sortkey;
|
||||
13
migrations/20260425_nationalities_sortkey_is_active.sql
Normal file
13
migrations/20260425_nationalities_sortkey_is_active.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE nationalities
|
||||
ADD COLUMN sortkey INT NULL AFTER name,
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER note,
|
||||
ADD KEY idx_nationalities_sortkey (sortkey),
|
||||
ADD KEY idx_nationalities_is_active (is_active);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE nationalities
|
||||
DROP KEY idx_nationalities_is_active,
|
||||
DROP KEY idx_nationalities_sortkey,
|
||||
DROP COLUMN is_active,
|
||||
DROP COLUMN sortkey;
|
||||
30
migrations/20260427_file_lifecycle_gc.sql
Normal file
30
migrations/20260427_file_lifecycle_gc.sql
Normal file
@@ -0,0 +1,30 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE file_files
|
||||
ADD COLUMN lifecycle_status VARCHAR(32) NOT NULL DEFAULT 'temp' AFTER status,
|
||||
ADD COLUMN attached_at DATETIME(6) NULL AFTER lifecycle_status,
|
||||
ADD COLUMN orphaned_at DATETIME(6) NULL AFTER attached_at,
|
||||
ADD COLUMN lifecycle_deleted_at DATETIME(6) NULL AFTER orphaned_at,
|
||||
ADD KEY idx_file_files_lifecycle_status_orphaned (lifecycle_status, orphaned_at);
|
||||
|
||||
UPDATE file_files
|
||||
SET lifecycle_status = CASE
|
||||
WHEN deleted_at IS NOT NULL THEN 'deleted'
|
||||
WHEN status = 'ready' AND name_slot = 'live' THEN 'active'
|
||||
ELSE 'temp'
|
||||
END,
|
||||
attached_at = CASE
|
||||
WHEN status = 'ready' AND name_slot = 'live' AND deleted_at IS NULL THEN COALESCE(attached_at, updated_at)
|
||||
ELSE attached_at
|
||||
END,
|
||||
lifecycle_deleted_at = CASE
|
||||
WHEN deleted_at IS NOT NULL THEN COALESCE(lifecycle_deleted_at, deleted_at)
|
||||
ELSE lifecycle_deleted_at
|
||||
END;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE file_files
|
||||
DROP KEY idx_file_files_lifecycle_status_orphaned,
|
||||
DROP COLUMN lifecycle_deleted_at,
|
||||
DROP COLUMN orphaned_at,
|
||||
DROP COLUMN attached_at,
|
||||
DROP COLUMN lifecycle_status;
|
||||
2
migrations/20260427_flights_mission_type_nullable.sql
Normal file
2
migrations/20260427_flights_mission_type_nullable.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE flights
|
||||
MODIFY COLUMN mission_type VARCHAR(32) NULL;
|
||||
31
migrations/20260429_rename_duty_roster_tables.sql
Normal file
31
migrations/20260429_rename_duty_roster_tables.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
SET @has_old_rosters := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hems_duty_rosters'
|
||||
);
|
||||
SET @has_new_rosters := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_rosters'
|
||||
);
|
||||
SET @sql_rosters := IF(@has_old_rosters = 1 AND @has_new_rosters = 0,
|
||||
'RENAME TABLE hems_duty_rosters TO duty_rosters',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_rosters FROM @sql_rosters;
|
||||
EXECUTE stmt_rosters;
|
||||
DEALLOCATE PREPARE stmt_rosters;
|
||||
|
||||
SET @has_old_crews := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hems_duty_roster_crews'
|
||||
);
|
||||
SET @has_new_crews := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_roster_crews'
|
||||
);
|
||||
SET @sql_crews := IF(@has_old_crews = 1 AND @has_new_crews = 0,
|
||||
'RENAME TABLE hems_duty_roster_crews TO duty_roster_crews',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_crews FROM @sql_crews;
|
||||
EXECUTE stmt_crews;
|
||||
DEALLOCATE PREPARE stmt_crews;
|
||||
135
migrations/20260430_normalize_duty_roster_legacy.sql
Normal file
135
migrations/20260430_normalize_duty_roster_legacy.sql
Normal file
@@ -0,0 +1,135 @@
|
||||
-- +goose Up
|
||||
-- Normalize legacy HEMS duty roster artifacts into neutral duty roster naming.
|
||||
|
||||
-- 1) Rename legacy tables when old name exists and new name does not.
|
||||
SET @has_old_rosters := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hems_duty_rosters'
|
||||
);
|
||||
SET @has_new_rosters := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_rosters'
|
||||
);
|
||||
SET @sql_rename_rosters := IF(@has_old_rosters = 1 AND @has_new_rosters = 0,
|
||||
'RENAME TABLE hems_duty_rosters TO duty_rosters',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_rename_rosters FROM @sql_rename_rosters;
|
||||
EXECUTE stmt_rename_rosters;
|
||||
DEALLOCATE PREPARE stmt_rename_rosters;
|
||||
|
||||
SET @has_old_crews := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'hems_duty_roster_crews'
|
||||
);
|
||||
SET @has_new_crews := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_roster_crews'
|
||||
);
|
||||
SET @sql_rename_crews := IF(@has_old_crews = 1 AND @has_new_crews = 0,
|
||||
'RENAME TABLE hems_duty_roster_crews TO duty_roster_crews',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_rename_crews FROM @sql_rename_crews;
|
||||
EXECUTE stmt_rename_crews;
|
||||
DEALLOCATE PREPARE stmt_rename_crews;
|
||||
|
||||
-- 2) Rename legacy header column.
|
||||
SET @has_duty_rosters := (
|
||||
SELECT COUNT(*) FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'duty_rosters'
|
||||
);
|
||||
SET @has_hems_base_id := (
|
||||
SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'duty_rosters'
|
||||
AND COLUMN_NAME = 'hems_base_id'
|
||||
);
|
||||
SET @has_base_id := (
|
||||
SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'duty_rosters'
|
||||
AND COLUMN_NAME = 'base_id'
|
||||
);
|
||||
SET @sql_rename_base_col := IF(@has_duty_rosters = 1 AND @has_hems_base_id = 1 AND @has_base_id = 0,
|
||||
'ALTER TABLE duty_rosters RENAME COLUMN hems_base_id TO base_id',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_rename_base_col FROM @sql_rename_base_col;
|
||||
EXECUTE stmt_rename_base_col;
|
||||
DEALLOCATE PREPARE stmt_rename_base_col;
|
||||
|
||||
-- 3) Ensure confirm_at exists on normalized crews table.
|
||||
SET @has_confirm_at_new_crews := (
|
||||
SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'duty_roster_crews'
|
||||
AND COLUMN_NAME = 'confirm_at'
|
||||
);
|
||||
SET @sql_add_confirm_at_new_crews := IF(@has_new_crews = 1 AND @has_confirm_at_new_crews = 0,
|
||||
'ALTER TABLE duty_roster_crews ADD COLUMN confirm_at DATETIME NULL AFTER email',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_confirm_at_new_crews FROM @sql_add_confirm_at_new_crews;
|
||||
EXECUTE stmt_add_confirm_at_new_crews;
|
||||
DEALLOCATE PREPARE stmt_add_confirm_at_new_crews;
|
||||
|
||||
-- 4) If legacy crew table still exists, keep it compatible too.
|
||||
SET @has_confirm_at_old_crews := (
|
||||
SELECT COUNT(*) FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'hems_duty_roster_crews'
|
||||
AND COLUMN_NAME = 'confirm_at'
|
||||
);
|
||||
SET @sql_add_confirm_at_old_crews := IF(@has_old_crews = 1 AND @has_confirm_at_old_crews = 0,
|
||||
'ALTER TABLE hems_duty_roster_crews ADD COLUMN confirm_at DATETIME NULL AFTER email',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_confirm_at_old_crews FROM @sql_add_confirm_at_old_crews;
|
||||
EXECUTE stmt_add_confirm_at_old_crews;
|
||||
DEALLOCATE PREPARE stmt_add_confirm_at_old_crews;
|
||||
|
||||
-- 5) Normalize legacy FK references to duty_rosters where needed.
|
||||
SET @fk_roster_crews_ref := (
|
||||
SELECT COALESCE(MAX(kcu.REFERENCED_TABLE_NAME), '')
|
||||
FROM information_schema.TABLE_CONSTRAINTS tc
|
||||
JOIN information_schema.KEY_COLUMN_USAGE kcu
|
||||
ON tc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA
|
||||
AND tc.TABLE_NAME = kcu.TABLE_NAME
|
||||
AND tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
|
||||
WHERE tc.CONSTRAINT_SCHEMA = DATABASE()
|
||||
AND tc.TABLE_NAME = 'roster_crews'
|
||||
AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
||||
AND tc.CONSTRAINT_NAME = 'fk_roster_crews_roster'
|
||||
);
|
||||
SET @sql_rewire_roster_crews_fk := IF(@has_new_rosters = 1 AND @fk_roster_crews_ref = 'hems_duty_rosters',
|
||||
'ALTER TABLE roster_crews DROP FOREIGN KEY fk_roster_crews_roster, ADD CONSTRAINT fk_roster_crews_roster FOREIGN KEY (roster_id) REFERENCES duty_rosters(id)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_rewire_roster_crews_fk FROM @sql_rewire_roster_crews_fk;
|
||||
EXECUTE stmt_rewire_roster_crews_fk;
|
||||
DEALLOCATE PREPARE stmt_rewire_roster_crews_fk;
|
||||
|
||||
SET @fk_other_persons_ref := (
|
||||
SELECT COALESCE(MAX(kcu.REFERENCED_TABLE_NAME), '')
|
||||
FROM information_schema.TABLE_CONSTRAINTS tc
|
||||
JOIN information_schema.KEY_COLUMN_USAGE kcu
|
||||
ON tc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA
|
||||
AND tc.TABLE_NAME = kcu.TABLE_NAME
|
||||
AND tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME
|
||||
WHERE tc.CONSTRAINT_SCHEMA = DATABASE()
|
||||
AND tc.TABLE_NAME = 'duty_roster_other_persons'
|
||||
AND tc.CONSTRAINT_TYPE = 'FOREIGN KEY'
|
||||
AND tc.CONSTRAINT_NAME = 'fk_duty_roster_other_persons_roster'
|
||||
);
|
||||
SET @sql_rewire_other_persons_fk := IF(@has_new_rosters = 1 AND @fk_other_persons_ref = 'hems_duty_rosters',
|
||||
'ALTER TABLE duty_roster_other_persons DROP FOREIGN KEY fk_duty_roster_other_persons_roster, ADD CONSTRAINT fk_duty_roster_other_persons_roster FOREIGN KEY (roster_id) REFERENCES duty_rosters(id)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_rewire_other_persons_fk FROM @sql_rewire_other_persons_fk;
|
||||
EXECUTE stmt_rewire_other_persons_fk;
|
||||
DEALLOCATE PREPARE stmt_rewire_other_persons_fk;
|
||||
|
||||
-- +goose Down
|
||||
-- Intentionally no-op: legacy normalization is one-way to keep schema stable.
|
||||
SELECT 1;
|
||||
2
migrations/20260430_users_sso_email.sql
Normal file
2
migrations/20260430_users_sso_email.sql
Normal file
@@ -0,0 +1,2 @@
|
||||
ALTER TABLE users
|
||||
ADD COLUMN sso_email VARCHAR(191) NULL AFTER email;
|
||||
116
migrations/20260502_cleanup_legacy_hems_bases.sql
Normal file
116
migrations/20260502_cleanup_legacy_hems_bases.sql
Normal file
@@ -0,0 +1,116 @@
|
||||
-- Cleanup legacy hems_bases table after consolidation to unified bases table.
|
||||
-- Safe/idempotent behavior:
|
||||
-- 1) If only hems_bases exists -> rename to bases.
|
||||
-- 2) If both tables exist -> copy missing rows from hems_bases into bases as HEMS category.
|
||||
-- 3) Drop hems_bases afterwards when possible.
|
||||
|
||||
SET @schema := DATABASE();
|
||||
|
||||
SET @has_hems_bases := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = 'hems_bases'
|
||||
);
|
||||
|
||||
SET @has_bases := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = 'bases'
|
||||
);
|
||||
|
||||
-- Ensure HEMS category exists when unified bases table is present.
|
||||
SET @has_base_categories := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = 'base_categories'
|
||||
);
|
||||
|
||||
SET @sql_seed_hems_category := IF(@has_bases = 1 AND @has_base_categories = 1,
|
||||
'INSERT INTO base_categories (id, `key`, name, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), ''hems'', ''HEMS Base'', UTC_TIMESTAMP(3), UTC_TIMESTAMP(3)
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM base_categories WHERE `key` = ''hems''
|
||||
)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql_seed_hems_category;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Case A: legacy only => rename directly.
|
||||
SET @sql_rename_hems_bases := IF(@has_hems_bases = 1 AND @has_bases = 0,
|
||||
'RENAME TABLE hems_bases TO bases',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql_rename_hems_bases;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Re-evaluate after possible rename.
|
||||
SET @has_hems_bases := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = 'hems_bases'
|
||||
);
|
||||
|
||||
SET @has_bases := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.TABLES
|
||||
WHERE TABLE_SCHEMA = @schema AND TABLE_NAME = 'bases'
|
||||
);
|
||||
|
||||
-- Case B: both exist => backfill rows from legacy table into unified table.
|
||||
SET @sql_backfill := IF(@has_hems_bases = 1 AND @has_bases = 1,
|
||||
'INSERT INTO bases (
|
||||
id, base, base_category_id, base_abbreviation, address,
|
||||
landline_number, mobile_number, email,
|
||||
position, sms_alert, checklist, leg_time,
|
||||
default_shift_time, utc, foto,
|
||||
dry, control_center, dul, visible,
|
||||
notes, is_active,
|
||||
created_by, updated_by, created_at, updated_at
|
||||
)
|
||||
SELECT
|
||||
hb.id,
|
||||
hb.base,
|
||||
bc.id,
|
||||
hb.base_abbreviation,
|
||||
hb.address,
|
||||
hb.landline_number,
|
||||
hb.mobile_number,
|
||||
hb.email,
|
||||
hb.position,
|
||||
hb.sms_alert,
|
||||
hb.checklist,
|
||||
hb.leg_time,
|
||||
hb.default_shift_time,
|
||||
hb.utc,
|
||||
hb.foto,
|
||||
hb.dry,
|
||||
hb.control_center,
|
||||
hb.dul,
|
||||
hb.visible,
|
||||
hb.notes,
|
||||
hb.is_active,
|
||||
hb.created_by,
|
||||
hb.updated_by,
|
||||
hb.created_at,
|
||||
hb.updated_at
|
||||
FROM hems_bases hb
|
||||
LEFT JOIN base_categories bc ON bc.`key` = ''hems''
|
||||
LEFT JOIN bases b ON b.id = hb.id
|
||||
WHERE b.id IS NULL',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql_backfill;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- Drop legacy table if still present.
|
||||
SET @sql_drop_hems_bases := IF(@has_hems_bases = 1,
|
||||
'DROP TABLE hems_bases',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql_drop_hems_bases;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
36
migrations/20260502_duty_roster_permissions_unification.sql
Normal file
36
migrations/20260502_duty_roster_permissions_unification.sql
Normal file
@@ -0,0 +1,36 @@
|
||||
-- Add canonical duty_roster permissions and map existing role grants from legacy hems_duty_roster keys.
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Create Duty Roster', 'duty_roster.create', 'Create duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.create');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Read Duty Roster', 'duty_roster.read', 'Read duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.read');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Update Duty Roster', 'duty_roster.update', 'Update duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.update');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Delete Duty Roster', 'duty_roster.delete', 'Delete duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.delete');
|
||||
|
||||
INSERT INTO role_permissions (id, role_id, permission_id, created_at, updated_at)
|
||||
SELECT
|
||||
UUID_TO_BIN(UUID(), true),
|
||||
rp.role_id,
|
||||
p_new.id,
|
||||
UTC_TIMESTAMP(),
|
||||
UTC_TIMESTAMP()
|
||||
FROM role_permissions rp
|
||||
JOIN permissions p_old ON p_old.id = rp.permission_id
|
||||
JOIN permissions p_new ON p_new.`key` = CONCAT('duty_roster.', SUBSTRING_INDEX(p_old.`key`, '.', -1))
|
||||
LEFT JOIN role_permissions rp_existing ON rp_existing.role_id = rp.role_id AND rp_existing.permission_id = p_new.id
|
||||
WHERE p_old.`key` IN (
|
||||
'hems_duty_roster.create',
|
||||
'hems_duty_roster.read',
|
||||
'hems_duty_roster.update',
|
||||
'hems_duty_roster.delete'
|
||||
)
|
||||
AND rp_existing.id IS NULL;
|
||||
@@ -0,0 +1,59 @@
|
||||
-- Purge legacy hems_duty_roster.* permissions.
|
||||
-- Safe flow:
|
||||
-- 1) Ensure canonical duty_roster.* permissions exist.
|
||||
-- 2) Grant canonical permission to any role that still has legacy permission.
|
||||
-- 3) Remove legacy role_permissions rows.
|
||||
-- 4) Remove legacy permission rows.
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Create Duty Roster', 'duty_roster.create', 'Create duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.create');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Read Duty Roster', 'duty_roster.read', 'Read duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.read');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Update Duty Roster', 'duty_roster.update', 'Update duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.update');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID(), true), 'Delete Duty Roster', 'duty_roster.delete', 'Delete duty roster', 0, UTC_TIMESTAMP(), UTC_TIMESTAMP()
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'duty_roster.delete');
|
||||
|
||||
INSERT INTO role_permissions (id, role_id, permission_id, created_at, updated_at)
|
||||
SELECT
|
||||
UUID_TO_BIN(UUID(), true),
|
||||
rp.role_id,
|
||||
p_new.id,
|
||||
UTC_TIMESTAMP(),
|
||||
UTC_TIMESTAMP()
|
||||
FROM role_permissions rp
|
||||
JOIN permissions p_old ON p_old.id = rp.permission_id
|
||||
JOIN permissions p_new ON p_new.`key` = CONCAT('duty_roster.', SUBSTRING_INDEX(p_old.`key`, '.', -1))
|
||||
LEFT JOIN role_permissions rp_existing ON rp_existing.role_id = rp.role_id AND rp_existing.permission_id = p_new.id
|
||||
WHERE p_old.`key` IN (
|
||||
'hems_duty_roster.create',
|
||||
'hems_duty_roster.read',
|
||||
'hems_duty_roster.update',
|
||||
'hems_duty_roster.delete'
|
||||
)
|
||||
AND rp_existing.id IS NULL;
|
||||
|
||||
DELETE rp
|
||||
FROM role_permissions rp
|
||||
JOIN permissions p ON p.id = rp.permission_id
|
||||
WHERE p.`key` IN (
|
||||
'hems_duty_roster.create',
|
||||
'hems_duty_roster.read',
|
||||
'hems_duty_roster.update',
|
||||
'hems_duty_roster.delete'
|
||||
);
|
||||
|
||||
DELETE FROM permissions
|
||||
WHERE `key` IN (
|
||||
'hems_duty_roster.create',
|
||||
'hems_duty_roster.read',
|
||||
'hems_duty_roster.update',
|
||||
'hems_duty_roster.delete'
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
-- Allow multiple duty roster headers on the same base and duty date.
|
||||
-- Previous schema enforced unique(base_id, duty_date) via idx_roster_base_date.
|
||||
|
||||
ALTER TABLE duty_rosters
|
||||
DROP INDEX idx_roster_base_date;
|
||||
|
||||
CREATE INDEX idx_roster_base_date
|
||||
ON duty_rosters (base_id, duty_date);
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
-- +goose Up
|
||||
SET @sql := (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1 FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'federal_states' AND COLUMN_NAME = 'description'
|
||||
),
|
||||
'ALTER TABLE federal_states DROP COLUMN description',
|
||||
'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 = 'federal_states' AND COLUMN_NAME = 'note'
|
||||
),
|
||||
'ALTER TABLE federal_states DROP COLUMN note',
|
||||
'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 = 'lands' AND COLUMN_NAME = 'description'
|
||||
),
|
||||
'ALTER TABLE lands DROP COLUMN description',
|
||||
'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 = 'lands' AND COLUMN_NAME = 'note'
|
||||
),
|
||||
'ALTER TABLE lands DROP COLUMN note',
|
||||
'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 = 'nationalities' AND COLUMN_NAME = 'description'
|
||||
),
|
||||
'ALTER TABLE nationalities DROP COLUMN description',
|
||||
'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 = 'nationalities' AND COLUMN_NAME = 'note'
|
||||
),
|
||||
'ALTER TABLE nationalities DROP COLUMN note',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
|
||||
-- +goose Down
|
||||
SET @sql := (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1 FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'federal_states' AND COLUMN_NAME = 'description'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE federal_states ADD COLUMN description VARCHAR(256) NULL AFTER sortkey'
|
||||
)
|
||||
);
|
||||
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 = 'federal_states' AND COLUMN_NAME = 'note'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE federal_states ADD COLUMN note TEXT NULL AFTER description'
|
||||
)
|
||||
);
|
||||
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 = 'lands' AND COLUMN_NAME = 'description'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE lands ADD COLUMN description VARCHAR(256) NULL AFTER sortkey'
|
||||
)
|
||||
);
|
||||
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 = 'lands' AND COLUMN_NAME = 'note'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE lands ADD COLUMN note TEXT NULL AFTER description'
|
||||
)
|
||||
);
|
||||
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 = 'nationalities' AND COLUMN_NAME = 'description'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE nationalities ADD COLUMN description VARCHAR(256) NULL AFTER sortkey'
|
||||
)
|
||||
);
|
||||
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 = 'nationalities' AND COLUMN_NAME = 'note'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE nationalities ADD COLUMN note TEXT NULL AFTER description'
|
||||
)
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
265
migrations/20260505_seed_lands_from_legacy_country.sql
Normal file
265
migrations/20260505_seed_lands_from_legacy_country.sql
Normal file
@@ -0,0 +1,265 @@
|
||||
-- +goose Up
|
||||
INSERT INTO lands (id, name, land_iso_code, sortkey, is_active, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID()), src.name, src.iso_code, src.sortkey, 1, NOW(3), NOW(3)
|
||||
FROM (
|
||||
SELECT 'AC' AS iso_code, 'Ascension' AS name, 1 AS sortkey
|
||||
UNION ALL SELECT 'AD', 'Andorra', 2
|
||||
UNION ALL SELECT 'AE', 'Vereinigte Arabische Emirate', 3
|
||||
UNION ALL SELECT 'AF', 'Afghanistan', 4
|
||||
UNION ALL SELECT 'AG', 'Antigua und Barbuda', 5
|
||||
UNION ALL SELECT 'AI', 'Anguilla', 6
|
||||
UNION ALL SELECT 'AL', 'Albanien', 7
|
||||
UNION ALL SELECT 'AM', 'Armenien', 8
|
||||
UNION ALL SELECT 'AN', 'Niederländische Antillen', 9
|
||||
UNION ALL SELECT 'AO', 'Angola', 10
|
||||
UNION ALL SELECT 'AQ', 'Antarktis', 11
|
||||
UNION ALL SELECT 'AR', 'Argentinien', 12
|
||||
UNION ALL SELECT 'AS', 'Amerikanisch Samoa', 13
|
||||
UNION ALL SELECT 'AT', 'Österreich', 14
|
||||
UNION ALL SELECT 'AU', 'Australien', 15
|
||||
UNION ALL SELECT 'AW', 'Aruba', 16
|
||||
UNION ALL SELECT 'AX', 'Aland', 17
|
||||
UNION ALL SELECT 'AZ', 'Aserbaidschan', 18
|
||||
UNION ALL SELECT 'BA', 'Bosnien-Herzegowina', 19
|
||||
UNION ALL SELECT 'BB', 'Barbados', 20
|
||||
UNION ALL SELECT 'BD', 'Bangladesch', 21
|
||||
UNION ALL SELECT 'BE', 'Belgien', 22
|
||||
UNION ALL SELECT 'BF', 'Burkina Faso', 23
|
||||
UNION ALL SELECT 'BG', 'Bulgarien', 24
|
||||
UNION ALL SELECT 'BH', 'Bahrain', 25
|
||||
UNION ALL SELECT 'BJ', 'Benin', 26
|
||||
UNION ALL SELECT 'BL', 'Burundi', 27
|
||||
UNION ALL SELECT 'BM', 'Bermuda', 28
|
||||
UNION ALL SELECT 'BN', 'Brunei Darussalam', 29
|
||||
UNION ALL SELECT 'BO', 'Bolivien', 30
|
||||
UNION ALL SELECT 'BR', 'Brasilien', 31
|
||||
UNION ALL SELECT 'BS', 'Bahamas', 32
|
||||
UNION ALL SELECT 'BT', 'Bhutan', 33
|
||||
UNION ALL SELECT 'BV', 'Bouvetinseln', 34
|
||||
UNION ALL SELECT 'BW', 'Botsuana', 35
|
||||
UNION ALL SELECT 'BY', 'Belarus', 36
|
||||
UNION ALL SELECT 'BZ', 'Belize ', 37
|
||||
UNION ALL SELECT 'CA', 'Kanada', 38
|
||||
UNION ALL SELECT 'CC', 'Kokosinseln', 39
|
||||
UNION ALL SELECT 'CD', 'Demokratische Republik Kongo', 40
|
||||
UNION ALL SELECT 'CF', 'Zentralafrikanische Republik', 41
|
||||
UNION ALL SELECT 'CG', 'Kongo', 42
|
||||
UNION ALL SELECT 'CH', 'Schweiz', 43
|
||||
UNION ALL SELECT 'CI', 'Elfenbeinküste', 44
|
||||
UNION ALL SELECT 'CK', 'Cookinseln', 45
|
||||
UNION ALL SELECT 'CL', 'Chile', 46
|
||||
UNION ALL SELECT 'CM', 'Kamerun', 47
|
||||
UNION ALL SELECT 'CO', 'Kolumbien', 48
|
||||
UNION ALL SELECT 'CR', 'Costa Rica', 49
|
||||
UNION ALL SELECT 'CU', 'Kuba', 50
|
||||
UNION ALL SELECT 'CV', 'Kap Verde', 51
|
||||
UNION ALL SELECT 'CX', 'Weihnachtsinsel', 52
|
||||
UNION ALL SELECT 'CY', 'Zypern', 53
|
||||
UNION ALL SELECT 'CZ', 'Tschechische Republik', 54
|
||||
UNION ALL SELECT 'DB', 'Dubai', 55
|
||||
UNION ALL SELECT 'DE', 'Deutschland', 56
|
||||
UNION ALL SELECT 'DJ', 'Dschibuti', 57
|
||||
UNION ALL SELECT 'DK', 'Dänemark', 58
|
||||
UNION ALL SELECT 'DM', 'Dominica', 59
|
||||
UNION ALL SELECT 'DO', 'Dominikanische Republik', 60
|
||||
UNION ALL SELECT 'DZ', 'Algerien', 61
|
||||
UNION ALL SELECT 'EC', 'Ecuador', 62
|
||||
UNION ALL SELECT 'EE', 'Estland', 63
|
||||
UNION ALL SELECT 'EG', 'Ägypten', 64
|
||||
UNION ALL SELECT 'EH', 'Western Sahara', 65
|
||||
UNION ALL SELECT 'ER', 'Eritrea', 66
|
||||
UNION ALL SELECT 'ES', 'Spanien', 67
|
||||
UNION ALL SELECT 'ET', 'Äthiopien', 68
|
||||
UNION ALL SELECT 'FI', 'Finnland', 69
|
||||
UNION ALL SELECT 'FJ', 'Fidschi', 70
|
||||
UNION ALL SELECT 'FK', 'Falklandinseln', 71
|
||||
UNION ALL SELECT 'FM', 'Mikronesien', 72
|
||||
UNION ALL SELECT 'FO', 'Färöer', 73
|
||||
UNION ALL SELECT 'FR', 'Frankreich', 74
|
||||
UNION ALL SELECT 'GA', 'Gabun', 75
|
||||
UNION ALL SELECT 'GB', 'Vereinigtes Königreich', 76
|
||||
UNION ALL SELECT 'GD', 'Grenada', 77
|
||||
UNION ALL SELECT 'GE', 'Georgien', 78
|
||||
UNION ALL SELECT 'GF', 'Französische Guyana', 79
|
||||
UNION ALL SELECT 'GG', 'Guernsey', 80
|
||||
UNION ALL SELECT 'GH', 'Ghana', 81
|
||||
UNION ALL SELECT 'GI', 'Gibraltar', 82
|
||||
UNION ALL SELECT 'GL', 'Grönland', 83
|
||||
UNION ALL SELECT 'GM', 'Gambia', 84
|
||||
UNION ALL SELECT 'GN', 'Guinea', 85
|
||||
UNION ALL SELECT 'GP', 'Guadeloupe', 86
|
||||
UNION ALL SELECT 'GQ', 'Äquatorialguinea', 87
|
||||
UNION ALL SELECT 'GR', 'Griechenland', 88
|
||||
UNION ALL SELECT 'GS', 'South Georgia and the South Sandwich Islands', 89
|
||||
UNION ALL SELECT 'GT', 'Guatemala', 90
|
||||
UNION ALL SELECT 'GU', 'Guam', 91
|
||||
UNION ALL SELECT 'GW', 'Guinea-Bissau', 92
|
||||
UNION ALL SELECT 'GY', 'Guyana', 93
|
||||
UNION ALL SELECT 'HK', 'Hong Kong', 94
|
||||
UNION ALL SELECT 'HM', 'Heard Island and McDonald Islands', 95
|
||||
UNION ALL SELECT 'HN', 'Honduras', 96
|
||||
UNION ALL SELECT 'HR', 'Kroatien', 97
|
||||
UNION ALL SELECT 'HT', 'Haiti', 98
|
||||
UNION ALL SELECT 'HU', 'Ungarn', 99
|
||||
UNION ALL SELECT 'ID', 'Indonesien', 100
|
||||
UNION ALL SELECT 'IE', 'Irland', 101
|
||||
UNION ALL SELECT 'IL', 'Israel', 102
|
||||
UNION ALL SELECT 'IM', 'Isle of Man', 103
|
||||
UNION ALL SELECT 'IN', 'Indien', 104
|
||||
UNION ALL SELECT 'IO', 'Br.Territ./Ind.Ozean', 105
|
||||
UNION ALL SELECT 'IQ', 'Irak', 106
|
||||
UNION ALL SELECT 'IR', 'Iran', 107
|
||||
UNION ALL SELECT 'IS', 'Island', 108
|
||||
UNION ALL SELECT 'IT', 'Italien', 109
|
||||
UNION ALL SELECT 'JE', 'Jersey', 110
|
||||
UNION ALL SELECT 'JM', 'Jamaika', 111
|
||||
UNION ALL SELECT 'JO', 'Jordanien', 112
|
||||
UNION ALL SELECT 'JP', 'Japan', 113
|
||||
UNION ALL SELECT 'KE', 'Kenien', 114
|
||||
UNION ALL SELECT 'KG', 'Kirgisistan', 115
|
||||
UNION ALL SELECT 'KH', 'Kambodscha', 116
|
||||
UNION ALL SELECT 'KI', 'Kiribati', 117
|
||||
UNION ALL SELECT 'KM', 'Komoren', 118
|
||||
UNION ALL SELECT 'KN', 'St. Kittis und Nevis', 119
|
||||
UNION ALL SELECT 'KO', 'Kosovo', 120
|
||||
UNION ALL SELECT 'KP', 'Korea, Demo. VR', 121
|
||||
UNION ALL SELECT 'KR', 'Korea', 122
|
||||
UNION ALL SELECT 'KW', 'Kuwait', 123
|
||||
UNION ALL SELECT 'KY', 'Kaimaninseln', 124
|
||||
UNION ALL SELECT 'KZ', 'Kasachstan', 125
|
||||
UNION ALL SELECT 'LA', 'Laos', 126
|
||||
UNION ALL SELECT 'LB', 'Libanon', 127
|
||||
UNION ALL SELECT 'LC', 'Sankt Lucia', 128
|
||||
UNION ALL SELECT 'LI', 'Liechtenstein', 129
|
||||
UNION ALL SELECT 'LK', 'Sri Lanka', 130
|
||||
UNION ALL SELECT 'LR', 'Liberia', 131
|
||||
UNION ALL SELECT 'LS', 'Lesotho', 132
|
||||
UNION ALL SELECT 'LT', 'Litauen', 133
|
||||
UNION ALL SELECT 'LU', 'Luxemburg', 134
|
||||
UNION ALL SELECT 'LV', 'Lettland', 135
|
||||
UNION ALL SELECT 'LY', 'Lybien', 136
|
||||
UNION ALL SELECT 'MA', 'Marokko', 137
|
||||
UNION ALL SELECT 'MC', 'Monaco', 138
|
||||
UNION ALL SELECT 'MD', 'Moldova', 139
|
||||
UNION ALL SELECT 'ME', 'Montenegro', 140
|
||||
UNION ALL SELECT 'MG', 'Madagaskar', 141
|
||||
UNION ALL SELECT 'MH', 'Marshallinseln', 142
|
||||
UNION ALL SELECT 'MK', 'Mazedonien', 143
|
||||
UNION ALL SELECT 'ML', 'Mali', 144
|
||||
UNION ALL SELECT 'MM', 'Myanmar', 145
|
||||
UNION ALL SELECT 'MN', 'Mongolei', 146
|
||||
UNION ALL SELECT 'MO', 'Macau', 147
|
||||
UNION ALL SELECT 'MP', 'Marianen', 148
|
||||
UNION ALL SELECT 'MQ', 'Martinique', 149
|
||||
UNION ALL SELECT 'MR', 'Mauretanien', 150
|
||||
UNION ALL SELECT 'MS', 'Montserrat', 151
|
||||
UNION ALL SELECT 'MT', 'Malta', 152
|
||||
UNION ALL SELECT 'MU', 'Mauritius', 153
|
||||
UNION ALL SELECT 'MV', 'Malediven', 154
|
||||
UNION ALL SELECT 'MW', 'Malawi', 155
|
||||
UNION ALL SELECT 'MX', 'Mexiko', 156
|
||||
UNION ALL SELECT 'MY', 'Malaysia', 157
|
||||
UNION ALL SELECT 'MZ', 'Mosambik', 158
|
||||
UNION ALL SELECT 'NA', 'Namibia', 159
|
||||
UNION ALL SELECT 'NC', 'Neukaledonien', 160
|
||||
UNION ALL SELECT 'NE', 'Niger', 161
|
||||
UNION ALL SELECT 'NF', 'Norfolkins', 162
|
||||
UNION ALL SELECT 'NG', 'Nigeria', 163
|
||||
UNION ALL SELECT 'NI', 'Nicaragua', 164
|
||||
UNION ALL SELECT 'NL', 'Niederlande', 165
|
||||
UNION ALL SELECT 'NO', 'Norwegen', 166
|
||||
UNION ALL SELECT 'NP', 'Nepal', 167
|
||||
UNION ALL SELECT 'NR', 'Nauru', 168
|
||||
UNION ALL SELECT 'NU', 'Niue', 169
|
||||
UNION ALL SELECT 'NZ', 'Neuseeland', 170
|
||||
UNION ALL SELECT 'O', 'unbekannt', 171
|
||||
UNION ALL SELECT 'OM', 'Oman', 172
|
||||
UNION ALL SELECT 'PA', 'Panama', 173
|
||||
UNION ALL SELECT 'PE', 'Peru', 174
|
||||
UNION ALL SELECT 'PF', 'Französchisch Polynesien', 175
|
||||
UNION ALL SELECT 'PG', 'Papua Neuguinea', 176
|
||||
UNION ALL SELECT 'PH', 'Philippinen', 177
|
||||
UNION ALL SELECT 'PK', 'Pakistan', 178
|
||||
UNION ALL SELECT 'PL', 'Polen', 179
|
||||
UNION ALL SELECT 'PM', 'St Pierre und Miquelon', 180
|
||||
UNION ALL SELECT 'PN', 'Pitkern', 181
|
||||
UNION ALL SELECT 'PR', 'Puerto Rico', 182
|
||||
UNION ALL SELECT 'PS', 'Palestina', 183
|
||||
UNION ALL SELECT 'PT', 'Portugal', 184
|
||||
UNION ALL SELECT 'PW', 'Palau', 185
|
||||
UNION ALL SELECT 'PY', 'Paraguay', 186
|
||||
UNION ALL SELECT 'Q', 'Katar', 187
|
||||
UNION ALL SELECT 'RE', 'Reunion', 188
|
||||
UNION ALL SELECT 'RM', 'San Marino', 189
|
||||
UNION ALL SELECT 'RO', 'Rumänien', 190
|
||||
UNION ALL SELECT 'RS', 'Serbien', 191
|
||||
UNION ALL SELECT 'RU', 'Russische Föderation', 192
|
||||
UNION ALL SELECT 'RW', 'Ruanda', 193
|
||||
UNION ALL SELECT 'SA', 'Saudi Arabien', 194
|
||||
UNION ALL SELECT 'SB', 'Salomonen', 195
|
||||
UNION ALL SELECT 'SC', 'Seychellen', 196
|
||||
UNION ALL SELECT 'SD', 'Sudan', 197
|
||||
UNION ALL SELECT 'SE', 'Schweden', 198
|
||||
UNION ALL SELECT 'SG', 'Singapur', 199
|
||||
UNION ALL SELECT 'SH', 'Sankt Helena', 200
|
||||
UNION ALL SELECT 'SI', 'Slowenien', 201
|
||||
UNION ALL SELECT 'SJ', 'Svalbard', 202
|
||||
UNION ALL SELECT 'SK', 'Slowakei', 203
|
||||
UNION ALL SELECT 'SL', 'Sierra Leone', 204
|
||||
UNION ALL SELECT 'SN', 'Senegal', 205
|
||||
UNION ALL SELECT 'SO', 'Somalia', 206
|
||||
UNION ALL SELECT 'SR', 'Suriname', 207
|
||||
UNION ALL SELECT 'ST', 'Sao Tome und Pricipe', 208
|
||||
UNION ALL SELECT 'SV', 'El Salvador', 209
|
||||
UNION ALL SELECT 'SY', 'Syrien', 210
|
||||
UNION ALL SELECT 'SZ', 'Swasiland', 211
|
||||
UNION ALL SELECT 'TA', 'Tristan da Cunha', 212
|
||||
UNION ALL SELECT 'TC', 'Turks und Caicosinseln', 213
|
||||
UNION ALL SELECT 'TD', 'Tschad', 214
|
||||
UNION ALL SELECT 'TF', 'French Southern and Antarctic Lands', 215
|
||||
UNION ALL SELECT 'TG', 'Togo', 216
|
||||
UNION ALL SELECT 'TH', 'Thailand', 217
|
||||
UNION ALL SELECT 'TI', 'Timor Leste', 218
|
||||
UNION ALL SELECT 'TJ', 'Tadschikistan', 219
|
||||
UNION ALL SELECT 'TK', 'Tokelau', 220
|
||||
UNION ALL SELECT 'TL', 'Ost-Timor', 221
|
||||
UNION ALL SELECT 'TM', 'Turkmenistan', 222
|
||||
UNION ALL SELECT 'TN', 'Tunesien', 223
|
||||
UNION ALL SELECT 'TO', 'Tonga', 224
|
||||
UNION ALL SELECT 'TP', 'Osttimor', 225
|
||||
UNION ALL SELECT 'TR', 'Türkei', 226
|
||||
UNION ALL SELECT 'TT', 'Trinidad und Tobago', 227
|
||||
UNION ALL SELECT 'TV', 'Tuvalu', 228
|
||||
UNION ALL SELECT 'TW', 'Taiwan', 229
|
||||
UNION ALL SELECT 'TZ', 'Tansania', 230
|
||||
UNION ALL SELECT 'UA', 'Ukraine', 231
|
||||
UNION ALL SELECT 'UG', 'Uganda', 232
|
||||
UNION ALL SELECT 'UK', 'Großbritannien', 233
|
||||
UNION ALL SELECT 'UM', 'Baker Island', 234
|
||||
UNION ALL SELECT 'US', 'Vereinigte Staaten (USA)', 235
|
||||
UNION ALL SELECT 'UY', 'Uruguay', 236
|
||||
UNION ALL SELECT 'UZ', 'Usbekistan', 237
|
||||
UNION ALL SELECT 'V', 'Vatikanstadt', 238
|
||||
UNION ALL SELECT 'VC', 'St. Vincent udn Grenadinen', 239
|
||||
UNION ALL SELECT 'VE', 'Venezuela', 240
|
||||
UNION ALL SELECT 'VG', 'Jungferninseln', 241
|
||||
UNION ALL SELECT 'VI', 'US Jungferninseln', 242
|
||||
UNION ALL SELECT 'VN', 'Vietnam', 243
|
||||
UNION ALL SELECT 'VR', 'China', 244
|
||||
UNION ALL SELECT 'VU', 'Vanuatu', 245
|
||||
UNION ALL SELECT 'WF', 'Wallis und Futuna', 246
|
||||
UNION ALL SELECT 'WS', 'Samoa', 247
|
||||
UNION ALL SELECT 'X', 'Staatenlos', 248
|
||||
UNION ALL SELECT 'YE', 'Jemen', 249
|
||||
UNION ALL SELECT 'YT', 'Mayotte', 250
|
||||
UNION ALL SELECT 'YU', 'ehem. Jugoslawien', 251
|
||||
UNION ALL SELECT 'ZA', 'Südafrika', 252
|
||||
UNION ALL SELECT 'ZM', 'Sambia', 253
|
||||
UNION ALL SELECT 'ZW', 'Simbabwe', 254
|
||||
) AS src
|
||||
LEFT JOIN lands l ON l.land_iso_code = src.iso_code AND l.deleted_at IS NULL
|
||||
WHERE l.id IS NULL;
|
||||
|
||||
-- +goose Down
|
||||
-- Intentionally no-op to avoid deleting existing production reference data.
|
||||
SELECT 1;
|
||||
23
migrations/20260505_user_microsoft_oauth_tokens.sql
Normal file
23
migrations/20260505_user_microsoft_oauth_tokens.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
CREATE TABLE IF NOT EXISTS user_microsoft_oauth_tokens (
|
||||
id BINARY(16) NOT NULL,
|
||||
user_id BINARY(16) NOT NULL,
|
||||
provider VARCHAR(32) NOT NULL,
|
||||
tenant_id VARCHAR(128) NOT NULL,
|
||||
microsoft_object_id VARCHAR(191) NOT NULL,
|
||||
microsoft_subject VARCHAR(191) NOT NULL,
|
||||
refresh_token_encrypted BLOB NOT NULL,
|
||||
access_token_encrypted BLOB NULL,
|
||||
id_token_encrypted BLOB NULL,
|
||||
scope TEXT NULL,
|
||||
token_type VARCHAR(32) NULL,
|
||||
access_token_expires_at DATETIME(3) NULL,
|
||||
refresh_token_rotated_at DATETIME(3) NULL,
|
||||
created_at DATETIME(3) NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(3) NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY ux_user_ms_oauth_user_provider (user_id, provider),
|
||||
KEY idx_user_ms_oauth_tenant_id (tenant_id),
|
||||
CONSTRAINT fk_user_ms_oauth_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
22
migrations/20260507_base_contact_roles.sql
Normal file
22
migrations/20260507_base_contact_roles.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS base_contact_roles (
|
||||
id BINARY(16) NOT NULL,
|
||||
base_id BINARY(16) NOT NULL,
|
||||
contact_id BINARY(16) NOT NULL,
|
||||
role_code VARCHAR(64) NOT NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_base_contact_roles_base_contact_role (base_id, contact_id, role_code),
|
||||
KEY idx_base_contact_roles_base_id (base_id),
|
||||
KEY idx_base_contact_roles_contact_id (contact_id),
|
||||
KEY idx_base_contact_roles_role_code (role_code),
|
||||
CONSTRAINT fk_base_contact_roles_base FOREIGN KEY (base_id) REFERENCES bases(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_base_contact_roles_contact FOREIGN KEY (contact_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT chk_base_contact_roles_role_code CHECK (role_code IN ('responsible_flight_rescuer', 'chief_physician_in_charge'))
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS base_contact_roles;
|
||||
8
migrations/20260508_helicopter_files_position.sql
Normal file
8
migrations/20260508_helicopter_files_position.sql
Normal file
@@ -0,0 +1,8 @@
|
||||
ALTER TABLE helicopter_files
|
||||
ADD COLUMN position INT NOT NULL DEFAULT 1 AFTER section,
|
||||
ADD KEY idx_helicopter_files_position (position);
|
||||
|
||||
UPDATE helicopter_files
|
||||
SET position = 1
|
||||
WHERE position IS NULL OR position <= 0;
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
-- Drop legacy completion metadata columns from flight_inspections.
|
||||
-- Completion is derived from stage tables (before/prep/after) instead.
|
||||
|
||||
SET @schema_name := DATABASE();
|
||||
|
||||
-- before_flight_completed_at
|
||||
SELECT COUNT(*) INTO @has_before_completed_at
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'before_flight_completed_at';
|
||||
SET @drop_before_completed_at_sql := IF(
|
||||
@has_before_completed_at > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN before_flight_completed_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_before_completed_at FROM @drop_before_completed_at_sql;
|
||||
EXECUTE stmt_drop_before_completed_at;
|
||||
DEALLOCATE PREPARE stmt_drop_before_completed_at;
|
||||
|
||||
-- before_flight_completed_by
|
||||
SELECT COUNT(*) INTO @has_before_completed_by
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'before_flight_completed_by';
|
||||
SET @drop_before_completed_by_sql := IF(
|
||||
@has_before_completed_by > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN before_flight_completed_by',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_before_completed_by FROM @drop_before_completed_by_sql;
|
||||
EXECUTE stmt_drop_before_completed_by;
|
||||
DEALLOCATE PREPARE stmt_drop_before_completed_by;
|
||||
|
||||
-- flight_prep_completed_at
|
||||
SELECT COUNT(*) INTO @has_prep_completed_at
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'flight_prep_completed_at';
|
||||
SET @drop_prep_completed_at_sql := IF(
|
||||
@has_prep_completed_at > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN flight_prep_completed_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_prep_completed_at FROM @drop_prep_completed_at_sql;
|
||||
EXECUTE stmt_drop_prep_completed_at;
|
||||
DEALLOCATE PREPARE stmt_drop_prep_completed_at;
|
||||
|
||||
-- flight_prep_completed_by
|
||||
SELECT COUNT(*) INTO @has_prep_completed_by
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'flight_prep_completed_by';
|
||||
SET @drop_prep_completed_by_sql := IF(
|
||||
@has_prep_completed_by > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN flight_prep_completed_by',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_prep_completed_by FROM @drop_prep_completed_by_sql;
|
||||
EXECUTE stmt_drop_prep_completed_by;
|
||||
DEALLOCATE PREPARE stmt_drop_prep_completed_by;
|
||||
|
||||
-- after_flight_completed_at
|
||||
SELECT COUNT(*) INTO @has_after_completed_at
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'after_flight_completed_at';
|
||||
SET @drop_after_completed_at_sql := IF(
|
||||
@has_after_completed_at > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN after_flight_completed_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_after_completed_at FROM @drop_after_completed_at_sql;
|
||||
EXECUTE stmt_drop_after_completed_at;
|
||||
DEALLOCATE PREPARE stmt_drop_after_completed_at;
|
||||
|
||||
-- after_flight_completed_by
|
||||
SELECT COUNT(*) INTO @has_after_completed_by
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'after_flight_completed_by';
|
||||
SET @drop_after_completed_by_sql := IF(
|
||||
@has_after_completed_by > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN after_flight_completed_by',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_after_completed_by FROM @drop_after_completed_by_sql;
|
||||
EXECUTE stmt_drop_after_completed_by;
|
||||
DEALLOCATE PREPARE stmt_drop_after_completed_by;
|
||||
|
||||
-- final_completed_at
|
||||
SELECT COUNT(*) INTO @has_final_completed_at
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'final_completed_at';
|
||||
SET @drop_final_completed_at_sql := IF(
|
||||
@has_final_completed_at > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN final_completed_at',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_final_completed_at FROM @drop_final_completed_at_sql;
|
||||
EXECUTE stmt_drop_final_completed_at;
|
||||
DEALLOCATE PREPARE stmt_drop_final_completed_at;
|
||||
|
||||
-- final_completed_by
|
||||
SELECT COUNT(*) INTO @has_final_completed_by
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'flight_inspections'
|
||||
AND COLUMN_NAME = 'final_completed_by';
|
||||
SET @drop_final_completed_by_sql := IF(
|
||||
@has_final_completed_by > 0,
|
||||
'ALTER TABLE flight_inspections DROP COLUMN final_completed_by',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_final_completed_by FROM @drop_final_completed_by_sql;
|
||||
EXECUTE stmt_drop_final_completed_by;
|
||||
DEALLOCATE PREPARE stmt_drop_final_completed_by;
|
||||
119
migrations/20260516_drop_nationality_module.sql
Normal file
119
migrations/20260516_drop_nationality_module.sql
Normal file
@@ -0,0 +1,119 @@
|
||||
-- +goose Up
|
||||
-- Remove deprecated nationality module storage.
|
||||
|
||||
SET @drop_fk_nationality := (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'patient_data'
|
||||
AND COLUMN_NAME = 'nationality_id'
|
||||
AND REFERENCED_TABLE_NAME IS NOT NULL
|
||||
),
|
||||
(
|
||||
SELECT CONCAT('ALTER TABLE patient_data DROP FOREIGN KEY ', CONSTRAINT_NAME)
|
||||
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'patient_data'
|
||||
AND COLUMN_NAME = 'nationality_id'
|
||||
AND REFERENCED_TABLE_NAME IS NOT NULL
|
||||
LIMIT 1
|
||||
),
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt_drop_fk_nationality FROM @drop_fk_nationality;
|
||||
EXECUTE stmt_drop_fk_nationality;
|
||||
DEALLOCATE PREPARE stmt_drop_fk_nationality;
|
||||
|
||||
SET @drop_idx_nationality := (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'patient_data'
|
||||
AND INDEX_NAME = 'idx_patient_data_nationality_id'
|
||||
),
|
||||
'ALTER TABLE patient_data DROP INDEX idx_patient_data_nationality_id',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt_drop_idx_nationality FROM @drop_idx_nationality;
|
||||
EXECUTE stmt_drop_idx_nationality;
|
||||
DEALLOCATE PREPARE stmt_drop_idx_nationality;
|
||||
|
||||
SET @drop_col_nationality := (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'patient_data'
|
||||
AND COLUMN_NAME = 'nationality_id'
|
||||
),
|
||||
'ALTER TABLE patient_data DROP COLUMN nationality_id',
|
||||
'SELECT 1'
|
||||
)
|
||||
);
|
||||
PREPARE stmt_drop_col_nationality FROM @drop_col_nationality;
|
||||
EXECUTE stmt_drop_col_nationality;
|
||||
DEALLOCATE PREPARE stmt_drop_col_nationality;
|
||||
|
||||
DROP TABLE IF EXISTS nationalities;
|
||||
|
||||
-- +goose Down
|
||||
-- Recreate minimal nationality storage.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS nationalities (
|
||||
id BINARY(16) NOT NULL PRIMARY KEY,
|
||||
land_id BINARY(16) NULL,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
sortkey INT NULL,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
KEY idx_nationalities_land_id (land_id),
|
||||
KEY idx_nationalities_sortkey (sortkey),
|
||||
KEY idx_nationalities_is_active (is_active),
|
||||
KEY idx_nationalities_deleted_at (deleted_at)
|
||||
);
|
||||
|
||||
SET @add_col_nationality := (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'patient_data'
|
||||
AND COLUMN_NAME = 'nationality_id'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE patient_data ADD COLUMN nationality_id BINARY(16) NULL AFTER co_insured'
|
||||
)
|
||||
);
|
||||
PREPARE stmt_add_col_nationality FROM @add_col_nationality;
|
||||
EXECUTE stmt_add_col_nationality;
|
||||
DEALLOCATE PREPARE stmt_add_col_nationality;
|
||||
|
||||
SET @add_idx_nationality := (
|
||||
SELECT IF(
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM INFORMATION_SCHEMA.STATISTICS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = 'patient_data'
|
||||
AND INDEX_NAME = 'idx_patient_data_nationality_id'
|
||||
),
|
||||
'SELECT 1',
|
||||
'ALTER TABLE patient_data ADD KEY idx_patient_data_nationality_id (nationality_id)'
|
||||
)
|
||||
);
|
||||
PREPARE stmt_add_idx_nationality FROM @add_idx_nationality;
|
||||
EXECUTE stmt_add_idx_nationality;
|
||||
DEALLOCATE PREPARE stmt_add_idx_nationality;
|
||||
@@ -0,0 +1,17 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE icaos
|
||||
ADD COLUMN land_id BINARY(16) NULL AFTER federal_state_id,
|
||||
ADD KEY idx_icaos_land_id (land_id);
|
||||
|
||||
ALTER TABLE health_insurance_companies
|
||||
ADD COLUMN land_id BINARY(16) NULL AFTER sortkey,
|
||||
ADD KEY idx_health_insurance_companies_land_id (land_id);
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE icaos
|
||||
DROP KEY idx_icaos_land_id,
|
||||
DROP COLUMN land_id;
|
||||
|
||||
ALTER TABLE health_insurance_companies
|
||||
DROP KEY idx_health_insurance_companies_land_id,
|
||||
DROP COLUMN land_id;
|
||||
48
migrations/20260517_remove_bmd_module.sql
Normal file
48
migrations/20260517_remove_bmd_module.sql
Normal file
@@ -0,0 +1,48 @@
|
||||
-- +goose Up
|
||||
-- Remove BMD module artifacts: role-permission links, permissions, and table.
|
||||
|
||||
DELETE rp
|
||||
FROM role_permissions rp
|
||||
INNER JOIN permissions p ON p.id = rp.permission_id
|
||||
WHERE p.`key` IN ('bmd.create', 'bmd.read', 'bmd.update', 'bmd.delete');
|
||||
|
||||
DELETE FROM permissions
|
||||
WHERE `key` IN ('bmd.create', 'bmd.read', 'bmd.update', 'bmd.delete');
|
||||
|
||||
DROP TABLE IF EXISTS bmds;
|
||||
|
||||
-- +goose Down
|
||||
-- Recreate BMD table and baseline permissions (without restoring historical data/links).
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bmds (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
country_name VARCHAR(128) NOT NULL,
|
||||
note VARCHAR(255) NULL,
|
||||
sortkey INT NULL,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
eu_accession_code SMALLINT NOT NULL,
|
||||
created_at DATETIME(3) NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(3) NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME(3) NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
KEY idx_bmds_sortkey (sortkey),
|
||||
KEY idx_bmds_is_active (is_active)
|
||||
);
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID()), 'Create BMD', 'bmd.create', 'Create BMD', 1, UTC_TIMESTAMP(3), UTC_TIMESTAMP(3)
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'bmd.create');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID()), 'Read BMD', 'bmd.read', 'Read BMD', 0, UTC_TIMESTAMP(3), UTC_TIMESTAMP(3)
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'bmd.read');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID()), 'Update BMD', 'bmd.update', 'Update BMD', 1, UTC_TIMESTAMP(3), UTC_TIMESTAMP(3)
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'bmd.update');
|
||||
|
||||
INSERT INTO permissions (id, name, `key`, description, requires_pin, created_at, updated_at)
|
||||
SELECT UUID_TO_BIN(UUID()), 'Delete BMD', 'bmd.delete', 'Delete BMD', 1, UTC_TIMESTAMP(3), UTC_TIMESTAMP(3)
|
||||
WHERE NOT EXISTS (SELECT 1 FROM permissions WHERE `key` = 'bmd.delete');
|
||||
55
migrations/20260518_medicine_groups_motor_reactions.sql
Normal file
55
migrations/20260518_medicine_groups_motor_reactions.sql
Normal file
@@ -0,0 +1,55 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS medicine_groups (
|
||||
id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
sortkey INT NULL,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME(6) NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_medicine_groups_is_active (is_active),
|
||||
KEY idx_medicine_groups_sortkey (sortkey)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS motor_reactions (
|
||||
id BINARY(16) NOT NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
score BIGINT NULL,
|
||||
sortkey INT NULL,
|
||||
is_active TINYINT(1) NOT NULL DEFAULT 1,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME(6) NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_motor_reactions_is_active (is_active),
|
||||
KEY idx_motor_reactions_sortkey (sortkey)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
ALTER TABLE medicines
|
||||
ADD COLUMN weight BIGINT NULL AFTER dose,
|
||||
ADD COLUMN medicine_group_id BINARY(16) NULL AFTER `column`,
|
||||
ADD COLUMN motor_reaction_id BINARY(16) NULL AFTER medicine_group_id,
|
||||
ADD KEY idx_medicines_medicine_group_id (medicine_group_id),
|
||||
ADD KEY idx_medicines_motor_reaction_id (motor_reaction_id),
|
||||
ADD CONSTRAINT fk_medicines_medicine_group FOREIGN KEY (medicine_group_id) REFERENCES medicine_groups(id) ON UPDATE CASCADE ON DELETE SET NULL,
|
||||
ADD CONSTRAINT fk_medicines_motor_reaction FOREIGN KEY (motor_reaction_id) REFERENCES motor_reactions(id) ON UPDATE CASCADE ON DELETE SET NULL;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE medicines
|
||||
DROP FOREIGN KEY fk_medicines_medicine_group,
|
||||
DROP FOREIGN KEY fk_medicines_motor_reaction,
|
||||
DROP KEY idx_medicines_medicine_group_id,
|
||||
DROP KEY idx_medicines_motor_reaction_id,
|
||||
DROP COLUMN medicine_group_id,
|
||||
DROP COLUMN motor_reaction_id,
|
||||
DROP COLUMN weight;
|
||||
|
||||
DROP TABLE IF EXISTS motor_reactions;
|
||||
DROP TABLE IF EXISTS medicine_groups;
|
||||
17
migrations/20260518_medicine_motor_reactions.sql
Normal file
17
migrations/20260518_medicine_motor_reactions.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS medicine_motor_reactions (
|
||||
medicine_id BINARY(16) NOT NULL,
|
||||
motor_reaction_id BINARY(16) NOT NULL,
|
||||
PRIMARY KEY (medicine_id, motor_reaction_id),
|
||||
KEY idx_mmr_motor_reaction_id (motor_reaction_id),
|
||||
CONSTRAINT fk_mmr_medicine FOREIGN KEY (medicine_id) REFERENCES medicines(id) ON UPDATE CASCADE ON DELETE CASCADE,
|
||||
CONSTRAINT fk_mmr_motor_reaction FOREIGN KEY (motor_reaction_id) REFERENCES motor_reactions(id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
INSERT IGNORE INTO medicine_motor_reactions (medicine_id, motor_reaction_id)
|
||||
SELECT id, motor_reaction_id
|
||||
FROM medicines
|
||||
WHERE motor_reaction_id IS NOT NULL;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS medicine_motor_reactions;
|
||||
24
migrations/20260518_user_email_login_otps.sql
Normal file
24
migrations/20260518_user_email_login_otps.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS user_email_login_otps (
|
||||
id BINARY(16) NOT NULL,
|
||||
user_id BINARY(16) NOT NULL,
|
||||
otp_hash BINARY(32) NOT NULL,
|
||||
expires_at DATETIME(6) NOT NULL,
|
||||
used_at DATETIME(6) NULL,
|
||||
attempt_count INT NOT NULL DEFAULT 0,
|
||||
max_attempts INT NOT NULL DEFAULT 5,
|
||||
resend_count INT NOT NULL DEFAULT 1,
|
||||
last_sent_at DATETIME(6) NOT NULL,
|
||||
created_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6),
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(6) NOT NULL DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
updated_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_user_email_login_otps_user_id (user_id),
|
||||
KEY idx_user_email_login_otps_expires_at (expires_at),
|
||||
KEY idx_user_email_login_otps_used_at (used_at),
|
||||
CONSTRAINT fk_user_email_login_otps_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS user_email_login_otps;
|
||||
3
migrations/20260518_users_role_id_nullable.sql
Normal file
3
migrations/20260518_users_role_id_nullable.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE users
|
||||
MODIFY COLUMN role_id BINARY(16) NULL;
|
||||
|
||||
22
migrations/20260519_lands_land_iso_code_unique.sql
Normal file
22
migrations/20260519_lands_land_iso_code_unique.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE lands
|
||||
ADD UNIQUE KEY uq_lands_land_iso_code (land_iso_code);
|
||||
|
||||
-- +goose Down
|
||||
SET @idx_exists := (
|
||||
SELECT COUNT(1)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'lands'
|
||||
AND index_name = 'uq_lands_land_iso_code'
|
||||
);
|
||||
|
||||
SET @drop_sql := IF(
|
||||
@idx_exists > 0,
|
||||
'ALTER TABLE lands DROP INDEX uq_lands_land_iso_code',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt FROM @drop_sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
4
migrations/20260520_drop_bases_position_visible.sql
Normal file
4
migrations/20260520_drop_bases_position_visible.sql
Normal file
@@ -0,0 +1,4 @@
|
||||
ALTER TABLE bases
|
||||
DROP COLUMN IF EXISTS note,
|
||||
DROP COLUMN IF EXISTS position,
|
||||
DROP COLUMN IF EXISTS visible;
|
||||
13
migrations/20260521_drop_sortkey_from_medicine_entities.sql
Normal file
13
migrations/20260521_drop_sortkey_from_medicine_entities.sql
Normal file
@@ -0,0 +1,13 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE medicine_groups
|
||||
DROP COLUMN sortkey;
|
||||
|
||||
ALTER TABLE motor_reactions
|
||||
DROP COLUMN sortkey;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE medicine_groups
|
||||
ADD COLUMN sortkey INT NULL AFTER name;
|
||||
|
||||
ALTER TABLE motor_reactions
|
||||
ADD COLUMN sortkey INT NULL AFTER score;
|
||||
@@ -0,0 +1,23 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE opcs
|
||||
DROP COLUMN description;
|
||||
|
||||
ALTER TABLE forces_present
|
||||
DROP COLUMN description;
|
||||
|
||||
ALTER TABLE vocations
|
||||
DROP COLUMN description;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE opcs
|
||||
ADD COLUMN description VARCHAR(255) NULL AFTER note;
|
||||
|
||||
ALTER TABLE forces_present
|
||||
ADD COLUMN description VARCHAR(255) NULL AFTER note;
|
||||
|
||||
ALTER TABLE vocations
|
||||
ADD COLUMN description VARCHAR(255) NULL AFTER note;
|
||||
-- +goose StatementEnd
|
||||
@@ -0,0 +1,21 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE medicine_groups
|
||||
DROP INDEX idx_medicine_groups_is_active,
|
||||
DROP COLUMN is_active;
|
||||
|
||||
ALTER TABLE motor_reactions
|
||||
DROP INDEX idx_motor_reactions_is_active,
|
||||
DROP COLUMN is_active;
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE medicine_groups
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER name,
|
||||
ADD KEY idx_medicine_groups_is_active (is_active);
|
||||
|
||||
ALTER TABLE motor_reactions
|
||||
ADD COLUMN is_active TINYINT(1) NOT NULL DEFAULT 1 AFTER score,
|
||||
ADD KEY idx_motor_reactions_is_active (is_active);
|
||||
-- +goose StatementEnd
|
||||
14
migrations/20260525_add_date_to_duls.sql
Normal file
14
migrations/20260525_add_date_to_duls.sql
Normal file
@@ -0,0 +1,14 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE duls
|
||||
ADD COLUMN IF NOT EXISTS date DATE NULL AFTER name;
|
||||
|
||||
UPDATE duls
|
||||
SET date = COALESCE(date, DATE(created_at), CURRENT_DATE())
|
||||
WHERE date IS NULL;
|
||||
|
||||
ALTER TABLE duls
|
||||
MODIFY COLUMN date DATE NOT NULL;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE duls
|
||||
DROP COLUMN IF EXISTS date;
|
||||
22
migrations/20260525_create_duls.sql
Normal file
22
migrations/20260525_create_duls.sql
Normal file
@@ -0,0 +1,22 @@
|
||||
-- +goose Up
|
||||
CREATE TABLE IF NOT EXISTS duls (
|
||||
id BINARY(16) NOT NULL,
|
||||
no BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
name VARCHAR(128) NOT NULL,
|
||||
date DATE NOT NULL,
|
||||
info TEXT NULL,
|
||||
base_id BINARY(16) NOT NULL,
|
||||
created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uq_duls_no (no),
|
||||
KEY idx_duls_base_id (base_id),
|
||||
CONSTRAINT fk_duls_base FOREIGN KEY (base_id) REFERENCES bases(id) ON UPDATE CASCADE ON DELETE RESTRICT
|
||||
);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS duls;
|
||||
35
migrations/20260526_reserve_acs_add_notes.sql
Normal file
35
migrations/20260526_reserve_acs_add_notes.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
-- +goose Up
|
||||
SET @schema_name := DATABASE();
|
||||
|
||||
SELECT COUNT(*) INTO @has_notes
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND COLUMN_NAME = 'notes';
|
||||
|
||||
SET @add_notes_sql := IF(
|
||||
@has_notes = 0,
|
||||
'ALTER TABLE reserve_acs ADD COLUMN notes TEXT NULL AFTER base_id',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_notes FROM @add_notes_sql;
|
||||
EXECUTE stmt_add_notes;
|
||||
DEALLOCATE PREPARE stmt_add_notes;
|
||||
|
||||
-- +goose Down
|
||||
SET @schema_name := DATABASE();
|
||||
|
||||
SELECT COUNT(*) INTO @has_notes
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND COLUMN_NAME = 'notes';
|
||||
|
||||
SET @drop_notes_sql := IF(
|
||||
@has_notes = 1,
|
||||
'ALTER TABLE reserve_acs DROP COLUMN notes',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_notes FROM @drop_notes_sql;
|
||||
EXECUTE stmt_drop_notes;
|
||||
DEALLOCATE PREPARE stmt_drop_notes;
|
||||
114
migrations/20260526_takeover_schema_alignment.sql
Normal file
114
migrations/20260526_takeover_schema_alignment.sql
Normal file
@@ -0,0 +1,114 @@
|
||||
-- +goose Up
|
||||
-- Align schema for single-request takeover create flow.
|
||||
-- Only apply additive changes when columns/constraints are missing.
|
||||
|
||||
SET @schema_name := DATABASE();
|
||||
|
||||
-- reserve_acs.base_id
|
||||
SELECT COUNT(*) INTO @reserve_acs_has_base_id
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND COLUMN_NAME = 'base_id';
|
||||
|
||||
SET @add_reserve_acs_base_id_sql := IF(
|
||||
@reserve_acs_has_base_id = 0,
|
||||
'ALTER TABLE reserve_acs ADD COLUMN base_id BINARY(16) NULL AFTER status',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_reserve_acs_base_id FROM @add_reserve_acs_base_id_sql;
|
||||
EXECUTE stmt_add_reserve_acs_base_id;
|
||||
DEALLOCATE PREPARE stmt_add_reserve_acs_base_id;
|
||||
|
||||
-- Index reserve_acs.base_id
|
||||
SELECT COUNT(*) INTO @reserve_acs_has_base_id_idx
|
||||
FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND INDEX_NAME = 'idx_reserve_acs_base_id';
|
||||
|
||||
SET @add_reserve_acs_base_id_idx_sql := IF(
|
||||
@reserve_acs_has_base_id_idx = 0,
|
||||
'CREATE INDEX idx_reserve_acs_base_id ON reserve_acs(base_id)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_reserve_acs_base_id_idx FROM @add_reserve_acs_base_id_idx_sql;
|
||||
EXECUTE stmt_add_reserve_acs_base_id_idx;
|
||||
DEALLOCATE PREPARE stmt_add_reserve_acs_base_id_idx;
|
||||
|
||||
-- FK reserve_acs.base_id -> bases.id
|
||||
SELECT COUNT(*) INTO @reserve_acs_has_base_fk
|
||||
FROM information_schema.TABLE_CONSTRAINTS
|
||||
WHERE CONSTRAINT_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND CONSTRAINT_NAME = 'fk_reserve_acs_base'
|
||||
AND CONSTRAINT_TYPE = 'FOREIGN KEY';
|
||||
|
||||
SET @add_reserve_acs_base_fk_sql := IF(
|
||||
@reserve_acs_has_base_fk = 0,
|
||||
'ALTER TABLE reserve_acs ADD CONSTRAINT fk_reserve_acs_base FOREIGN KEY (base_id) REFERENCES bases(id)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_add_reserve_acs_base_fk FROM @add_reserve_acs_base_fk_sql;
|
||||
EXECUTE stmt_add_reserve_acs_base_fk;
|
||||
DEALLOCATE PREPARE stmt_add_reserve_acs_base_fk;
|
||||
|
||||
-- Optional backfill reserve_acs.base_id from linked flight -> duty_roster.
|
||||
-- Safe to run repeatedly.
|
||||
UPDATE reserve_acs ra
|
||||
JOIN flights f ON f.reserve_ac_id = ra.id AND f.deleted_at IS NULL
|
||||
JOIN duty_rosters dr ON dr.id = f.duty_roster_id AND dr.deleted_at IS NULL
|
||||
SET ra.base_id = dr.base_id
|
||||
WHERE ra.base_id IS NULL
|
||||
AND ra.deleted_at IS NULL;
|
||||
|
||||
-- +goose Down
|
||||
-- Keep data; only drop FK/index/column if present.
|
||||
|
||||
SET @schema_name := DATABASE();
|
||||
|
||||
SELECT COUNT(*) INTO @reserve_acs_has_base_fk
|
||||
FROM information_schema.TABLE_CONSTRAINTS
|
||||
WHERE CONSTRAINT_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND CONSTRAINT_NAME = 'fk_reserve_acs_base'
|
||||
AND CONSTRAINT_TYPE = 'FOREIGN KEY';
|
||||
|
||||
SET @drop_reserve_acs_base_fk_sql := IF(
|
||||
@reserve_acs_has_base_fk = 1,
|
||||
'ALTER TABLE reserve_acs DROP FOREIGN KEY fk_reserve_acs_base',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_reserve_acs_base_fk FROM @drop_reserve_acs_base_fk_sql;
|
||||
EXECUTE stmt_drop_reserve_acs_base_fk;
|
||||
DEALLOCATE PREPARE stmt_drop_reserve_acs_base_fk;
|
||||
|
||||
SELECT COUNT(*) INTO @reserve_acs_has_base_id_idx
|
||||
FROM information_schema.STATISTICS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND INDEX_NAME = 'idx_reserve_acs_base_id';
|
||||
|
||||
SET @drop_reserve_acs_base_id_idx_sql := IF(
|
||||
@reserve_acs_has_base_id_idx = 1,
|
||||
'DROP INDEX idx_reserve_acs_base_id ON reserve_acs',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_reserve_acs_base_id_idx FROM @drop_reserve_acs_base_id_idx_sql;
|
||||
EXECUTE stmt_drop_reserve_acs_base_id_idx;
|
||||
DEALLOCATE PREPARE stmt_drop_reserve_acs_base_id_idx;
|
||||
|
||||
SELECT COUNT(*) INTO @reserve_acs_has_base_id
|
||||
FROM information_schema.COLUMNS
|
||||
WHERE TABLE_SCHEMA = @schema_name
|
||||
AND TABLE_NAME = 'reserve_acs'
|
||||
AND COLUMN_NAME = 'base_id';
|
||||
|
||||
SET @drop_reserve_acs_base_id_sql := IF(
|
||||
@reserve_acs_has_base_id = 1,
|
||||
'ALTER TABLE reserve_acs DROP COLUMN base_id',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt_drop_reserve_acs_base_id FROM @drop_reserve_acs_base_id_sql;
|
||||
EXECUTE stmt_drop_reserve_acs_base_id;
|
||||
DEALLOCATE PREPARE stmt_drop_reserve_acs_base_id;
|
||||
26
migrations/20260529_add_name_to_icaos.sql
Normal file
26
migrations/20260529_add_name_to_icaos.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
-- Add optional name field to ICAO table.
|
||||
|
||||
SET @has_table := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'icaos'
|
||||
);
|
||||
|
||||
SET @has_column := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'icaos'
|
||||
AND column_name = 'name'
|
||||
);
|
||||
|
||||
SET @sql := IF(
|
||||
@has_table > 0 AND @has_column = 0,
|
||||
'ALTER TABLE icaos ADD COLUMN name VARCHAR(128) NULL AFTER icao_code',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
18
migrations/20260529_create_fleet_status_service_logs.sql
Normal file
18
migrations/20260529_create_fleet_status_service_logs.sql
Normal file
@@ -0,0 +1,18 @@
|
||||
CREATE TABLE IF NOT EXISTS fleet_status_service_logs (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
fleet_status_id BINARY(16) NOT NULL,
|
||||
helicopter_id BINARY(16) NOT NULL,
|
||||
inspection_type VARCHAR(16) NOT NULL,
|
||||
type VARCHAR(255) NOT NULL,
|
||||
due VARCHAR(255) NULL,
|
||||
ext VARCHAR(255) NULL,
|
||||
serviced_at DATETIME(3) NOT NULL,
|
||||
created_at DATETIME(3) NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
INDEX idx_fleet_status_service_logs_fleet_status_id (fleet_status_id),
|
||||
INDEX idx_fleet_status_service_logs_helicopter_id (helicopter_id),
|
||||
INDEX idx_fleet_status_service_logs_serviced_at (serviced_at),
|
||||
CONSTRAINT chk_fleet_status_service_logs_inspection_type CHECK (inspection_type IN ('A/F','ENG1','ENG2','MAIN1','MAIN2')),
|
||||
CONSTRAINT fk_fleet_status_service_logs_fleet_status FOREIGN KEY (fleet_status_id) REFERENCES fleet_statuses(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_fleet_status_service_logs_helicopter FOREIGN KEY (helicopter_id) REFERENCES helicopters(id)
|
||||
);
|
||||
35
migrations/20260529_create_fleet_status_tables.sql
Normal file
35
migrations/20260529_create_fleet_status_tables.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
CREATE TABLE IF NOT EXISTS fleet_statuses (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
helicopter_id BINARY(16) NOT NULL,
|
||||
created_at DATETIME(3) NULL,
|
||||
created_by BINARY(16) NULL,
|
||||
updated_at DATETIME(3) NULL,
|
||||
updated_by BINARY(16) NULL,
|
||||
deleted_at DATETIME(3) NULL,
|
||||
deleted_by BINARY(16) NULL,
|
||||
INDEX idx_fleet_statuses_helicopter_id (helicopter_id),
|
||||
INDEX idx_fleet_statuses_deleted_at (deleted_at),
|
||||
CONSTRAINT fk_fleet_statuses_helicopter FOREIGN KEY (helicopter_id) REFERENCES helicopters(id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS maintenance_schedules (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
fleet_status_id BINARY(16) NOT NULL,
|
||||
inspection_type VARCHAR(16) NOT NULL,
|
||||
type VARCHAR(255) NOT NULL,
|
||||
due VARCHAR(255) NULL,
|
||||
ext VARCHAR(255) NULL,
|
||||
INDEX idx_maintenance_schedules_fleet_status_id (fleet_status_id),
|
||||
CONSTRAINT chk_maintenance_schedules_inspection_type CHECK (inspection_type IN ('A/F','ENG1','ENG2','MAIN1','MAIN2')),
|
||||
CONSTRAINT fk_maintenance_schedules_fleet_status FOREIGN KEY (fleet_status_id) REFERENCES fleet_statuses(id) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fleet_status_files (
|
||||
id BINARY(16) PRIMARY KEY,
|
||||
fleet_status_id BINARY(16) NOT NULL,
|
||||
file_attachment_id BINARY(16) NOT NULL,
|
||||
INDEX idx_fleet_status_files_fleet_status_id (fleet_status_id),
|
||||
INDEX idx_fleet_status_files_attachment_id (file_attachment_id),
|
||||
CONSTRAINT fk_fleet_status_files_fleet_status FOREIGN KEY (fleet_status_id) REFERENCES fleet_statuses(id) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT fk_fleet_status_files_attachment FOREIGN KEY (file_attachment_id) REFERENCES attachments(id)
|
||||
);
|
||||
11
migrations/20260529_motor_reactions_score_nullable.sql
Normal file
11
migrations/20260529_motor_reactions_score_nullable.sql
Normal file
@@ -0,0 +1,11 @@
|
||||
-- +goose Up
|
||||
ALTER TABLE motor_reactions
|
||||
MODIFY COLUMN score BIGINT NULL;
|
||||
|
||||
-- +goose Down
|
||||
UPDATE motor_reactions
|
||||
SET score = 0
|
||||
WHERE score IS NULL;
|
||||
|
||||
ALTER TABLE motor_reactions
|
||||
MODIFY COLUMN score BIGINT NOT NULL;
|
||||
26
migrations/20260529_rename_hospitals_to_no_icao_codes.sql
Normal file
26
migrations/20260529_rename_hospitals_to_no_icao_codes.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
-- Rename hospital table to no_icao_codes
|
||||
-- This keeps existing data and constraints while moving to the new table name.
|
||||
|
||||
SET @has_hospitals := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hospitals'
|
||||
);
|
||||
|
||||
SET @has_no_icao_codes := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'no_icao_codes'
|
||||
);
|
||||
|
||||
SET @rename_sql := IF(
|
||||
@has_hospitals > 0 AND @has_no_icao_codes = 0,
|
||||
'RENAME TABLE hospitals TO no_icao_codes',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt FROM @rename_sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
25
migrations/20260529_rename_opcs_to_hems_opcs.sql
Normal file
25
migrations/20260529_rename_opcs_to_hems_opcs.sql
Normal file
@@ -0,0 +1,25 @@
|
||||
-- Rename OPC table to hems_opcs.
|
||||
|
||||
SET @has_opcs := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'opcs'
|
||||
);
|
||||
|
||||
SET @has_hems_opcs := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.tables
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'hems_opcs'
|
||||
);
|
||||
|
||||
SET @rename_sql := IF(
|
||||
@has_opcs > 0 AND @has_hems_opcs = 0,
|
||||
'RENAME TABLE opcs TO hems_opcs',
|
||||
'SELECT 1'
|
||||
);
|
||||
|
||||
PREPARE stmt FROM @rename_sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
10
migrations/20260602_add_flight_id_to_duty_rosters.sql
Normal file
10
migrations/20260602_add_flight_id_to_duty_rosters.sql
Normal file
@@ -0,0 +1,10 @@
|
||||
ALTER TABLE duty_rosters
|
||||
ADD COLUMN flight_id BINARY(16) NULL AFTER id;
|
||||
|
||||
CREATE UNIQUE INDEX idx_roster_flight_id
|
||||
ON duty_rosters (flight_id);
|
||||
|
||||
-- Keep base/date as a non-unique lookup index so existing roster views still work.
|
||||
DROP INDEX idx_roster_base_date ON duty_rosters;
|
||||
CREATE INDEX idx_roster_base_date
|
||||
ON duty_rosters (base_id, duty_date);
|
||||
@@ -0,0 +1,18 @@
|
||||
-- Keep fleet status service log schema aligned with service timestamp usage.
|
||||
|
||||
SET @has_status_col := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'fleet_status_service_logs'
|
||||
AND column_name = 'serviced_at'
|
||||
);
|
||||
|
||||
SET @sql := IF(
|
||||
@has_status_col = 0,
|
||||
'ALTER TABLE fleet_status_service_logs ADD COLUMN serviced_at DATETIME(3) NOT NULL AFTER ext',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt FROM @sql;
|
||||
EXECUTE stmt;
|
||||
DEALLOCATE PREPARE stmt;
|
||||
@@ -0,0 +1,69 @@
|
||||
-- Add explicit service state to fleet statuses.
|
||||
|
||||
SET @has_status := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'fleet_statuses'
|
||||
AND column_name = 'status'
|
||||
);
|
||||
|
||||
SET @has_serviced_at := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.columns
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'fleet_statuses'
|
||||
AND column_name = 'serviced_at'
|
||||
);
|
||||
|
||||
SET @sql1 := IF(
|
||||
@has_status = 0,
|
||||
'ALTER TABLE fleet_statuses ADD COLUMN status VARCHAR(16) NOT NULL DEFAULT ''active'' AFTER helicopter_id',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt1 FROM @sql1;
|
||||
EXECUTE stmt1;
|
||||
DEALLOCATE PREPARE stmt1;
|
||||
|
||||
SET @sql2 := IF(
|
||||
@has_serviced_at = 0,
|
||||
'ALTER TABLE fleet_statuses ADD COLUMN serviced_at DATETIME(3) NULL AFTER status',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt2 FROM @sql2;
|
||||
EXECUTE stmt2;
|
||||
DEALLOCATE PREPARE stmt2;
|
||||
|
||||
SET @idx_status := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'fleet_statuses'
|
||||
AND index_name = 'idx_fleet_statuses_status'
|
||||
);
|
||||
|
||||
SET @sql3 := IF(
|
||||
@idx_status = 0,
|
||||
'ALTER TABLE fleet_statuses ADD INDEX idx_fleet_statuses_status (status)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt3 FROM @sql3;
|
||||
EXECUTE stmt3;
|
||||
DEALLOCATE PREPARE stmt3;
|
||||
|
||||
SET @idx_serviced := (
|
||||
SELECT COUNT(*)
|
||||
FROM information_schema.statistics
|
||||
WHERE table_schema = DATABASE()
|
||||
AND table_name = 'fleet_statuses'
|
||||
AND index_name = 'idx_fleet_statuses_serviced_at'
|
||||
);
|
||||
|
||||
SET @sql4 := IF(
|
||||
@idx_serviced = 0,
|
||||
'ALTER TABLE fleet_statuses ADD INDEX idx_fleet_statuses_serviced_at (serviced_at)',
|
||||
'SELECT 1'
|
||||
);
|
||||
PREPARE stmt4 FROM @sql4;
|
||||
EXECUTE stmt4;
|
||||
DEALLOCATE PREPARE stmt4;
|
||||
6
migrations/20260602_add_status_to_flights.sql
Normal file
6
migrations/20260602_add_status_to_flights.sql
Normal file
@@ -0,0 +1,6 @@
|
||||
ALTER TABLE flights
|
||||
ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'draft' AFTER id;
|
||||
|
||||
UPDATE flights
|
||||
SET status = 'draft'
|
||||
WHERE status IS NULL OR status = '';
|
||||
12
migrations/20260602_add_takeover_ac_id_refs.sql
Normal file
12
migrations/20260602_add_takeover_ac_id_refs.sql
Normal file
@@ -0,0 +1,12 @@
|
||||
ALTER TABLE flights
|
||||
ADD COLUMN takeover_ac_id BINARY(16) NULL AFTER reserve_ac_id,
|
||||
ADD INDEX idx_flights_takeover_ac_id (takeover_ac_id);
|
||||
|
||||
ALTER TABLE duty_roster_crews
|
||||
ADD COLUMN takeover_ac_id BINARY(16) NULL AFTER confirm_at,
|
||||
ADD INDEX idx_duty_roster_crews_takeover_ac_id (takeover_ac_id);
|
||||
|
||||
ALTER TABLE duty_roster_other_persons
|
||||
ADD COLUMN takeover_ac_id BINARY(16) NULL AFTER email,
|
||||
ADD INDEX idx_duty_roster_other_persons_takeover_ac_id (takeover_ac_id);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user