@@ -13,10 +13,21 @@ import {
1313} from "../constants/api-constants" ;
1414import { createSupplierData , runCreateLetter } from "./pnpm-helpers" ;
1515import { logger } from "./pino-logger" ;
16+ import z from "zod" ;
1617
1718const ddb = new DynamoDBClient ( { } ) ;
1819const docClient = DynamoDBDocumentClient . from ( ddb ) ;
1920
21+ export const PendingLetterSchema = z . object ( {
22+ supplierId : z . string ( ) ,
23+ letterId : z . string ( ) ,
24+ queueTimestamp : z . string ( ) ,
25+ visibilityTimestamp : z . string ( ) ,
26+ queueSortOrderSk : z . string ( ) . describe ( "Secondary index SK" ) ,
27+ priority : z . int ( ) . min ( 0 ) . max ( 99 ) . optional ( ) ,
28+ } ) ;
29+ export type PendingLetter = z . infer < typeof PendingLetterSchema > ;
30+
2031export interface SupplierApiLetters {
2132 supplierId : string ;
2233 specificationId : string ;
@@ -211,3 +222,78 @@ export async function checkLetterQueueTable(
211222 return [ false ] ;
212223 }
213224}
225+
226+ export async function getLettersFromQueueViaIndex (
227+ supplierId : string ,
228+ ) : Promise < PendingLetter [ ] > {
229+ const MAX_ATTEMPTS = 5 ;
230+ const RETRY_DELAY_MS = 10_000 ;
231+
232+ try {
233+ const params = {
234+ TableName : LETTERQUEUE_TABLENAME ,
235+ IndexName : "queueSortOrder-index" ,
236+ KeyConditionExpression :
237+ "supplierId = :supplierId" ,
238+ ExpressionAttributeValues : {
239+ ":supplierId" : supplierId
240+ } ,
241+ } ;
242+
243+ for ( let attempt = 1 ; attempt <= MAX_ATTEMPTS ; attempt ++ ) {
244+ const { Items } = await docClient . send ( new QueryCommand ( params ) ) ;
245+
246+ if ( Items !== undefined && Items . length > 0 ) {
247+ logger . info (
248+ `Queried letter queue table to verify existence for supplier ${ supplierId } and found items.` ,
249+ ) ;
250+
251+ return z . array ( PendingLetterSchema ) . parse ( Items ) ;
252+ }
253+ if ( attempt < MAX_ATTEMPTS ) {
254+ logger . info (
255+ `Retrying get letters from queue for supplierId ${ supplierId } in ${ RETRY_DELAY_MS } ms` ,
256+ ) ;
257+ await delay ( RETRY_DELAY_MS ) ;
258+ }
259+ }
260+ return [ ] ;
261+ } catch ( error ) {
262+ logger . error ( { supplierId, error } , "Letter queue query failed" ) ;
263+ return [ ] ;
264+ }
265+ }
266+
267+ // async getLetters(
268+ // supplierId: string,
269+ // limit: number,
270+ // ): Promise<PendingLetter[]> {
271+ // const letters: PendingLetter[] = [];
272+ // let lastEvaluatedKey: Record<string, unknown> | undefined;
273+
274+ // do {
275+ // const result = await this.ddbClient.send(
276+ // new QueryCommand({
277+ // TableName: this.config.letterQueueTableName,
278+ // IndexName: "queueSortOrder-index",
279+ // KeyConditionExpression: "supplierId = :supplierId",
280+ // FilterExpression: "visibilityTimestamp < :now",
281+ // ExpressionAttributeValues: {
282+ // ":supplierId": supplierId,
283+ // ":now": new Date().toISOString(),
284+ // },
285+ // // 1000 is a compromise - a smaller number might result in a lot of round trips, a larger one might
286+ // // entail fetching and then throwing away a lot of data
287+ // Limit: this.config.queryPageSize ?? 1000,
288+ // ExclusiveStartKey: lastEvaluatedKey,
289+ // }),
290+ // );
291+
292+ // const page = z.array(PendingLetterSchema).parse(result.Items);
293+ // letters.push(...page);
294+
295+ // lastEvaluatedKey = result.LastEvaluatedKey;
296+ // } while (lastEvaluatedKey !== undefined && letters.length < limit);
297+
298+ // return letters.slice(0, limit);
299+ // }
0 commit comments