add explicit counterpart labels for ticket link types
preserve stored link direction so the opposite ticket can show the counterpart label automatically
update metadata UI/resources/factories/tests for counterpart-aware link types
Verification
npm run build
php artisan test tests/Feature/Models/TicketLinkTypeTest.php tests/Feature/Models/TicketLinkTest.php tests/Feature/Projects/ProjectTicketLinkControllerTest.php tests/Feature/Projects/ProjectTicketMetadataSettingsControllerTest.php tests/Feature/Projects/ProjectTicketControllerTest.php tests/Feature/Api/TicketApiTest.php
## Summary
- add explicit counterpart labels for ticket link types
- preserve stored link direction so the opposite ticket can show the counterpart label automatically
- update metadata UI/resources/factories/tests for counterpart-aware link types
## Verification
- npm run build
- php artisan test tests/Feature/Models/TicketLinkTypeTest.php tests/Feature/Models/TicketLinkTest.php tests/Feature/Projects/ProjectTicketLinkControllerTest.php tests/Feature/Projects/ProjectTicketMetadataSettingsControllerTest.php tests/Feature/Projects/ProjectTicketControllerTest.php tests/Feature/Api/TicketApiTest.php
Short summary:
The directional counterpart labeling works nicely end-to-end, but the new storage strategy removes the old canonical uniqueness guarantee for ticket pairs.
Findings:
Blocker: none
Should fix: concurrent link creation from opposite ticket pages can now persist duplicate logical links as both (source=A,target=B) and (source=B,target=A).
Nit/Optional: none
Risk notes:
I did not flag legacy-data/backfill concerns because you confirmed KanbanGit is not production deployed yet.
The main risk here is correctness under concurrent writes.
Suggested follow-ups/tests:
Add a regression test around relinking/reorienting an existing reverse-direction link, and keep a lock/canonical uniqueness guard around the create path.
Verdict: REQUEST_CHANGES
Short summary:
The directional counterpart labeling works nicely end-to-end, but the new storage strategy removes the old canonical uniqueness guarantee for ticket pairs.
Findings:
- Blocker: none
- Should fix: concurrent link creation from opposite ticket pages can now persist duplicate logical links as both `(source=A,target=B)` and `(source=B,target=A)`.
- Nit/Optional: none
Risk notes:
- I did not flag legacy-data/backfill concerns because you confirmed KanbanGit is not production deployed yet.
- The main risk here is correctness under concurrent writes.
Suggested follow-ups/tests:
- Add a regression test around relinking/reorienting an existing reverse-direction link, and keep a lock/canonical uniqueness guard around the create path.
Should fix: dropping the canonical ticket-pair key here also drops the database-level protection against duplicates for the same two tickets. Two users can now create the same link concurrently from opposite ticket pages and end up with both (A,B) and (B,A) rows, because the lookup runs before either insert commits and the unique index only covers the ordered pair. Please serialize on the ticket pair before the lookup/create path (or add an equivalent canonical uniqueness guarantee) so one logical link cannot be created twice.
Should fix: dropping the canonical ticket-pair key here also drops the database-level protection against duplicates for the same two tickets. Two users can now create the same link concurrently from opposite ticket pages and end up with both `(A,B)` and `(B,A)` rows, because the lookup runs before either insert commits and the unique index only covers the ordered pair. Please serialize on the ticket pair before the lookup/create path (or add an equivalent canonical uniqueness guarantee) so one logical link cannot be created twice.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Verification
Verdict: REQUEST_CHANGES
Short summary:
The directional counterpart labeling works nicely end-to-end, but the new storage strategy removes the old canonical uniqueness guarantee for ticket pairs.
Findings:
(source=A,target=B)and(source=B,target=A).Risk notes:
Suggested follow-ups/tests:
Should fix: dropping the canonical ticket-pair key here also drops the database-level protection against duplicates for the same two tickets. Two users can now create the same link concurrently from opposite ticket pages and end up with both
(A,B)and(B,A)rows, because the lookup runs before either insert commits and the unique index only covers the ordered pair. Please serialize on the ticket pair before the lookup/create path (or add an equivalent canonical uniqueness guarantee) so one logical link cannot be created twice.Here is the improvements PR: OpenSource/KanbanGit#82