Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
e47b0a3
chore: plan size deduplication and cross-reference table migrations
Copilot Apr 21, 2026
7803c51
feat: deduplicate sizes and create sizes_sizegroup cross-reference table
Copilot Apr 21, 2026
b060b78
revert: undo cs-fixer formatting changes outside db/migrations and co…
Copilot Apr 21, 2026
e15c5bd
Avoid implicit cross join
pylipp Apr 21, 2026
ed6df37
progress: planning remaining fixes from review
Copilot Apr 21, 2026
18aab4f
fix: remap itemsout+distro_events_* before DELETE; update sizes.php, …
Copilot Apr 21, 2026
e59d36d
refactor: use explicit distro_events table names instead of INFORMATI…
Copilot Apr 21, 2026
84080f2
Merge branch 'master' into copilot/clean-up-sizes-and-sizegroups
pylipp Apr 21, 2026
7f65b3e
revert-css
pylipp Apr 21, 2026
5c342ef
feat: add down() to re-insert deleted size rows from init.sql
Copilot Apr 22, 2026
ce45957
refactor: swap migration order — CreateSizesSizegroupTable first, Ded…
Copilot Apr 23, 2026
0d088d8
wip: before fixing sizes_sizegroup remap in DeduplicateSizes migration
Copilot Apr 23, 2026
9c7340e
fix: remap sizes_sizegroup rows in DeduplicateSizes instead of deleti…
Copilot Apr 23, 2026
72ad601
fix: restore minified.css to master version
Copilot Apr 23, 2026
58d3566
Update comment
pylipp Apr 23, 2026
de116c2
Use phinx methods
pylipp Apr 23, 2026
37af64e
feat: add migration to drop audit columns (created, created_by, modif…
Copilot May 13, 2026
16a68ed
plan: add 4th migration to fix sizes data inconsistencies
Copilot May 13, 2026
04d0dfc
feat: add migration 4 to fix seq values and add All ages to sizegroup…
Copilot May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions db/migrations/20260421120000_create_sizes_sizegroup_table.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?php

declare(strict_types=1);

use Phinx\Migration\AbstractMigration;

/**
* Creates the sizes_sizegroup cross-reference table that stores the many-to-many
* relationship between sizes and sizegroups, then drops the now-redundant
* sizegroup_id and seq columns from the sizes table.
*
* This migration runs BEFORE DeduplicateSizes so that every size – including
* the duplicates that will later be removed – already has a row in
* sizes_sizegroup before deduplication happens. When DeduplicateSizes removes
* duplicate rows from sizes, the corresponding sizes_sizegroup rows are removed
* automatically via the size_id foreign key's ON DELETE CASCADE behavior.
*/
final class CreateSizesSizegroupTable extends AbstractMigration
{
public function up(): void
{
// ----------------------------------------------------------------
// 1. Create cross-reference table
// ----------------------------------------------------------------
$this->execute('CREATE TABLE `sizes_sizegroup` (
`size_id` INT UNSIGNED NOT NULL,
`sizegroup_id` INT UNSIGNED NOT NULL,
`seq` INT DEFAULT NULL,
PRIMARY KEY (`size_id`, `sizegroup_id`),
KEY `idx_sizegroup_id` (`sizegroup_id`),
CONSTRAINT `fk_ss_size_id`
FOREIGN KEY (`size_id`) REFERENCES `sizes` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `fk_ss_sizegroup_id`
FOREIGN KEY (`sizegroup_id`) REFERENCES `sizegroup` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC');

// ----------------------------------------------------------------
// 2. Populate from existing sizes.sizegroup_id (one row per size,
// including rows for the duplicates that DeduplicateSizes will
// later remove along with their sizes_sizegroup entries)
// ----------------------------------------------------------------
$this->execute('INSERT INTO `sizes_sizegroup` (`size_id`, `sizegroup_id`, `seq`)
SELECT `id`, `sizegroup_id`, `seq`
FROM `sizes`
WHERE `sizegroup_id` IS NOT NULL');

// ----------------------------------------------------------------
// 3. Drop the now-redundant columns from sizes
// ----------------------------------------------------------------
$this->table('sizes')->dropForeignKey('sizegroup_id')->save();
$this->table('sizes')->removeColumn('sizegroup_id')->save();
$this->table('sizes')->removeColumn('seq')->save();
}

public function down(): void
{
// Restore sizegroup_id and seq columns on sizes
$this->execute('ALTER TABLE `sizes`
ADD COLUMN `sizegroup_id` INT UNSIGNED DEFAULT NULL AFTER `label`,
ADD COLUMN `seq` INT DEFAULT NULL AFTER `sizegroup_id`,
ADD KEY `sizegroup_id` (`sizegroup_id`),
ADD CONSTRAINT `sizes_ibfk_4`
FOREIGN KEY (`sizegroup_id`) REFERENCES `sizegroup` (`id`)
ON UPDATE CASCADE');

// Re-populate from the cross-reference table.
// Where a size belongs to multiple sizegroups, pick the row with the
// smallest sizegroup_id as the "primary" one (mirrors the original data).
$this->execute('UPDATE `sizes` s
JOIN (
SELECT size_id, sizegroup_id, seq
FROM sizes_sizegroup ss1
WHERE sizegroup_id = (
SELECT MIN(sizegroup_id)
FROM sizes_sizegroup ss2
WHERE ss2.size_id = ss1.size_id
)
) best ON best.size_id = s.id
SET s.sizegroup_id = best.sizegroup_id,
s.seq = best.seq');

$this->execute('DROP TABLE `sizes_sizegroup`');
}
}
Loading
Loading