feat(data-access): add TicketSuggestion bulk accessors allBySuggestionIds and allByTicketIds (SITES-44690)#1804
Conversation
|
This PR will trigger a minor release when merged. |
…essors to TicketSuggestionCollection (SITES-44690) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1eb97c4 to
5e4941e
Compare
…stion accessors (SITES-44690) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Hey @prithipalpatwal,
⚠ Degraded review - no spec document was found for this change (searched the PR links, the touched repos' docs, the architecture/guidelines docs, and linked Jira). This review covers code-level quality but could not validate the change against an agreed design, so confidence is reduced. Add a spec link (PR template section 4) and re-request review for a full-confidence pass.
Verdict: Request changes - missing IN-filter chunking diverges from the reference pattern and risks production failures at scale.
Complexity: LOW - small, single-service, follows established pattern.
Changes: Adds two bulk query methods (allBySuggestionIds, allByTicketIds) to TicketSuggestionCollection using op.in via this.all() (2 files).
Must fix before merge
- [Important] Missing IN-filter chunking for large ID arrays -
ticket-suggestion.collection.js:35-44,57-66(details inline)
Non-blocking (3): minor issues and suggestions
- nit: Input validation uses ad-hoc
Array.isArraycheck instead ofguardArrayutility (the referenceallByOpportunityIdsusesguardArraywhich throws on invalid input and validates element types) -ticket-suggestion.collection.js:35,57 - nit: Missing deduplication of input IDs before querying (reference uses
[...new Set(ids)]) -ticket-suggestion.collection.js:38,60 - nit: Test file uses direct
import { stub } from 'sinon'instead of documentedsinon.createSandbox()withafterEach(() => sandbox.restore())pattern per root CLAUDE.md -ticket-suggestion.collection.test.js:16
Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 1m 46s | Cost: $3.87 | Commit: 7141a2846cb0e49a2b86ef39927409f9b6ae0084
If this code review was useful, please react with 👍. Otherwise, react with 👎.
| try { | ||
| return await this.all( | ||
| {}, | ||
| { where: (attrs, op) => op.in(attrs.suggestionId, suggestionIds) }, |
There was a problem hiding this comment.
issue (blocking): Both allBySuggestionIds and allByTicketIds pass the full ID array to a single op.in() call without chunking. The reference pattern (FixEntityCollection.allByOpportunityIds) explicitly chunks at IN_FILTER_CHUNK_SIZE = 50 because PostgREST serializes IN-filters into the URL, and large ID lists exceed the ~8KB URL length limit.
Since these methods are described as "bulk" operations (pre-flight duplicate check, bulk-load bridge rows), callers can plausibly pass 100+ UUIDs.
Fix: adopt the same chunking pattern from the reference:
const uniqueIds = [...new Set(suggestionIds)];
const chunks = [];
for (let i = 0; i < uniqueIds.length; i += IN_FILTER_CHUNK_SIZE) {
chunks.push(uniqueIds.slice(i, i + IN_FILTER_CHUNK_SIZE));
}
const results = await Promise.all(
chunks.map((chunk) => this.all(
{},
{ where: (attrs, op) => op.in(attrs.suggestionId, chunk) },
)),
);
return results.flat();This also applies to allByTicketIds below (same pattern, same fix).
…erence pattern (SITES-44690) - Add IN-filter chunking (size 50) with parallel Promise.all to prevent URL-length failures on large ID arrays - Replace ad-hoc Array.isArray guard with guardArray() for consistent ValidationError on invalid input - Deduplicate input IDs with [...new Set()] before chunking - Switch test stubs from bare sinon.stub() to sandbox pattern with afterEach restore - Add test cases for ValidationError, deduplication, and chunking behaviour Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Hey @prithipalpatwal,
⚠ Degraded review - no spec document was found for this change (searched the PR links, the touched repos' docs, the architecture/guidelines docs, and linked Jira). This review covers code-level quality but could not validate the change against an agreed design, so confidence is reduced. Add a spec link (PR template section 4) and re-request review for a full-confidence pass.
Verdict: Approve - all prior findings addressed, implementation follows the established pattern cleanly.
Complexity: HIGH - medium diff; models/ path fires Database/Schema risk signal.
Changes: Adds two bulk query methods (allBySuggestionIds, allByTicketIds) to TicketSuggestionCollection with chunking, dedup, and validation (2 files).
Non-blocking (1): minor issues and suggestions
- nit: The chunking loop (build chunks array, slice at IN_FILTER_CHUNK_SIZE) is duplicated verbatim across both methods. Tolerable at two instances (the reference pattern in FixEntityCollection inlines it the same way), but a small private helper would reduce drift surface if the logic ever changes -
ticket-suggestion.collection.js:40-43,74-77
Previously flagged, now resolved
- IN-filter chunking at size 50 now present
- guardArray validation replaces ad-hoc Array.isArray check
- Deduplication via
[...new Set(ids)]before querying - Test file uses sinon.createSandbox() with afterEach restore
Skill: pr-review | Model: us.anthropic.claude-opus-4-6-v1[1m] | Duration: 2m 50s | Cost: $4.30 | Commit: 5b30c85680a45e2a724bc63a33aec4a8ceb29525
If this code review was useful, please react with 👍. Otherwise, react with 👎.
## [@adobe/spacecat-shared-data-access-v4.7.0](https://github.com/adobe/spacecat-shared/compare/@adobe/spacecat-shared-data-access-v4.6.0...@adobe/spacecat-shared-data-access-v4.7.0) (2026-07-13) ### Features * **data-access:** add TicketSuggestion bulk accessors allBySuggestionIds and allByTicketIds (SITES-44690) ([#1804](#1804)) ([99387f6](99387f6))
|
🎉 This PR is included in version @adobe/spacecat-shared-data-access-v4.7.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Jira: SITES-44690
Summary
Adds two bulk query methods to
TicketSuggestionCollectionto replace rawpostgrestClientcalls in spacecat-api-service.Both methods use
this.all()withop.in(the established pattern fromFixEntityCollection.allByOpportunityIds) — no directpostgrestServiceaccess in the subclass.Changes
allBySuggestionIds(suggestionIds)— pre-flight duplicate check before ticket creationallByTicketIds(ticketIds)— bulk-load bridge rows when listing ticketsAlignment
Schema aligned with mysticat-data-service PR #720: field names map automatically (
suggestionId→suggestion_id,ticketId→ticket_id) via theapplyWhereattrs proxy.