Skip to content

Commit 7f51584

Browse files
committed
init
1 parent 2c318eb commit 7f51584

File tree

10 files changed

+135
-64
lines changed

10 files changed

+135
-64
lines changed

lambdas/backend-api/src/templates/api/proof.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export function createHandler({
1212

1313
const templateId = event.pathParameters?.templateId;
1414

15-
if (!userId || !templateId) {
15+
if (!userId || !templateId || !clientId) {
1616
return apiFailure(400, 'Invalid request');
1717
}
1818

lambdas/backend-api/src/templates/app/template-client.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@ import { LETTER_MULTIPART } from 'nhs-notify-backend-client/src/schemas/constant
1616
import {
1717
$CreateLetterTemplate,
1818
DatabaseTemplate,
19+
User,
20+
UserWithClient,
1921
} from 'nhs-notify-web-template-management-utils';
2022
import { Logger } from 'nhs-notify-web-template-management-utils/logger';
2123
import { LetterUploadRepository } from '../infra/letter-upload-repository';
2224
import { ProofingQueue } from '../infra/proofing-queue';
23-
import type { User } from '../types';
2425
import { ClientConfigRepository } from '../infra/client-config-repository';
2526

2627
export class TemplateClient {
@@ -347,7 +348,7 @@ export class TemplateClient {
347348

348349
async requestProof(
349350
templateId: string,
350-
user: User
351+
user: UserWithClient
351352
): Promise<Result<TemplateDto>> {
352353
const log = this.logger.child({ templateId, user });
353354

@@ -363,10 +364,15 @@ export class TemplateClient {
363364
return clientConfigurationResult;
364365
}
365366

366-
if (!clientConfigurationResult.data?.features.proofing) {
367+
const clientConfig = clientConfigurationResult.data;
368+
const clientProofingEnabled = clientConfig?.features.proofing;
369+
const campaignId = clientConfig?.campaignId;
370+
371+
if (!clientProofingEnabled || !campaignId) {
367372
log.error({
368373
code: ErrorCase.FEATURE_DISABLED,
369374
description: 'User cannot request a proof',
375+
clientConfig,
370376
});
371377

372378
return failure(ErrorCase.FEATURE_DISABLED, 'User cannot request a proof');
@@ -402,13 +408,19 @@ export class TemplateClient {
402408

403409
const pdfVersionId = templateDTO.files.pdfTemplate.currentVersion;
404410
const testDataVersionId = templateDTO.files.testDataCsv?.currentVersion;
405-
const personalisationParameters = templateDTO.personalisationParameters;
411+
const personalisationParameters =
412+
templateDTO.personalisationParameters ?? [];
413+
const letterType = templateDTO.letterType;
414+
const language = templateDTO.language;
406415

407416
const sendQueueResult = await this.proofingQueue.send(
408417
templateId,
409418
templateDTO.name,
410-
user.userId,
411-
personalisationParameters!,
419+
user,
420+
campaignId,
421+
personalisationParameters,
422+
letterType,
423+
language,
412424
pdfVersionId,
413425
testDataVersionId,
414426
this.defaultLetterSupplier

lambdas/backend-api/src/templates/infra/proofing-queue.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
import { SendMessageCommand, SQSClient } from '@aws-sdk/client-sqs';
22
import { failure, success } from '@backend-api/utils/result';
3-
import { ErrorCase } from 'nhs-notify-backend-client';
3+
import {
4+
ErrorCase,
5+
type Language,
6+
type LetterType,
7+
} from 'nhs-notify-backend-client';
8+
import type { UserWithClient } from 'nhs-notify-web-template-management-utils';
49

510
export class ProofingQueue {
611
constructor(
@@ -11,8 +16,11 @@ export class ProofingQueue {
1116
async send(
1217
templateId: string,
1318
templateName: string,
14-
owner: string,
19+
user: UserWithClient,
20+
campaignId: string,
1521
personalisationParameters: string[],
22+
letterType: LetterType,
23+
language: Language,
1624
pdfVersionId: string,
1725
testDataVersionId: string | undefined,
1826
supplier: string
@@ -22,13 +30,16 @@ export class ProofingQueue {
2230
new SendMessageCommand({
2331
QueueUrl: this.queueUrl,
2432
MessageBody: JSON.stringify({
25-
owner,
33+
campaignId,
34+
language,
35+
letterType,
2636
pdfVersionId,
2737
personalisationParameters,
2838
supplier,
2939
templateId,
3040
templateName,
3141
testDataVersionId,
42+
user,
3243
}),
3344
})
3445
);

lambdas/backend-api/src/templates/types.ts

Lines changed: 0 additions & 4 deletions
This file was deleted.

lambdas/sftp-letters/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"ksuid": "^3.0.0",
1212
"nhs-notify-entity-update-command-builder": "*",
1313
"nhs-notify-web-template-management-utils": "*",
14+
"nhs-notify-backend-client": "*",
1415
"node-cache": "^5.1.2",
1516
"ssh2-sftp-client": "^9.1.0",
1617
"zod": "^3.24.2"

lambdas/sftp-letters/src/app/poll.ts

Lines changed: 44 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,58 +17,60 @@ export class App {
1717
const { sftpClient, baseDownloadDir } =
1818
await this.sftpSupplierClientRepository.getClient(supplier);
1919

20-
this.logger.info('Polling SFTP');
20+
const baseSftpPath = `${baseDownloadDir}/${this.sftpEnvironment}/proofs`;
21+
const baseS3Path = `proofs/${supplier}`;
22+
23+
const basePathLogger = this.logger.child({ baseSftpPath, baseS3Path });
24+
25+
basePathLogger.info('Polling SFTP');
2126
await sftpClient.connect();
2227

23-
this.logger.info(
28+
basePathLogger.info(
2429
`Copying files from folder ${baseDownloadDir}/${this.sftpEnvironment}/proofs to proofs`
2530
);
2631

2732
try {
2833
await this.pollBaseFolder(
2934
sftpClient,
30-
`${baseDownloadDir}/${this.sftpEnvironment}/proofs`,
31-
`proofs/${supplier}`
35+
baseSftpPath,
36+
baseS3Path,
37+
basePathLogger
3238
);
3339
} finally {
3440
await sftpClient.end();
3541
}
3642

37-
this.logger.info('Finished polling SFTP');
43+
basePathLogger.info('Finished polling SFTP');
3844
}
3945

4046
private async pollBaseFolder(
4147
sftpClient: SftpClient,
4248
baseSftpPath: string,
43-
baseS3Path: string
49+
baseS3Path: string,
50+
logger: Logger
4451
) {
45-
this.logger.info({
46-
description: 'Copying folder',
47-
baseSftpPath,
48-
baseS3Path,
49-
});
52+
logger.info('Copying folder');
5053
const isDir = await this.isDirectory(sftpClient, baseSftpPath);
5154

5255
if (!isDir) {
53-
this.logger.info(`Path '${baseSftpPath}' does not exist`);
56+
logger.info(`Base SFTP path does not exist`);
5457
return;
5558
}
5659

57-
const templateIdFolders = await sftpClient.list(baseSftpPath);
60+
const idFolders = await sftpClient.list(baseSftpPath);
5861

59-
for (const templateIdFolder of templateIdFolders) {
60-
if (templateIdFolder.type === 'd') {
61-
await this.pollTemplateIdFolder(
62+
for (const idFolder of idFolders) {
63+
if (idFolder.type === 'd') {
64+
await this.pollIdFolder(
6265
sftpClient,
6366
baseSftpPath,
6467
baseS3Path,
65-
templateIdFolder.name
68+
idFolder.name,
69+
logger
6670
);
6771
} else {
68-
this.logger.info({
69-
description: 'Unexpected non-directory item found',
70-
baseSftpPath,
71-
templateIdFolder,
72+
logger.info('Unexpected non-directory item found', {
73+
expandedTemplateId: idFolder,
7274
});
7375
}
7476
}
@@ -78,38 +80,44 @@ export class App {
7880
return (await sftpClient.exists(path)) === 'd';
7981
}
8082

81-
private async pollTemplateIdFolder(
83+
private getInternalTemplateId(expandedTemplateId: string) {
84+
return expandedTemplateId.split('_')[2];
85+
}
86+
87+
private async pollIdFolder(
8288
sftpClient: SftpClient,
8389
baseSftpPath: string,
8490
baseS3Path: string,
85-
templateId: string
91+
expandedTemplateId: string,
92+
logger: Logger
8693
) {
87-
const proofFiles = await sftpClient.list(`${baseSftpPath}/${templateId}`);
94+
const proofFiles = await sftpClient.list(
95+
`${baseSftpPath}/${expandedTemplateId}`
96+
);
97+
const templateId = this.getInternalTemplateId(expandedTemplateId);
98+
const idLogger = logger.child({ expandedTemplateId, templateId });
8899

89100
for (const proofFile of proofFiles) {
90101
if (proofFile.type === '-') {
91102
await this.copyFileToS3(
92103
sftpClient,
93-
`${baseSftpPath}/${templateId}/${proofFile.name}`,
94-
`${baseS3Path}/${templateId}/${proofFile.name}`
104+
`${baseSftpPath}/${expandedTemplateId}/${proofFile.name}`,
105+
`${baseS3Path}/${templateId}/${proofFile.name}`,
106+
logger
95107
);
96108
} else {
97-
this.logger.info({
98-
description: 'Unexpected non-file item found',
99-
baseSftpPath,
100-
templateId,
101-
proofFile,
102-
});
109+
idLogger.info('Unexpected non-file item found');
103110
}
104111
}
105112
}
106113

107114
private async copyFileToS3(
108115
sftpClient: SftpClient,
109116
sftpPath: string,
110-
s3Path: string
117+
s3Path: string,
118+
logger: Logger
111119
) {
112-
this.logger.info({ description: 'Copying file', sftpPath, s3Path });
120+
logger.info('Copying file');
113121
try {
114122
const data = (await sftpClient.get(sftpPath)) as Buffer;
115123

@@ -118,18 +126,12 @@ export class App {
118126
if (fileValidation) {
119127
await this.s3Repository.putRawData(data, s3Path);
120128
} else {
121-
this.logger.error({
122-
description: 'PDF file failed validation',
123-
sftpPath,
124-
s3Path,
125-
});
129+
logger.error('PDF file failed validation');
126130
}
127131

128132
await sftpClient.delete(sftpPath);
129133
} catch (error) {
130-
this.logger
131-
.child({ description: 'Failed to process file', sftpPath, s3Path })
132-
.error(error);
134+
logger.error('Failed to process file', error);
133135
}
134136
}
135137

0 commit comments

Comments
 (0)