Skip to content

Commit b5d0ac4

Browse files
committed
CCM-11201 Store MI in DDB
1 parent 1d0a6a5 commit b5d0ac4

File tree

5 files changed

+136
-10
lines changed

5 files changed

+136
-10
lines changed

internal/datastore/src/__test__/db.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export async function setupDynamoDBContainer() {
3030
region: 'us-west-2',
3131
endpoint,
3232
lettersTableName: 'letters',
33+
miTableName: 'management-info',
3334
ttlHours: 1
3435
};
3536

@@ -44,10 +45,7 @@ export async function setupDynamoDBContainer() {
4445

4546
export type DBContext = Awaited<ReturnType<typeof setupDynamoDBContainer>>;
4647

47-
export async function createTables(context: DBContext) {
48-
const { ddbClient } = context;
49-
50-
await ddbClient.send(new CreateTableCommand({
48+
const createLetterTableCommand = new CreateTableCommand({
5149
TableName: 'letters',
5250
BillingMode: 'PAY_PER_REQUEST',
5351
KeySchema: [
@@ -72,15 +70,37 @@ export async function createTables(context: DBContext) {
7270
{ AttributeName: 'supplierStatus', AttributeType: 'S' },
7371
{ AttributeName: 'supplierStatusSk', AttributeType: 'S' },
7472
]
75-
}));
73+
});
7674

77-
await ddbClient.send(new UpdateTimeToLiveCommand({
75+
const updateTimeToLiveCommand = new UpdateTimeToLiveCommand({
7876
TableName: 'letters',
7977
TimeToLiveSpecification: {
8078
AttributeName: 'ttl',
8179
Enabled: true
8280
}
83-
}));
81+
});
82+
83+
const createMITableCommand = new CreateTableCommand({
84+
TableName: 'management-info',
85+
BillingMode: 'PAY_PER_REQUEST',
86+
KeySchema: [
87+
{ AttributeName: 'supplierId', KeyType: 'HASH' }, // Partition key
88+
{ AttributeName: 'id', KeyType: 'RANGE' } // Sort key
89+
],
90+
AttributeDefinitions: [
91+
{ AttributeName: 'supplierId', AttributeType: 'S' },
92+
{ AttributeName: 'id', AttributeType: 'S' },
93+
]
94+
});
95+
96+
97+
export async function createTables(context: DBContext) {
98+
const { ddbClient } = context;
99+
100+
await ddbClient.send(createLetterTableCommand);
101+
await ddbClient.send(updateTimeToLiveCommand);
102+
103+
await ddbClient.send(createMITableCommand);
84104
}
85105

86106

@@ -90,4 +110,8 @@ export async function deleteTables(context: DBContext) {
90110
await ddbClient.send(new DeleteTableCommand({
91111
TableName: 'letters'
92112
}));
113+
114+
await ddbClient.send(new DeleteTableCommand({
115+
TableName: 'management-info'
116+
}));
93117
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { Logger } from "pino";
2+
import { LetterRepository } from "../letter-repository";
3+
import { setupDynamoDBContainer, createTables, DBContext, deleteTables } from "./db";
4+
import { createTestLogger, LogStream } from "./logs";
5+
import { MIRepository } from "../mi-repository";
6+
7+
describe('MiRepository', () => {
8+
let db: DBContext;
9+
let miRepository: MIRepository;
10+
let logStream: LogStream;
11+
let logger: Logger;
12+
13+
14+
beforeAll(async () => {
15+
db = await setupDynamoDBContainer();
16+
});
17+
18+
beforeEach(async () => {
19+
await createTables(db);
20+
(
21+
{ logStream, logger } = createTestLogger()
22+
);
23+
24+
miRepository = new MIRepository(db.docClient, logger, db.config);
25+
});
26+
27+
afterEach(async () => {
28+
await deleteTables(db);
29+
jest.useRealTimers();
30+
});
31+
32+
afterAll(async () => {
33+
await db.container.stop();
34+
});
35+
36+
describe('putMi', () => {
37+
38+
it('creates a letter with id and timestamps', async () => {
39+
40+
jest.useFakeTimers();
41+
// Month is zero-indexed in JS Date
42+
jest.setSystemTime(new Date(2020, 1, 1));
43+
const mi = {
44+
specificationId: 'spec1',
45+
supplierId: 'supplier1',
46+
groupId:'group1',
47+
lineItem: 'item1',
48+
quantity: 12,
49+
stockRemaining: 0
50+
};
51+
52+
const persistedMi = await(miRepository.putMI(mi));
53+
54+
expect(persistedMi).toEqual(expect.objectContaining({
55+
id: expect.any(String),
56+
createdAt: '2020-02-01T00:00:00.000Z',
57+
updatedAt: '2020-02-01T00:00:00.000Z',
58+
...mi
59+
}));
60+
});
61+
});
62+
});

internal/datastore/src/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@ export type DatastoreConfig = {
22
region: string,
33
endpoint?: string,
44
lettersTableName: string,
5+
miTableName: string,
56
ttlHours: number
67
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import {
2+
DynamoDBDocumentClient,
3+
PutCommand
4+
} from '@aws-sdk/lib-dynamodb';
5+
import { MI, MISchema } from './types';
6+
import { Logger } from 'pino';
7+
import { v4 as uuidv4 } from 'uuid';
8+
9+
export type MIRepositoryConfig = {
10+
miTableName: string
11+
};
12+
13+
export class MIRepository {
14+
constructor(readonly ddbClient: DynamoDBDocumentClient,
15+
readonly log: Logger,
16+
readonly config: MIRepositoryConfig) {
17+
}
18+
19+
async putMI(mi: Omit<MI, 'id' | 'createdAt' | 'updatedAt'>): Promise<MI> {
20+
const now = new Date().toISOString();
21+
const miDb = {
22+
...mi,
23+
id: uuidv4(),
24+
createdAt: now,
25+
updatedAt: now
26+
};
27+
28+
await this.ddbClient.send(new PutCommand({
29+
TableName: this.config.miTableName,
30+
Item: miDb
31+
}));
32+
33+
return MISchema.parse(miDb);
34+
}
35+
};

internal/datastore/src/types.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,20 @@ export const LetterSchema = LetterSchemaBase.extend({
4646
export type Letter = z.infer<typeof LetterSchema>;
4747
export type LetterBase = z.infer<typeof LetterSchemaBase>;
4848

49-
export const MISchema = z.object({
49+
export const MISchemaBase = z.object({
5050
id: z.string(),
51-
supplierId: idRef(SupplierSchema),
5251
specificationId: z.string(),
5352
groupId: z.string(),
5453
lineItem: z.string(),
5554
quantity: z.number(),
56-
stockRemaining: z.number(),
55+
stockRemaining: z.number()
56+
});
57+
58+
export const MISchema = MISchemaBase.extend({
59+
supplierId: idRef(SupplierSchema),
5760
createdAt: z.string(),
5861
updatedAt: z.string()
5962
}).describe('MI');
6063

6164
export type MI = z.infer<typeof MISchema>;
65+
export type MIBase = z.infer<typeof MISchemaBase>;

0 commit comments

Comments
 (0)