-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathletter-queue-repository.ts
More file actions
83 lines (78 loc) · 2.27 KB
/
letter-queue-repository.ts
File metadata and controls
83 lines (78 loc) · 2.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import {
DeleteCommand,
DynamoDBDocumentClient,
PutCommand,
} from "@aws-sdk/lib-dynamodb";
import { Logger } from "pino";
import {
InsertPendingLetter,
PendingLetter,
PendingLetterSchema,
} from "./types";
import { LetterAlreadyExistsError } from "./letter-already-exists-error";
import { LetterDoesNotExistError } from "./letter-does-not-exist-error";
type LetterQueueRepositoryConfig = {
letterQueueTableName: string;
letterQueueTtlHours: number;
};
export default class LetterQueueRepository {
constructor(
readonly ddbClient: DynamoDBDocumentClient,
readonly log: Logger,
readonly config: LetterQueueRepositoryConfig,
) {}
async putLetter(
insertPendingLetter: InsertPendingLetter,
): Promise<PendingLetter> {
// needs to be an ISO timestamp as Db sorts alphabetically
const now = new Date().toISOString();
const pendingLetter: PendingLetter = {
...insertPendingLetter,
queueTimestamp: now,
visibilityTimestamp: now,
ttl: Math.floor(
Date.now() / 1000 + 60 * 60 * this.config.letterQueueTtlHours,
),
};
try {
await this.ddbClient.send(
new PutCommand({
TableName: this.config.letterQueueTableName,
Item: pendingLetter,
ConditionExpression: "attribute_not_exists(letterId)", // Ensures the supplierId/letterId combination is unique
}),
);
} catch (error) {
if (
error instanceof Error &&
error.name === "ConditionalCheckFailedException"
) {
throw new LetterAlreadyExistsError(
insertPendingLetter.supplierId,
insertPendingLetter.letterId,
);
}
throw error;
}
return PendingLetterSchema.parse(pendingLetter);
}
async deleteLetter(supplierId: string, letterId: string): Promise<void> {
try {
await this.ddbClient.send(
new DeleteCommand({
TableName: this.config.letterQueueTableName,
Key: { supplierId, letterId },
ConditionExpression: "attribute_exists(letterId)",
}),
);
} catch (error) {
if (
error instanceof Error &&
error.name === "ConditionalCheckFailedException"
) {
throw new LetterDoesNotExistError(supplierId, letterId);
}
throw error;
}
}
}