Skip to content

Commit ca03279

Browse files
committed
adding config service
1 parent 71f7a41 commit ca03279

File tree

10 files changed

+86
-35
lines changed

10 files changed

+86
-35
lines changed

infrastructure/terraform/modules/backend-api/locals.tf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ locals {
3939
}
4040

4141
backend_lambda_environment_variables = {
42+
CSI = local.csi
4243
DEFAULT_LETTER_SUPPLIER = local.default_letter_supplier_name
4344
ENVIRONMENT = var.environment
4445
NODE_OPTIONS = "--enable-source-maps"

lambdas/backend-api/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"@aws-sdk/client-dynamodb": "3.775.0",
55
"@aws-sdk/client-s3": "3.775.0",
66
"@aws-sdk/client-sqs": "3.775.0",
7+
"@aws-sdk/client-ssm": "3.775.0",
78
"@aws-sdk/lib-dynamodb": "3.775.0",
89
"@aws-sdk/util-dynamodb": "3.775.0",
910
"csv-parse": "^5.6.0",

lambdas/backend-api/src/templates/api/create-letter.ts

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
import type { APIGatewayProxyHandler } from 'aws-lambda';
22
import { apiFailure, apiSuccess } from './responses';
3-
import {
4-
ClientConfiguration,
5-
type CreateUpdateTemplate,
6-
} from 'nhs-notify-backend-client';
3+
import { type CreateUpdateTemplate } from 'nhs-notify-backend-client';
74
import { getLetterUploadParts } from '../app/get-letter-upload-parts';
85
import { TemplateClient } from '../app/template-client';
6+
import { ClientConfigurationService } from '../app/client-configuration-service';
97

108
export function createHandler({
119
templateClient,
10+
clientConfigurationService,
1211
}: {
1312
templateClient: TemplateClient;
13+
clientConfigurationService: ClientConfigurationService;
1414
}): APIGatewayProxyHandler {
1515
return async function (event) {
1616
const { user: userId, clientId } = event.requestContext.authorizer ?? {};
@@ -31,7 +31,8 @@ export function createHandler({
3131
return apiFailure(400, getLetterPartsError.message);
3232
}
3333

34-
const client = await ClientConfiguration.fetch(authorizationToken);
34+
const clientConfiguration =
35+
await clientConfigurationService.fetch(clientId);
3536

3637
const { template, pdf, csv } = letterParts;
3738

@@ -41,7 +42,7 @@ export function createHandler({
4142
{ userId, clientId },
4243
pdf,
4344
csv,
44-
client?.campaignId
45+
clientConfiguration?.campaignId
4546
);
4647

4748
if (createTemplateError) {
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { ClientConfigurationRepository } from '../infra/client-configuration-repository';
2+
import { $ClientConfiguration } from 'nhs-notify-backend-client/src/schemas/client-configuration';
3+
4+
export class ClientConfigurationService {
5+
constructor(
6+
private readonly clientConfigurationRepository: ClientConfigurationRepository
7+
) {}
8+
9+
async fetch(clientId: string) {
10+
return $ClientConfiguration.parse(
11+
this.clientConfigurationRepository.get(clientId)
12+
);
13+
}
14+
}

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

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ import { ProofingQueue } from './infra/proofing-queue';
88
import { SQSClient } from '@aws-sdk/client-sqs';
99
import { loadConfig } from './infra/config';
1010
import { logger } from 'nhs-notify-web-template-management-utils/logger';
11+
import { ClientConfigurationRepository } from './infra/client-configuration-repository';
12+
import { SSMClient } from '@aws-sdk/client-ssm';
13+
import { ClientConfigurationService } from './app/client-configuration-service';
1114

1215
const sqsClient = new SQSClient({ region: 'eu-west-2' });
1316

@@ -33,11 +36,20 @@ export function createContainer() {
3336
config.downloadBucket
3437
);
3538

39+
const clientConfigurationRepository = new ClientConfigurationRepository(
40+
new SSMClient({ region: 'eu-west-2' }),
41+
config.csi
42+
);
43+
3644
const proofingQueue = new ProofingQueue(
3745
sqsClient,
3846
config.requestProofQueueUrl
3947
);
4048

49+
const clientConfigurationService = new ClientConfigurationService(
50+
clientConfigurationRepository
51+
);
52+
4153
const templateClient = new TemplateClient(
4254
templateRepository,
4355
letterUploadRepository,
@@ -47,9 +59,10 @@ export function createContainer() {
4759
);
4860

4961
return {
62+
clientConfigurationService,
63+
letterUploadRepository,
5064
templateClient,
5165
templateRepository,
52-
letterUploadRepository,
5366
};
5467
}
5568

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm';
2+
3+
export class ClientConfigurationRepository {
4+
constructor(
5+
private readonly ssm: SSMClient,
6+
private readonly csi: string
7+
) {}
8+
9+
async get(clientId: string) {
10+
return await this.ssm.send(
11+
new GetParameterCommand({ Name: `/${this.csi}/clients/${clientId}` })
12+
);
13+
}
14+
}

lambdas/backend-api/src/templates/infra/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import z from 'zod';
22

33
const $Env = z.object({
4+
CSI: z.string(),
45
DEFAULT_LETTER_SUPPLIER: z.string(),
56
ENABLE_PROOFING: z.enum(['true', 'false']).default('false'),
67
ENVIRONMENT: z.string(),
@@ -15,6 +16,7 @@ export function loadConfig() {
1516
const env = $Env.parse(process.env);
1617

1718
return {
19+
csi: env.CSI,
1820
defaultLetterSupplier: env.DEFAULT_LETTER_SUPPLIER,
1921
enableProofing: env.ENABLE_PROOFING === 'true',
2022
environment: env.ENVIRONMENT,
Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,43 @@
1-
import type {
2-
Features,
3-
IClientConfiguration,
4-
} from './types/client-configuration';
1+
import type { ClientConfiguration } from './types/client-configuration';
52
import { $ClientConfiguration } from './schemas/client-configuration';
3+
import { catchAxiosError, createAxiosClient } from './axios-client';
4+
import { Result } from './types/result';
65

7-
export class ClientConfiguration implements IClientConfiguration {
8-
private constructor(
9-
public readonly features: Readonly<Features>,
10-
public readonly campaignId?: string
11-
) {}
12-
13-
featureEnabled(feature: keyof Features) {
14-
return this.features[feature] === true;
15-
}
6+
export class ClientConfigurationApiService {
7+
constructor(public readonly client = createAxiosClient()) {}
168

179
/**
1810
* Gets and validates client configuration via AWS API gateway
1911
* @param {string} token user's JWT to authenticate against API gateway
2012
* @returns {Promise<ClientConfiguration>} client configuration.
2113
*/
22-
static async fetch(token: string): Promise<ClientConfiguration | undefined> {
23-
const client = await ClientConfiguration._fetch(token);
14+
async fetch(token: string): Promise<Result<ClientConfiguration>> {
15+
const client = await this._fetch(token);
2416

25-
return new ClientConfiguration(client.features, client.campaignId);
17+
return client;
2618
}
2719

28-
// Note: Temporary until we have some sort of API.
29-
private static async _fetch(_: string): Promise<IClientConfiguration> {
30-
return $ClientConfiguration.parse({
31-
clientId: 'example-clientId',
32-
campaignId: 'example-campaignId',
33-
name: 'example-name',
34-
features: {
35-
proofing: true,
36-
},
37-
});
20+
private async _fetch(token: string): Promise<Result<ClientConfiguration>> {
21+
const response = await catchAxiosError(
22+
this.client.get<{
23+
statusCode: number;
24+
clientConfiguration: ClientConfiguration;
25+
}>('/v1/client-configuration', {
26+
headers: {
27+
'Content-Type': 'application/json',
28+
Authorization: token,
29+
},
30+
})
31+
);
32+
33+
if (response.error) {
34+
return {
35+
error: response.error,
36+
};
37+
}
38+
39+
return {
40+
data: $ClientConfiguration.parse(response.data.clientConfiguration),
41+
};
3842
}
3943
}

lambdas/backend-client/src/types/client-configuration.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ export type Features = {
22
proofing: boolean;
33
};
44

5-
export interface IClientConfiguration {
5+
export type ClientConfiguration = {
66
campaignId?: string;
77
features: Features;
8-
}
8+
};

package-lock.json

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)