Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
220 changes: 171 additions & 49 deletions architecture/home-test-consumer-api.yaml

Large diffs are not rendered by default.

82 changes: 37 additions & 45 deletions lambdas/src/lib/db/order-db.test.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,50 @@
import { OrderResultSummary, OrderService } from "./order-db";
import { OrderStatus, ResultStatus } from "../types/status";

import { Commons } from "../commons";
import { OrderResultSummary, OrderService } from "./order-db";

const normalizeWhitespace = (sql: string): string => sql.replace(/\s+/g, " ").trim();

describe("OrderService", () => {
let dbClient: any;
let commons: Pick<Commons, "logError">;
let orderService: OrderService;

const mockQuery = jest.fn();
const mockWithTransaction = jest.fn();

beforeEach(() => {
mockQuery.mockClear();
dbClient = {
query: jest.fn(),
withTransaction: jest.fn(),
query: mockQuery,
withTransaction: mockWithTransaction,
};
commons = {
logError: jest.fn(),
};
orderService = new OrderService(dbClient, commons as any as Commons);
orderService = new OrderService(dbClient);
});

describe("retrieveOrderDetails", () => {
const expectedRetrieveOrderDetailsQuery = `
SELECT
o.order_uid,
o.supplier_id,
o.patient_uid,
r.status AS result_status,
r.correlation_id,
os.status_code AS order_status_code
FROM test_order o
LEFT JOIN result_status r ON o.order_uid = r.order_uid
LEFT JOIN order_status os ON o.order_uid = os.order_uid
WHERE o.order_uid = $1::uuid
ORDER BY os.created_at DESC
LIMIT 1;
`;
SELECT
o.order_uid,
o.supplier_id,
o.patient_uid,
r.status AS result_status,
r.correlation_id,
os.status_code AS order_status_code
FROM test_order o
LEFT JOIN Lateral (
SELECT
r.status,
r.correlation_id
FROM result_status r
WHERE o.order_uid = r.order_uid
ORDER BY r.created_at DESC LIMIT 1
) r ON true
LEFT JOIN Lateral (
SELECT os.status_code
FROM order_status os
WHERE o.order_uid = os.order_uid
ORDER BY os.created_at DESC LIMIT 1
) os ON true
WHERE o.order_uid = $1::uuid;
`;

it("should return order details when found", async () => {
const mockSummary: OrderResultSummary = {
Expand Down Expand Up @@ -72,7 +80,7 @@ describe("OrderService", () => {
expect(result).toBeNull();
});

it("should log and rethrow when retrieving order details fails", async () => {
it("should rethrow when retrieving order details fails", async () => {
const error = new Error("query failed");
dbClient.query.mockRejectedValue(error);

Expand All @@ -83,14 +91,6 @@ describe("OrderService", () => {
normalizeWhitespace(expectedRetrieveOrderDetailsQuery),
);
expect(dbClient.query.mock.calls[0][1]).toEqual(["order-500"]);
expect(commons.logError).toHaveBeenCalledWith(
"order-db",
"Failed to retrieve order details",
{
error,
orderUid: "order-500",
},
);
});
});

Expand All @@ -116,7 +116,8 @@ describe("OrderService", () => {
`;
const expectedResultStatusQuery = `
INSERT INTO result_status (order_uid, status, correlation_id)
VALUES ($1::uuid, $2, $3::uuid);`;
VALUES ($1::uuid, $2, $3::uuid);
`;

await orderService.updateOrderStatusAndResultStatus(
"order-1",
Expand All @@ -142,7 +143,7 @@ describe("OrderService", () => {
]);
});

it("should log and rethrow when the transaction fails", async () => {
it("should rethrow when the transaction fails", async () => {
const error = new Error("transaction failed");
dbClient.withTransaction.mockRejectedValue(error);

Expand All @@ -153,16 +154,7 @@ describe("OrderService", () => {
ResultStatus.Result_Available,
"corr-1",
),
).rejects.toThrow(error);

expect(commons.logError).toHaveBeenCalledWith(
"order-db",
"Failed to update order and result status",
{
error,
orderUid: "order-1",
},
);
).rejects.toThrow("Failed to update order and result status");
});
});
});
38 changes: 24 additions & 14 deletions lambdas/src/lib/db/order-db.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { OrderStatus, ResultStatus } from "../types/status";

import { Commons } from "../commons";
import { DBClient } from "./db-client";

export interface OrderResultSummary {
Expand All @@ -14,10 +12,8 @@ export interface OrderResultSummary {

export class OrderService {
private readonly dbClient: DBClient;
private readonly commons: Commons;
constructor(dbClient: DBClient, commons: Commons) {
constructor(dbClient: DBClient) {
this.dbClient = dbClient;
this.commons = commons;
}

async retrieveOrderDetails(orderUid: string): Promise<OrderResultSummary | null> {
Expand All @@ -30,18 +26,28 @@ export class OrderService {
r.correlation_id,
os.status_code AS order_status_code
FROM test_order o
LEFT JOIN result_status r ON o.order_uid = r.order_uid
LEFT JOIN order_status os ON o.order_uid = os.order_uid
WHERE o.order_uid = $1::uuid
ORDER BY os.created_at DESC
LIMIT 1;
LEFT JOIN Lateral (
SELECT
r.status,
r.correlation_id
FROM result_status r
WHERE o.order_uid = r.order_uid
ORDER BY r.created_at DESC LIMIT 1
) r ON true
LEFT JOIN Lateral (
SELECT os.status_code
FROM order_status os
WHERE o.order_uid = os.order_uid
ORDER BY os.created_at DESC LIMIT 1
) os ON true
WHERE o.order_uid = $1::uuid;
`;

try {
const result = await this.dbClient.query<OrderResultSummary, [string]>(query, [orderUid]);
return result.rows[0] || null;
} catch (error) {
this.commons.logError("order-db", "Failed to retrieve order details", { error, orderUid });
console.error("order-db", "Failed to retrieve order details", { error, orderUid });
throw error;
Comment thread
TSeelig marked this conversation as resolved.
Comment thread
TSeelig marked this conversation as resolved.
}
}
Expand Down Expand Up @@ -69,15 +75,19 @@ export class OrderService {

const resultStatusQuery = `
INSERT INTO result_status (order_uid, status, correlation_id)
VALUES ($1::uuid, $2, $3::uuid);`;
VALUES ($1::uuid, $2, $3::uuid);
`;
await dbClient.query(resultStatusQuery, [orderUid, resultStatus, correlationId]);
});
} catch (error) {
this.commons.logError("order-db", "Failed to update order and result status", {
console.error("order-db", "Failed to update order and result status", {
error,
orderUid,
correlationId,
statusCode,
resultStatus,
});
Comment thread
TSeelig marked this conversation as resolved.
throw error;
throw new Error(`Failed to update order and result status`, { cause: error });
}
Comment thread
TSeelig marked this conversation as resolved.
}
}
2 changes: 1 addition & 1 deletion lambdas/src/order-result-lambda/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export function buildEnvironment(): Environment {
const homeTestBaseUrl = retrieveMandatoryEnvVariable("HOME_TEST_BASE_URL");
const secretsClient = new AwsSecretsClient(awsRegion);
const dbClient = new PostgresDbClient(postgresConfigFromEnv(secretsClient));
const orderService = new OrderService(dbClient, commons);
const orderService = new OrderService(dbClient);
const orderStatusDb = new OrderStatusService(dbClient);
const patientDbClient = new PatientDbClient(dbClient);
const orderDbClient = new OrderDbClient(dbClient);
Expand Down
12 changes: 12 additions & 0 deletions lambdas/src/result-status-lambda/cors-configuration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { type Options } from "@middy/http-cors";

import { defaultCorsOptions as sharedDefaultCorsOptions } from "../lib/security/cors-configuration";

const customCorsOptions: Options = {
methods: "POST, OPTIONS",
};

export const corsOptions: Options = {
...sharedDefaultCorsOptions,
...customCorsOptions,
};
Loading
Loading