Create papertrail versions for newly created/updated add_on_purchases
What does this MR do and why?
The GitlabSubscriptions::Duo::BulkAssignService uses upsert_all to create addon assignments, but this bypasses ActiveRecord callbacks which are required by papertrail to create version records. This results in orphaned addon assignments without corresponding subscription_user_add_on_assignment_versions records, causing data inconsistencies in ClickHouse historical data.
Example of the insert query and the query plan:
=== SQL ===
INSERT INTO subscription_user_add_on_assignment_versions (organization_id, item_id, purchase_id, user_id, created_at, item_type, event, namespace_path, add_on_name, whodunnit, object) VALUES (1030, 290, 41, 114, '2025-09-04 10:18:20.192383', 'GitlabSubscriptions::UserAddOnAssignment', 'create', '1030/', 'code_suggestions', NULL, '{"id":290,"add_on_purchase_id":41,"user_id":114,"created_at":"2025-09-04T10:18:20.192+00:00","updated_at":"2025-09-04T10:18:20.192+00:00","organization_id":1030}'), (1030, 291, 41, 113, '2025-09-04 10:18:20.192383', 'GitlabSubscriptions::UserAddOnAssignment', 'create', '1030/', 'code_suggestions', NULL, '{"id":291,"add_on_purchase_id":41,"user_id":113,"created_at":"2025-09-04T10:18:20.192+00:00","updated_at":"2025-09-04T10:18:20.192+00:00","organization_id":1030}')
.=== QUERY PLAN ===
QUERY PLAN
------------------------------------------------------------------------------------------
Insert on subscription_user_add_on_assignment_versions (cost=0.00..0.01 rows=0 width=0)
-> Result (cost=0.00..0.01 rows=1 width=240)
References
Screenshots or screen recordings
| Before | After |
|---|---|
How to set up and validate locally
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #566532 (closed)
Edited by Amr Taha