ES /docs

Api::V1::IssuesController#create (avg 2481ms, max 2615ms)

Completeness#

# Plan Item Status Evidence
1 create.ts: Remove getIssueWithFullInfo() call, construct response in-memory using write data + issueType object, parallelize notifications with Promise.all() PASS applications/issue-service/src/lambda/issue/create.ts: lines 98-126 show removal of getIssueWithFullInfo(client, issueId) call, in-memory issue object construction (lines 100-113), and Promise.all(notifications) pattern (lines 115-121)
2 lambda-helper.ts: LambdaClient as module-scope singleton, remove per-function instantiation PASS applications/issue-service/src/common/lambda-helper.ts: line 4 declares const lambdaClient = new LambdaClient() at module scope; lines 6 and 20 show removal of const lambdaClient = new LambdaClient() inside each function
3 config.ts: Add singleton DynamoDBClient export PASS applications/issue-service/src/common/config.ts: line 1 adds import { DynamoDBClient } and line 10 adds export const dynamoDBClient = new DynamoDBClient(dynamoDBClientConfig)
4 dynamodb-helper.ts: No changes (API compatibility maintained) PASS File does not appear in the diff -- no modifications made, as planned

Acceptance Criteria#

# Criterion Status Evidence
1 create.ts removes getIssueWithFullInfo import and call PASS create.ts: line 10 shows import changed from { getIssueTypByErrorCode, getIssueTypById, getIssueWithFullInfo } to { getIssueTypByErrorCode, getIssueTypById }; line 100 area shows getIssueWithFullInfo(client, issueId) call removed
2 Response object constructed in-memory with issueType data PASS create.ts: lines 100-113 build issue object with fields from data and issueType directly, including issue_type: issueType
3 Notification calls parallelized with Promise.all() PASS create.ts: lines 115-121 build notifications array conditionally, then await Promise.all(notifications) at line 122
4 LambdaClient is module-scope singleton in lambda-helper.ts PASS lambda-helper.ts: line 4 declares const lambdaClient = new LambdaClient() outside any function
5 DynamoDBClient singleton exported from config.ts, reused in create.ts and findIssueType() PASS config.ts: line 10 exports dynamoDBClient; create.ts: line 6 imports dynamoDBClient from config, line 98 uses it for BatchWriteItemCommand, lines 19/21 use it in findIssueType() via getIssueTypById(dynamoDBClient, ...) and getIssueTypByErrorCode(dynamoDBClient, ...)
6 Existing error handling (try-catch) structure maintained PASS create.ts: try-catch block preserved at lines 97-126 (handler) and lines 17-23 (findIssueType)
7 issue.issue_type.error_code?.startsWith("AGT") condition works correctly PASS create.ts: line 119 checks !issueType.error_code?.startsWith("AGT") -- uses issueType directly which is the same object assigned to issue.issue_type, functionally equivalent to the original check

Issues Found#

No blocking issues found.

Observations#

  1. unmarshall import removed: The diff removes the unmarshall import from create.ts (line 2). This is correct since getIssueWithFullInfo (which used unmarshalled DynamoDB responses) is no longer called.

  2. Notification invocation type: Both sendEmailNotification and sendMondayNotification use InvocationType.Event (fire-and-forget async Lambda invocation). The Promise.all() wrapping them will resolve once the invoke API call returns (not when the downstream Lambda completes). This is functionally equivalent to the original sequential awaits but with reduced wall-clock time.

  3. In-memory response fidelity: The constructed issue object includes fields like created_at: Date.now() which may differ slightly from what DynamoDB would return (if there was any server-side transformation). Since the data was just written with the same values, this is acceptable.

  4. Null coalescing on issueType fields: issueType.issue_type_id ?? null and issueType.error_code ?? null safely handle cases where issueType might be the empty object {} returned when findIssueType returns null (line 90 area, not shown in diff but inferred from the existing code flow where issueType defaults). This is a minor robustness note -- the caller should verify that issueType is guaranteed non-null at this point in the flow.