@chevre/domain 21.2.0-alpha.4 → 21.2.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/example/src/chevre/lockStockHolder.ts +48 -0
- package/lib/chevre/repo/orderNumber.d.ts +0 -1
- package/lib/chevre/repo/orderNumber.js +2 -12
- package/lib/chevre/repo/serviceOutputIdentifier.d.ts +0 -1
- package/lib/chevre/repo/serviceOutputIdentifier.js +2 -12
- package/lib/chevre/repo/stockHolder.d.ts +1 -0
- package/lib/chevre/repo/stockHolder.js +44 -7
- package/lib/chevre/repo/transactionNumber.d.ts +0 -1
- package/lib/chevre/repo/transactionNumber.js +2 -12
- package/lib/chevre/settings.d.ts +0 -1
- package/lib/chevre/settings.js +2 -5
- package/package.json +1 -1
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// tslint:disable:no-console
|
|
2
|
+
import * as moment from 'moment';
|
|
3
|
+
import * as redis from 'redis';
|
|
4
|
+
|
|
5
|
+
import { chevre } from '../../../lib/index';
|
|
6
|
+
|
|
7
|
+
// const project = { id: String(process.env.PROJECT_ID) };
|
|
8
|
+
|
|
9
|
+
// tslint:disable-next-line:max-func-body-length
|
|
10
|
+
async function main() {
|
|
11
|
+
const client = redis.createClient<redis.RedisDefaultModules, Record<string, never>, Record<string, never>>({
|
|
12
|
+
socket: {
|
|
13
|
+
port: Number(<string>process.env.REDIS_PORT),
|
|
14
|
+
host: <string>process.env.REDIS_HOST
|
|
15
|
+
},
|
|
16
|
+
password: <string>process.env.REDIS_KEY
|
|
17
|
+
});
|
|
18
|
+
await client.connect();
|
|
19
|
+
|
|
20
|
+
const startDate = moment('2023-04-18T00:00:00Z');
|
|
21
|
+
|
|
22
|
+
const stockHolderRepo = new chevre.repository.StockHolder(client);
|
|
23
|
+
await stockHolderRepo.lock({
|
|
24
|
+
eventId: 'sampleEventId',
|
|
25
|
+
startDate: startDate.toDate(),
|
|
26
|
+
offers: [
|
|
27
|
+
{
|
|
28
|
+
seatSection: 'sampleSeatSection',
|
|
29
|
+
seatNumber: 'sampleSeatNumber'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
seatSection: 'sampleSeatSection1',
|
|
33
|
+
seatNumber: 'sampleSeatNumber1'
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
expires: moment(startDate)
|
|
37
|
+
.add(1, 'month')
|
|
38
|
+
.toDate(),
|
|
39
|
+
holder: 'sampleStockHolder'
|
|
40
|
+
});
|
|
41
|
+
console.log('locked');
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
main()
|
|
45
|
+
.then(() => {
|
|
46
|
+
console.log('success!');
|
|
47
|
+
})
|
|
48
|
+
.catch(console.error);
|
|
@@ -16,7 +16,6 @@ const util = require("util");
|
|
|
16
16
|
// tslint:disable-next-line:no-require-imports no-var-requires
|
|
17
17
|
const fpe = require('node-fpe');
|
|
18
18
|
const factory = require("../factory");
|
|
19
|
-
const settings_1 = require("../settings");
|
|
20
19
|
const ORDER_NUMBER_SEPARATOR = '-';
|
|
21
20
|
/**
|
|
22
21
|
* 注文番号リポジトリ
|
|
@@ -26,15 +25,7 @@ class RedisRepository {
|
|
|
26
25
|
this.redisClient = redisClient;
|
|
27
26
|
}
|
|
28
27
|
static createKey(params) {
|
|
29
|
-
|
|
30
|
-
&& moment(params.orderDate)
|
|
31
|
-
.isSameOrAfter(settings_1.USE_NEW_ORDER_NUMBER_KEY_FROM);
|
|
32
|
-
if (useNewKey) {
|
|
33
|
-
return util.format('%s:%s:%s', RedisRepository.REDIS_KEY_PREFIX_NEW, params.projectPrefix, params.timestamp);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
return util.format('%s:%s:%s', RedisRepository.REDIS_KEY_PREFIX, params.projectPrefix, params.timestamp);
|
|
37
|
-
}
|
|
28
|
+
return util.format('%s:%s:%s', RedisRepository.REDIS_KEY_PREFIX, params.projectPrefix, params.timestamp);
|
|
38
29
|
}
|
|
39
30
|
/**
|
|
40
31
|
* タイムスタンプから発行する
|
|
@@ -79,6 +70,5 @@ class RedisRepository {
|
|
|
79
70
|
});
|
|
80
71
|
}
|
|
81
72
|
}
|
|
82
|
-
RedisRepository.
|
|
83
|
-
RedisRepository.REDIS_KEY_PREFIX = 'cinerino:orderNumber';
|
|
73
|
+
RedisRepository.REDIS_KEY_PREFIX = 'orderNumber';
|
|
84
74
|
exports.RedisRepository = RedisRepository;
|
|
@@ -3,7 +3,6 @@ import { RedisClientType } from 'redis';
|
|
|
3
3
|
* サービスアウトプット識別子リポジトリ
|
|
4
4
|
*/
|
|
5
5
|
export declare class RedisRepository {
|
|
6
|
-
private static readonly REDIS_KEY_PREFIX_NEW;
|
|
7
6
|
private static readonly REDIS_KEY_PREFIX;
|
|
8
7
|
private readonly redisClient;
|
|
9
8
|
constructor(redisClient: RedisClientType);
|
|
@@ -16,7 +16,6 @@ const util = require("util");
|
|
|
16
16
|
// tslint:disable-next-line:no-require-imports no-var-requires
|
|
17
17
|
const fpe = require('node-fpe');
|
|
18
18
|
const factory = require("../factory");
|
|
19
|
-
const settings_1 = require("../settings");
|
|
20
19
|
/**
|
|
21
20
|
* サービスアウトプット識別子リポジトリ
|
|
22
21
|
*/
|
|
@@ -25,15 +24,7 @@ class RedisRepository {
|
|
|
25
24
|
this.redisClient = redisClient;
|
|
26
25
|
}
|
|
27
26
|
static createKey(params) {
|
|
28
|
-
|
|
29
|
-
&& moment(params.startDate)
|
|
30
|
-
.isSameOrAfter(settings_1.USE_NEW_ORDER_NUMBER_KEY_FROM);
|
|
31
|
-
if (useNewKey) {
|
|
32
|
-
return util.format('%s:%s', RedisRepository.REDIS_KEY_PREFIX_NEW, params.timestamp);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
return util.format('%s:%s', RedisRepository.REDIS_KEY_PREFIX, params.timestamp);
|
|
36
|
-
}
|
|
27
|
+
return util.format('%s:%s', RedisRepository.REDIS_KEY_PREFIX, params.timestamp);
|
|
37
28
|
}
|
|
38
29
|
/**
|
|
39
30
|
* タイムスタンプから発行する
|
|
@@ -68,6 +59,5 @@ class RedisRepository {
|
|
|
68
59
|
});
|
|
69
60
|
}
|
|
70
61
|
}
|
|
71
|
-
RedisRepository.
|
|
72
|
-
RedisRepository.REDIS_KEY_PREFIX = 'chevre:serviceOutputIdentifier';
|
|
62
|
+
RedisRepository.REDIS_KEY_PREFIX = 'serviceOutputIdentifier';
|
|
73
63
|
exports.RedisRepository = RedisRepository;
|
|
@@ -32,9 +32,11 @@ class StockHolderRepository {
|
|
|
32
32
|
return `${params.seatSection}:${params.seatNumber}`;
|
|
33
33
|
}
|
|
34
34
|
static createKey(params) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
if (!(params.startDate instanceof Date)) {
|
|
36
|
+
throw new factory.errors.Argument('startDate', 'must be Date');
|
|
37
|
+
}
|
|
38
|
+
const useNewKey = moment(params.startDate)
|
|
39
|
+
.isSameOrAfter(settings_1.USE_NEW_EVENT_AVAILABILITY_KEY_FROM);
|
|
38
40
|
if (useNewKey) {
|
|
39
41
|
return `${StockHolderRepository.KEY_PREFIX_NEW}:${params.eventId}`;
|
|
40
42
|
}
|
|
@@ -64,7 +66,11 @@ class StockHolderRepository {
|
|
|
64
66
|
*/
|
|
65
67
|
lock(lockKey) {
|
|
66
68
|
return __awaiter(this, void 0, void 0, function* () {
|
|
69
|
+
if (!(lockKey.expires instanceof Date)) {
|
|
70
|
+
throw new factory.errors.Argument('expires', 'must be Date');
|
|
71
|
+
}
|
|
67
72
|
const key = StockHolderRepository.createKey({ eventId: lockKey.eventId, startDate: lockKey.startDate });
|
|
73
|
+
yield this.checkIfConflicted({ key, eventId: lockKey.eventId });
|
|
68
74
|
const value = lockKey.holder;
|
|
69
75
|
const multi = this.redisClient.multi();
|
|
70
76
|
const fields = lockKey.offers.map((offer) => StockHolderRepository.offer2field(offer));
|
|
@@ -74,7 +80,6 @@ class StockHolderRepository {
|
|
|
74
80
|
const results = yield multi.expireAt(key, moment(lockKey.expires)
|
|
75
81
|
.unix())
|
|
76
82
|
.exec();
|
|
77
|
-
debug('results:', results);
|
|
78
83
|
const lockedFields = [];
|
|
79
84
|
if (Array.isArray(results)) {
|
|
80
85
|
results.slice(0, fields.length)
|
|
@@ -84,17 +89,25 @@ class StockHolderRepository {
|
|
|
84
89
|
}
|
|
85
90
|
});
|
|
86
91
|
}
|
|
87
|
-
debug('locked fields:', lockedFields);
|
|
88
92
|
const lockedAll = lockedFields.length === fields.length;
|
|
89
93
|
debug('lockedAll?', lockedAll);
|
|
90
|
-
|
|
94
|
+
// expireAtReplyの検証も追加する(2023-04-19~)
|
|
95
|
+
const expiredAll = results.slice(fields.length)
|
|
96
|
+
.every((r) => (r === 1 || r === true));
|
|
97
|
+
debug('expiredAll?', expiredAll);
|
|
98
|
+
if (!lockedAll || !expiredAll) {
|
|
91
99
|
if (lockedFields.length > 0) {
|
|
92
100
|
// 全て仮押さえできなければ仮押さえできたものは解除
|
|
93
101
|
yield this.redisClient.multi()
|
|
94
102
|
.hDel(key, lockedFields)
|
|
95
103
|
.exec();
|
|
96
104
|
}
|
|
97
|
-
|
|
105
|
+
if (!lockedAll) {
|
|
106
|
+
throw new factory.errors.AlreadyInUse(factory.reservationType.EventReservation, ['ticketedSeat'], 'Already hold');
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
throw new factory.errors.ServiceUnavailable('timeout cannot be set unexpectedly');
|
|
110
|
+
}
|
|
98
111
|
}
|
|
99
112
|
});
|
|
100
113
|
}
|
|
@@ -104,6 +117,7 @@ class StockHolderRepository {
|
|
|
104
117
|
unlock(params) {
|
|
105
118
|
return __awaiter(this, void 0, void 0, function* () {
|
|
106
119
|
const key = StockHolderRepository.createKey({ eventId: params.eventId, startDate: params.startDate });
|
|
120
|
+
yield this.checkIfConflicted({ key, eventId: params.eventId });
|
|
107
121
|
const field = StockHolderRepository.offer2field(params.offer);
|
|
108
122
|
yield this.redisClient.multi()
|
|
109
123
|
.hDel(key, field)
|
|
@@ -200,6 +214,29 @@ class StockHolderRepository {
|
|
|
200
214
|
return result;
|
|
201
215
|
});
|
|
202
216
|
}
|
|
217
|
+
checkIfConflicted(params) {
|
|
218
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
219
|
+
// 旧キーと新キーの両方存在検証(念のため)
|
|
220
|
+
const oldKey = StockHolderRepository.createKey({ eventId: params.eventId, startDate: new Date('2020-01-01T00:00:00Z') });
|
|
221
|
+
const newKey = StockHolderRepository.createKey({ eventId: params.eventId, startDate: new Date('2030-01-01T00:00:00Z') });
|
|
222
|
+
if (params.key !== oldKey) {
|
|
223
|
+
// newの場合oldが存在するはずがない
|
|
224
|
+
const existingOldKeyCount = yield this.redisClient.exists(oldKey);
|
|
225
|
+
debug('existingOldKeyCount:', existingOldKeyCount);
|
|
226
|
+
if (existingOldKeyCount > 0) {
|
|
227
|
+
throw new factory.errors.ServiceUnavailable('stockHolder keys conflicted');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (params.key !== newKey) {
|
|
231
|
+
// oldの場合newが存在するはずがない
|
|
232
|
+
const existingNewKeyCount = yield this.redisClient.exists(newKey);
|
|
233
|
+
debug('existingNewKeyCount:', existingNewKeyCount);
|
|
234
|
+
if (existingNewKeyCount > 0) {
|
|
235
|
+
throw new factory.errors.ServiceUnavailable('stockHolder keys conflicted');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
}
|
|
203
240
|
}
|
|
204
241
|
StockHolderRepository.KEY_PREFIX_NEW = 'stockHolder';
|
|
205
242
|
StockHolderRepository.KEY_PREFIX = 'chevre:itemAvailability:screeningEvent';
|
|
@@ -16,7 +16,6 @@ const util = require("util");
|
|
|
16
16
|
// tslint:disable-next-line:no-require-imports no-var-requires
|
|
17
17
|
const fpe = require('node-fpe');
|
|
18
18
|
const factory = require("../factory");
|
|
19
|
-
const settings_1 = require("../settings");
|
|
20
19
|
/**
|
|
21
20
|
* 取引番号リポジトリ
|
|
22
21
|
*/
|
|
@@ -25,15 +24,7 @@ class RedisRepository {
|
|
|
25
24
|
this.redisClient = redisClient;
|
|
26
25
|
}
|
|
27
26
|
static createKey(params) {
|
|
28
|
-
|
|
29
|
-
&& moment(params.startDate)
|
|
30
|
-
.isSameOrAfter(settings_1.USE_NEW_ORDER_NUMBER_KEY_FROM);
|
|
31
|
-
if (useNewKey) {
|
|
32
|
-
return util.format('%s:%s', RedisRepository.REDIS_KEY_PREFIX_NEW, params.timestamp);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
return util.format('%s:%s', RedisRepository.REDIS_KEY_PREFIX, params.timestamp);
|
|
36
|
-
}
|
|
27
|
+
return util.format('%s:%s', RedisRepository.REDIS_KEY_PREFIX, params.timestamp);
|
|
37
28
|
}
|
|
38
29
|
/**
|
|
39
30
|
* タイムスタンプから発行する
|
|
@@ -68,6 +59,5 @@ class RedisRepository {
|
|
|
68
59
|
});
|
|
69
60
|
}
|
|
70
61
|
}
|
|
71
|
-
RedisRepository.
|
|
72
|
-
RedisRepository.REDIS_KEY_PREFIX = 'chevre:transactionNumber';
|
|
62
|
+
RedisRepository.REDIS_KEY_PREFIX = 'transactionNumber';
|
|
73
63
|
exports.RedisRepository = RedisRepository;
|
package/lib/chevre/settings.d.ts
CHANGED
|
@@ -31,7 +31,6 @@ export declare const USE_ASSET_TRANSACTION_SYNC_PROCESSING: boolean;
|
|
|
31
31
|
export declare const USE_PAY_ASSET_TRANSACTION_SYNC_PROCESSING: boolean;
|
|
32
32
|
export declare const USE_NEW_EVENT_AVAILABILITY_KEY_FROM: moment.Moment;
|
|
33
33
|
export declare const USE_NEW_CONFIRMATION_NUMBER_KEY_FROM: moment.Moment;
|
|
34
|
-
export declare const USE_NEW_ORDER_NUMBER_KEY_FROM: moment.Moment;
|
|
35
34
|
/**
|
|
36
35
|
* グローバル設定
|
|
37
36
|
*/
|
package/lib/chevre/settings.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.settings = exports.
|
|
3
|
+
exports.settings = exports.USE_NEW_CONFIRMATION_NUMBER_KEY_FROM = exports.USE_NEW_EVENT_AVAILABILITY_KEY_FROM = exports.USE_PAY_ASSET_TRANSACTION_SYNC_PROCESSING = exports.USE_ASSET_TRANSACTION_SYNC_PROCESSING = exports.DEFAULT_PAYMENT_METHOD_TYPE_FOR_CREDIT_CARD = exports.DEFAULT_SENDER_EMAIL = exports.TRANSACTION_CANCELED_STORAGE_PERIOD_IN_DAYS = exports.TRANSACTION_CONFIRMED_STORAGE_PERIOD_IN_DAYS = exports.ASSET_TRANSACTION_STORAGE_PERIOD_IN_DAYS = exports.ABORTED_TASKS_WITHOUT_REPORT = void 0;
|
|
4
4
|
const moment = require("moment");
|
|
5
5
|
const factory = require("./factory");
|
|
6
6
|
const transactionWebhookUrls = (typeof process.env.INFORM_TRANSACTION_URL === 'string')
|
|
@@ -48,13 +48,10 @@ exports.USE_ASSET_TRANSACTION_SYNC_PROCESSING = process.env.USE_ASSET_TRANSACTIO
|
|
|
48
48
|
exports.USE_PAY_ASSET_TRANSACTION_SYNC_PROCESSING = process.env.USE_PAY_ASSET_TRANSACTION_SYNC_PROCESSING === '1';
|
|
49
49
|
exports.USE_NEW_EVENT_AVAILABILITY_KEY_FROM = (typeof process.env.USE_NEW_EVENT_AVAILABILITY_KEY_FROM === 'string')
|
|
50
50
|
? moment(process.env.USE_NEW_EVENT_AVAILABILITY_KEY_FROM)
|
|
51
|
-
: moment('2023-
|
|
51
|
+
: moment('2023-08-31T15:00:00Z');
|
|
52
52
|
exports.USE_NEW_CONFIRMATION_NUMBER_KEY_FROM = (typeof process.env.USE_NEW_CONFIRMATION_NUMBER_KEY_FROM === 'string')
|
|
53
53
|
? moment(process.env.USE_NEW_CONFIRMATION_NUMBER_KEY_FROM)
|
|
54
54
|
: moment('2023-04-30T15:00:00Z');
|
|
55
|
-
exports.USE_NEW_ORDER_NUMBER_KEY_FROM = (typeof process.env.USE_NEW_ORDER_NUMBER_KEY_FROM === 'string')
|
|
56
|
-
? moment(process.env.USE_NEW_ORDER_NUMBER_KEY_FROM)
|
|
57
|
-
: moment('2023-04-18T15:00:00Z');
|
|
58
55
|
/**
|
|
59
56
|
* グローバル設定
|
|
60
57
|
*/
|
package/package.json
CHANGED