Skip to content

Commit 3fc04b4

Browse files
committed
fix: address code reviews
1 parent 68c9f19 commit 3fc04b4

File tree

2 files changed

+59
-47
lines changed

2 files changed

+59
-47
lines changed

packages/spacecat-shared-data-access/src/models/suggestion-grant/suggestion-grant.collection.js

Lines changed: 52 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ import DataAccessError from '../../errors/data-access.error.js';
1717

1818
/**
1919
* SuggestionGrantCollection - Manages SuggestionGrant records (suggestion_grants table).
20-
* Table is insert-only; inserts happen via grant_suggestions RPC. This collection
21-
* provides read-only lookup by suggestion IDs.
20+
* Inserts happen via the grant_suggestions RPC and deletes via the revoke_suggestion_grant
21+
* RPC. This collection provides read-only lookup by suggestion IDs as well as grant and
22+
* revoke operations.
2223
*
2324
* @class SuggestionGrantCollection
2425
* @extends BaseCollection
@@ -119,51 +120,6 @@ class SuggestionGrantCollection extends BaseCollection {
119120
return grantedIds.length > 0;
120121
}
121122

122-
/**
123-
* Invokes the revoke_suggestion_grant RPC. Deletes suggestion_grants rows for the given
124-
* grant ID and decrements tokens.used by 1.
125-
* RPC name and parameter shape live in this collection (suggestion_grants).
126-
*
127-
* @async
128-
* @param {string} grantId - Grant ID to revoke.
129-
* @returns {Promise<{ data: Array|null, error: object|null }>}
130-
*/
131-
async invokeRevokeSuggestionGrantRpc(grantId) {
132-
return this.postgrestService.rpc('revoke_suggestion_grant', {
133-
p_grant_id: grantId,
134-
});
135-
}
136-
137-
/**
138-
* Revokes a suggestion grant by grant ID. Calls the revoke_suggestion_grant RPC to
139-
* atomically delete suggestion_grants rows and refund the consumed token.
140-
*
141-
* @async
142-
* @param {string} grantId - The grant ID to revoke.
143-
* @returns {Promise<{ success: boolean, reason?: string, revokedCount?: number }>}
144-
* @throws {DataAccessError} - On missing inputs or RPC failure.
145-
*/
146-
async revokeSuggestionGrant(grantId) {
147-
if (!hasText(grantId)) {
148-
throw new DataAccessError('revokeSuggestionGrant: grantId is required', this);
149-
}
150-
151-
const rpcResult = await this.invokeRevokeSuggestionGrantRpc(grantId);
152-
const { data, error } = rpcResult;
153-
154-
if (error) {
155-
this.log.error('revokeSuggestionGrant: RPC failed', error);
156-
throw new DataAccessError('Failed to revoke suggestion grant (revoke_suggestion_grant)', this, error);
157-
}
158-
159-
const row = Array.isArray(data) && data.length > 0 ? data[0] : null;
160-
if (!row || !row.success) {
161-
return { success: false, reason: row?.reason || 'rpc_no_result' };
162-
}
163-
164-
return { success: true, revokedCount: row.revoked_count };
165-
}
166-
167123
/**
168124
* Grants one or more suggestions by consuming a single token for the given token type.
169125
* Resolves the current cycle token via TokenCollection#findBySiteIdAndTokenType
@@ -217,6 +173,55 @@ class SuggestionGrantCollection extends BaseCollection {
217173

218174
return { success: true, grantedSuggestions: row.granted_suggestions };
219175
}
176+
177+
/**
178+
* Invokes the revoke_suggestion_grant RPC. Deletes suggestion_grants rows for the given
179+
* grant ID and decrements tokens.used by 1.
180+
* RPC name and parameter shape live in this collection (suggestion_grants).
181+
*
182+
* @async
183+
* @param {string} grantId - Grant ID to revoke.
184+
* @returns {Promise<{ data: Array|null, error: object|null }>}
185+
* @throws {DataAccessError} - On missing grantId.
186+
*/
187+
async invokeRevokeSuggestionGrantRpc(grantId) {
188+
if (!hasText(grantId)) {
189+
throw new DataAccessError('invokeRevokeSuggestionGrantRpc: grantId is required', this);
190+
}
191+
return this.postgrestService.rpc('revoke_suggestion_grant', {
192+
p_grant_id: grantId,
193+
});
194+
}
195+
196+
/**
197+
* Revokes a suggestion grant by grant ID. Calls the revoke_suggestion_grant RPC to
198+
* atomically delete suggestion_grants rows and refund the consumed token.
199+
*
200+
* @async
201+
* @param {string} grantId - The grant ID to revoke.
202+
* @returns {Promise<{ success: boolean, reason?: string, revokedCount?: number }>}
203+
* @throws {DataAccessError} - On missing inputs or RPC failure.
204+
*/
205+
async revokeSuggestionGrant(grantId) {
206+
if (!hasText(grantId)) {
207+
throw new DataAccessError('revokeSuggestionGrant: grantId is required', this);
208+
}
209+
210+
const rpcResult = await this.invokeRevokeSuggestionGrantRpc(grantId);
211+
const { data, error } = rpcResult;
212+
213+
if (error) {
214+
this.log.error('revokeSuggestionGrant: RPC failed', error);
215+
throw new DataAccessError('Failed to revoke suggestion grant (revoke_suggestion_grant)', this, error);
216+
}
217+
218+
const row = Array.isArray(data) && data.length > 0 ? data[0] : null;
219+
if (!row || !row.success) {
220+
return { success: false, reason: row?.reason || 'rpc_no_result' };
221+
}
222+
223+
return { success: true, revokedCount: row.revoked_count };
224+
}
220225
}
221226

222227
export default SuggestionGrantCollection;

packages/spacecat-shared-data-access/test/unit/models/suggestion-grant/suggestion-grant.collection.test.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,13 @@ describe('SuggestionGrantCollection', () => {
455455

456456
expect(result).to.deep.equal(rpcResult);
457457
});
458+
459+
it('throws DataAccessError when grantId is missing', async () => {
460+
await expect(instance.invokeRevokeSuggestionGrantRpc(''))
461+
.to.be.rejectedWith(DataAccessError, 'grantId is required');
462+
await expect(instance.invokeRevokeSuggestionGrantRpc(null))
463+
.to.be.rejectedWith(DataAccessError, 'grantId is required');
464+
});
458465
});
459466

460467
describe('invokeGrantSuggestionsRpc', () => {

0 commit comments

Comments
 (0)