@chevre/domain
Version:
Chevre Domain Library for Node.js
618 lines (617 loc) • 31.4 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.authorize = authorize;
exports.cancelMoneyTransfer = cancelMoneyTransfer;
exports.moneyTransfer = moneyTransfer;
/**
* 通貨転送サービス
*/
const moment = require("moment");
const pecorinoapi = require("../pecorinoapi");
const factory = require("../factory");
const errorHandler_1 = require("../errorHandler");
/**
* 口座残高差し押さえ
*/
function authorize(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const project = yield repos.project.findById({
id: params.project.id,
inclusion: ['settings', 'typeOf']
});
const transaction = yield repos.assetTransaction.findById({
typeOf: params.purpose.typeOf,
id: params.purpose.id
});
// 口座取引開始
// let pendingTransaction: factory.action.transfer.moneyTransfer.IPendingTransaction;
try {
yield processAccountTransaction({
typeOf: params.typeOf,
identifier: params.identifier,
transactionNumber: params.transactionNumber,
project: { id: project.id, typeOf: project.typeOf },
object: params.object,
agent: params.agent,
recipient: params.recipient,
transaction: transaction
})(repos);
}
catch (error) {
// PecorinoAPIのエラーをハンドリング
error = (0, errorHandler_1.handlePecorinoError)(error);
throw error;
}
// return pendingTransaction;
});
}
function processAccountTransaction(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const transaction = params.transaction;
const agent = createAccountTransactionAgent(params);
const recipient = createAccountTransactionRecipient(params);
const description = (typeof params.object.description === 'string') ? params.object.description : `for transaction ${transaction.id}`;
// 最大1ヵ月のオーソリ
const expires = moment()
.add(1, 'month')
.toDate();
const issuedThroughId = getIssuedThroughId(params);
const permitServiceCredentials = yield createPermitServiceCredentials({ issuedThrough: { id: issuedThroughId } })(repos);
const permitService = new (yield pecorinoapi.loadPecorino()).service.Permit({
endpoint: permitServiceCredentials.permitServiceEndpoint,
auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
domain: permitServiceCredentials.permitServiceAuthorizeServerDomain,
clientId: permitServiceCredentials.permitServiceClientId,
clientSecret: permitServiceCredentials.permitServiceClientSecret,
scopes: [],
state: ''
})
});
switch (params.typeOf) {
case factory.account.transactionType.Deposit:
yield processDepositTransaction({
identifier: params.identifier,
transactionNumber: params.transactionNumber,
project: params.project,
object: params.object,
agent,
recipient,
expires,
description,
permitServiceCredentials
})({ permit: permitService });
break;
case factory.account.transactionType.Transfer:
yield processTransferTransaction({
identifier: params.identifier,
transactionNumber: params.transactionNumber,
project: params.project,
object: params.object,
agent,
recipient,
expires,
description,
permitServiceCredentials
})({ permit: permitService });
break;
case factory.account.transactionType.Withdraw:
yield processWithdrawTransaction({
identifier: params.identifier,
transactionNumber: params.transactionNumber,
project: params.project,
object: params.object,
agent,
recipient,
expires,
description,
permitServiceCredentials
})({ permit: permitService });
break;
default:
throw new factory.errors.Argument('Object', 'At least one of accounts from and to must be specified');
}
// return pendingTransaction;
});
}
function processDepositTransaction(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a;
const accountTransactionService = new (yield pecorinoapi.loadPecorino()).service.AccountTransaction({
endpoint: params.permitServiceCredentials.permitServiceEndpoint,
auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
domain: params.permitServiceCredentials.permitServiceAuthorizeServerDomain,
clientId: params.permitServiceCredentials.permitServiceClientId,
clientSecret: params.permitServiceCredentials.permitServiceClientSecret,
scopes: [],
state: ''
})
});
if (typeof params.object.toLocation.identifier !== 'string') {
throw new factory.errors.ArgumentNull('object.toLocation.identifier');
}
const permit = yield repos.permit.findByIdentifier({
project: { id: params.project.id },
identifier: params.object.toLocation.identifier,
issuedThrough: { typeOf: factory.product.ProductType.PaymentCard }
});
return accountTransactionService.start(Object.assign({ transactionNumber: params.transactionNumber, project: { typeOf: params.project.typeOf, id: params.project.id }, typeOf: factory.account.transactionType.Deposit, agent: params.agent, expires: params.expires, recipient: params.recipient, object: {
amount: { value: params.object.amount },
description: params.description,
toLocation: {
accountNumber: String((_a = permit.paymentAccount) === null || _a === void 0 ? void 0 : _a.accountNumber)
}
} }, (typeof params.identifier === 'string') ? { identifier: params.identifier } : undefined));
});
}
function processTransferTransaction(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a, _b;
const accountTransactionService = new (yield pecorinoapi.loadPecorino()).service.AccountTransaction({
endpoint: params.permitServiceCredentials.permitServiceEndpoint,
auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
domain: params.permitServiceCredentials.permitServiceAuthorizeServerDomain,
clientId: params.permitServiceCredentials.permitServiceClientId,
clientSecret: params.permitServiceCredentials.permitServiceClientSecret,
scopes: [],
state: ''
})
});
if (typeof params.object.fromLocation.identifier !== 'string') {
throw new factory.errors.ArgumentNull('object.fromLocation.identifier');
}
if (typeof params.object.toLocation.identifier !== 'string') {
throw new factory.errors.ArgumentNull('object.toLocation.identifier');
}
let fromAccountNumber = params.object.fromLocation.identifier;
if (params.object.fromLocation.hasNoPermit === true) {
// no op
}
else {
const fromLocationPermit = yield repos.permit.findByIdentifier({
project: { id: params.project.id },
identifier: params.object.fromLocation.identifier,
issuedThrough: { typeOf: factory.product.ProductType.PaymentCard }
});
fromAccountNumber = String((_a = fromLocationPermit.paymentAccount) === null || _a === void 0 ? void 0 : _a.accountNumber);
}
let toAccountNumber = params.object.toLocation.identifier;
if (params.object.toLocation.hasNoPermit === true) {
// no op
}
else {
const toLocationPermit = yield repos.permit.findByIdentifier({
project: { id: params.project.id },
identifier: params.object.toLocation.identifier,
issuedThrough: { typeOf: factory.product.ProductType.PaymentCard }
});
toAccountNumber = String((_b = toLocationPermit.paymentAccount) === null || _b === void 0 ? void 0 : _b.accountNumber);
}
return accountTransactionService.start(Object.assign({ transactionNumber: params.transactionNumber, project: { typeOf: params.project.typeOf, id: params.project.id }, typeOf: factory.account.transactionType.Transfer, agent: params.agent, expires: params.expires, recipient: params.recipient, object: {
amount: { value: params.object.amount },
description: params.description,
fromLocation: { accountNumber: fromAccountNumber },
toLocation: { accountNumber: toAccountNumber }
} }, (typeof params.identifier === 'string') ? { identifier: params.identifier } : undefined));
});
}
function processWithdrawTransaction(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a;
// 転送先口座が指定されていない場合は、出金取引
const accountTransactionService = new (yield pecorinoapi.loadPecorino()).service.AccountTransaction({
endpoint: params.permitServiceCredentials.permitServiceEndpoint,
auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
domain: params.permitServiceCredentials.permitServiceAuthorizeServerDomain,
clientId: params.permitServiceCredentials.permitServiceClientId,
clientSecret: params.permitServiceCredentials.permitServiceClientSecret,
scopes: [],
state: ''
})
});
if (typeof params.object.fromLocation.identifier !== 'string') {
throw new factory.errors.ArgumentNull('object.toLocation.identifier');
}
const fromLocationPermit4withdraw = yield repos.permit.findByIdentifier({
project: { id: params.project.id },
identifier: params.object.fromLocation.identifier,
issuedThrough: { typeOf: factory.product.ProductType.PaymentCard }
});
return accountTransactionService.start(Object.assign({ transactionNumber: params.transactionNumber, project: { typeOf: params.project.typeOf, id: params.project.id }, typeOf: factory.account.transactionType.Withdraw, agent: params.agent, expires: params.expires, recipient: params.recipient, object: {
amount: { value: params.object.amount },
description: params.description,
fromLocation: {
accountNumber: String((_a = fromLocationPermit4withdraw.paymentAccount) === null || _a === void 0 ? void 0 : _a.accountNumber)
},
force: params.object.force === true
} }, (typeof params.identifier === 'string') ? { identifier: params.identifier } : undefined));
});
}
function createAccountTransactionAgent(params) {
return {
typeOf: params.agent.typeOf,
id: String(params.agent.id),
name: (typeof params.agent.name === 'string')
? params.agent.name
: `${params.transaction.typeOf} Transaction ${params.transaction.id}`
};
}
function createAccountTransactionRecipient(params) {
const transaction = params.transaction;
let recipient;
const recipientType = params.recipient.typeOf;
if (recipientType === factory.organizationType.Corporation) {
recipient = {
typeOf: recipientType,
id: String(params.recipient.id),
name: (typeof params.recipient.name === 'string')
? params.recipient.name
: `${transaction.typeOf} Transaction ${transaction.id}`
};
}
else {
if (recipientType === factory.creativeWorkType.SoftwareApplication) {
throw new factory.errors.NotImplemented(`recipient.typeOf [${recipientType}] not implemented`);
}
const recipientButSeller = {
typeOf: recipientType,
id: String(params.recipient.id),
name: (typeof params.recipient.name === 'string')
? params.recipient.name
: `${transaction.typeOf} Transaction ${transaction.id}`
};
recipient = recipientButSeller;
}
return recipient;
}
function getIssuedThroughId(params) {
var _a, _b;
let issuedThroughId;
switch (params.typeOf) {
case factory.account.transactionType.Deposit:
issuedThroughId = String((_a = params.object.toLocation.issuedThrough) === null || _a === void 0 ? void 0 : _a.id);
break;
case factory.account.transactionType.Transfer:
case factory.account.transactionType.Withdraw:
issuedThroughId = String((_b = params.object.fromLocation.issuedThrough) === null || _b === void 0 ? void 0 : _b.id);
break;
default:
throw new factory.errors.Argument('AccountTransactionType', `invalid type: ${params.typeOf}`);
}
return issuedThroughId;
}
function getIssuedThroughIdByTransaction(params) {
var _a, _b, _c;
let issuedThroughId;
const pendingTransactionType = (_a = params.transaction.object.pendingTransaction) === null || _a === void 0 ? void 0 : _a.typeOf;
switch (pendingTransactionType) {
case factory.account.transactionType.Deposit:
issuedThroughId =
String((_b = params.transaction.object.toLocation.issuedThrough) === null || _b === void 0 ? void 0 : _b.id);
break;
case factory.account.transactionType.Transfer:
case factory.account.transactionType.Withdraw:
issuedThroughId =
String((_c = params.transaction.object.fromLocation.issuedThrough) === null || _c === void 0 ? void 0 : _c.id);
break;
default:
throw new factory.errors.Argument('AccountTransactionType', `invalid type: ${pendingTransactionType}`);
}
return issuedThroughId;
}
function getIssuedThroughIdByAction(params) {
var _a, _b;
let issuedThroughId;
const pendingTransactionType = params.pendingTransactionType;
switch (pendingTransactionType) {
case factory.account.transactionType.Deposit:
issuedThroughId =
String((_a = params.action.toLocation.issuedThrough) === null || _a === void 0 ? void 0 : _a.id);
break;
case factory.account.transactionType.Transfer:
case factory.account.transactionType.Withdraw:
issuedThroughId =
String((_b = params.action.fromLocation.issuedThrough) === null || _b === void 0 ? void 0 : _b.id);
break;
default:
throw new factory.errors.Argument('AccountTransactionType', `invalid type: ${pendingTransactionType}`);
}
return issuedThroughId;
}
function createPermitServiceCredentials(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g;
const paymentCardService = (yield repos.product.projectFields({
limit: 1,
page: 1,
id: { $eq: params.issuedThrough.id },
typeOf: { $eq: factory.product.ProductType.PaymentCard }
}, ['availableChannel']
// []
)).shift();
if (paymentCardService === undefined) {
throw new factory.errors.NotFound(factory.product.ProductType.PaymentCard);
}
const permitServiceEndpoint = (_a = paymentCardService.availableChannel) === null || _a === void 0 ? void 0 : _a.serviceUrl;
const permitServiceAuthorizeServerDomain = (_c = (_b = paymentCardService.availableChannel) === null || _b === void 0 ? void 0 : _b.credentials) === null || _c === void 0 ? void 0 : _c.authorizeServerDomain;
const permitServiceClientId = (_e = (_d = paymentCardService.availableChannel) === null || _d === void 0 ? void 0 : _d.credentials) === null || _e === void 0 ? void 0 : _e.clientId;
const permitServiceClientSecret = (_g = (_f = paymentCardService.availableChannel) === null || _f === void 0 ? void 0 : _f.credentials) === null || _g === void 0 ? void 0 : _g.clientSecret;
if (typeof permitServiceEndpoint !== 'string' || permitServiceEndpoint.length === 0
|| typeof permitServiceAuthorizeServerDomain !== 'string' || permitServiceAuthorizeServerDomain.length === 0
|| typeof permitServiceClientId !== 'string' || permitServiceClientId.length === 0
|| typeof permitServiceClientSecret !== 'string' || permitServiceClientSecret.length === 0) {
throw new factory.errors.Internal('membershipService availableChannel invalid');
}
return {
permitServiceEndpoint,
permitServiceAuthorizeServerDomain,
permitServiceClientId,
permitServiceClientSecret
};
});
}
/**
* 口座承認取消
*/
function cancelMoneyTransfer(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a;
const transactions = yield repos.assetTransaction.search({
typeOf: factory.assetTransactionType.MoneyTransfer,
ids: [params.purpose.id]
});
if (transactions.length > 0) {
for (const transaction of transactions) {
const pendingTransaction = (_a = transaction.object) === null || _a === void 0 ? void 0 : _a.pendingTransaction;
if (typeof (pendingTransaction === null || pendingTransaction === void 0 ? void 0 : pendingTransaction.transactionNumber) === 'string') {
const issuedThroughId = getIssuedThroughIdByTransaction({ transaction });
const { permitServiceEndpoint, permitServiceAuthorizeServerDomain, permitServiceClientId, permitServiceClientSecret } = yield createPermitServiceCredentials({ issuedThrough: { id: issuedThroughId } })(repos);
// 汎用中止サービスを使用(2022-09-27~)
const accountTransactionService = new (yield pecorinoapi.loadPecorino()).service.AccountTransaction({
endpoint: permitServiceEndpoint,
auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
domain: permitServiceAuthorizeServerDomain,
clientId: permitServiceClientId,
clientSecret: permitServiceClientSecret,
scopes: [],
state: ''
})
});
// 取引存在検証(2022-10-26~)
const searchAccountTransactionsResult = yield accountTransactionService.search({
limit: 1,
project: { id: { $eq: transaction.project.id } },
transactionNumber: { $eq: pendingTransaction.transactionNumber }
});
if (searchAccountTransactionsResult.data.length > 0) {
yield accountTransactionService.cancelSync({ transactionNumber: pendingTransaction.transactionNumber });
}
}
}
}
});
}
function moneyTransfer(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const action = yield repos.action.start(params);
try {
const pendingTransaction = params.object.pendingTransaction;
let transactionType = params.object.typeOf;
if (pendingTransaction !== undefined) {
transactionType = pendingTransaction.typeOf;
}
const transactionNumber = yield fixAccountTransactionNumber(params)({ transactionNumber: repos.transactionNumber });
const issuedThroughId = getIssuedThroughIdByAction({ action: params, pendingTransactionType: transactionType });
const permitServiceCredentials = yield createPermitServiceCredentials({ issuedThrough: { id: issuedThroughId } })(repos);
const accountTransactionService = new (yield pecorinoapi.loadPecorino()).service.AccountTransaction({
endpoint: permitServiceCredentials.permitServiceEndpoint,
auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
domain: permitServiceCredentials.permitServiceAuthorizeServerDomain,
clientId: permitServiceCredentials.permitServiceClientId,
clientSecret: permitServiceCredentials.permitServiceClientSecret,
scopes: [],
state: ''
})
});
// 入金取引の場合、承認済でないケースがある(ポイント付与など)
if (transactionType === factory.account.transactionType.Deposit && pendingTransaction === undefined) {
yield processDepositFromNow(params, permitServiceCredentials, transactionNumber)({
accountTransactionService
});
}
else {
yield accountTransactionService.confirmSync({ transactionNumber: transactionNumber });
}
}
catch (error) {
try {
yield repos.action.giveUp({ typeOf: action.typeOf, id: action.id, error });
}
catch (__) {
// no op
}
throw error;
}
const actionResult = {};
yield repos.action.completeWithVoid({ typeOf: action.typeOf, id: action.id, result: actionResult });
});
}
function fixAccountTransactionNumber(params) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
const pendingTransaction = params.object.pendingTransaction;
let transactionNumber = params.object.transactionNumber;
if (pendingTransaction !== undefined) {
transactionNumber = pendingTransaction.transactionNumber;
}
// 取引番号指定でなければ発行
if (typeof transactionNumber !== 'string') {
const publishTransactionNumberResult = yield repos.transactionNumber.publishByTimestamp({
startDate: new Date()
});
transactionNumber = publishTransactionNumberResult.transactionNumber;
}
return transactionNumber;
});
}
/**
* 新規で入金取引を確定させる
* 処理順序は?
* 1.Confirmedでない取引があれば中止する
* 2.Confirmedの取引があれば再度confirmSync
* 3.取引が存在しなければ新たに取引開始してconfirmSync
*/
function processDepositFromNow(params, permitServiceCredentials, transactionNumber) {
return (repos) => __awaiter(this, void 0, void 0, function* () {
var _a;
const accountTransactionIdentifier = params.purpose.identifier;
// すでに入金済かどうか確認
let confirmedAccountTransactionNumber;
if (typeof accountTransactionIdentifier === 'string') {
// 口座取引で確認する(2022-10-27~)
const searchAccountTransactionsResult = yield repos.accountTransactionService.search({
limit: 100,
project: { id: { $eq: params.project.id } },
identifier: { $eq: accountTransactionIdentifier }
});
const existingAccountTransactions = searchAccountTransactionsResult.data;
for (const existingAccountTransaction of existingAccountTransactions) {
if (existingAccountTransaction.status === factory.transactionStatusType.Confirmed) {
confirmedAccountTransactionNumber = existingAccountTransaction.transactionNumber;
}
else {
yield repos.accountTransactionService.cancelSync({ transactionNumber: existingAccountTransaction.transactionNumber });
}
}
}
if (typeof confirmedAccountTransactionNumber === 'string') {
// 念のためconfirm
yield repos.accountTransactionService.confirmSync({ transactionNumber: confirmedAccountTransactionNumber });
return;
}
const agent = createAgent4depositFromNow(params);
const recipient = createRecipient4depositFromNow(params);
const expires = moment()
.add(1, 'minutes')
.toDate();
const amount = (typeof params.amount.value === 'number') ? params.amount.value : 0;
const description = (typeof params.description === 'string') ? params.description : params.purpose.typeOf;
const permitIdentifier = String(params.toLocation.identifier);
// Permitの存在確認
const permitService = new (yield pecorinoapi.loadPecorino()).service.Permit({
endpoint: permitServiceCredentials.permitServiceEndpoint,
auth: yield pecorinoapi.auth.ClientCredentials.createInstance({
domain: permitServiceCredentials.permitServiceAuthorizeServerDomain,
clientId: permitServiceCredentials.permitServiceClientId,
clientSecret: permitServiceCredentials.permitServiceClientSecret,
scopes: [],
state: ''
})
});
const permit = yield permitService.findByIdentifier({
project: { id: params.project.id },
identifier: permitIdentifier,
issuedThrough: { typeOf: factory.product.ProductType.PaymentCard }
});
yield repos.accountTransactionService.start(Object.assign({ transactionNumber, project: { typeOf: params.project.typeOf, id: params.project.id }, typeOf: factory.account.transactionType.Deposit, agent,
expires,
recipient, object: {
amount: { value: amount },
description: description,
// fromLocation: params.fromLocation,
toLocation: { accountNumber: String((_a = permit.paymentAccount) === null || _a === void 0 ? void 0 : _a.accountNumber) }
} }, (typeof accountTransactionIdentifier === 'string') ? { identifier: accountTransactionIdentifier } : undefined));
try {
yield repos.accountTransactionService.confirmSync({ transactionNumber });
}
catch (error) {
yield repos.accountTransactionService.cancelSync({ transactionNumber });
throw error;
}
});
}
function createAgent4depositFromNow(params) {
return {
typeOf: params.agent.typeOf,
id: String(params.agent.id),
name: (typeof params.agent.name === 'string')
? params.agent.name
: params.fromLocation.typeOf
};
}
function createRecipient4depositFromNow(params) {
var _a, _b;
let recipient = {
typeOf: factory.personType.Person,
id: String(String(params.toLocation.identifier)),
name: params.toLocation.typeOf
};
if (((_a = params.recipient) === null || _a === void 0 ? void 0 : _a.typeOf) === factory.organizationType.Corporation) {
recipient = {
typeOf: params.recipient.typeOf,
id: String(params.recipient.id),
name: (typeof params.recipient.name === 'string')
? params.recipient.name
: params.toLocation.typeOf
};
}
else if (typeof ((_b = params.recipient) === null || _b === void 0 ? void 0 : _b.typeOf) === 'string') {
if (params.recipient.typeOf === factory.creativeWorkType.SoftwareApplication) {
throw new factory.errors.NotImplemented(`recipient.typeOf [${params.recipient.typeOf}] not implemented`);
}
const recipientButSeller = {
typeOf: params.recipient.typeOf,
id: String(params.recipient.id),
name: (typeof params.recipient.name === 'string')
? params.recipient.name
: params.toLocation.typeOf
};
recipient = recipientButSeller;
}
return recipient;
}
/**
* 返金後のアクション
* @param refundActionAttributes 返金アクション属性
*/
// function onRefund(refundActionAttributes: factory.action.trade.refund.IAttributes<factory.paymentMethodType>) {
// return async (repos: { task: TaskRepo }) => {
// const potentialActions = refundActionAttributes.potentialActions;
// const now = new Date();
// const taskAttributes: factory.task.IAttributes<factory.taskName>[] = [];
// // tslint:disable-next-line:no-single-line-block-comment
// /* istanbul ignore else */
// if (potentialActions !== undefined) {
// // tslint:disable-next-line:no-single-line-block-comment
// /* istanbul ignore else */
// if (Array.isArray(potentialActions.sendEmailMessage)) {
// potentialActions.sendEmailMessage.forEach((s) => {
// const sendEmailMessageTask: factory.task.IAttributes<factory.taskName.SendEmailMessage> = {
// project: s.project,
// name: factory.taskName.SendEmailMessage,
// status: factory.taskStatus.Ready,
// runsAt: now, // なるはやで実行
// remainingNumberOfTries: 3,
// numberOfTried: 0,
// executionResults: [],
// data: {
// actionAttributes: s
// }
// };
// taskAttributes.push(sendEmailMessageTask);
// });
// }
// }
// // タスク保管
// await Promise.all(taskAttributes.map(async (taskAttribute) => {
// return repos.task.save(taskAttribute);
// }));
// };
// }