fix(migration): case-insensitive dedupe on units backfill + use insertOrIgnore
MariaDB default collation is case-insensitive on VARCHAR unique indexes, so 'L' and 'l' clash on units_company_id_code_unique. When a tenant had 'L' in parts.unit (uppercase) and the migration seeds 'l' (lowercase), the extras loop tried to re-insert 'L' and errored out — blocking all subsequent migrations (including the new injector_protocols tables). Fix: lowercase the comparison + switch the extras insert to insertOrIgnore so a residual race is a no-op. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -81,11 +81,14 @@ return new class extends Migration
|
|||||||
}
|
}
|
||||||
$extraCodes = $extraCodes->unique();
|
$extraCodes = $extraCodes->unique();
|
||||||
|
|
||||||
$existingCodes = DB::table('units')->where('company_id', $companyId)->pluck('code')->all();
|
// Case-insensitive dedupe: MariaDB default collation treats 'L' == 'l'
|
||||||
|
// as the same value on the unique index, so we compare lowercased.
|
||||||
|
$existingCodes = DB::table('units')->where('company_id', $companyId)
|
||||||
|
->pluck('code')->map(fn ($c) => mb_strtolower((string) $c))->all();
|
||||||
foreach ($extraCodes as $code) {
|
foreach ($extraCodes as $code) {
|
||||||
if (in_array($code, $existingCodes, true)) continue;
|
if (in_array(mb_strtolower($code), $existingCodes, true)) continue;
|
||||||
if (mb_strlen($code) > 16) continue;
|
if (mb_strlen($code) > 16) continue;
|
||||||
DB::table('units')->insert([
|
DB::table('units')->insertOrIgnore([
|
||||||
'company_id' => $companyId,
|
'company_id' => $companyId,
|
||||||
'code' => $code,
|
'code' => $code,
|
||||||
'name_ro' => $code,
|
'name_ro' => $code,
|
||||||
|
|||||||
Reference in New Issue
Block a user