@chevre/domain 22.9.0-alpha.101 → 22.9.0-alpha.103

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.
@@ -11,7 +11,7 @@ mongoose.Model.on('index', (...args) => {
11
11
  async function main() {
12
12
  await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
13
13
 
14
- await chevre.repository.AggregateOffer.createInstance(mongoose.connection);
14
+ await chevre.repository.Setting.createInstance(mongoose.connection);
15
15
  console.log('success!');
16
16
  }
17
17
 
@@ -8,9 +8,12 @@ import { PendingReservationRepo } from '../../../../lib/chevre/repo/pendingReser
8
8
  const today = moment()
9
9
  .tz('Asia/Tokyo')
10
10
  .format('YYYYMMDD');
11
- // const project = { id: String(process.env.PROJECT_ID) };
12
- const eventId = `sampleEventId${today}:01`;
11
+ const project = { id: String(process.env.PROJECT_ID) };
12
+ const eventId = `sampleEventId${today}:02`;
13
13
  const eventStartDate = new Date('2025-05-01T00:00:00Z');
14
+ const seatSection = 'SampleSectionNameXXXXXXXXXXXXXXXXXXX';
15
+ // tslint:disable-next-line:no-magic-numbers prefer-array-literal
16
+ const allSeatNumbers = [...Array(10000)].map((__, seatKey) => `SampleSeatNumber-${seatKey}`);
14
17
 
15
18
  const client = redis.createClient<redis.RedisDefaultModules, Record<string, never>, Record<string, never>>({
16
19
  socket: {
@@ -38,15 +41,14 @@ async function main() {
38
41
  // const stockHolderRepo = await chevre.repository.StockHolder.createInstance(client, mongoose.connection);
39
42
  const pendingReservationRepo = new PendingReservationRepo(mongoose.connection);
40
43
 
41
- result = await pendingReservationRepo.countUnavailableOffers(
42
- {
43
- event: {
44
- id: eventId,
45
- startDate: eventStartDate,
46
- hasTicketedSeat: true
47
- }
44
+ result = await pendingReservationRepo.countUnavailableOffers({
45
+ project: { id: project.id },
46
+ event: {
47
+ id: eventId,
48
+ startDate: eventStartDate,
49
+ hasTicketedSeat: true
48
50
  }
49
- );
51
+ });
50
52
  console.log('countUnavailableOffersResult:', result);
51
53
 
52
54
  startTime = process.hrtime();
@@ -66,15 +68,37 @@ async function main() {
66
68
  console.log('countUnavailableOffersByNumSeatsResult:', result);
67
69
  console.log('diff:', [diff[0], formatter.format(diff[1])]);
68
70
 
69
- // const size = await pendingReservationRepo.getSize({
70
- // project: {
71
- // id: project.id
72
- // },
71
+ startTime = process.hrtime();
72
+ const searchHoldersResult = await pendingReservationRepo.searchHolders({
73
+ project: { id: project.id },
74
+ eventId,
75
+ startDate: eventStartDate,
76
+ hasTicketedSeat: true,
77
+ offers: [
78
+ // tslint:disable-next-line:no-magic-numbers
79
+ ...allSeatNumbers.slice(0, 10)
80
+ .map((seatNumber) => ({ seatSection, seatNumber }))
81
+ ]
82
+ });
83
+ diff = process.hrtime(startTime);
84
+ console.log('searchHoldersResult:', searchHoldersResult, searchHoldersResult.length);
85
+ console.log('diff:', [diff[0], formatter.format(diff[1])]);
86
+
87
+ // startTime = process.hrtime();
88
+ // const searchHolders2Result = await pendingReservationRepo.searchHolders2({
89
+ // project: { id: project.id },
73
90
  // eventId,
74
91
  // startDate: eventStartDate,
75
- // hasTicketedSeat: true
92
+ // hasTicketedSeat: true,
93
+ // offers: [
94
+ // // tslint:disable-next-line:no-magic-numbers
95
+ // ...allSeatNumbers.slice(0, 10)
96
+ // .map((seatNumber) => ({ seatSection, seatNumber }))
97
+ // ]
76
98
  // });
77
- // console.log('size:', size);
99
+ // diff = process.hrtime(startTime);
100
+ // console.log('searchHolders2:', searchHolders2Result, searchHolders2Result.length);
101
+ // console.log('diff:', [diff[0], formatter.format(diff[1])]);
78
102
  }
79
103
 
80
104
  main()
@@ -8,7 +8,7 @@ const today = moment()
8
8
  .tz('Asia/Tokyo')
9
9
  .format('YYYYMMDD');
10
10
  const project = { id: String(process.env.PROJECT_ID) };
11
- const eventId = `sampleEventId${today}:01`;
11
+ const eventId = `sampleEventId${today}:02`;
12
12
  const eventStartDate = new Date('2025-05-01T00:00:00Z');
13
13
  const seatSection = 'SampleSectionNameXXXXXXXXXXXXXXXXXXX';
14
14
  // tslint:disable-next-line:no-magic-numbers prefer-array-literal
@@ -59,13 +59,13 @@ async function lockSeatsForcibly(params: {
59
59
 
60
60
  const stockHolderRepo = await chevre.repository.StockHolder.createInstance(
61
61
  client,
62
- mongoose.connection,
63
- { useMongooseForce: true }
62
+ mongoose.connection
64
63
  );
65
64
 
66
65
  startTime = process.hrtime();
67
66
  console.log('counting unavailableOffers...');
68
67
  let countUnavailableOffersResult = await stockHolderRepo.countUnavailableOffers({
68
+ project: { id: project.id },
69
69
  event: {
70
70
  id: eventId,
71
71
  startDate: eventStartDate,
@@ -79,9 +79,7 @@ async function lockSeatsForcibly(params: {
79
79
  startTime = process.hrtime();
80
80
  console.log('counting searching holders...');
81
81
  const searchHoldersResult = await stockHolderRepo.searchHolders({
82
- project: {
83
- id: project.id
84
- },
82
+ project: { id: project.id },
85
83
  eventId,
86
84
  startDate: eventStartDate,
87
85
  hasTicketedSeat: true,
@@ -89,14 +87,10 @@ async function lockSeatsForcibly(params: {
89
87
  // tslint:disable-next-line:no-magic-numbers
90
88
  ...allSeatNumbers.slice(0, 100)
91
89
  .map((seatNumber) => ({ seatSection, seatNumber }))
92
- // { seatNumber: 'invalid', seatSection: 'invalid' }
93
90
  ]
94
91
  });
95
92
  diff = process.hrtime(startTime);
96
- // console.log('searchHoldersResult:', searchHoldersResult);
97
- console.log(
98
- 'searchHoldersResult.length:', searchHoldersResult.length
99
- );
93
+ console.log('searchHoldersResult.length:', searchHoldersResult.length);
100
94
  console.log('diff:', [diff[0], formatter.format(diff[1])]);
101
95
 
102
96
  // select 2 seats
@@ -117,9 +111,7 @@ async function lockSeatsForcibly(params: {
117
111
  const currentHolders: string[] = [];
118
112
  for (const seatNumber of seatNumbers) {
119
113
  const currentHolder = await stockHolderRepo.getHolder({
120
- project: {
121
- id: project.id
122
- },
114
+ project: { id: project.id },
123
115
  eventId,
124
116
  startDate: eventStartDate,
125
117
  hasTicketedSeat: true,
@@ -192,9 +184,7 @@ async function lockSeatsForcibly(params: {
192
184
  startTime = process.hrtime();
193
185
  console.log('unlocking...', currentHolder, seatSection, seatNumber);
194
186
  const unlockResult = await stockHolderRepo.unlock({
195
- project: {
196
- id: project.id
197
- },
187
+ project: { id: project.id },
198
188
  eventId,
199
189
  startDate: eventStartDate,
200
190
  hasTicketedSeat: true,
@@ -210,6 +200,7 @@ async function lockSeatsForcibly(params: {
210
200
 
211
201
  await sleep(OPERATION_INTERVAL);
212
202
  countUnavailableOffersResult = await stockHolderRepo.countUnavailableOffers({
203
+ project: { id: project.id },
213
204
  event: {
214
205
  id: eventId,
215
206
  startDate: eventStartDate,
@@ -221,34 +212,11 @@ async function lockSeatsForcibly(params: {
221
212
  }
222
213
 
223
214
  async function main() {
224
- // const stockHolderRepo = await chevre.repository.StockHolder.createInstance(
225
- // client,
226
- // mongoose.connection,
227
- // { useMongooseForce: true }
228
- // );
229
- // const newHolder = Date.now()
230
- // .toString();
231
- // // tslint:disable-next-line:no-magic-numbers
232
- // const seatNumbers = allSeatNumbers.slice(0, 1000);
233
- // const lockResult = await stockHolderRepo.lock({
234
- // project: {
235
- // id: project.id
236
- // },
237
- // eventId,
238
- // startDate: eventStartDate,
239
- // hasTicketedSeat: true,
240
- // offers: seatNumbers.map((seatNumber) => ({ seatSection, seatNumber })),
241
- // expires: new Date(),
242
- // holder: newHolder
243
- // });
244
- // console.log(lockResult);
245
- // return;
246
-
247
215
  // tslint:disable-next-line:no-magic-numbers
248
- const maximumCapacity = (typeof process.argv[2] === 'string') ? Number(process.argv[2]) : undefined;
216
+ const numLock = (typeof process.argv[2] === 'string') ? Number(process.argv[2]) : 1;
217
+ // tslint:disable-next-line:no-magic-numbers
218
+ const maximumCapacity = (typeof process.argv[3] === 'string') ? Number(process.argv[3]) : undefined;
249
219
 
250
- // const NUM_LOCK = 1;
251
- const NUM_LOCK = 2000;
252
220
  const LOCK_INTERVAL = 300;
253
221
  let i = 0;
254
222
  let lockedCount = 0;
@@ -262,7 +230,7 @@ async function main() {
262
230
 
263
231
  timeout = setInterval(
264
232
  () => {
265
- if (i >= NUM_LOCK) {
233
+ if (i >= numLock) {
266
234
  clearInterval(timeout);
267
235
 
268
236
  return;
@@ -177,6 +177,10 @@ function handleMvtkReserveError(error) {
177
177
  case http_status_1.TOO_MANY_REQUESTS: // 429
178
178
  handledError = new factory_1.errors.RateLimitExceeded(message);
179
179
  break;
180
+ // handle 504(2025-04-25~)
181
+ case http_status_1.GATEWAY_TIMEOUT: // 504
182
+ handledError = new factory_1.errors.GatewayTimeout(message);
183
+ break;
180
184
  default:
181
185
  handledError = new factory_1.errors.Internal(message);
182
186
  }
@@ -121,6 +121,7 @@ export interface ISetting {
121
121
  userPoolIdNew?: string;
122
122
  waiter?: IWaiterSettings;
123
123
  useMongoAsStockHolder?: boolean;
124
+ useMongoAsStockHolderProjects?: string[];
124
125
  }
125
126
  type IDocType = ISetting;
126
127
  type IModel = Model<IDocType>;
@@ -23,7 +23,8 @@ const schemaDefinition = {
23
23
  userPoolIdOld: String,
24
24
  userPoolIdNew: String,
25
25
  waiter: mongoose_1.SchemaTypes.Mixed,
26
- useMongoAsStockHolder: Boolean
26
+ useMongoAsStockHolder: Boolean,
27
+ useMongoAsStockHolderProjects: [String]
27
28
  };
28
29
  const schemaOptions = {
29
30
  autoIndex: settings_1.MONGO_AUTO_INDEX,
@@ -15,6 +15,9 @@ export declare class PendingReservationRepo implements AbstractStockHolderRepo {
15
15
  * 現時点での保留予約数を集計する
16
16
  */
17
17
  countUnavailableOffers(params: {
18
+ project: {
19
+ id: string;
20
+ };
18
21
  event: {
19
22
  id: string;
20
23
  startDate: Date;
@@ -235,22 +235,29 @@ class PendingReservationRepo {
235
235
  const { eventId, offers, hasTicketedSeat } = params;
236
236
  const reservationIdentifiers = offers.map((offer) => PendingReservationRepo.offer2identifier(offer, hasTicketedSeat));
237
237
  const aggregate = this.pendingReservationModel.aggregate([
238
+ // unwind,matchの順序
239
+ // unwind->matchでは遅い?
240
+ // match->unwind->matchにする
241
+ {
242
+ $match: {
243
+ 'reservationFor.id': { $eq: eventId },
244
+ 'subReservation.identifier': { $exists: true, $in: reservationIdentifiers }
245
+ }
246
+ },
238
247
  {
239
248
  $unwind: {
240
249
  path: '$subReservation'
241
- // includeArrayIndex: 'xxx'
242
250
  }
243
251
  },
244
252
  {
245
253
  $match: {
246
- 'reservationFor.id': { $eq: eventId },
247
254
  'subReservation.identifier': { $exists: true, $in: reservationIdentifiers }
248
255
  }
249
256
  },
250
257
  {
251
258
  $project: {
252
259
  _id: 0,
253
- reservationNumber: '$reservationNumber',
260
+ // reservationNumber: '$reservationNumber',
254
261
  identifier: '$subReservation.identifier'
255
262
  }
256
263
  }
@@ -259,13 +266,86 @@ class PendingReservationRepo {
259
266
  .option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
260
267
  .exec();
261
268
  debug('searchHolders: aggregated.', docs, docs.length, 'docs');
269
+ // reservationNumberを正確に返す必要はなく、存在しているかどうかだけ分かればよい(stringを返せばよい)
262
270
  return reservationIdentifiers.map((reservationIdentifier) => {
263
271
  const doc = docs.find(({ identifier }) => identifier === reservationIdentifier);
264
272
  // tslint:disable-next-line:no-null-keyword
265
- return (doc !== undefined) ? doc.reservationNumber : null;
273
+ // return (doc !== undefined) ? doc.reservationNumber : null;
274
+ // tslint:disable-next-line:no-null-keyword
275
+ return (doc !== undefined) ? doc.identifier : null;
266
276
  });
267
277
  });
268
278
  }
279
+ // public async searchHolders2(params: {
280
+ // project: { id: string };
281
+ // eventId: string;
282
+ // startDate: Date;
283
+ // hasTicketedSeat: boolean;
284
+ // offers: IOffer[];
285
+ // }): Promise<IGetHolderResult[]> {
286
+ // const { eventId, offers, hasTicketedSeat } = params;
287
+ // const reservationIdentifiers = offers.map((offer) => PendingReservationRepo.offer2identifier(offer, hasTicketedSeat));
288
+ // const aggregate = this.pendingReservationModel.aggregate<{
289
+ // // reservationNumber: string;
290
+ // identifier: string;
291
+ // }>([
292
+ // // unwind,matchの順序
293
+ // // unwind->matchでは遅い?
294
+ // // match->limit->unwind->matchにする
295
+ // {
296
+ // $unwind: {
297
+ // path: '$subReservation'
298
+ // }
299
+ // },
300
+ // {
301
+ // $match: {
302
+ // 'reservationFor.id': { $eq: eventId },
303
+ // 'subReservation.identifier': { $exists: true, $in: reservationIdentifiers }
304
+ // }
305
+ // },
306
+ // { $limit: reservationIdentifiers.length },
307
+ // {
308
+ // $project: {
309
+ // _id: 0,
310
+ // // reservationNumber: '$reservationNumber',
311
+ // identifier: '$subReservation.identifier'
312
+ // }
313
+ // }
314
+ // ]);
315
+ // const docs = await aggregate
316
+ // .option({ maxTimeMS: MONGO_MAX_TIME_MS })
317
+ // .exec();
318
+ // debug('searchHolders: aggregated.', docs, docs.length, 'docs');
319
+ // // reservationNumberを正確に返す必要はなく、存在しているかどうかだけ分かればよい(stringを返せばよい)
320
+ // return reservationIdentifiers.map((reservationIdentifier) => {
321
+ // const doc = docs.find(({ identifier }) => identifier === reservationIdentifier);
322
+ // // tslint:disable-next-line:no-null-keyword
323
+ // // return (doc !== undefined) ? doc.reservationNumber : null;
324
+ // // tslint:disable-next-line:no-null-keyword
325
+ // return (doc !== undefined) ? doc.identifier : null;
326
+ // });
327
+ // }
328
+ // public async searchHoldersByDistinct(params: {
329
+ // project: { id: string };
330
+ // eventId: string;
331
+ // startDate: Date;
332
+ // hasTicketedSeat: boolean;
333
+ // offers: IOffer[];
334
+ // }) {
335
+ // const { eventId, offers, hasTicketedSeat } = params;
336
+ // const reservationIdentifiers = offers.map((offer) => PendingReservationRepo.offer2identifier(offer, hasTicketedSeat));
337
+ // const doc = await this.pendingReservationModel.distinct(
338
+ // 'subReservation.identifier',
339
+ // {
340
+ // 'reservationFor.id': { $eq: eventId },
341
+ // 'subReservation.identifier': { $exists: true, $in: reservationIdentifiers }
342
+ // }
343
+ // )
344
+ // .setOptions({ maxTimeMS: MONGO_MAX_TIME_MS })
345
+ // .exec();
346
+ // debug('searchHolders: distinct.', doc);
347
+ // return doc;
348
+ // }
269
349
  // public async getSize(params: Omit<IUnlockKey, 'holder' | 'offer'>) {
270
350
  // const { eventId } = params;
271
351
  // const aggregate = this.aggregateReservationModel.aggregate([
@@ -10,10 +10,7 @@ export declare class StockHolderRepo implements AbstractStockHolderRepo {
10
10
  private readonly redisClient;
11
11
  private readonly settingModel;
12
12
  private readonly pendingReservationRepo;
13
- private readonly useMongooseForce;
14
- constructor(redisClient: RedisClientType, connection: Connection, options?: {
15
- useMongooseForce: boolean;
16
- });
13
+ constructor(redisClient: RedisClientType, connection: Connection);
17
14
  private static offer2field;
18
15
  private static createKey;
19
16
  /**
@@ -32,6 +29,9 @@ export declare class StockHolderRepo implements AbstractStockHolderRepo {
32
29
  * 空席でない座席をカウントする
33
30
  */
34
31
  countUnavailableOffers(params: {
32
+ project: {
33
+ id: string;
34
+ };
35
35
  event: {
36
36
  id: string;
37
37
  startDate: Date;
@@ -55,4 +55,6 @@ export declare class StockHolderRepo implements AbstractStockHolderRepo {
55
55
  * 新リポジトリを使用するかどうか
56
56
  */
57
57
  private useMongoose;
58
+ private useMongoAsStockHolderBySettings;
59
+ private redisKeyExists;
58
60
  }
@@ -21,11 +21,10 @@ const SEARCH_OFFERS_MAX_LENGTH = 100;
21
21
  * イベントストックホルダーリポジトリ
22
22
  */
23
23
  class StockHolderRepo {
24
- constructor(redisClient, connection, options) {
24
+ constructor(redisClient, connection) {
25
25
  this.redisClient = redisClient;
26
26
  this.settingModel = connection.model(setting_1.modelName, (0, setting_1.createSchema)());
27
27
  this.pendingReservationRepo = new pendingReservation_1.PendingReservationRepo(connection);
28
- this.useMongooseForce = (options === null || options === void 0 ? void 0 : options.useMongooseForce) === true;
29
28
  }
30
29
  static offer2field(params, hasTicketedSeat) {
31
30
  var _a, _b;
@@ -55,6 +54,7 @@ class StockHolderRepo {
55
54
  lockIfNotLimitExceeded(lockKey, maximum) {
56
55
  return __awaiter(this, void 0, void 0, function* () {
57
56
  const useMongoose = yield this.useMongoose({
57
+ project: { id: lockKey.project.id },
58
58
  eventId: lockKey.eventId,
59
59
  startDate: lockKey.startDate,
60
60
  hasTicketedSeat: lockKey.hasTicketedSeat
@@ -87,6 +87,7 @@ class StockHolderRepo {
87
87
  throw new factory.errors.Argument('expires', 'must be Date');
88
88
  }
89
89
  const useMongoose = yield this.useMongoose({
90
+ project: { id: lockKey.project.id },
90
91
  eventId: lockKey.eventId,
91
92
  startDate: lockKey.startDate,
92
93
  hasTicketedSeat: lockKey.hasTicketedSeat
@@ -150,6 +151,7 @@ class StockHolderRepo {
150
151
  unlock(params) {
151
152
  return __awaiter(this, void 0, void 0, function* () {
152
153
  const useMongoose = yield this.useMongoose({
154
+ project: { id: params.project.id },
153
155
  eventId: params.eventId,
154
156
  startDate: params.startDate,
155
157
  hasTicketedSeat: params.hasTicketedSeat
@@ -174,6 +176,7 @@ class StockHolderRepo {
174
176
  countUnavailableOffers(params) {
175
177
  return __awaiter(this, void 0, void 0, function* () {
176
178
  if (yield this.useMongoose({
179
+ project: { id: params.project.id },
177
180
  eventId: params.event.id,
178
181
  startDate: params.event.startDate,
179
182
  hasTicketedSeat: params.event.hasTicketedSeat
@@ -198,6 +201,7 @@ class StockHolderRepo {
198
201
  getHolder(params) {
199
202
  return __awaiter(this, void 0, void 0, function* () {
200
203
  if (yield this.useMongoose({
204
+ project: { id: params.project.id },
201
205
  eventId: params.eventId,
202
206
  startDate: params.startDate,
203
207
  hasTicketedSeat: params.hasTicketedSeat
@@ -219,6 +223,7 @@ class StockHolderRepo {
219
223
  throw new factory.errors.Argument('offers', `offers.length must be <= ${SEARCH_OFFERS_MAX_LENGTH}`);
220
224
  }
221
225
  if (yield this.useMongoose({
226
+ project: { id: params.project.id },
222
227
  eventId: params.eventId,
223
228
  startDate: params.startDate,
224
229
  hasTicketedSeat: params.hasTicketedSeat
@@ -251,17 +256,10 @@ class StockHolderRepo {
251
256
  }
252
257
  let useMongoose = false;
253
258
  // useMongoAsStockHolder設定有の場合のみmongo利用(2025-04-18~)
254
- const setting = yield this.settingModel.findOne({ 'project.id': { $eq: '*' } }, {
255
- _id: 0,
256
- useMongoAsStockHolder: 1
257
- })
258
- .lean()
259
- .exec();
260
- if ((setting === null || setting === void 0 ? void 0 : setting.useMongoAsStockHolder) === true) {
261
- const key = StockHolderRepo.createKey({ eventId: params.eventId, startDate: params.startDate });
262
- const existingRedisKeyCount = yield this.redisClient.exists(key);
263
- // console.log('existingRedisKeyCount:', existingRedisKeyCount);
264
- if (typeof existingRedisKeyCount === 'number' && existingRedisKeyCount > 0) {
259
+ const useMongoAsStockHolderBySettings = yield this.useMongoAsStockHolderBySettings({ project: { id: params.project.id } });
260
+ if (useMongoAsStockHolderBySettings) {
261
+ const redisKeyExists = yield this.redisKeyExists(params);
262
+ if (redisKeyExists) {
265
263
  useMongoose = false;
266
264
  }
267
265
  else {
@@ -269,14 +267,34 @@ class StockHolderRepo {
269
267
  useMongoose = true;
270
268
  }
271
269
  }
272
- else {
273
- if (this.useMongooseForce) {
274
- useMongoose = true;
275
- }
276
- }
277
270
  return useMongoose;
278
271
  });
279
272
  }
273
+ useMongoAsStockHolderBySettings(params) {
274
+ return __awaiter(this, void 0, void 0, function* () {
275
+ // useMongoAsStockHolder設定有の場合のみmongo利用(2025-04-18~)
276
+ const setting = yield this.settingModel.findOne({ 'project.id': { $eq: '*' } }, {
277
+ _id: 0,
278
+ useMongoAsStockHolder: 1,
279
+ useMongoAsStockHolderProjects: 1
280
+ })
281
+ .lean()
282
+ .exec();
283
+ const useMongoGlobally = (setting === null || setting === void 0 ? void 0 : setting.useMongoAsStockHolder) === true;
284
+ const useMongoAsStockHolderProjects = setting === null || setting === void 0 ? void 0 : setting.useMongoAsStockHolderProjects;
285
+ const useMongoByProject = Array.isArray(useMongoAsStockHolderProjects)
286
+ && useMongoAsStockHolderProjects.includes(params.project.id);
287
+ return useMongoGlobally || useMongoByProject;
288
+ });
289
+ }
290
+ redisKeyExists(params) {
291
+ return __awaiter(this, void 0, void 0, function* () {
292
+ const key = StockHolderRepo.createKey(params);
293
+ const existingRedisKeyCount = yield this.redisClient.exists(key);
294
+ // console.log('existingRedisKeyCount:', existingRedisKeyCount);
295
+ return typeof existingRedisKeyCount === 'number' && existingRedisKeyCount > 0;
296
+ });
297
+ }
280
298
  }
281
299
  exports.StockHolderRepo = StockHolderRepo;
282
300
  StockHolderRepo.KEY_PREFIX_NEW = 'stockHolder';
@@ -57,6 +57,9 @@ export declare abstract class AbstractStockHolderRepo {
57
57
  * 空席でない座席をカウントする
58
58
  */
59
59
  abstract countUnavailableOffers(params: {
60
+ project: {
61
+ id: string;
62
+ };
60
63
  event: {
61
64
  id: string;
62
65
  startDate: Date;
@@ -252,6 +252,7 @@ function aggregateReservationByEvent(params) {
252
252
  if (typeof maximumAttendeeCapacity === 'number') {
253
253
  // 残席数を座席ロック数から計算
254
254
  const unavailableOfferCount = yield repos.stockHolder.countUnavailableOffers({
255
+ project: { id: params.event.project.id },
255
256
  event: {
256
257
  id: params.event.id,
257
258
  startDate: moment(params.event.startDate)
package/package.json CHANGED
@@ -113,5 +113,5 @@
113
113
  "postversion": "git push origin --tags",
114
114
  "prepublishOnly": "npm run clean && npm run build && npm test && npm run doc"
115
115
  },
116
- "version": "22.9.0-alpha.101"
116
+ "version": "22.9.0-alpha.103"
117
117
  }