[LFXV2-1223] Fix delete object ID corruption#47
Conversation
…ehensive unit tests Jira Ticket: https://linuxfoundation.atlassian.net/browse/LFXV2-1223 Assisted by [Claude Code](https://claude.ai/code) Signed-off-by: Mauricio Zanetti Salomao <mauriciozanetti86@gmail.com>
Jira Ticket: https://linuxfoundation.atlassian.net/browse/LFXV2-1223 Assisted by [Claude Code](https://claude.ai/code) Signed-off-by: Mauricio Zanetti Salomao <mauriciozanetti86@gmail.com>
WalkthroughThe changes modify transaction data decoding in the indexer service to handle base64 decoding only for create/update actions (removing delete action handling), and introduce helper functions in the GroupsIO enricher to extract group names and aliases. Comprehensive tests are added for both components. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Comment |
There was a problem hiding this comment.
Pull request overview
This PR addresses a delete-action data decoding bug that could silently corrupt object IDs, enhances GroupsIO mailing list enrichment to prefer group_name for naming/sorting, and adds observability plus tests around transaction data decoding.
Changes:
- Prevent delete transactions from mutating
transaction.Dataduring base64 decode (and add decoding debug context). - Prefer
group_nameforSortNameandNameAndAliasesinGroupsIOMailingListEnricher. - Add unit tests covering
decodeTransactionDatabehavior and new GroupsIO naming behavior.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| internal/enrichers/groupsio_mailing_list_enricher.go | Adds custom sort-name and alias extraction using group_name. |
| internal/enrichers/groupsio_mailing_list_enricher_test.go | Adds tests validating group_name prioritization and trimming behavior. |
| internal/domain/services/indexer_service.go | Updates decodeTransactionData behavior and adds debug logging around decoding. |
| internal/domain/services/indexer_service_test.go | Adds unit tests for decodeTransactionData across create/update/delete scenarios. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
There was a problem hiding this comment.
🧹 Nitpick comments (1)
internal/enrichers/groupsio_mailing_list_enricher_test.go (1)
90-101: Consider adding NameAndAliases assertion for this case.This test case verifies that SortName falls back to "Fallback" when
group_nameis empty, but it doesn't verifyNameAndAliases. Based onextractGroupNameAndAliaseslogic, whengroup_nameis empty andnameis "Fallback", the expectedNameAndAliasesshould be["Fallback"].The current assertion at line 129-131 skips validation when
expectedBody.NameAndAliasesis nil, which could hide unexpected behavior.🔧 Suggested enhancement
{ name: "empty group_name falls back to name", parsedData: map[string]any{ "uid": "ml-empty", "group_name": "", "name": "Fallback", }, expectedBody: &contracts.TransactionBody{ - ObjectID: "ml-empty", - SortName: "Fallback", + ObjectID: "ml-empty", + SortName: "Fallback", + NameAndAliases: []string{"Fallback"}, }, },🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@internal/enrichers/groupsio_mailing_list_enricher_test.go` around lines 90 - 101, The test case "empty group_name falls back to name" should also assert NameAndAliases is populated; update the test vector for that case to set expectedBody.NameAndAliases to []string{"Fallback"} and add an assertion in the test's validation block (the same place that currently checks SortName/ObjectID) to compare the actual body's NameAndAliases against expectedBody.NameAndAliases so extractGroupNameAndAliases behavior is verified rather than implicitly skipped when expectedBody.NameAndAliases is nil.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@internal/enrichers/groupsio_mailing_list_enricher_test.go`:
- Around line 90-101: The test case "empty group_name falls back to name" should
also assert NameAndAliases is populated; update the test vector for that case to
set expectedBody.NameAndAliases to []string{"Fallback"} and add an assertion in
the test's validation block (the same place that currently checks
SortName/ObjectID) to compare the actual body's NameAndAliases against
expectedBody.NameAndAliases so extractGroupNameAndAliases behavior is verified
rather than implicitly skipped when expectedBody.NameAndAliases is nil.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 43f7325e-a8d0-4f3a-b8ac-d8c2fd9a7856
📒 Files selected for processing (4)
internal/domain/services/indexer_service.gointernal/domain/services/indexer_service_test.gointernal/enrichers/groupsio_mailing_list_enricher.gointernal/enrichers/groupsio_mailing_list_enricher_test.go
… functions and simplifying default enricher initialization Jira Ticket: https://linuxfoundation.atlassian.net/browse/LFXV2-1223 Assisted by [Claude Code](https://claude.ai/code) Signed-off-by: Mauricio Zanetti Salomao <mauriciozanetti86@gmail.com>
Overview
Jira ticket https://linuxfoundation.atlassian.net/browse/LFXV2-1223
decodeTransactionDatato surface action/type context during base64 decodingBug Fix — Delete Action Corrupts Object ID
What happened
decodeTransactionDataapplied base64 decoding to all three action types (create, update, delete). For delete actions,transaction.Datais always a plain string object ID — not a base64-encoded payload.When an object ID happened to be composed entirely of base64-legal characters and had a length that is a multiple of 4,
base64.StdEncoding.DecodeStringsucceeded silently and overwrote the original ID with garbage bytes — causing the delete to target the wrong document in OpenSearch.UUIDs (which contain
-) and most short numeric IDs are immune by accident, which masked the bug during testing.Observable impact
The corruption surfaced in janitor logs where
object_refcontained garbled bytes instead of a valid ID:{"time":"2026-03-12T16:40:12.651285-03:00","level":"INFO","msg":"Single document found, no janitor action needed", "component":"cleanup_repository","object_ref":"groupsio_member:|\ufffd\ufffd4","document_id":"groupsio_member:|<22>4"}The janitor located a document using the corrupted ID, but it was never the intended target.
Which IDs are affected
550e8400-e29b-41d4-a716-446655440000-, not valid base6415554981610(11 chars)DecodeStringerrors on odd lengthgroupsio_memberIDsFix
Removed the
case s.isDeleteActionbranch fromdecodeTransactionData. Base64 decoding now only runs for create and update actions, which are the only ones that carry a base64-encoded JSON payload. Delete actions pass through untouched.