Clean up sizes/sizegroup: deduplicate sizes + cross-reference table#821
Clean up sizes/sizegroup: deduplicate sizes + cross-reference table#821
Conversation
Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/870cef39-acd9-49fe-8c16-4dfd54f3b425 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Migration 1 (20260421120000): removes 75 duplicate size rows, updating references in stock, shipment_detail, and history tables. Migration 2 (20260421130000): creates sizes_sizegroup cross-reference table with all size-sizegroup relationships (including extra sizegroup memberships from merged duplicates), then drops sizes.sizegroup_id and sizes.seq. Updates include/container-stock.php to JOIN sizes_sizegroup instead of filtering on sizes.sizegroup_id. Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/870cef39-acd9-49fe-8c16-4dfd54f3b425 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
…ntainer-stock.php Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/363f3d93-798a-48aa-b118-9a9a41ecb889 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Refactors the app’s size/sizegroup data model by removing duplicate sizes rows and moving from a 1→many (sizes.sizegroup_id) relationship to a many→many relationship via a new sizes_sizegroup cross-reference table, updating stockroom querying accordingly.
Changes:
- Add a migration to deduplicate
sizeslabels by remapping foreign keys and deleting duplicate rows. - Add a migration to create/populate
sizes_sizegroup, then dropsizes.sizegroup_idandsizes.seq. - Update the stockroom listing query to join sizes via
sizes_sizegroupinstead ofsizes.sizegroup_id.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| include/container-stock.php | Switches sizegroup matching logic to use the new sizes_sizegroup join. |
| db/migrations/20260421120000_deduplicate_sizes.php | Remaps references to removed size IDs and deletes duplicate sizes rows. |
| db/migrations/20260421130000_create_sizes_sizegroup_table.php | Introduces sizes_sizegroup, migrates memberships, and drops legacy sizes columns. |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Philipp Metzner <10617122+pylipp@users.noreply.github.com>
|
@copilot apply changes based on the comments in this thread |
Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/ce308e1f-588a-4185-aa41-13ca1c14601d Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
…getsizes.php, stock_edit.php, sizes_edit.php to use sizes_sizegroup Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/ce308e1f-588a-4185-aa41-13ca1c14601d Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Done in 18aab4f. Applied all three review changes:
|
…ON_SCHEMA Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/2c1f475d-e3cc-4a30-83d0-3a45e2ba207c Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
pylipp
left a comment
There was a problem hiding this comment.
@copilot work on the requested changes
- do NOT bring any unrelated changes into the PR (e.g. minified.css)
- update the PR description to the content it had after the very first agent run (containing the table overview of replaced sizes)
Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/ca2517b0-c9c2-497a-9e87-c76fca107d62 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Done — |
…uplicateSizes second Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/ca6077f8-c7fa-4a6f-bf02-d8793b688a47 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/f5db50ea-15bf-4438-9c1e-b0d0bf82d2d9 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
…ng them Agent-Logs-Url: https://github.com/boxwise/dropapp/sessions/f5db50ea-15bf-4438-9c1e-b0d0bf82d2d9 Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
Co-authored-by: pylipp <10617122+pylipp@users.noreply.github.com>
|
@HaGuesto the way I tested this was:
I could verify
|
| // from their duplicates during up(). Each pair below is | ||
| // (canonical_size_id, sizegroup_id_of_the_duplicate). | ||
| $this->execute('DELETE FROM `sizes_sizegroup` | ||
| WHERE (`size_id`, `sizegroup_id`) IN ( | ||
| ( 1, 5), ( 2, 5), ( 3, 5), | ||
| (33, 8), (34, 8), (35, 8), | ||
| (28, 9), (29, 9), | ||
| (52, 1), (52, 5), | ||
| (97, 2), (97, 4), (97, 23), (97, 24), | ||
| (44, 2), (47, 2), (48, 2), | ||
| (117, 18), (118, 18), | ||
| (116, 20), | ||
| (119, 22), | ||
| (10, 23), (11, 23), | ||
| (18, 26), (19, 26), (20, 26), (21, 26), (22, 26), (23, 26), | ||
| (24, 26), (25, 26), (26, 26), (27, 26), | ||
| (28, 26), (29, 26), (30, 26), (31, 26), (32, 26), | ||
| (33, 26), (34, 26), (35, 26), | ||
| (60, 26), (61, 26), (62, 26), (63, 26), | ||
| (52, 2), (52, 3), (52, 4), (52, 7), (52, 8), (52, 9), | ||
| (52, 12), (52, 13), (52, 16), (52, 17), (52, 18), (52, 19), | ||
| (52, 20), (52, 21), (52, 22), (52, 23), (52, 24), (52, 25), | ||
| (52, 26), (52, 27) | ||
| )'); |
There was a problem hiding this comment.
The rollback logic depends on a large hard-coded list of (canonical_size_id, sizegroup_id) pairs. This is brittle and easy to get out of sync with the actual remapping logic (or with small data differences across environments), which could make down() delete the wrong memberships. Consider deriving the memberships-to-remove from data at rollback time (e.g., compute inherited memberships by joining restored duplicate sizes to their canonical label sibling(s) and their sizes_sizegroup rows), or persist a small audit table during up() that records exactly which (size_id, sizegroup_id) rows were inserted so down() can delete precisely those.
| // from their duplicates during up(). Each pair below is | |
| // (canonical_size_id, sizegroup_id_of_the_duplicate). | |
| $this->execute('DELETE FROM `sizes_sizegroup` | |
| WHERE (`size_id`, `sizegroup_id`) IN ( | |
| ( 1, 5), ( 2, 5), ( 3, 5), | |
| (33, 8), (34, 8), (35, 8), | |
| (28, 9), (29, 9), | |
| (52, 1), (52, 5), | |
| (97, 2), (97, 4), (97, 23), (97, 24), | |
| (44, 2), (47, 2), (48, 2), | |
| (117, 18), (118, 18), | |
| (116, 20), | |
| (119, 22), | |
| (10, 23), (11, 23), | |
| (18, 26), (19, 26), (20, 26), (21, 26), (22, 26), (23, 26), | |
| (24, 26), (25, 26), (26, 26), (27, 26), | |
| (28, 26), (29, 26), (30, 26), (31, 26), (32, 26), | |
| (33, 26), (34, 26), (35, 26), | |
| (60, 26), (61, 26), (62, 26), (63, 26), | |
| (52, 2), (52, 3), (52, 4), (52, 7), (52, 8), (52, 9), | |
| (52, 12), (52, 13), (52, 16), (52, 17), (52, 18), (52, 19), | |
| (52, 20), (52, 21), (52, 22), (52, 23), (52, 24), (52, 25), | |
| (52, 26), (52, 27) | |
| )'); | |
| // from their duplicates during up(). Derive the memberships to | |
| // remove from the restored duplicate rows instead of relying on a | |
| // separately maintained hard-coded list of (canonical_size_id, | |
| // sizegroup_id) pairs. | |
| $this->execute('DELETE canonical_memberships | |
| FROM `sizes_sizegroup` AS canonical_memberships | |
| INNER JOIN ( | |
| SELECT DISTINCT | |
| '.self::REMAP_CASE.' AS canonical_size_id, | |
| `sizegroup_id` | |
| FROM `sizes_sizegroup` | |
| WHERE `size_id` IN ('.self::REMOVED_IDS.') | |
| ) AS inherited_memberships | |
| ON canonical_memberships.`size_id` = inherited_memberships.`canonical_size_id` | |
| AND canonical_memberships.`sizegroup_id` = inherited_memberships.`sizegroup_id`'); |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Philipp Metzner <10617122+pylipp@users.noreply.github.com>
Implements the size/sizegroup database cleanup.
Migration 1 –
20260421120000_CreateSizesSizegroupTablesizes_sizegroupcross-reference table (many-to-many betweensizesandsizegroup).sizes.sizegroup_idfor every size currently in the table — including the 75 duplicates that Migration 2 will later remove (so no "extra memberships" block is needed).sizegroup_idandseqcolumns fromsizes.The
down()method restoressizegroup_id/seq, re-populates them fromsizes_sizegroup, and drops the cross-reference table.Migration 2 –
20260421130000_DeduplicateSizesRemoves 75 duplicate size rows from the
sizestable (keeping the entry with the smallest ID for each label). Before deleting the duplicates, all foreign-key references are redirected to the surviving ID:stocksize_idshipment_detailsource_size_id,target_size_idhistoryfrom_int,to_int(fortablename='stock',changes='size_id')itemsoutsize_iddistro_events_packing_list_entriessize_iddistro_events_tracking_logssize_iddistro_events_unboxed_item_collectionssize_idsizes_sizegrouprows for duplicate sizes are then remapped to their canonical ID viaINSERT IGNORE(so canonical sizes inherit all sizegroup memberships from their duplicates). TheON DELETE CASCADEonfk_ss_size_idremoves the old duplicate rows when the duplicatesizesrows are deleted.The
down()method re-inserts the 75 deletedsizesrows (id + label only, sincesizegroup_id/seqare managed by Migration 1) and their correspondingsizes_sizegroupentries, then removes the inherited sizegroup memberships from the canonical sizes (partial rollback; FK remappings cannot be reconstructed).Code changes
include/container-stock.phpINNER JOIN sizes_sizegroup … INNER JOIN sizeslibrary/ajax/getsizes.phpsizes_sizegroupinclude/stock_edit.phpsizes_sizegroupVerification
vendor/bin/parallel-lint– no errorsphp-cs-fixer– 0 files to fix (excluding auto-generated templates)