Merge branch 'develop'

This commit is contained in:
SAITO-PC-3\saito.k 2024-04-03 18:51:31 +09:00
commit c600d9f818
6 changed files with 634 additions and 21 deletions

View File

@ -165,9 +165,7 @@ import { CheckHeaderMiddleware } from './common/check-header.middleware';
})
export class AppModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('');
consumer.apply(LoggerMiddleware).forRoutes('');
// stage=localの場合はmiddlewareを適用しない
// ローカル環境ではサーバーから静的ファイルも返すため、APIリクエスト以外のリクエストにもmiddlewareが適用されてしまう
if (process.env.STAGE !== 'local') {

View File

@ -8,6 +8,7 @@ import {
createUserGroupAndMember,
getTaskFromJobNumber,
makeTestingModuleWithBlobAndNotification,
updateTaskStatusAndIsJobNumberEnabled,
} from './test/utility';
import { FilesService } from './files.service';
import { makeContext } from '../../common/log';
@ -319,7 +320,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const NotificationHubService = module.get<NotificationhubService>(
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
@ -340,9 +341,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
optionItemList,
false,
);
expect(result).toEqual({ jobNumber: '00000001' });
expect(result.jobNumber).toEqual('00000001');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
@ -420,7 +421,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const NotificationHubService = module.get<NotificationhubService>(
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
@ -441,9 +442,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
optionItemList,
false,
);
expect(result).toEqual({ jobNumber: '00000002' });
expect(result.jobNumber).toEqual('00000002');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
@ -543,7 +544,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const NotificationHubService = module.get<NotificationhubService>(
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
@ -564,9 +565,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
optionItemList,
false,
);
expect(result).toEqual({ jobNumber: '00000001' });
expect(result.jobNumber).toEqual('00000001');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
@ -665,7 +666,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const NotificationHubService = module.get<NotificationhubService>(
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
@ -686,9 +687,9 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
optionItemList,
false,
);
expect(result).toEqual({ jobNumber: '00000001' });
expect(result.jobNumber).toEqual('00000001');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(NotificationHubService.notify).toHaveBeenCalledWith(
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
@ -755,7 +756,7 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
optionItemList,
false,
);
expect(result).toEqual({ jobNumber: '00000001' });
expect(result.jobNumber).toEqual('00000001');
// タスクを取得
const resultTask = await getTaskFromJobNumber(source, result.jobNumber);
// タスクのチェックアウト権限を取得
@ -957,6 +958,603 @@ describe('タスク作成から自動ルーティング(DB使用)', () => {
),
);
});
it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバーが有効でない場合)', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const {
external_id: authorExternalId,
id: authorUserId,
author_id: authorAuthorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
author_id: undefined,
});
// ワークタイプを作成
const { id: worktypeId, custom_worktype_id } = await createWorktype(
source,
accountId,
'worktypeId',
);
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'templateFile',
'http://blob/url/templateFile.zip',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
worktypeId,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, typistUserId);
const blobParam = makeBlobstorageServiceMockValue();
const notificationParam = makeDefaultNotificationhubServiceMockValue();
// タスクを10件作成, ジョブナンバーは00000001から00000010まで
for (let i = 1; i <= 10; i++) {
await createTask(
source,
accountId,
`http://blob/url/file_${i}.zip`,
`file_${i}.zip`,
'01',
typistUserId,
authorAuthorId ?? '',
i.toString().padStart(8, '0'),
);
}
// 最新のジョブナンバーでタスクを取得
const latestTask = await getTaskFromJobNumber(source, '00000010');
// 最新のタスクのステータスとis_job_number_enabledを更新
await updateTaskStatusAndIsJobNumberEnabled(
source,
latestTask?.id ?? 0,
'Backup',
false,
);
const module = await makeTestingModuleWithBlobAndNotification(
source,
blobParam,
notificationParam,
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
makeContext('trackingId', 'requestId'),
authorExternalId,
'http://blob/url/file.zip',
authorAuthorId ?? '',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
custom_worktype_id,
optionItemList,
false,
);
expect(result.jobNumber).toEqual('00000011');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
authorId: 'AUTHOR_ID',
filename: 'file',
priority: 'High',
uploadedAt: '2023-05-26T11:22:33.444',
},
);
// 作成したタスクを取得
const resultTask = await getTaskFromJobNumber(source, result.jobNumber);
// タスクのチェックアウト権限を取得
const resultCheckoutPermission = await getCheckoutPermissions(
source,
resultTask?.id ?? 0,
);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(templateFileId);
// タスクのチェックアウト権限が想定通りワークフローで設定されているのユーザーIDで作成されているか確認
expect(resultCheckoutPermission.length).toEqual(1);
expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId);
});
it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバー有効である場合)', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const {
external_id: authorExternalId,
id: authorUserId,
author_id: authorAuthorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
author_id: undefined,
});
// ワークタイプを作成
const { id: worktypeId, custom_worktype_id } = await createWorktype(
source,
accountId,
'worktypeId',
);
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'templateFile',
'http://blob/url/templateFile.zip',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
worktypeId,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, typistUserId);
const blobParam = makeBlobstorageServiceMockValue();
const notificationParam = makeDefaultNotificationhubServiceMockValue();
// タスクを10件作成, ジョブナンバーは00000001から00000010まで
for (let i = 1; i <= 10; i++) {
await createTask(
source,
accountId,
`http://blob/url/file_${i}.zip`,
`file_${i}.zip`,
'01',
typistUserId,
authorAuthorId ?? '',
i.toString().padStart(8, '0'),
);
}
const module = await makeTestingModuleWithBlobAndNotification(
source,
blobParam,
notificationParam,
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
makeContext('trackingId', 'requestId'),
authorExternalId,
'http://blob/url/file.zip',
authorAuthorId ?? '',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
custom_worktype_id,
optionItemList,
false,
);
expect(result.jobNumber).toEqual('00000011');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
authorId: 'AUTHOR_ID',
filename: 'file',
priority: 'High',
uploadedAt: '2023-05-26T11:22:33.444',
},
);
// 作成したタスクを取得
const resultTask = await getTaskFromJobNumber(source, result.jobNumber);
// タスクのチェックアウト権限を取得
const resultCheckoutPermission = await getCheckoutPermissions(
source,
resultTask?.id ?? 0,
);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(templateFileId);
// タスクのチェックアウト権限が想定通りワークフローで設定されているのユーザーIDで作成されているか確認
expect(resultCheckoutPermission.length).toEqual(1);
expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId);
});
it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(途中のタスクのジョブナンバーが有効でない場合)', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const {
external_id: authorExternalId,
id: authorUserId,
author_id: authorAuthorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
author_id: undefined,
});
// ワークタイプを作成
const { id: worktypeId, custom_worktype_id } = await createWorktype(
source,
accountId,
'worktypeId',
);
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'templateFile',
'http://blob/url/templateFile.zip',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
worktypeId,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, typistUserId);
const blobParam = makeBlobstorageServiceMockValue();
const notificationParam = makeDefaultNotificationhubServiceMockValue();
// タスクを10件作成, ジョブナンバーは00000001から00000010まで
for (let i = 1; i <= 10; i++) {
await createTask(
source,
accountId,
`http://blob/url/file_${i}.zip`,
`file_${i}.zip`,
'01',
typistUserId,
authorAuthorId ?? '',
i.toString().padStart(8, '0'),
);
}
// ジョブナンバー00000005のタスクを取得
const middleTask = await getTaskFromJobNumber(source, '00000005');
// ジョブナンバー00000005のタスクのステータスとis_job_number_enabledを更新
await updateTaskStatusAndIsJobNumberEnabled(
source,
middleTask?.id ?? 0,
'Backup',
false,
);
const module = await makeTestingModuleWithBlobAndNotification(
source,
blobParam,
notificationParam,
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
makeContext('trackingId', 'requestId'),
authorExternalId,
'http://blob/url/file.zip',
authorAuthorId ?? '',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
custom_worktype_id,
optionItemList,
false,
);
expect(result.jobNumber).toEqual('00000011');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
authorId: 'AUTHOR_ID',
filename: 'file',
priority: 'High',
uploadedAt: '2023-05-26T11:22:33.444',
},
);
// 作成したタスクを取得
const resultTask = await getTaskFromJobNumber(source, result.jobNumber);
// タスクのチェックアウト権限を取得
const resultCheckoutPermission = await getCheckoutPermissions(
source,
resultTask?.id ?? 0,
);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(templateFileId);
// タスクのチェックアウト権限が想定通りワークフローで設定されているのユーザーIDで作成されているか確認
expect(resultCheckoutPermission.length).toEqual(1);
expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId);
});
it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバーが99999999で有効でない場合)', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const {
external_id: authorExternalId,
id: authorUserId,
author_id: authorAuthorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
author_id: undefined,
});
// ワークタイプを作成
const { id: worktypeId, custom_worktype_id } = await createWorktype(
source,
accountId,
'worktypeId',
);
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'templateFile',
'http://blob/url/templateFile.zip',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
worktypeId,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, typistUserId);
const blobParam = makeBlobstorageServiceMockValue();
const notificationParam = makeDefaultNotificationhubServiceMockValue();
// タスクを10件作成, ジョブナンバーは99999989から99999999まで
for (let i = 99999989; i <= 99999999; i++) {
await createTask(
source,
accountId,
`http://blob/url/file_${i}.zip`,
`file_${i}.zip`,
'01',
typistUserId,
authorAuthorId ?? '',
i.toString().padStart(8, '0'),
);
}
// 最新ジョブナンバーのタスクを取得
const latestTask = await getTaskFromJobNumber(source, '99999999');
// 最新のタスクのステータスとis_job_number_enabledを更新
await updateTaskStatusAndIsJobNumberEnabled(
source,
latestTask?.id ?? 0,
'Backup',
false,
);
const module = await makeTestingModuleWithBlobAndNotification(
source,
blobParam,
notificationParam,
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
makeContext('trackingId', 'requestId'),
authorExternalId,
'http://blob/url/file.zip',
authorAuthorId ?? '',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
custom_worktype_id,
optionItemList,
false,
);
expect(result.jobNumber).toEqual('00000001');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
authorId: 'AUTHOR_ID',
filename: 'file',
priority: 'High',
uploadedAt: '2023-05-26T11:22:33.444',
},
);
// 作成したタスクを取得
const resultTask = await getTaskFromJobNumber(source, result.jobNumber);
// タスクのチェックアウト権限を取得
const resultCheckoutPermission = await getCheckoutPermissions(
source,
resultTask?.id ?? 0,
);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(templateFileId);
// タスクのチェックアウト権限が想定通りワークフローで設定されているのユーザーIDで作成されているか確認
expect(resultCheckoutPermission.length).toEqual(1);
expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId);
});
it('タスク作成時に採番されるジョブナンバーが常に最新タスクのジョブナンバー + 1となる(最新タスクのジョブナンバーが99999999で有効な場合)', async () => {
if (!source) fail();
const { id: accountId } = await makeTestSimpleAccount(source);
const {
external_id: authorExternalId,
id: authorUserId,
author_id: authorAuthorId,
} = await makeTestUser(source, {
account_id: accountId,
external_id: 'author-user-external-id',
role: 'author',
author_id: 'AUTHOR_ID',
});
const { id: typistUserId } = await makeTestUser(source, {
account_id: accountId,
external_id: 'typist-user-external-id',
role: 'typist',
author_id: undefined,
});
// ワークタイプを作成
const { id: worktypeId, custom_worktype_id } = await createWorktype(
source,
accountId,
'worktypeId',
);
// テンプレートファイルを作成
const { id: templateFileId } = await createTemplateFile(
source,
accountId,
'templateFile',
'http://blob/url/templateFile.zip',
);
// ワークフローを作成
const { id: workflowId } = await createWorkflow(
source,
accountId,
authorUserId,
worktypeId,
templateFileId,
);
// ワークフロータイピストを作成
await createWorkflowTypist(source, workflowId, typistUserId);
const blobParam = makeBlobstorageServiceMockValue();
const notificationParam = makeDefaultNotificationhubServiceMockValue();
// タスクを10件作成, ジョブナンバーは99999989から99999999まで
for (let i = 99999989; i <= 99999999; i++) {
await createTask(
source,
accountId,
`http://blob/url/file_${i}.zip`,
`file_${i}.zip`,
'01',
typistUserId,
authorAuthorId ?? '',
i.toString().padStart(8, '0'),
);
}
const module = await makeTestingModuleWithBlobAndNotification(
source,
blobParam,
notificationParam,
);
if (!module) fail();
const service = module.get<FilesService>(FilesService);
const notificationHubService = module.get<NotificationhubService>(
NotificationhubService,
);
const result = await service.uploadFinished(
makeContext('trackingId', 'requestId'),
authorExternalId,
'http://blob/url/file.zip',
authorAuthorId ?? '',
'file.zip',
'11:22:33',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
'2023-05-26T11:22:33.444',
256,
'01',
'DS2',
'comment',
custom_worktype_id,
optionItemList,
false,
);
expect(result.jobNumber).toEqual('00000001');
// 通知処理が想定通りの引数で呼ばれているか確認
expect(notificationHubService.notify).toHaveBeenCalledWith(
makeContext('trackingId', 'requestId'),
[`user_${typistUserId}`],
{
authorId: 'AUTHOR_ID',
filename: 'file',
priority: 'High',
uploadedAt: '2023-05-26T11:22:33.444',
},
);
// 作成したタスクを取得
const resultTask = await getTaskFromJobNumber(source, result.jobNumber);
// タスクのチェックアウト権限を取得
const resultCheckoutPermission = await getCheckoutPermissions(
source,
resultTask?.id ?? 0,
);
// タスクのテンプレートファイルIDを確認
expect(resultTask?.template_file_id).toEqual(templateFileId);
// タスクのチェックアウト権限が想定通りワークフローで設定されているのユーザーIDで作成されているか確認
expect(resultCheckoutPermission.length).toEqual(1);
expect(resultCheckoutPermission[0].user_id).toEqual(typistUserId);
});
});
describe('音声ファイルダウンロードURL取得', () => {

View File

@ -53,6 +53,7 @@ export const createTask = async (
status: string,
typist_user_id?: number | undefined,
author_id?: string | undefined,
job_number?: string | undefined,
): Promise<{ audioFileId: number }> => {
const { identifiers: audioFileIdentifiers } = await datasource
.getRepository(AudioFile)
@ -87,7 +88,7 @@ export const createTask = async (
const templateFile = templateFileIdentifiers.pop() as TemplateFile;
await datasource.getRepository(Task).insert({
job_number: '00000001',
job_number: job_number ?? '00000001',
account_id: account_id,
is_job_number_enabled: true,
audio_file_id: audioFile.id,
@ -114,6 +115,21 @@ export const getTaskFromJobNumber = async (
return task;
};
// 指定したタスクのステータスとis_job_number_enabledを更新する
export const updateTaskStatusAndIsJobNumberEnabled = async (
datasource: DataSource,
taskId: number,
status: string,
isJobNumberEnabled: boolean,
): Promise<void> => {
await datasource
.getRepository(Task)
.update(
{ id: taskId },
{ status: status, is_job_number_enabled: isJobNumberEnabled },
);
};
// ユーザーグループとユーザーグループメンバーを作成する
export const createUserGroupAndMember = async (
datasource: DataSource,

View File

@ -117,7 +117,7 @@ export class LicensesService {
parentAccountId,
);
this.sendgridService.sendMailWithU105(
await this.sendgridService.sendMailWithU105(
context,
customer.adminEmails,
customer.companyName,

View File

@ -489,7 +489,7 @@ export class TasksService {
getUserNameAndMailAddress(primaryAdmin);
// メール送信
this.sendgridService.sendMailWithU117(
await this.sendgridService.sendMailWithU117(
context,
authorNotification ? authorEmail : null,
typistEmail,

View File

@ -899,9 +899,10 @@ export class TasksRepositoryService {
const taskRepo = entityManager.getRepository(Task);
// アカウント内でJOBナンバーが有効なタスクのうち最新のものを取得
// バグ 3954: [4/8リリース]タスクをすべてBackupした後、タスクを作成するとジョブナンバーがから採番される暫定対応
// アカウント内で最新タスクのタスクを取得し、そのJOBナンバーをインクリメントして新しいタスクのJOBナンバーを設定する
const lastTask = await taskRepo.findOne({
where: { account_id: account_id, is_job_number_enabled: true },
where: { account_id: account_id },
order: { created_at: 'DESC', job_number: 'DESC' },
comment: `${context.getTrackingId()}_${new Date().toUTCString()}`,
lock: { mode: 'pessimistic_write' },