Skip to content

Commit 8d24517

Browse files
committed
feat(export): set up multi-service export capabilities
At this time the behavior should be the same, but there is an additional layer acting like a state machine to schedule the work, determine if it's finished, and notify the user if it is.
1 parent ed6d0d9 commit 8d24517

File tree

24 files changed

+813
-358
lines changed

24 files changed

+813
-358
lines changed

infrastructure/account-data-deleter/src/config/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ export const config = {
4343
listImportBatchQueue: `${prefix}-List-Import-Batches`,
4444
databaseTz: 'US/Central',
4545
eventBusName: `PocketEventBridge-${environment}-Shared-Event-Bus`,
46-
shareListSecretName: `ShareableListsApi-Prod/shareablelistsapi-prod20230207160218618400000003`,
4746
},
4847
isDev,
4948
isProd,
5049
lambda: {
5150
snsTopicName: {
5251
userEvents: `PocketEventBridge-${environment}-UserEvents`,
5352
listEvents: `PocketEventBridge-${environment}-ListEvents`,
53+
exportUpdateEvents: `PocketEventBridge-${environment}-ListExportReadyEvents`,
5454
},
5555
batchDeleteLambda: {
5656
name: 'BatchDeleteLambda',

infrastructure/account-data-deleter/src/dataDeleterApp.ts

+4
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ export class DataDeleterApp extends Construct {
122122
name: 'EXPORT_REQUEST_QUEUE_URL',
123123
value: `https://sqs.${region.name}.amazonaws.com/${caller.accountId}/${config.envVars.exportRequestQueueName}`,
124124
},
125+
{
126+
name: 'EXPORT_REQUEST_STATE_TABLE',
127+
value: this.config.exportStateDb.name,
128+
},
125129
{
126130
name: 'SQS_LIST_EXPORT_QUEUE_URL',
127131
value: `https://sqs.${region.name}.amazonaws.com/${caller.accountId}/${config.envVars.listExportQueueName}`,

infrastructure/account-data-deleter/src/main.ts

+16
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,22 @@ class AccountDataDeleter extends TerraformStack {
150150
},
151151
);
152152

153+
// Forward status updates on export components (shareable list, list, annotations)
154+
new ApplicationSqsSnsTopicSubscription(
155+
this,
156+
'export-status-events-sns-subscription',
157+
{
158+
name: `${config.envVars.exportRequestQueueName}-Status-SNS`,
159+
snsTopicArn: `arn:aws:sns:${pocketVpc.region}:${pocketVpc.accountId}:${config.lambda.snsTopicName.exportUpdateEvents}`,
160+
sqsQueue: exportRequestQueue.sqsQueue,
161+
filterPolicyScope: 'MessageBody',
162+
filterPolicy: JSON.stringify({
163+
'detail-type': ['export-part-complete'],
164+
}),
165+
tags: config.tags,
166+
},
167+
);
168+
153169
// Bucket for exports plus auto-expiry rules
154170
const exportBucket = new s3Bucket.S3Bucket(this, 'list-export-bucket', {
155171
bucket: `com.getpocket-${config.environment.toLowerCase()}.list-exports`,

infrastructure/pocket-event-bridge/src/main.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -272,8 +272,11 @@ class PocketEventBus extends TerraformStack {
272272
name: 'ListExportReadyEvents',
273273
tags: config.tags,
274274
eventPattern: {
275-
'detail-type': [PocketEventType.EXPORT_READY],
276-
source: ['account-data-deleter'],
275+
'detail-type': [
276+
PocketEventType.EXPORT_READY,
277+
PocketEventType.EXPORT_PART_COMPLETE,
278+
],
279+
source: ['account-data-deleter', 'shareable-list-events'],
277280
},
278281
});
279282
}

infrastructure/transactional-emails/src/config/index.ts

+7-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,13 @@ export const config = {
4444
{ name: 'PremiumPurchaseEvents' },
4545
{ name: 'UserRegistrationEvents' },
4646
{ name: 'ForgotPasswordEvents' },
47-
{ name: 'ListExportReadyEvents' },
47+
{
48+
name: 'ListExportReadyEvents',
49+
filterPolicyScope: 'MessageBody',
50+
filterPolicy: JSON.stringify({
51+
'detail-type': ['list-export-ready'],
52+
}),
53+
},
4854
{
4955
name: 'ListEvents',
5056
filterPolicyScope: 'MessageBody',

packages/event-bridge/src/events/events.ts

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ export enum PocketEventType {
1111
ACCOUNT_PASSWORD_CHANGED = 'account-password-changed', //source: user-event
1212
FORGOT_PASSWORD = 'Forgot Password Request', //source: web-repo
1313
EXPORT_READY = 'list-export-ready', // source: account-data-deleter
14+
EXPORT_PART_COMPLETE = 'export-part-complete', // source: account-data-deleter or shareable-lists-api
1415
EXPORT_REQUESTED = 'list-export-requested', // source: list-api
1516
// List Events
1617
ADD_ITEM = 'ADD_ITEM',

packages/event-bridge/src/events/generated/schema.json

+49
Original file line numberDiff line numberDiff line change
@@ -2237,6 +2237,55 @@
22372237
],
22382238
"type": "object"
22392239
},
2240+
"ExportPartComplete": {
2241+
"properties": {
2242+
"detail": {
2243+
"properties": {
2244+
"encodedId": {
2245+
"type": "string"
2246+
},
2247+
"prefix": {
2248+
"type": "string"
2249+
},
2250+
"requestId": {
2251+
"type": "string"
2252+
},
2253+
"service": {
2254+
"enum": [
2255+
"list",
2256+
"shareable-lists",
2257+
"annotations"
2258+
],
2259+
"type": "string"
2260+
},
2261+
"timestamp": {
2262+
"type": "string"
2263+
}
2264+
},
2265+
"required": [
2266+
"encodedId",
2267+
"requestId",
2268+
"service",
2269+
"timestamp",
2270+
"prefix"
2271+
],
2272+
"type": "object"
2273+
},
2274+
"detail-type": {
2275+
"const": "export-part-complete",
2276+
"type": "string"
2277+
},
2278+
"source": {
2279+
"type": "string"
2280+
}
2281+
},
2282+
"required": [
2283+
"detail",
2284+
"detail-type",
2285+
"source"
2286+
],
2287+
"type": "object"
2288+
},
22402289
"ExportReady": {
22412290
"properties": {
22422291
"detail": {

packages/event-bridge/src/events/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
CollectionUpdated,
5050
ProspectDismissed,
5151
IncomingBaseEvent,
52+
ExportPartComplete,
5253
} from './types/index.ts';
5354
import { ProspectEvent } from './types/prospect.ts';
5455
export * from './types/index.ts';
@@ -59,6 +60,7 @@ export type PocketEvent =
5960
| AccountEvent
6061
| ExportReady
6162
| ExportRequested
63+
| ExportPartComplete
6264
| PremiumPurchaseEvent
6365
| ListEvent
6466
| ShareableListEvent
@@ -80,6 +82,7 @@ export type PocketEventTypeMap = {
8082
[PocketEventType.PREMIUM_PURCHASE]: PremiumPurchaseEvent;
8183
[PocketEventType.EXPORT_READY]: ExportReady;
8284
[PocketEventType.EXPORT_REQUESTED]: ExportRequested;
85+
[PocketEventType.EXPORT_PART_COMPLETE]: ExportPartComplete;
8386
[PocketEventType.ADD_ITEM]: AddItem;
8487
[PocketEventType.DELETE_ITEM]: DeleteItem;
8588
[PocketEventType.FAVORITE_ITEM]: FavoriteItem;

packages/event-bridge/src/events/types/account.ts

+12
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ export interface ExportReady extends BaseEvent {
5252
};
5353
}
5454

55+
export interface ExportPartComplete extends BaseEvent {
56+
// 'source': 'account-data-deleter' | 'shareable-lists-api';
57+
'detail-type': PocketEventType.EXPORT_PART_COMPLETE;
58+
detail: {
59+
encodedId: string;
60+
requestId: string;
61+
service: 'list' | 'shareable-lists' | 'annotations';
62+
timestamp: string; // ISO-formatted string
63+
prefix: string; //
64+
};
65+
}
66+
5567
export interface AccountPayload {
5668
email: string;
5769
isPremium: boolean;

0 commit comments

Comments
 (0)