init push
This commit is contained in:
37
migrations/goose/20260414_helicopter_import_staging.sql
Normal file
37
migrations/goose/20260414_helicopter_import_staging.sql
Normal file
@@ -0,0 +1,37 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy helicopter dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS helicopter_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(50) NOT NULL,
|
||||
type varchar(20) DEFAULT NULL,
|
||||
counter int(11) DEFAULT NULL,
|
||||
engine1 varchar(50) DEFAULT NULL,
|
||||
engine2 varchar(50) DEFAULT NULL,
|
||||
consumption double(10,2) DEFAULT NULL,
|
||||
service varchar(255) DEFAULT NULL,
|
||||
nr1 tinyint(1) DEFAULT 0,
|
||||
nr2 tinyint(1) DEFAULT 0,
|
||||
lh tinyint(1) DEFAULT 0,
|
||||
rh tinyint(1) DEFAULT 0,
|
||||
mgb tinyint(1) DEFAULT 0,
|
||||
igb tinyint(1) DEFAULT 0,
|
||||
tgb tinyint(1) DEFAULT 0,
|
||||
utc varchar(10) DEFAULT NULL,
|
||||
disabled tinyint(1) DEFAULT 0,
|
||||
visible tinyint(1) DEFAULT 1,
|
||||
dry tinyint(1) DEFAULT 0,
|
||||
docs text,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS helicopter_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_helicopter_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS helicopter_old_id_map;
|
||||
DROP TABLE IF EXISTS helicopter_old_import;
|
||||
140
migrations/goose/20260415_helicopter_import_apply.sql
Normal file
140
migrations/goose/20260415_helicopter_import_apply.sql
Normal file
@@ -0,0 +1,140 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy helicopter staging data into `helicopters`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `helicopter_old_import`.
|
||||
-- 2) Import old dump rows into `helicopter_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUIDv7-style IDs,
|
||||
-- then upserts into `helicopters` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
-- Self-heal when staging migration is marked applied but tables were dropped/reset manually.
|
||||
CREATE TABLE IF NOT EXISTS helicopter_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(50) NOT NULL,
|
||||
type varchar(20) DEFAULT NULL,
|
||||
counter int(11) DEFAULT NULL,
|
||||
engine1 varchar(50) DEFAULT NULL,
|
||||
engine2 varchar(50) DEFAULT NULL,
|
||||
consumption double(10,2) DEFAULT NULL,
|
||||
service varchar(255) DEFAULT NULL,
|
||||
nr1 tinyint(1) DEFAULT 0,
|
||||
nr2 tinyint(1) DEFAULT 0,
|
||||
lh tinyint(1) DEFAULT 0,
|
||||
rh tinyint(1) DEFAULT 0,
|
||||
mgb tinyint(1) DEFAULT 0,
|
||||
igb tinyint(1) DEFAULT 0,
|
||||
tgb tinyint(1) DEFAULT 0,
|
||||
utc varchar(10) DEFAULT NULL,
|
||||
disabled tinyint(1) DEFAULT 0,
|
||||
visible tinyint(1) DEFAULT 1,
|
||||
dry tinyint(1) DEFAULT 0,
|
||||
docs text,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS helicopter_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_helicopter_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
INSERT INTO helicopter_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
-- UUID layout must be 8-4-4-4-12 (32 hex chars => 16 bytes).
|
||||
-- Put millisecond timestamp (48-bit) in first 8+4 chars for time ordering.
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM helicopter_old_import s
|
||||
LEFT JOIN helicopter_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO helicopters (
|
||||
id,
|
||||
designation,
|
||||
identifier,
|
||||
report_sequence,
|
||||
type,
|
||||
counter,
|
||||
engine_1,
|
||||
engine_2,
|
||||
consumption_lt_min,
|
||||
nr1,
|
||||
nr2,
|
||||
lh,
|
||||
rh,
|
||||
mgb,
|
||||
igb,
|
||||
tgb,
|
||||
utc_offset,
|
||||
dry,
|
||||
note,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
TRIM(s.name) AS designation,
|
||||
TRIM(s.name) AS identifier,
|
||||
0 AS report_sequence,
|
||||
COALESCE(NULLIF(TRIM(s.type), ''), 'Unknown') AS type,
|
||||
0 AS counter,
|
||||
TRIM(COALESCE(s.engine1, '')) AS engine_1,
|
||||
TRIM(COALESCE(s.engine2, '')) AS engine_2,
|
||||
COALESCE(s.consumption, 0) AS consumption_lt_min,
|
||||
COALESCE(s.nr1, 0) AS nr1,
|
||||
COALESCE(s.nr2, 0) AS nr2,
|
||||
COALESCE(s.lh, 0) AS lh,
|
||||
COALESCE(s.rh, 0) AS rh,
|
||||
COALESCE(s.mgb, 0) AS mgb,
|
||||
COALESCE(s.igb, 0) AS igb,
|
||||
COALESCE(s.tgb, 0) AS tgb,
|
||||
COALESCE(CAST(NULLIF(TRIM(s.utc), '') AS SIGNED), 0) AS utc_offset,
|
||||
COALESCE(s.dry, 0) AS dry,
|
||||
s.docs AS note,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM helicopter_old_import s
|
||||
JOIN helicopter_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
designation = VALUES(designation),
|
||||
identifier = VALUES(identifier),
|
||||
type = VALUES(type),
|
||||
engine_1 = VALUES(engine_1),
|
||||
engine_2 = VALUES(engine_2),
|
||||
consumption_lt_min = VALUES(consumption_lt_min),
|
||||
nr1 = VALUES(nr1),
|
||||
nr2 = VALUES(nr2),
|
||||
lh = VALUES(lh),
|
||||
rh = VALUES(rh),
|
||||
mgb = VALUES(mgb),
|
||||
igb = VALUES(igb),
|
||||
tgb = VALUES(tgb),
|
||||
utc_offset = VALUES(utc_offset),
|
||||
dry = VALUES(dry),
|
||||
note = VALUES(note),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
265
migrations/goose/20260505_seed_lands_from_legacy_country.sql
Normal file
265
migrations/goose/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/goose/20260506_hospital_import_staging.sql
Normal file
23
migrations/goose/20260506_hospital_import_staging.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy hospital dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS hospital_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(150) DEFAULT NULL,
|
||||
address varchar(255) DEFAULT NULL,
|
||||
office varchar(150) DEFAULT NULL,
|
||||
mobile varchar(150) DEFAULT NULL,
|
||||
email varchar(150) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS hospital_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_hospital_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS hospital_old_id_map;
|
||||
DROP TABLE IF EXISTS hospital_old_import;
|
||||
69
migrations/goose/20260507_hospital_import_apply.sql
Normal file
69
migrations/goose/20260507_hospital_import_apply.sql
Normal file
@@ -0,0 +1,69 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy hospital staging data into `hospitals`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `hospital_old_import`.
|
||||
-- 2) Import old dump rows into `hospital_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `hospitals` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO hospital_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM hospital_old_import s
|
||||
LEFT JOIN hospital_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO hospitals (
|
||||
id,
|
||||
hospital_name,
|
||||
address,
|
||||
landline_number,
|
||||
mobile_number,
|
||||
email,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Hospital ', s.id)), 128) AS hospital_name,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 256) AS address,
|
||||
LEFT(TRIM(COALESCE(s.office, '')), 20) AS landline_number,
|
||||
LEFT(TRIM(COALESCE(s.mobile, '')), 20) AS mobile_number,
|
||||
LEFT(TRIM(COALESCE(s.email, '')), 128) AS email,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM hospital_old_import s
|
||||
JOIN hospital_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
hospital_name = VALUES(hospital_name),
|
||||
address = VALUES(address),
|
||||
landline_number = VALUES(landline_number),
|
||||
mobile_number = VALUES(mobile_number),
|
||||
email = VALUES(email),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
23
migrations/goose/20260508_icao_import_staging.sql
Normal file
23
migrations/goose/20260508_icao_import_staging.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy ICAO dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS icao_old_import (
|
||||
id int(11) NOT NULL,
|
||||
code varchar(150) NOT NULL,
|
||||
address varchar(255) DEFAULT NULL,
|
||||
phone varchar(50) DEFAULT NULL,
|
||||
mobile varchar(50) DEFAULT NULL,
|
||||
email varchar(50) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS icao_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_icao_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS icao_old_id_map;
|
||||
DROP TABLE IF EXISTS icao_old_import;
|
||||
69
migrations/goose/20260509_icao_import_apply.sql
Normal file
69
migrations/goose/20260509_icao_import_apply.sql
Normal file
@@ -0,0 +1,69 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy ICAO staging data into `icaos`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `icao_old_import`.
|
||||
-- 2) Import old dump rows into `icao_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `icaos` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO icao_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM icao_old_import s
|
||||
LEFT JOIN icao_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO icaos (
|
||||
id,
|
||||
icao_code,
|
||||
address,
|
||||
landline_number,
|
||||
mobile_number,
|
||||
email,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.code), ''), CONCAT('ICAO-', s.id)), 16) AS icao_code,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 256) AS address,
|
||||
LEFT(TRIM(COALESCE(s.phone, '')), 20) AS landline_number,
|
||||
LEFT(TRIM(COALESCE(s.mobile, '')), 20) AS mobile_number,
|
||||
LEFT(TRIM(COALESCE(s.email, '')), 128) AS email,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM icao_old_import s
|
||||
JOIN icao_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
icao_code = VALUES(icao_code),
|
||||
address = VALUES(address),
|
||||
landline_number = VALUES(landline_number),
|
||||
mobile_number = VALUES(mobile_number),
|
||||
email = VALUES(email),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
23
migrations/goose/20260510_kassa_import_staging.sql
Normal file
23
migrations/goose/20260510_kassa_import_staging.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy kassa dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS kassa_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(150) DEFAULT NULL,
|
||||
region varchar(255) DEFAULT NULL,
|
||||
address varchar(255) DEFAULT NULL,
|
||||
phone varchar(150) DEFAULT NULL,
|
||||
email varchar(150) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS kassa_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_kassa_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS kassa_old_id_map;
|
||||
DROP TABLE IF EXISTS kassa_old_import;
|
||||
69
migrations/goose/20260511_kassa_import_apply.sql
Normal file
69
migrations/goose/20260511_kassa_import_apply.sql
Normal file
@@ -0,0 +1,69 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy kassa staging data into `health_insurance_companies`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `kassa_old_import`.
|
||||
-- 2) Import old dump rows into `kassa_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `health_insurance_companies` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO kassa_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM kassa_old_import s
|
||||
LEFT JOIN kassa_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO health_insurance_companies (
|
||||
id,
|
||||
name,
|
||||
state,
|
||||
address,
|
||||
mobile_number,
|
||||
email,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Kassa ', s.id)), 128) AS name,
|
||||
LEFT(TRIM(COALESCE(s.region, '')), 128) AS state,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 256) AS address,
|
||||
LEFT(TRIM(COALESCE(s.phone, '')), 20) AS mobile_number,
|
||||
LEFT(TRIM(COALESCE(s.email, '')), 128) AS email,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM kassa_old_import s
|
||||
JOIN kassa_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
state = VALUES(state),
|
||||
address = VALUES(address),
|
||||
mobile_number = VALUES(mobile_number),
|
||||
email = VALUES(email),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
20
migrations/goose/20260512_nationality_import_staging.sql
Normal file
20
migrations/goose/20260512_nationality_import_staging.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy nationality dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS nationality_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(150) NOT NULL,
|
||||
description varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS nationality_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_nationality_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS nationality_old_id_map;
|
||||
DROP TABLE IF EXISTS nationality_old_import;
|
||||
88
migrations/goose/20260513_nationality_import_apply.sql
Normal file
88
migrations/goose/20260513_nationality_import_apply.sql
Normal file
@@ -0,0 +1,88 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy nationality staging data into `nationalities`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `nationality_old_import`.
|
||||
-- 2) Import old dump rows into `nationality_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `nationalities` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO nationality_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM nationality_old_import s
|
||||
LEFT JOIN nationality_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO lands (
|
||||
id,
|
||||
name,
|
||||
land_iso_code,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
UUID_TO_BIN(UUID()) AS id,
|
||||
src.land_name AS name,
|
||||
'' AS land_iso_code,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM (
|
||||
SELECT DISTINCT
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Nationality ', s.id)), 128) AS land_name
|
||||
FROM nationality_old_import s
|
||||
) src
|
||||
LEFT JOIN lands l
|
||||
ON LOWER(TRIM(l.name)) = LOWER(src.land_name)
|
||||
AND l.deleted_at IS NULL
|
||||
WHERE l.id IS NULL;
|
||||
|
||||
INSERT INTO nationalities (
|
||||
id,
|
||||
land_id,
|
||||
name,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
l.id AS land_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Nationality ', s.id)), 128) AS name,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM nationality_old_import s
|
||||
JOIN nationality_old_id_map m ON m.old_id = s.id
|
||||
LEFT JOIN lands l
|
||||
ON LOWER(TRIM(l.name)) = LOWER(LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Nationality ', s.id)), 128))
|
||||
AND l.deleted_at IS NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
land_id = VALUES(land_id),
|
||||
name = VALUES(name),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
20
migrations/goose/20260514_bundesland_import_staging.sql
Normal file
20
migrations/goose/20260514_bundesland_import_staging.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy bundesland dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bundesland_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(150) NOT NULL,
|
||||
state varchar(150) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bundesland_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_bundesland_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS bundesland_old_id_map;
|
||||
DROP TABLE IF EXISTS bundesland_old_import;
|
||||
140
migrations/goose/20260515_bundesland_import_apply.sql
Normal file
140
migrations/goose/20260515_bundesland_import_apply.sql
Normal file
@@ -0,0 +1,140 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy bundesland staging data into `federal_states`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `bundesland_old_import`.
|
||||
-- 2) Import old dump rows into `bundesland_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `federal_states` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO bundesland_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM bundesland_old_import s
|
||||
LEFT JOIN bundesland_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO lands (
|
||||
id,
|
||||
name,
|
||||
land_iso_code,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
UUID_TO_BIN(UUID()) AS id,
|
||||
src.land_name AS name,
|
||||
'' AS land_iso_code,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM (
|
||||
SELECT DISTINCT
|
||||
LEFT(
|
||||
CASE
|
||||
WHEN NULLIF(TRIM(s.state), '') IS NOT NULL THEN TRIM(s.state)
|
||||
WHEN TRIM(s.name) IN (
|
||||
'Vorarlberg',
|
||||
'Tirol',
|
||||
'Burgenland',
|
||||
'Wien',
|
||||
'Salzburg',
|
||||
'Steiermark',
|
||||
'Kärnten',
|
||||
'Oberösterreich',
|
||||
'Niederösterreich'
|
||||
) THEN 'Österreich'
|
||||
ELSE ''
|
||||
END,
|
||||
128
|
||||
) AS land_name
|
||||
FROM bundesland_old_import s
|
||||
WHERE NULLIF(
|
||||
CASE
|
||||
WHEN NULLIF(TRIM(s.state), '') IS NOT NULL THEN TRIM(s.state)
|
||||
WHEN TRIM(s.name) IN (
|
||||
'Vorarlberg',
|
||||
'Tirol',
|
||||
'Burgenland',
|
||||
'Wien',
|
||||
'Salzburg',
|
||||
'Steiermark',
|
||||
'Kärnten',
|
||||
'Oberösterreich',
|
||||
'Niederösterreich'
|
||||
) THEN 'Österreich'
|
||||
ELSE ''
|
||||
END,
|
||||
''
|
||||
) IS NOT NULL
|
||||
) src
|
||||
LEFT JOIN lands l
|
||||
ON LOWER(TRIM(l.name)) = LOWER(src.land_name)
|
||||
AND l.deleted_at IS NULL
|
||||
WHERE l.id IS NULL;
|
||||
|
||||
INSERT INTO federal_states (
|
||||
id,
|
||||
land_id,
|
||||
name,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
l.id AS land_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Federal State ', s.id)), 128) AS name,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM bundesland_old_import s
|
||||
JOIN bundesland_old_id_map m ON m.old_id = s.id
|
||||
LEFT JOIN lands l
|
||||
ON LOWER(TRIM(l.name)) = LOWER(LEFT(
|
||||
CASE
|
||||
WHEN NULLIF(TRIM(s.state), '') IS NOT NULL THEN TRIM(s.state)
|
||||
WHEN TRIM(s.name) IN (
|
||||
'Vorarlberg',
|
||||
'Tirol',
|
||||
'Burgenland',
|
||||
'Wien',
|
||||
'Salzburg',
|
||||
'Steiermark',
|
||||
'Kärnten',
|
||||
'Oberösterreich',
|
||||
'Niederösterreich'
|
||||
) THEN 'Österreich'
|
||||
ELSE ''
|
||||
END,
|
||||
128
|
||||
))
|
||||
AND l.deleted_at IS NULL
|
||||
ON DUPLICATE KEY UPDATE
|
||||
land_id = VALUES(land_id),
|
||||
name = VALUES(name),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
20
migrations/goose/20260516_opc_import_staging.sql
Normal file
20
migrations/goose/20260516_opc_import_staging.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy OPC dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS opc_old_import (
|
||||
id int(11) NOT NULL,
|
||||
title varchar(150) NOT NULL,
|
||||
description varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS opc_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_opc_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS opc_old_id_map;
|
||||
DROP TABLE IF EXISTS opc_old_import;
|
||||
57
migrations/goose/20260517_opc_import_apply.sql
Normal file
57
migrations/goose/20260517_opc_import_apply.sql
Normal file
@@ -0,0 +1,57 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy OPC staging data into `opcs`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `opc_old_import`.
|
||||
-- 2) Import old dump rows into `opc_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `opcs` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO opc_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM opc_old_import s
|
||||
LEFT JOIN opc_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO opcs (
|
||||
id,
|
||||
name,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.title), ''), CONCAT('OPC ', s.id)), 64) AS name,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM opc_old_import s
|
||||
JOIN opc_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
20
migrations/goose/20260518_forces_import_staging.sql
Normal file
20
migrations/goose/20260518_forces_import_staging.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy forces dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS forces_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(150) NOT NULL,
|
||||
description varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS forces_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_forces_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS forces_old_id_map;
|
||||
DROP TABLE IF EXISTS forces_old_import;
|
||||
57
migrations/goose/20260519_forces_import_apply.sql
Normal file
57
migrations/goose/20260519_forces_import_apply.sql
Normal file
@@ -0,0 +1,57 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy forces staging data into `forces_present`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `forces_old_import`.
|
||||
-- 2) Import old dump rows into `forces_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `forces_present` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO forces_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM forces_old_import s
|
||||
LEFT JOIN forces_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO forces_present (
|
||||
id,
|
||||
name,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Forces ', s.id)), 128) AS name,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM forces_old_import s
|
||||
JOIN forces_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
20
migrations/goose/20260520_vocation_import_staging.sql
Normal file
20
migrations/goose/20260520_vocation_import_staging.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy vocation dump import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vocation_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(150) NOT NULL,
|
||||
description varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vocation_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_vocation_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS vocation_old_id_map;
|
||||
DROP TABLE IF EXISTS vocation_old_import;
|
||||
57
migrations/goose/20260521_vocation_import_apply.sql
Normal file
57
migrations/goose/20260521_vocation_import_apply.sql
Normal file
@@ -0,0 +1,57 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy vocation staging data into `vocations`.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `vocation_old_import`.
|
||||
-- 2) Import old dump rows into `vocation_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `vocations` with `is_active` forced to 1.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO vocation_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM vocation_old_import s
|
||||
LEFT JOIN vocation_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO vocations (
|
||||
id,
|
||||
name,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Vocation ', s.id)), 64) AS name,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM vocation_old_import s
|
||||
JOIN vocation_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
60
migrations/goose/20260522_medicine_legacy_import_staging.sql
Normal file
60
migrations/goose/20260522_medicine_legacy_import_staging.sql
Normal file
@@ -0,0 +1,60 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy medicine import:
|
||||
-- - cmedikamente
|
||||
-- - cmedikamente_group
|
||||
-- - cmotorische_reaktion
|
||||
|
||||
CREATE TABLE IF NOT EXISTS medicine_group_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS medicine_group_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_medicine_group_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS motor_reaction_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
ball int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS motor_reaction_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_motor_reaction_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS medicine_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
dose varchar(255) DEFAULT NULL,
|
||||
weight int(11) DEFAULT NULL,
|
||||
`col` int(11) DEFAULT NULL,
|
||||
cmedikamente_group_id int(11) DEFAULT NULL,
|
||||
motor_reaction_old_id int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_medicine_old_import_group (cmedikamente_group_id),
|
||||
KEY idx_medicine_old_import_reaction (motor_reaction_old_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS medicine_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_medicine_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS medicine_old_id_map;
|
||||
DROP TABLE IF EXISTS medicine_old_import;
|
||||
DROP TABLE IF EXISTS motor_reaction_old_id_map;
|
||||
DROP TABLE IF EXISTS motor_reaction_old_import;
|
||||
DROP TABLE IF EXISTS medicine_group_old_id_map;
|
||||
DROP TABLE IF EXISTS medicine_group_old_import;
|
||||
163
migrations/goose/20260523_medicine_legacy_import_apply.sql
Normal file
163
migrations/goose/20260523_medicine_legacy_import_apply.sql
Normal file
@@ -0,0 +1,163 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy medicine staging data into:
|
||||
-- - medicine_groups
|
||||
-- - motor_reactions
|
||||
-- - medicines
|
||||
--
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run staging migration that creates *_old_import tables.
|
||||
-- 2) Load legacy dump data into:
|
||||
-- - medicine_group_old_import
|
||||
-- - motor_reaction_old_import
|
||||
-- - medicine_old_import
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
INSERT INTO medicine_group_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM medicine_group_old_import s
|
||||
LEFT JOIN medicine_group_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO motor_reaction_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM motor_reaction_old_import s
|
||||
LEFT JOIN motor_reaction_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO medicine_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM medicine_old_import s
|
||||
LEFT JOIN medicine_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO medicine_groups (
|
||||
id,
|
||||
name,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Medicine Group ', s.id)), 255) AS name,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM medicine_group_old_import s
|
||||
JOIN medicine_group_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
INSERT INTO motor_reactions (
|
||||
id,
|
||||
name,
|
||||
score,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Motor Reaction ', s.id)), 255) AS name,
|
||||
s.ball AS score,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM motor_reaction_old_import s
|
||||
JOIN motor_reaction_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
score = VALUES(score),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
INSERT INTO medicines (
|
||||
id,
|
||||
name,
|
||||
dose,
|
||||
weight,
|
||||
`column`,
|
||||
medicine_group_id,
|
||||
motor_reaction_id,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
med_map.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Medicine ', s.id)), 128) AS name,
|
||||
LEFT(TRIM(COALESCE(s.dose, '')), 128) AS dose,
|
||||
s.weight AS weight,
|
||||
COALESCE(s.`col`, 0) AS `column`,
|
||||
grp_map.new_id AS medicine_group_id,
|
||||
react_map.new_id AS motor_reaction_id,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM medicine_old_import s
|
||||
JOIN medicine_old_id_map med_map ON med_map.old_id = s.id
|
||||
LEFT JOIN medicine_group_old_id_map grp_map ON grp_map.old_id = s.cmedikamente_group_id
|
||||
LEFT JOIN motor_reaction_old_id_map react_map ON react_map.old_id = s.motor_reaction_old_id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
dose = VALUES(dose),
|
||||
weight = VALUES(weight),
|
||||
`column` = VALUES(`column`),
|
||||
medicine_group_id = VALUES(medicine_group_id),
|
||||
motor_reaction_id = VALUES(motor_reaction_id),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
SELECT 1;
|
||||
@@ -0,0 +1,58 @@
|
||||
-- +goose Up
|
||||
-- Staging table set for legacy medicine dump format:
|
||||
-- - cmedikamente_group
|
||||
-- - cmotorische_reaktion
|
||||
-- - cmedikamente
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_group_old_import (
|
||||
id INT(11) NOT NULL,
|
||||
name VARCHAR(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmotorische_old_import (
|
||||
id INT(11) NOT NULL,
|
||||
name VARCHAR(255) DEFAULT NULL,
|
||||
ball INT(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_old_import (
|
||||
id INT(11) NOT NULL,
|
||||
name VARCHAR(255) DEFAULT NULL,
|
||||
dose VARCHAR(255) DEFAULT NULL,
|
||||
weight INT(11) DEFAULT NULL,
|
||||
col INT(11) DEFAULT NULL,
|
||||
cmedikamente_group_id INT(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_cmedikamente_old_group_id (cmedikamente_group_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_group_old_id_map (
|
||||
old_id INT(11) NOT NULL,
|
||||
new_id BINARY(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_cmedikamente_group_old_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmotorische_old_id_map (
|
||||
old_id INT(11) NOT NULL,
|
||||
new_id BINARY(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_cmotorische_old_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_old_id_map (
|
||||
old_id INT(11) NOT NULL,
|
||||
new_id BINARY(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_cmedikamente_old_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS cmedikamente_old_id_map;
|
||||
DROP TABLE IF EXISTS cmotorische_old_id_map;
|
||||
DROP TABLE IF EXISTS cmedikamente_group_old_id_map;
|
||||
DROP TABLE IF EXISTS cmedikamente_old_import;
|
||||
DROP TABLE IF EXISTS cmotorische_old_import;
|
||||
DROP TABLE IF EXISTS cmedikamente_group_old_import;
|
||||
165
migrations/goose/20260525_medicine_clegacy_import_apply.sql
Normal file
165
migrations/goose/20260525_medicine_clegacy_import_apply.sql
Normal file
@@ -0,0 +1,165 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy c* staging data into target tables:
|
||||
-- - medicine_groups
|
||||
-- - motor_reactions
|
||||
-- - medicines
|
||||
-- - medicine_motor_reactions (optional backfill via motor_reaction_id)
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_group_old_import (
|
||||
id INT(11) NOT NULL,
|
||||
name VARCHAR(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmotorische_old_import (
|
||||
id INT(11) NOT NULL,
|
||||
name VARCHAR(255) DEFAULT NULL,
|
||||
ball INT(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_old_import (
|
||||
id INT(11) NOT NULL,
|
||||
name VARCHAR(255) DEFAULT NULL,
|
||||
dose VARCHAR(255) DEFAULT NULL,
|
||||
weight INT(11) DEFAULT NULL,
|
||||
col INT(11) DEFAULT NULL,
|
||||
cmedikamente_group_id INT(11) DEFAULT NULL,
|
||||
PRIMARY KEY (id),
|
||||
KEY idx_cmedikamente_old_import_group_id (cmedikamente_group_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_group_old_id_map (
|
||||
old_id INT(11) NOT NULL,
|
||||
new_id BINARY(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_cmedikamente_group_old_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmotorische_old_id_map (
|
||||
old_id INT(11) NOT NULL,
|
||||
new_id BINARY(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_cmotorische_old_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS cmedikamente_old_id_map (
|
||||
old_id INT(11) NOT NULL,
|
||||
new_id BINARY(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_cmedikamente_old_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
INSERT INTO cmedikamente_group_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id,
|
||||
UNHEX(REPLACE(UUID(), '-', ''))
|
||||
FROM cmedikamente_group_old_import s
|
||||
LEFT JOIN cmedikamente_group_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO cmotorische_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id,
|
||||
UNHEX(REPLACE(UUID(), '-', ''))
|
||||
FROM cmotorische_old_import s
|
||||
LEFT JOIN cmotorische_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO cmedikamente_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id,
|
||||
UNHEX(REPLACE(UUID(), '-', ''))
|
||||
FROM cmedikamente_old_import s
|
||||
LEFT JOIN cmedikamente_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
INSERT INTO medicine_groups (
|
||||
id,
|
||||
name,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
map.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Medicine Group ', s.id)), 255),
|
||||
1,
|
||||
UTC_TIMESTAMP(),
|
||||
UTC_TIMESTAMP()
|
||||
FROM cmedikamente_group_old_import s
|
||||
JOIN cmedikamente_group_old_id_map map ON map.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
INSERT INTO motor_reactions (
|
||||
id,
|
||||
name,
|
||||
score,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
map.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Motor Reaction ', s.id)), 255),
|
||||
s.ball,
|
||||
1,
|
||||
UTC_TIMESTAMP(),
|
||||
UTC_TIMESTAMP()
|
||||
FROM cmotorische_old_import s
|
||||
JOIN cmotorische_old_id_map map ON map.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
score = VALUES(score),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
INSERT INTO medicines (
|
||||
id,
|
||||
name,
|
||||
dose,
|
||||
weight,
|
||||
`column`,
|
||||
medicine_group_id,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
med_map.new_id,
|
||||
LEFT(COALESCE(NULLIF(TRIM(s.name), ''), CONCAT('Medicine ', s.id)), 128),
|
||||
LEFT(TRIM(COALESCE(s.dose, '')), 128),
|
||||
s.weight,
|
||||
COALESCE(s.col, 0),
|
||||
grp_map.new_id,
|
||||
1,
|
||||
UTC_TIMESTAMP(),
|
||||
UTC_TIMESTAMP()
|
||||
FROM cmedikamente_old_import s
|
||||
JOIN cmedikamente_old_id_map med_map ON med_map.old_id = s.id
|
||||
LEFT JOIN cmedikamente_group_old_id_map grp_map ON grp_map.old_id = s.cmedikamente_group_id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
name = VALUES(name),
|
||||
dose = VALUES(dose),
|
||||
weight = VALUES(weight),
|
||||
`column` = VALUES(`column`),
|
||||
medicine_group_id = VALUES(medicine_group_id),
|
||||
is_active = 1,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- Optional compatibility backfill: if medicines.motor_reaction_id exists, sync into join table.
|
||||
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;
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
SELECT 1;
|
||||
23
migrations/goose/20260526_auth_email_otp_toggle.sql
Normal file
23
migrations/goose/20260526_auth_email_otp_toggle.sql
Normal file
@@ -0,0 +1,23 @@
|
||||
-- +goose Up
|
||||
INSERT INTO master_setting_values (
|
||||
setting_key,
|
||||
value,
|
||||
is_encrypted,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES (
|
||||
'AUTH_LOGIN_EMAIL_OTP_ENABLED',
|
||||
'false',
|
||||
0,
|
||||
UTC_TIMESTAMP(),
|
||||
UTC_TIMESTAMP()
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
value = VALUES(value),
|
||||
is_encrypted = 0,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- +goose Down
|
||||
DELETE FROM master_setting_values
|
||||
WHERE setting_key = 'AUTH_LOGIN_EMAIL_OTP_ENABLED';
|
||||
103
migrations/goose/20260527_user_import_staging.sql
Normal file
103
migrations/goose/20260527_user_import_staging.sql
Normal file
@@ -0,0 +1,103 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy `user` dump import.
|
||||
-- Source table in old DB: `user` (not `users`).
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_old_import (
|
||||
id int(11) NOT NULL,
|
||||
state tinyint(1) DEFAULT 0,
|
||||
role int(2) NOT NULL,
|
||||
username varchar(30) DEFAULT NULL,
|
||||
password varchar(150) DEFAULT NULL,
|
||||
fullname varchar(50) DEFAULT NULL,
|
||||
shortName varchar(30) DEFAULT NULL,
|
||||
flightNumber varchar(20) DEFAULT NULL,
|
||||
license varchar(20) DEFAULT NULL,
|
||||
techLicense varchar(20) DEFAULT NULL,
|
||||
airport_pilot varchar(15) DEFAULT NULL,
|
||||
responsible_pilot varchar(15) DEFAULT NULL,
|
||||
second_pilot varchar(15) DEFAULT NULL,
|
||||
double_tax_pilot varchar(15) DEFAULT NULL,
|
||||
flight_instructor_pilot varchar(15) DEFAULT NULL,
|
||||
night_pilot varchar(15) DEFAULT NULL,
|
||||
fir_pilot varchar(15) DEFAULT NULL,
|
||||
start_date varchar(15) DEFAULT NULL,
|
||||
date_active varchar(15) DEFAULT NULL,
|
||||
address varchar(255) DEFAULT NULL,
|
||||
zipCode varchar(15) DEFAULT NULL,
|
||||
street varchar(255) DEFAULT NULL,
|
||||
phone varchar(50) DEFAULT NULL,
|
||||
mobile varchar(50) DEFAULT NULL,
|
||||
email varchar(70) DEFAULT NULL,
|
||||
photo varchar(50) DEFAULT NULL,
|
||||
token varchar(255) DEFAULT NULL,
|
||||
hash varchar(255) DEFAULT NULL,
|
||||
regDate timestamp NULL DEFAULT NULL,
|
||||
lastVisit timestamp NULL DEFAULT NULL,
|
||||
reportDate datetime DEFAULT NULL,
|
||||
deletedAt varchar(32) DEFAULT NULL,
|
||||
isDeleted tinyint(1) DEFAULT 0,
|
||||
visible tinyint(1) DEFAULT 1,
|
||||
lang varchar(5) DEFAULT 'de',
|
||||
bases varchar(255) DEFAULT NULL,
|
||||
legacy_url varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_user_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS legacy_user_role_map (
|
||||
legacy_role int(2) NOT NULL,
|
||||
role_code varchar(64) NOT NULL,
|
||||
staff_role_label varchar(120) DEFAULT NULL,
|
||||
pilot_category varchar(16) DEFAULT NULL,
|
||||
is_chief_pilot tinyint(1) NOT NULL DEFAULT 0,
|
||||
is_chief_physician tinyint(1) NOT NULL DEFAULT 0,
|
||||
is_chief_physician_in_charge tinyint(1) NOT NULL DEFAULT 0,
|
||||
is_chief_technician tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (legacy_role)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
INSERT INTO legacy_user_role_map (
|
||||
legacy_role,
|
||||
role_code,
|
||||
staff_role_label,
|
||||
pilot_category,
|
||||
is_chief_pilot,
|
||||
is_chief_physician,
|
||||
is_chief_physician_in_charge,
|
||||
is_chief_technician
|
||||
)
|
||||
VALUES
|
||||
(1, 'pilot', NULL, 'regular', 0, 0, 0, 0),
|
||||
(2, 'pilot', NULL, 'regular', 1, 0, 0, 0),
|
||||
(3, 'doctor', NULL, NULL, 0, 0, 0, 0),
|
||||
(4, 'doctor', NULL, NULL, 0, 1, 0, 0),
|
||||
(5, 'air_rescuer', NULL, NULL, 0, 0, 0, 0),
|
||||
(6, 'air_rescuer', NULL, NULL, 0, 0, 1, 0),
|
||||
(7, 'admin', 'administrator', NULL, 0, 0, 0, 0),
|
||||
(8, 'staff', 'billing', NULL, 0, 0, 0, 0),
|
||||
(9, 'technician', NULL, NULL, 0, 0, 0, 0),
|
||||
(10, 'technician', NULL, NULL, 0, 0, 0, 1),
|
||||
(11, 'flight_assistant', NULL, NULL, 0, 0, 0, 0),
|
||||
(12, 'staff', 'manager', NULL, 0, 0, 0, 0),
|
||||
(13, 'pilot', NULL, 'freelance', 0, 0, 0, 0),
|
||||
(14, 'pilot', NULL, 'dry_lease', 0, 0, 0, 0),
|
||||
(15, 'staff', 'control_center', NULL, 0, 0, 0, 0)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
role_code = VALUES(role_code),
|
||||
staff_role_label = VALUES(staff_role_label),
|
||||
pilot_category = VALUES(pilot_category),
|
||||
is_chief_pilot = VALUES(is_chief_pilot),
|
||||
is_chief_physician = VALUES(is_chief_physician),
|
||||
is_chief_physician_in_charge = VALUES(is_chief_physician_in_charge),
|
||||
is_chief_technician = VALUES(is_chief_technician);
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS legacy_user_role_map;
|
||||
DROP TABLE IF EXISTS user_old_id_map;
|
||||
DROP TABLE IF EXISTS user_old_import;
|
||||
421
migrations/goose/20260528_user_import_apply.sql
Normal file
421
migrations/goose/20260528_user_import_apply.sql
Normal file
@@ -0,0 +1,421 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy user staging data into new auth/contact schema.
|
||||
-- Expected flow before this migration:
|
||||
-- 1) Run previous migration that creates `user_old_import` and role map.
|
||||
-- 2) Import old dump rows into `user_old_import`.
|
||||
-- This migration maps old integer IDs into BINARY(16) UUID-style IDs,
|
||||
-- then upserts into `users`, `user_roles`, and role-specific profile tables.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1) Reuse existing users by normalized email when possible.
|
||||
INSERT INTO user_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
u.id AS new_id
|
||||
FROM user_old_import s
|
||||
JOIN users u
|
||||
ON LOWER(TRIM(u.email)) = LOWER(TRIM(s.email))
|
||||
LEFT JOIN user_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL
|
||||
AND s.email IS NOT NULL
|
||||
AND TRIM(s.email) <> '';
|
||||
|
||||
-- 2) Generate IDs for remaining legacy users.
|
||||
INSERT INTO user_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM user_old_import s
|
||||
LEFT JOIN user_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
-- 3) Upsert core users.
|
||||
INSERT INTO users (
|
||||
id,
|
||||
role_id,
|
||||
email,
|
||||
username,
|
||||
first_name,
|
||||
last_name,
|
||||
mobile_phone,
|
||||
timezone,
|
||||
is_active,
|
||||
password_hash,
|
||||
salt_value,
|
||||
email_verified_at,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS id,
|
||||
r.id AS role_id,
|
||||
CONCAT(
|
||||
COALESCE(
|
||||
NULLIF(LOWER(TRIM(SUBSTRING_INDEX(NULLIF(s.email, ''), '@', 1))), ''),
|
||||
CONCAT('legacy-user-', s.id)
|
||||
),
|
||||
'+u', s.id,
|
||||
'@mybit-innovation'
|
||||
) AS email,
|
||||
NULLIF(LEFT(TRIM(COALESCE(s.username, '')), 100), '') AS username,
|
||||
LEFT(SUBSTRING_INDEX(TRIM(COALESCE(NULLIF(s.fullname, ''), NULLIF(s.username, ''), CONCAT('Legacy User ', s.id))), ' ', 1), 100) AS first_name,
|
||||
LEFT(
|
||||
COALESCE(
|
||||
NULLIF(
|
||||
TRIM(
|
||||
SUBSTRING(
|
||||
TRIM(COALESCE(NULLIF(s.fullname, ''), NULLIF(s.username, ''), CONCAT('Legacy User ', s.id))),
|
||||
LENGTH(SUBSTRING_INDEX(TRIM(COALESCE(NULLIF(s.fullname, ''), NULLIF(s.username, ''), CONCAT('Legacy User ', s.id))), ' ', 1)) + 1
|
||||
)
|
||||
),
|
||||
''
|
||||
),
|
||||
'-'
|
||||
),
|
||||
100
|
||||
) AS last_name,
|
||||
LEFT(TRIM(COALESCE(s.mobile, s.phone, '')), 32) AS mobile_phone,
|
||||
'UTC' AS timezone,
|
||||
CASE WHEN COALESCE(s.visible, 1) = 1 THEN 1 ELSE 0 END AS is_active,
|
||||
NULL AS password_hash,
|
||||
NULL AS salt_value,
|
||||
NULL AS email_verified_at,
|
||||
COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
|
||||
COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
LEFT JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
JOIN roles r ON r.code = COALESCE(lrm.role_code, 'staff')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
role_id = VALUES(role_id),
|
||||
username = VALUES(username),
|
||||
first_name = VALUES(first_name),
|
||||
last_name = VALUES(last_name),
|
||||
mobile_phone = VALUES(mobile_phone),
|
||||
timezone = VALUES(timezone),
|
||||
is_active = VALUES(is_active),
|
||||
password_hash = NULL,
|
||||
salt_value = NULL,
|
||||
email_verified_at = NULL,
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 4) Ensure user_roles relation exists for mapped role.
|
||||
INSERT INTO user_roles (
|
||||
id,
|
||||
user_id,
|
||||
role_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS id,
|
||||
m.new_id AS user_id,
|
||||
r.id AS role_id,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
LEFT JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
JOIN roles r ON r.code = COALESCE(lrm.role_code, 'staff')
|
||||
ON DUPLICATE KEY UPDATE
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 5) Pilot profiles.
|
||||
INSERT INTO pilot_profiles (
|
||||
user_id,
|
||||
pilot_category,
|
||||
short_name,
|
||||
license_no,
|
||||
technician_license_no,
|
||||
is_chief_pilot,
|
||||
total_flight_minutes,
|
||||
responsible_pilot_minutes,
|
||||
second_pilot_minutes,
|
||||
double_command_minutes,
|
||||
flight_instructor_minutes,
|
||||
night_flight_minutes,
|
||||
ifr_flight_minutes,
|
||||
location,
|
||||
postcode,
|
||||
street_line,
|
||||
photo_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS user_id,
|
||||
COALESCE(NULLIF(lrm.pilot_category, ''), 'regular') AS pilot_category,
|
||||
LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
|
||||
LEFT(TRIM(COALESCE(s.license, '')), 120) AS license_no,
|
||||
LEFT(TRIM(COALESCE(s.techLicense, '')), 120) AS technician_license_no,
|
||||
COALESCE(lrm.is_chief_pilot, 0) AS is_chief_pilot,
|
||||
CASE WHEN TRIM(COALESCE(s.airport_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
|
||||
THEN CAST(SUBSTRING_INDEX(TRIM(s.airport_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.airport_pilot), ':', -1) AS UNSIGNED)
|
||||
ELSE 0 END AS total_flight_minutes,
|
||||
CASE WHEN TRIM(COALESCE(s.responsible_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
|
||||
THEN CAST(SUBSTRING_INDEX(TRIM(s.responsible_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.responsible_pilot), ':', -1) AS UNSIGNED)
|
||||
ELSE 0 END AS responsible_pilot_minutes,
|
||||
CASE WHEN TRIM(COALESCE(s.second_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
|
||||
THEN CAST(SUBSTRING_INDEX(TRIM(s.second_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.second_pilot), ':', -1) AS UNSIGNED)
|
||||
ELSE 0 END AS second_pilot_minutes,
|
||||
CASE WHEN TRIM(COALESCE(s.double_tax_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
|
||||
THEN CAST(SUBSTRING_INDEX(TRIM(s.double_tax_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.double_tax_pilot), ':', -1) AS UNSIGNED)
|
||||
ELSE 0 END AS double_command_minutes,
|
||||
CASE WHEN TRIM(COALESCE(s.flight_instructor_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
|
||||
THEN CAST(SUBSTRING_INDEX(TRIM(s.flight_instructor_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.flight_instructor_pilot), ':', -1) AS UNSIGNED)
|
||||
ELSE 0 END AS flight_instructor_minutes,
|
||||
CASE WHEN TRIM(COALESCE(s.night_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
|
||||
THEN CAST(SUBSTRING_INDEX(TRIM(s.night_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.night_pilot), ':', -1) AS UNSIGNED)
|
||||
ELSE 0 END AS night_flight_minutes,
|
||||
CASE WHEN TRIM(COALESCE(s.fir_pilot, '')) REGEXP '^[0-9]+:[0-9]{1,2}$'
|
||||
THEN CAST(SUBSTRING_INDEX(TRIM(s.fir_pilot), ':', 1) AS UNSIGNED) * 60 + CAST(SUBSTRING_INDEX(TRIM(s.fir_pilot), ':', -1) AS UNSIGNED)
|
||||
ELSE 0 END AS ifr_flight_minutes,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
|
||||
LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
|
||||
LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
|
||||
LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
|
||||
COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
|
||||
COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
JOIN users u ON u.id = m.new_id
|
||||
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
WHERE lrm.role_code = 'pilot'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
pilot_category = VALUES(pilot_category),
|
||||
short_name = VALUES(short_name),
|
||||
license_no = VALUES(license_no),
|
||||
technician_license_no = VALUES(technician_license_no),
|
||||
is_chief_pilot = VALUES(is_chief_pilot),
|
||||
total_flight_minutes = VALUES(total_flight_minutes),
|
||||
responsible_pilot_minutes = VALUES(responsible_pilot_minutes),
|
||||
second_pilot_minutes = VALUES(second_pilot_minutes),
|
||||
double_command_minutes = VALUES(double_command_minutes),
|
||||
flight_instructor_minutes = VALUES(flight_instructor_minutes),
|
||||
night_flight_minutes = VALUES(night_flight_minutes),
|
||||
ifr_flight_minutes = VALUES(ifr_flight_minutes),
|
||||
location = VALUES(location),
|
||||
postcode = VALUES(postcode),
|
||||
street_line = VALUES(street_line),
|
||||
photo_file_id = VALUES(photo_file_id),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 6) Doctor profiles.
|
||||
INSERT INTO doctor_profiles (
|
||||
user_id,
|
||||
short_name,
|
||||
medical_license_no,
|
||||
is_chief_physician,
|
||||
location,
|
||||
postcode,
|
||||
street_line,
|
||||
photo_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS user_id,
|
||||
LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
|
||||
LEFT(TRIM(COALESCE(s.license, '')), 120) AS medical_license_no,
|
||||
COALESCE(lrm.is_chief_physician, 0) AS is_chief_physician,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
|
||||
LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
|
||||
LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
|
||||
LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
|
||||
COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
|
||||
COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
JOIN users u ON u.id = m.new_id
|
||||
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
WHERE lrm.role_code = 'doctor'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
short_name = VALUES(short_name),
|
||||
medical_license_no = VALUES(medical_license_no),
|
||||
is_chief_physician = VALUES(is_chief_physician),
|
||||
location = VALUES(location),
|
||||
postcode = VALUES(postcode),
|
||||
street_line = VALUES(street_line),
|
||||
photo_file_id = VALUES(photo_file_id),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 7) Air rescuer profiles.
|
||||
INSERT INTO air_rescuer_profiles (
|
||||
user_id,
|
||||
short_name,
|
||||
is_chief_physician_in_charge,
|
||||
responsible_flight_rescuer,
|
||||
location,
|
||||
postcode,
|
||||
street_line,
|
||||
photo_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS user_id,
|
||||
LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
|
||||
COALESCE(lrm.is_chief_physician_in_charge, 0) AS is_chief_physician_in_charge,
|
||||
0 AS responsible_flight_rescuer,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
|
||||
LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
|
||||
LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
|
||||
LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
|
||||
COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
|
||||
COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
JOIN users u ON u.id = m.new_id
|
||||
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
WHERE lrm.role_code = 'air_rescuer'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
short_name = VALUES(short_name),
|
||||
is_chief_physician_in_charge = VALUES(is_chief_physician_in_charge),
|
||||
responsible_flight_rescuer = VALUES(responsible_flight_rescuer),
|
||||
location = VALUES(location),
|
||||
postcode = VALUES(postcode),
|
||||
street_line = VALUES(street_line),
|
||||
photo_file_id = VALUES(photo_file_id),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 8) Technician profiles.
|
||||
INSERT INTO technician_profiles (
|
||||
user_id,
|
||||
short_name,
|
||||
license_no,
|
||||
is_chief_technician,
|
||||
location,
|
||||
postcode,
|
||||
street_line,
|
||||
photo_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS user_id,
|
||||
LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
|
||||
LEFT(TRIM(COALESCE(s.license, '')), 120) AS license_no,
|
||||
COALESCE(lrm.is_chief_technician, 0) AS is_chief_technician,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
|
||||
LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
|
||||
LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
|
||||
LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
|
||||
COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
|
||||
COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
JOIN users u ON u.id = m.new_id
|
||||
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
WHERE lrm.role_code = 'technician'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
short_name = VALUES(short_name),
|
||||
license_no = VALUES(license_no),
|
||||
is_chief_technician = VALUES(is_chief_technician),
|
||||
location = VALUES(location),
|
||||
postcode = VALUES(postcode),
|
||||
street_line = VALUES(street_line),
|
||||
photo_file_id = VALUES(photo_file_id),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 9) Flight assistant profiles.
|
||||
INSERT INTO flight_assistant_profiles (
|
||||
user_id,
|
||||
short_name,
|
||||
location,
|
||||
postcode,
|
||||
street_line,
|
||||
photo_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS user_id,
|
||||
LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
|
||||
LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
|
||||
LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
|
||||
LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
|
||||
COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
|
||||
COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
JOIN users u ON u.id = m.new_id
|
||||
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
WHERE lrm.role_code = 'flight_assistant'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
short_name = VALUES(short_name),
|
||||
location = VALUES(location),
|
||||
postcode = VALUES(postcode),
|
||||
street_line = VALUES(street_line),
|
||||
photo_file_id = VALUES(photo_file_id),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 10) Staff profiles.
|
||||
INSERT INTO staff_profiles (
|
||||
user_id,
|
||||
short_name,
|
||||
role_label,
|
||||
location,
|
||||
postcode,
|
||||
street_line,
|
||||
photo_file_id,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS user_id,
|
||||
LEFT(TRIM(COALESCE(s.shortName, '')), 120) AS short_name,
|
||||
LEFT(TRIM(COALESCE(lrm.staff_role_label, 'staff')), 120) AS role_label,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 255) AS location,
|
||||
LEFT(TRIM(COALESCE(s.zipCode, '')), 32) AS postcode,
|
||||
LEFT(TRIM(COALESCE(s.street, '')), 255) AS street_line,
|
||||
LEFT(TRIM(COALESCE(s.photo, '')), 255) AS photo_file_id,
|
||||
COALESCE(s.regDate, UTC_TIMESTAMP()) AS created_at,
|
||||
COALESCE(s.lastVisit, UTC_TIMESTAMP()) AS updated_at
|
||||
FROM user_old_import s
|
||||
JOIN user_old_id_map m ON m.old_id = s.id
|
||||
JOIN users u ON u.id = m.new_id
|
||||
JOIN legacy_user_role_map lrm ON lrm.legacy_role = s.role
|
||||
WHERE lrm.role_code = 'staff'
|
||||
ON DUPLICATE KEY UPDATE
|
||||
short_name = VALUES(short_name),
|
||||
role_label = VALUES(role_label),
|
||||
location = VALUES(location),
|
||||
postcode = VALUES(postcode),
|
||||
street_line = VALUES(street_line),
|
||||
photo_file_id = VALUES(photo_file_id),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- Data migration is intentionally non-reversible.
|
||||
-- Keep imported data and ID mapping as audit trail.
|
||||
SELECT 1;
|
||||
35
migrations/goose/20260529_bases_import_staging.sql
Normal file
35
migrations/goose/20260529_bases_import_staging.sql
Normal file
@@ -0,0 +1,35 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy `bases` import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS bases_old_import (
|
||||
id int(11) NOT NULL,
|
||||
name varchar(50) NOT NULL,
|
||||
code varchar(10) NOT NULL,
|
||||
icao varchar(255) DEFAULT NULL,
|
||||
address varchar(255) DEFAULT NULL,
|
||||
phone varchar(50) DEFAULT NULL,
|
||||
mobile varchar(50) DEFAULT NULL,
|
||||
email varchar(50) DEFAULT NULL,
|
||||
rescue_emails varchar(255) DEFAULT NULL,
|
||||
doctor_emails varchar(255) DEFAULT NULL,
|
||||
sms_alert int(11) NOT NULL DEFAULT 1,
|
||||
check_list tinyint(1) DEFAULT 0,
|
||||
dry tinyint(1) DEFAULT 0,
|
||||
control_center tinyint(1) DEFAULT 0,
|
||||
service_transfer_list tinyint(1) DEFAULT 0,
|
||||
visible tinyint(1) DEFAULT 0,
|
||||
position tinyint(4) NOT NULL,
|
||||
type varchar(255) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS base_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_base_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS base_old_id_map;
|
||||
DROP TABLE IF EXISTS bases_old_import;
|
||||
193
migrations/goose/20260530_bases_import_apply.sql
Normal file
193
migrations/goose/20260530_bases_import_apply.sql
Normal file
@@ -0,0 +1,193 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy base staging data into new bases schema.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1) Reuse existing base rows by normalized (base, abbreviation) when possible.
|
||||
INSERT INTO base_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
b.id AS new_id
|
||||
FROM bases_old_import s
|
||||
JOIN bases b
|
||||
ON LOWER(TRIM(b.base)) = LOWER(TRIM(s.name))
|
||||
AND LOWER(TRIM(COALESCE(b.base_abbreviation, ''))) = LOWER(TRIM(COALESCE(s.code, '')))
|
||||
LEFT JOIN base_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
-- 2) Generate IDs for remaining legacy bases.
|
||||
INSERT INTO base_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM bases_old_import s
|
||||
LEFT JOIN base_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
-- 3) Upsert base rows.
|
||||
INSERT INTO bases (
|
||||
id,
|
||||
base,
|
||||
base_category_id,
|
||||
base_abbreviation,
|
||||
address,
|
||||
landline_number,
|
||||
mobile_number,
|
||||
email,
|
||||
sortkey,
|
||||
sms_alert,
|
||||
checklist,
|
||||
dry,
|
||||
control_center,
|
||||
dul,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS id,
|
||||
LEFT(TRIM(COALESCE(s.name, '')), 150) AS base,
|
||||
bc.id AS base_category_id,
|
||||
LEFT(TRIM(COALESCE(s.code, '')), 64) AS base_abbreviation,
|
||||
LEFT(TRIM(COALESCE(s.address, '')), 255) AS address,
|
||||
LEFT(TRIM(COALESCE(s.phone, '')), 64) AS landline_number,
|
||||
LEFT(TRIM(COALESCE(s.mobile, '')), 64) AS mobile_number,
|
||||
LEFT(TRIM(COALESCE(s.email, '')), 191) AS email,
|
||||
COALESCE(s.position, 0) AS sortkey,
|
||||
CASE WHEN COALESCE(s.sms_alert, 0) <> 0 THEN 1 ELSE 0 END AS sms_alert,
|
||||
CASE WHEN COALESCE(s.check_list, 0) <> 0 THEN 1 ELSE 0 END AS checklist,
|
||||
CASE WHEN COALESCE(s.dry, 0) <> 0 THEN 1 ELSE 0 END AS dry,
|
||||
CASE WHEN COALESCE(s.control_center, 0) <> 0 THEN 1 ELSE 0 END AS control_center,
|
||||
CASE WHEN COALESCE(s.service_transfer_list, 0) <> 0 THEN 1 ELSE 0 END AS dul,
|
||||
CASE WHEN COALESCE(s.visible, 0) <> 0 THEN 1 ELSE 0 END AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM bases_old_import s
|
||||
JOIN base_old_id_map m ON m.old_id = s.id
|
||||
LEFT JOIN base_categories bc
|
||||
ON bc.`key` = CASE WHEN LOWER(TRIM(COALESCE(s.type, ''))) = 'hems' THEN 'hems' ELSE 'regular' END
|
||||
ON DUPLICATE KEY UPDATE
|
||||
base = VALUES(base),
|
||||
base_category_id = VALUES(base_category_id),
|
||||
base_abbreviation = VALUES(base_abbreviation),
|
||||
address = VALUES(address),
|
||||
landline_number = VALUES(landline_number),
|
||||
mobile_number = VALUES(mobile_number),
|
||||
email = VALUES(email),
|
||||
sortkey = VALUES(sortkey),
|
||||
sms_alert = VALUES(sms_alert),
|
||||
checklist = VALUES(checklist),
|
||||
dry = VALUES(dry),
|
||||
control_center = VALUES(control_center),
|
||||
dul = VALUES(dul),
|
||||
is_active = VALUES(is_active),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
-- 4) Build extracted legacy base-contact links from serialized fields.
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp_base_contact_extract;
|
||||
CREATE TEMPORARY TABLE tmp_base_contact_extract (
|
||||
old_base_id int(11) NOT NULL,
|
||||
role_code varchar(64) NOT NULL,
|
||||
legacy_user_id int(11) NOT NULL,
|
||||
PRIMARY KEY (old_base_id, role_code, legacy_user_id)
|
||||
) ENGINE=MEMORY;
|
||||
|
||||
INSERT IGNORE INTO tmp_base_contact_extract (old_base_id, role_code, legacy_user_id)
|
||||
WITH RECURSIVE seq AS (
|
||||
SELECT 1 AS n
|
||||
UNION ALL
|
||||
SELECT n + 1 FROM seq WHERE n < 128
|
||||
),
|
||||
src AS (
|
||||
SELECT
|
||||
b.id AS old_base_id,
|
||||
'responsible_flight_rescuer' AS role_code,
|
||||
COALESCE(b.rescue_emails, '') AS serialized
|
||||
FROM bases_old_import b
|
||||
UNION ALL
|
||||
SELECT
|
||||
b.id AS old_base_id,
|
||||
'chief_physician_in_charge' AS role_code,
|
||||
COALESCE(b.doctor_emails, '') AS serialized
|
||||
FROM bases_old_import b
|
||||
)
|
||||
SELECT
|
||||
src.old_base_id,
|
||||
src.role_code,
|
||||
CAST(
|
||||
SUBSTRING_INDEX(
|
||||
SUBSTRING_INDEX(
|
||||
REGEXP_SUBSTR(src.serialized, 's:[0-9]+:"[0-9]+"', 1, seq.n),
|
||||
'"',
|
||||
2
|
||||
),
|
||||
'"',
|
||||
-1
|
||||
) AS UNSIGNED
|
||||
) AS legacy_user_id
|
||||
FROM src
|
||||
JOIN seq
|
||||
ON REGEXP_SUBSTR(src.serialized, 's:[0-9]+:"[0-9]+"', 1, seq.n) IS NOT NULL;
|
||||
|
||||
-- 5) Replace base_contact_roles for imported bases (targeted role codes only).
|
||||
DELETE bcr
|
||||
FROM base_contact_roles bcr
|
||||
JOIN base_old_id_map bm ON bm.new_id = bcr.base_id
|
||||
WHERE bcr.role_code IN ('responsible_flight_rescuer', 'chief_physician_in_charge');
|
||||
|
||||
-- 6) Insert deduplicated base_contact_roles by mapping legacy user IDs to new user IDs.
|
||||
INSERT INTO base_contact_roles (
|
||||
id,
|
||||
base_id,
|
||||
contact_id,
|
||||
role_code,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS id,
|
||||
bm.new_id AS base_id,
|
||||
um.new_id AS contact_id,
|
||||
e.role_code AS role_code,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM (
|
||||
SELECT DISTINCT old_base_id, role_code, legacy_user_id
|
||||
FROM tmp_base_contact_extract
|
||||
) e
|
||||
JOIN base_old_id_map bm ON bm.old_id = e.old_base_id
|
||||
JOIN user_old_id_map um ON um.old_id = e.legacy_user_id
|
||||
;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp_base_contact_extract;
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- no-op rollback
|
||||
24
migrations/goose/20260531_slings_import_staging.sql
Normal file
24
migrations/goose/20260531_slings_import_staging.sql
Normal file
@@ -0,0 +1,24 @@
|
||||
-- +goose Up
|
||||
-- Prepare staging tables for legacy `slings` import.
|
||||
|
||||
CREATE TABLE IF NOT EXISTS slings_old_import (
|
||||
id int(11) NOT NULL,
|
||||
cat int(11) NOT NULL,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
type varchar(255) DEFAULT NULL,
|
||||
length varchar(255) DEFAULT NULL,
|
||||
weight varchar(255) DEFAULT NULL,
|
||||
electric varchar(255) DEFAULT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS slings_old_id_map (
|
||||
old_id int(11) NOT NULL,
|
||||
new_id binary(16) NOT NULL,
|
||||
PRIMARY KEY (old_id),
|
||||
UNIQUE KEY uq_slings_old_id_map_new_id (new_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;
|
||||
|
||||
-- +goose Down
|
||||
DROP TABLE IF EXISTS slings_old_id_map;
|
||||
DROP TABLE IF EXISTS slings_old_import;
|
||||
99
migrations/goose/20260532_slings_import_apply.sql
Normal file
99
migrations/goose/20260532_slings_import_apply.sql
Normal file
@@ -0,0 +1,99 @@
|
||||
-- +goose Up
|
||||
-- Apply legacy sling staging data into new facilities schema.
|
||||
|
||||
START TRANSACTION;
|
||||
|
||||
-- 1) Reuse existing facilities rows by normalized (category, name, type) when possible.
|
||||
INSERT INTO slings_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
f.id AS new_id
|
||||
FROM slings_old_import s
|
||||
JOIN facilities f
|
||||
ON LOWER(TRIM(f.category)) = LOWER(TRIM(
|
||||
CASE
|
||||
WHEN s.cat = 1 THEN 'hems-hec-sling'
|
||||
WHEN s.cat = 2 THEN 'logging-sling'
|
||||
WHEN s.cat = 3 THEN 'heslo-sling'
|
||||
WHEN s.cat IN (4, 6) THEN 'fuel-truck'
|
||||
WHEN s.cat = 5 THEN 'hec-sling'
|
||||
ELSE 'hec-sling'
|
||||
END
|
||||
))
|
||||
AND LOWER(TRIM(f.name)) = LOWER(TRIM(COALESCE(s.name, '')))
|
||||
AND LOWER(TRIM(f.type)) = LOWER(TRIM(COALESCE(s.type, '')))
|
||||
LEFT JOIN slings_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
-- 2) Generate IDs for remaining legacy sling rows.
|
||||
INSERT INTO slings_old_id_map (old_id, new_id)
|
||||
SELECT
|
||||
s.id AS old_id,
|
||||
UNHEX(REPLACE(
|
||||
LOWER(CONCAT(
|
||||
LPAD(HEX(FLOOR(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED) / 65536)), 8, '0'),
|
||||
'-',
|
||||
LPAD(HEX(MOD(CAST(UNIX_TIMESTAMP(UTC_TIMESTAMP(3)) * 1000 AS UNSIGNED), 65536)), 4, '0'),
|
||||
'-',
|
||||
'7', LPAD(HEX(FLOOR(RAND() * 4096)), 3, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 16384) + 32768), 4, '0'),
|
||||
'-',
|
||||
LPAD(HEX(FLOOR(RAND() * 281474976710656)), 12, '0')
|
||||
)),
|
||||
'-', ''
|
||||
)) AS new_id
|
||||
FROM slings_old_import s
|
||||
LEFT JOIN slings_old_id_map m ON m.old_id = s.id
|
||||
WHERE m.old_id IS NULL;
|
||||
|
||||
-- 3) Upsert into facilities.
|
||||
INSERT INTO facilities (
|
||||
id,
|
||||
category,
|
||||
name,
|
||||
type,
|
||||
length,
|
||||
weight,
|
||||
electric,
|
||||
note,
|
||||
is_active,
|
||||
created_at,
|
||||
updated_at
|
||||
)
|
||||
SELECT
|
||||
m.new_id AS id,
|
||||
CASE
|
||||
WHEN s.cat = 1 THEN 'hems-hec-sling'
|
||||
WHEN s.cat = 2 THEN 'logging-sling'
|
||||
WHEN s.cat = 3 THEN 'heslo-sling'
|
||||
WHEN s.cat IN (4, 6) THEN 'fuel-truck'
|
||||
WHEN s.cat = 5 THEN 'hec-sling'
|
||||
ELSE 'hec-sling'
|
||||
END AS category,
|
||||
LEFT(TRIM(COALESCE(s.name, '')), 150) AS name,
|
||||
LEFT(TRIM(COALESCE(s.type, '')), 100) AS type,
|
||||
LEFT(TRIM(COALESCE(s.length, '')), 64) AS length,
|
||||
LEFT(TRIM(COALESCE(s.weight, '')), 64) AS weight,
|
||||
LEFT(TRIM(COALESCE(s.electric, '')), 255) AS electric,
|
||||
NULL AS note,
|
||||
1 AS is_active,
|
||||
UTC_TIMESTAMP() AS created_at,
|
||||
UTC_TIMESTAMP() AS updated_at
|
||||
FROM slings_old_import s
|
||||
JOIN slings_old_id_map m ON m.old_id = s.id
|
||||
ON DUPLICATE KEY UPDATE
|
||||
category = VALUES(category),
|
||||
name = VALUES(name),
|
||||
type = VALUES(type),
|
||||
length = VALUES(length),
|
||||
weight = VALUES(weight),
|
||||
electric = VALUES(electric),
|
||||
note = VALUES(note),
|
||||
is_active = VALUES(is_active),
|
||||
updated_at = UTC_TIMESTAMP();
|
||||
|
||||
COMMIT;
|
||||
|
||||
-- +goose Down
|
||||
-- no-op rollback
|
||||
17
migrations/goose/20260533_facilities_electric_to_string.sql
Normal file
17
migrations/goose/20260533_facilities_electric_to_string.sql
Normal file
@@ -0,0 +1,17 @@
|
||||
-- +goose Up
|
||||
-- +goose StatementBegin
|
||||
ALTER TABLE facilities
|
||||
MODIFY COLUMN electric VARCHAR(255) NOT NULL DEFAULT '';
|
||||
-- +goose StatementEnd
|
||||
|
||||
-- +goose Down
|
||||
-- +goose StatementBegin
|
||||
UPDATE facilities
|
||||
SET electric = CASE
|
||||
WHEN LOWER(TRIM(electric)) IN ('', '0', 'false', 'no', 'n') THEN '0'
|
||||
ELSE '1'
|
||||
END;
|
||||
|
||||
ALTER TABLE facilities
|
||||
MODIFY COLUMN electric TINYINT(1) NOT NULL DEFAULT 0;
|
||||
-- +goose StatementEnd
|
||||
26
migrations/goose/20260602_add_flight_id_to_duty_rosters.sql
Normal file
26
migrations/goose/20260602_add_flight_id_to_duty_rosters.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
-- +goose Up
|
||||
-- Align duty roster schema with takeover flow.
|
||||
-- A takeover creates a fresh roster row, so base/date must be a lookup index,
|
||||
-- not a unique constraint.
|
||||
|
||||
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);
|
||||
|
||||
DROP INDEX idx_roster_base_date ON duty_rosters;
|
||||
|
||||
CREATE INDEX idx_roster_base_date
|
||||
ON duty_rosters (base_id, duty_date);
|
||||
|
||||
-- +goose Down
|
||||
DROP INDEX idx_roster_base_date ON duty_rosters;
|
||||
|
||||
CREATE UNIQUE INDEX idx_roster_base_date
|
||||
ON duty_rosters (base_id, duty_date);
|
||||
|
||||
DROP INDEX idx_roster_flight_id ON duty_rosters;
|
||||
|
||||
ALTER TABLE duty_rosters
|
||||
DROP COLUMN flight_id;
|
||||
15
migrations/goose/20260610_contact_username_non_unique.sql
Normal file
15
migrations/goose/20260610_contact_username_non_unique.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
-- Username uniqueness is now enforced in the backend for contact flows,
|
||||
-- so keep a regular index for lookups instead of a unique constraint.
|
||||
|
||||
DROP INDEX IF EXISTS idx_users_username ON users;
|
||||
|
||||
CREATE INDEX idx_users_username
|
||||
ON users (username);
|
||||
|
||||
-- +goose Down
|
||||
DROP INDEX IF EXISTS idx_users_username ON users;
|
||||
|
||||
CREATE UNIQUE INDEX idx_users_username
|
||||
ON users (username);
|
||||
iya
|
||||
@@ -0,0 +1,53 @@
|
||||
-- +goose Up
|
||||
-- Normalize base operational shift times to use per-day ranges.
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
ADD COLUMN IF NOT EXISTS date_start DATE NULL AFTER base_id,
|
||||
ADD COLUMN IF NOT EXISTS date_end DATE NULL AFTER date_start;
|
||||
|
||||
UPDATE base_operational_shift_times
|
||||
SET date_start = COALESCE(date_start, operation_date),
|
||||
date_end = COALESCE(date_end, operation_date)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
DROP FOREIGN KEY fk_base_operational_shift_times_base;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
DROP INDEX idx_base_operational_shift_times_base_date;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
DROP COLUMN operation_date;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
ADD KEY idx_base_operational_shift_times_base_date (base_id, date_start, date_end),
|
||||
MODIFY COLUMN date_start DATE NULL,
|
||||
MODIFY COLUMN date_end DATE NULL,
|
||||
ADD CONSTRAINT fk_base_operational_shift_times_base
|
||||
FOREIGN KEY (base_id) REFERENCES bases(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
|
||||
-- +goose Down
|
||||
ALTER TABLE base_operational_shift_times
|
||||
ADD COLUMN IF NOT EXISTS operation_date DATE NULL AFTER base_id;
|
||||
|
||||
UPDATE base_operational_shift_times
|
||||
SET operation_date = COALESCE(operation_date, date_start)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
DROP FOREIGN KEY fk_base_operational_shift_times_base;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
DROP INDEX idx_base_operational_shift_times_base_date;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
ADD KEY idx_base_operational_shift_times_base_date (base_id, operation_date),
|
||||
DROP COLUMN date_start,
|
||||
DROP COLUMN date_end,
|
||||
MODIFY COLUMN operation_date DATE NOT NULL,
|
||||
ADD CONSTRAINT fk_base_operational_shift_times_base
|
||||
FOREIGN KEY (base_id) REFERENCES bases(id)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE;
|
||||
31
migrations/goose/20260619_mission_twilight_schedule.sql
Normal file
31
migrations/goose/20260619_mission_twilight_schedule.sql
Normal file
@@ -0,0 +1,31 @@
|
||||
-- +goose Up
|
||||
|
||||
ALTER TABLE bases
|
||||
ADD COLUMN IF NOT EXISTS latitude DECIMAL(10,7) NOT NULL DEFAULT 0 AFTER address,
|
||||
ADD COLUMN IF NOT EXISTS longitude DECIMAL(10,7) NOT NULL DEFAULT 0 AFTER latitude;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
ADD COLUMN IF NOT EXISTS start_time_type VARCHAR(16) NOT NULL DEFAULT 'FIXED' AFTER date_end,
|
||||
ADD COLUMN IF NOT EXISTS end_time_type VARCHAR(16) NOT NULL DEFAULT 'FIXED' AFTER start_time_type;
|
||||
|
||||
ALTER TABLE missions
|
||||
ADD COLUMN IF NOT EXISTS start_time TIME NULL AFTER note,
|
||||
ADD COLUMN IF NOT EXISTS end_time TIME NULL AFTER start_time;
|
||||
|
||||
ALTER TABLE missions
|
||||
MODIFY COLUMN start_time TIME NULL,
|
||||
MODIFY COLUMN end_time TIME NULL;
|
||||
|
||||
-- +goose Down
|
||||
|
||||
ALTER TABLE missions
|
||||
DROP COLUMN IF EXISTS end_time,
|
||||
DROP COLUMN IF EXISTS start_time;
|
||||
|
||||
ALTER TABLE base_operational_shift_times
|
||||
DROP COLUMN IF EXISTS end_time_type,
|
||||
DROP COLUMN IF EXISTS start_time_type;
|
||||
|
||||
ALTER TABLE bases
|
||||
DROP COLUMN IF EXISTS longitude,
|
||||
DROP COLUMN IF EXISTS latitude;
|
||||
15
migrations/goose/20260630_easa_release_sign_requires_pin.sql
Normal file
15
migrations/goose/20260630_easa_release_sign_requires_pin.sql
Normal file
@@ -0,0 +1,15 @@
|
||||
-- +goose Up
|
||||
-- Enable security-PIN confirmation for signing an EASA maintenance release
|
||||
-- (Release to Service). Fresh DBs get this via the default PIN policy at seed
|
||||
-- time; this backfills existing permission rows. The guard avoids overriding a
|
||||
-- value an admin has already customised (updated_by set).
|
||||
UPDATE permissions
|
||||
SET requires_pin = 1
|
||||
WHERE `key` = 'easa_release.sign'
|
||||
AND (updated_by IS NULL OR LENGTH(updated_by) = 0);
|
||||
|
||||
-- +goose Down
|
||||
UPDATE permissions
|
||||
SET requires_pin = 0
|
||||
WHERE `key` = 'easa_release.sign'
|
||||
AND (updated_by IS NULL OR LENGTH(updated_by) = 0);
|
||||
Reference in New Issue
Block a user