@chevre/domain 23.0.0-alpha.15 → 23.0.0-alpha.18

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.
@@ -6,8 +6,16 @@ import * as redis from 'redis';
6
6
  import { chevre } from '../../../../lib/index';
7
7
 
8
8
  const project = { id: String(process.env.PROJECT_ID) };
9
+ const { EVENT_ID, OFFER_ID, APPLICATION_ID, OFFER_TOKEN } = process.env;
9
10
 
11
+ // tslint:disable-next-line:max-func-body-length
10
12
  async function main() {
13
+ if (typeof EVENT_ID !== 'string'
14
+ || typeof OFFER_ID !== 'string'
15
+ || typeof APPLICATION_ID !== 'string') {
16
+ throw new Error('environment variables required');
17
+ }
18
+
11
19
  const redisClient = redis.createClient<redis.RedisDefaultModules, Record<string, never>, Record<string, never>>({
12
20
  socket: {
13
21
  port: Number(<string>process.env.REDIS_PORT),
@@ -21,59 +29,113 @@ async function main() {
21
29
  const transactionNumberRepo = await chevre.repository.TransactionNumber.createInstance({
22
30
  connection: mongoose.connection
23
31
  });
24
- const assetTransactionRepo = await chevre.repository.AssetTransaction.createInstance(mongoose.connection);
25
-
26
32
  const { transactionNumber } = await transactionNumberRepo.publishByTimestamp({ startDate: new Date() });
27
33
  const provider: chevre.factory.reservation.IProvider = {
28
34
  id: '59d20831e53ebc2b4e774466',
29
35
  typeOf: chevre.factory.organizationType.Corporation
30
36
  };
31
- const reserveTransaction = await assetTransactionRepo.start<chevre.factory.assetTransactionType.Reserve>({
32
- project: { id: project.id, typeOf: chevre.factory.organizationType.Project },
33
- typeOf: chevre.factory.assetTransactionType.Reserve,
34
- transactionNumber,
35
- agent: { ...provider, name: 'sample agent name' },
36
- object: {
37
- provider,
38
- reservationNumber: transactionNumber,
39
- reservationStatus: chevre.factory.reservationStatusType.ReservationPending,
40
- disablePendingReservations: true,
41
- useHoldStockByTransactionNumber: true,
42
- typeOf: chevre.factory.reservationType.ReservationPackage
43
- },
44
- expires: moment()
45
- .add(1, 'minute')
46
- .toDate()
47
- });
48
- let cancelResult = await assetTransactionRepo.cancel<chevre.factory.assetTransactionType.Reserve>({
49
- typeOf: reserveTransaction.typeOf,
50
- id: reserveTransaction.id
51
- });
52
- console.log('cancelResult:', cancelResult);
53
- cancelResult = await assetTransactionRepo.cancel<chevre.factory.assetTransactionType.Reserve>({
54
- typeOf: reserveTransaction.typeOf,
55
- id: reserveTransaction.id
56
- });
57
- console.log('cancelResult:', cancelResult);
58
37
 
59
- let transaction = await assetTransactionRepo.findById<chevre.factory.assetTransactionType.Reserve>(
38
+ const { transaction } = await (await chevre.service.assetTransaction.createService()).reserve.start(
60
39
  {
40
+ project: { id: project.id, typeOf: chevre.factory.organizationType.Project },
61
41
  typeOf: chevre.factory.assetTransactionType.Reserve,
62
- id: reserveTransaction.id
42
+ transactionNumber,
43
+ agent: { ...provider, name: 'sample agent name' },
44
+ object: {
45
+ acceptedOffer: [{
46
+ /**
47
+ * オファーID
48
+ */
49
+ id: OFFER_ID,
50
+ /**
51
+ * アイテム情報
52
+ * 予約の詳細指定など
53
+ */
54
+ itemOffered: {
55
+ serviceOutput: {
56
+ typeOf: chevre.factory.reservationType.EventReservation,
57
+ reservedTicket: {
58
+ /**
59
+ * チケット識別子
60
+ * 指定された場合、決済カードの対象チケット識別子と関連付けされます
61
+ * /^[0-9a-zA-Z]{8,16}$/
62
+ */
63
+ // identifier?: string;
64
+ // issuedBy?: ReservationFactory.IUnderName;
65
+ typeOf: 'Ticket',
66
+ ticketedSeat: {
67
+ typeOf: chevre.factory.placeType.Seat,
68
+ seatNumber: 'A-01',
69
+ seatRow: '',
70
+ seatSection: 'Default'
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }],
76
+ reservationFor: {
77
+ id: EVENT_ID,
78
+ offers: {
79
+ token: OFFER_TOKEN,
80
+ identifier: 'LegacyReservation'
81
+ }
82
+ }
83
+ },
84
+ expires: moment()
85
+ // tslint:disable-next-line:no-magic-numbers
86
+ .add(5, 'seconds')
87
+ .toDate(),
88
+ validateEvent: false,
89
+ validateEventOfferPeriod: true,
90
+ validateAppliesToMovieTicket: true,
91
+ instrument: [],
92
+ availableAtOrFrom: { id: APPLICATION_ID }
93
+ // stockHoldUntilDaysAfterEventEnd: STOCK_HOLD_UNTIL_DAYS_AFTER_EVENT_END
63
94
  },
64
- ['status', 'transactionNumber', 'project', 'typeOf']
65
- );
66
- console.log('transaction:', transaction);
67
-
68
- transaction = await assetTransactionRepo.findByTransactionNumber<chevre.factory.assetTransactionType.Reserve>(
95
+ { maxReservationGracePeriodInDays: 93 }
96
+ )(
69
97
  {
70
- typeOf: chevre.factory.assetTransactionType.Reserve,
71
- transactionNumber
98
+ advanceBookingRequirement: await chevre.repository.AdvanceBookingRequirement.createInstance(mongoose.connection),
99
+ project: await chevre.repository.Project.createInstance(mongoose.connection),
100
+ stockHolder: await chevre.repository.StockHolder.createInstance({ connection: mongoose.connection }),
101
+ event: await chevre.repository.Event.createInstance(mongoose.connection),
102
+ eventSeries: await chevre.repository.EventSeries.createInstance(mongoose.connection),
103
+ issuer: await chevre.repository.Issuer.createInstance(mongoose.connection),
104
+ memberProgram: await chevre.repository.MemberProgram.createInstance(mongoose.connection),
105
+ offer: await chevre.repository.Offer.createInstance(mongoose.connection),
106
+ offerCatalog: await chevre.repository.OfferCatalog.createInstance(mongoose.connection),
107
+ offerCatalogItem: await chevre.repository.OfferCatalogItem.createInstance(mongoose.connection),
108
+ offerRateLimit: await chevre.repository.rateLimit.Offer.createInstance(redisClient),
109
+ paymentService: await chevre.repository.PaymentService.createInstance(mongoose.connection),
110
+ priceSpecification: await chevre.repository.PriceSpecification.createInstance(mongoose.connection),
111
+ product: await chevre.repository.Product.createInstance(mongoose.connection),
112
+ productOffer: await chevre.repository.ProductOffer.createInstance(mongoose.connection),
113
+ seat: await chevre.repository.place.Seat.createInstance(mongoose.connection),
114
+ setting: await chevre.repository.Setting.createInstance(mongoose.connection),
115
+ task: await chevre.repository.Task.createInstance(mongoose.connection),
116
+ assetTransaction: await chevre.repository.AssetTransaction.createInstance(mongoose.connection)
72
117
  },
73
- ['status']
118
+ new chevre.settings.Settings({
119
+ abortedTasksWithoutReport: [],
120
+ numTryConfirmReserveTransaction: 10,
121
+ deliverOrderLimit: 1,
122
+ coa: { timeout: 20000 },
123
+ gmo: {
124
+ timeout: 5000,
125
+ timeoutBackground: 5000,
126
+ useFetch: true
127
+ },
128
+ movieticketReserve: {
129
+ timeout: 5000,
130
+ timeoutCheck: 5000,
131
+ minIntervalBetweenPayAndRefund: 1,
132
+ credentialsExpireInSeconds: 300
133
+ },
134
+ // useAssetTransactionSyncProcessing: process.env.USE_ASSET_TRANSACTION_SYNC_PROCESSING === '1',
135
+ useExperimentalFeature: false
136
+ })
74
137
  );
75
138
  console.log('transaction:', transaction);
76
-
77
139
  }
78
140
 
79
141
  main()
@@ -0,0 +1,100 @@
1
+ // tslint:disable:no-console
2
+ import * as moment from 'moment';
3
+ import * as mongoose from 'mongoose';
4
+
5
+ import { chevre } from '../../../../lib/index';
6
+
7
+ const project = { id: String(process.env.PROJECT_ID) };
8
+ const { EVENT_ID } = process.env;
9
+
10
+ async function main() {
11
+ if (typeof EVENT_ID !== 'string') {
12
+ throw new Error('environment variables required');
13
+ }
14
+
15
+ await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
16
+
17
+ const eventSellerMakesOfferRepo = await chevre.repository.EventSellerMakesOffer.createInstance(mongoose.connection);
18
+ const availabilityEnds = moment('2025-10-26T05:20:00.000Z')
19
+ .toDate();
20
+ const availabilityStarts = moment('2025-10-23T15:00:00.000Z')
21
+ .toDate();
22
+ const validFrom = moment('2025-10-12T15:00:00.000Z')
23
+ .toDate();
24
+ const validThrough = moment('2025-10-26T05:20:00.000Z')
25
+ .toDate();
26
+ const result = await eventSellerMakesOfferRepo.updateOffersByEventId(
27
+ {
28
+ project: { id: project.id },
29
+ offers: [
30
+ {
31
+ typeOf: chevre.factory.offerType.Offer,
32
+ availableAtOrFrom: {
33
+ id: '3eo6okferrsdpfd9j2ce1iv9k7'
34
+ },
35
+ availabilityEnds,
36
+ availabilityStarts,
37
+ validFrom,
38
+ validThrough
39
+ },
40
+ {
41
+ typeOf: chevre.factory.offerType.Offer,
42
+ availableAtOrFrom: {
43
+ id: '51qbjcfr72h62m06vtv5kkhgje'
44
+ },
45
+ availabilityEnds,
46
+ availabilityStarts,
47
+ validFrom,
48
+ validThrough
49
+ },
50
+ {
51
+ typeOf: chevre.factory.offerType.Offer,
52
+ availableAtOrFrom: {
53
+ id: '5h3gs22mu9j3ok7o63uog9o9i3'
54
+ },
55
+ availabilityEnds,
56
+ availabilityStarts,
57
+ validFrom,
58
+ validThrough
59
+ },
60
+ {
61
+ typeOf: chevre.factory.offerType.Offer,
62
+ availableAtOrFrom: {
63
+ id: '66e7p2g713675v96nrhdm975kg'
64
+ },
65
+ availabilityEnds,
66
+ availabilityStarts,
67
+ validFrom,
68
+ validThrough
69
+ },
70
+ {
71
+ typeOf: chevre.factory.offerType.Offer,
72
+ availableAtOrFrom: {
73
+ id: '7divuoimobsfgq95tp1csorjqq'
74
+ },
75
+ availabilityEnds,
76
+ availabilityStarts,
77
+ validFrom,
78
+ validThrough
79
+ },
80
+ {
81
+ typeOf: chevre.factory.offerType.Offer,
82
+ availableAtOrFrom: {
83
+ id: 'ckevmf3fueqcunnideu6artt'
84
+ },
85
+ availabilityEnds,
86
+ availabilityStarts,
87
+ validFrom,
88
+ validThrough
89
+ }
90
+ ],
91
+ itemOffered: { id: EVENT_ID }
92
+ }
93
+ );
94
+ // tslint:disable-next-line:no-null-keyword
95
+ console.dir(result, { depth: null });
96
+ }
97
+
98
+ main()
99
+ .then(console.log)
100
+ .catch(console.error);
@@ -3,13 +3,18 @@ import * as jwt from 'jsonwebtoken';
3
3
 
4
4
  async function main(): Promise<void> {
5
5
  const payload = {
6
- member: {
7
- memberOf: {
8
- identifier: 'bronze',
9
- isTierOf: {
10
- identifier: 'DefaultMemberProgram'
11
- }
12
- }
6
+ /**
7
+ * アプリケーションオファーコード
8
+ */
9
+ identifier: 'LegacyReservation',
10
+ validFrom: '2025-10-20T00:00:00Z',
11
+ validThrough: '2025-10-25T00:00:00Z',
12
+ eligibleQuantity: { maxValue: 1 },
13
+ itemOffered: {
14
+ /**
15
+ * イベント識別子
16
+ */
17
+ identifier: '251025001001010900'
13
18
  }
14
19
  };
15
20
 
@@ -1,6 +1,5 @@
1
1
  import { AnyExpression, Connection, FilterQuery, Types } from 'mongoose';
2
2
  import * as factory from '../factory';
3
- type IKeyOfProjection = keyof factory.categoryCode.ICategoryCode;
4
3
  type IUnset = {
5
4
  [key in keyof Pick<factory.categoryCode.ICategoryCode, 'additionalProperty' | 'color' | 'image' | 'paymentMethod'>]?: 1;
6
5
  };
@@ -17,6 +16,8 @@ type IMovieTicketType = Pick<factory.categoryCode.ICategoryCode, 'additionalProp
17
16
  identifier: factory.categoryCode.CategorySetIdentifier.MovieTicketType;
18
17
  };
19
18
  };
19
+ type IKeyOfProjection = keyof factory.categoryCode.ICategoryCode;
20
+ type IKeyOfProjectionExceptMovieTicketType = keyof ICategoryCodeExceptMovieTicketType;
20
21
  /**
21
22
  * 区分リポジトリ
22
23
  */
@@ -30,9 +31,11 @@ export declare class CategoryCodeRepo {
30
31
  [field: string]: AnyExpression;
31
32
  };
32
33
  /**
33
- * 集計検索(publicな属性検索が目的)
34
+ * 区分集計検索(publicな属性検索が目的)
34
35
  */
35
- searchByAggregate(conditions: factory.categoryCode.ISearchConditions, inclusion: IKeyOfProjection[]): Promise<factory.categoryCode.ICategoryCode[]>;
36
+ findCategoryCodesByAggregate(conditions: factory.categoryCode.ISearchConditions, inclusion: IKeyOfProjectionExceptMovieTicketType[]): Promise<(ICategoryCodeExceptMovieTicketType & {
37
+ id: string;
38
+ })[]>;
36
39
  /**
37
40
  * 区分検索
38
41
  */
@@ -192,9 +192,9 @@ class CategoryCodeRepo {
192
192
  return projectStage;
193
193
  }
194
194
  /**
195
- * 集計検索(publicな属性検索が目的)
195
+ * 区分集計検索(publicな属性検索が目的)
196
196
  */
197
- searchByAggregate(conditions, inclusion) {
197
+ findCategoryCodesByAggregate(conditions, inclusion) {
198
198
  return __awaiter(this, void 0, void 0, function* () {
199
199
  var _a;
200
200
  const matchStages = CategoryCodeRepo.CREATE_MONGO_CONDITIONS(conditions)
@@ -208,8 +208,6 @@ class CategoryCodeRepo {
208
208
  : [],
209
209
  { $project: projectStage }
210
210
  ]);
211
- // tslint:disable-next-line:no-single-line-block-comment
212
- /* istanbul ignore else */
213
211
  if (typeof conditions.limit === 'number' && conditions.limit > 0) {
214
212
  const page = (typeof conditions.page === 'number' && conditions.page > 0) ? conditions.page : 1;
215
213
  aggregate.limit(conditions.limit * page)
@@ -1,54 +1,21 @@
1
1
  import type { Connection } from 'mongoose';
2
2
  import * as factory from '../factory';
3
- type IAggregateMakesOfferResult = Pick<factory.event.screeningEvent.ISellerMakesOffer, 'availabilityEnds' | 'availabilityStarts' | 'validFrom' | 'validThrough'> & {
4
- itemOffered: {
5
- serviceOutput: {
6
- reservationFor: {
7
- /**
8
- * イベントID
9
- */
10
- id: string;
11
- };
12
- };
13
- };
14
- };
15
3
  /**
16
- * イベントの販売者makesOfferリポジトリ
4
+ * イベントのアプリケーションオファーリポジトリ
17
5
  */
18
6
  export declare class EventSellerMakesOfferRepo {
19
7
  private readonly eventModel;
20
8
  constructor(connection: Connection);
21
9
  /**
22
- * 指定クライアントのオファーを集計する(2024-10-09~)
10
+ * 単一イベントのmakesOfferを更新する
23
11
  */
24
- aggregateMakesOffer(conditions: {
25
- limit?: number;
26
- page?: number;
12
+ updateOffersByEventId(params: {
27
13
  project: {
28
- id: {
29
- $eq: string;
30
- };
31
- };
32
- /**
33
- * アプリケーション(指定必須)
34
- */
35
- availableAtOrFrom: {
36
- id: {
37
- $eq: string;
38
- };
14
+ id: string;
39
15
  };
16
+ offers: factory.event.screeningEvent.ISellerMakesOffer[];
40
17
  itemOffered: {
41
- serviceOutput: {
42
- reservationFor: {
43
- /**
44
- * イベントID
45
- */
46
- id: {
47
- $in?: string[];
48
- };
49
- };
50
- };
18
+ id: string;
51
19
  };
52
- }): Promise<IAggregateMakesOfferResult[]>;
20
+ }): Promise<void>;
53
21
  }
54
- export {};
@@ -11,62 +11,53 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.EventSellerMakesOfferRepo = void 0;
13
13
  const factory = require("../factory");
14
- const settings_1 = require("../settings");
14
+ // import { MONGO_MAX_TIME_MS } from '../settings';
15
15
  const event_1 = require("./mongoose/schemas/event");
16
+ // type IMatchStage = PipelineStage.Match;
17
+ // type IAggregateMakesOfferResult = Pick<
18
+ // factory.event.screeningEvent.ISellerMakesOffer,
19
+ // 'availabilityEnds' | 'availabilityStarts' | 'validFrom' | 'validThrough'
20
+ // > & {
21
+ // itemOffered: {
22
+ // serviceOutput: {
23
+ // reservationFor: {
24
+ // /**
25
+ // * イベントID
26
+ // */
27
+ // id: string;
28
+ // };
29
+ // };
30
+ // };
31
+ // };
16
32
  /**
17
- * イベントの販売者makesOfferリポジトリ
33
+ * イベントのアプリケーションオファーリポジトリ
18
34
  */
19
35
  class EventSellerMakesOfferRepo {
20
36
  constructor(connection) {
21
37
  this.eventModel = connection.model(event_1.modelName, (0, event_1.createSchema)());
22
38
  }
23
39
  /**
24
- * 指定クライアントのオファーを集計する(2024-10-09~)
40
+ * 単一イベントのmakesOfferを更新する
25
41
  */
26
- aggregateMakesOffer(conditions) {
42
+ updateOffersByEventId(params) {
27
43
  return __awaiter(this, void 0, void 0, function* () {
28
- var _a;
29
- const { availableAtOrFrom } = conditions;
30
- if (typeof ((_a = availableAtOrFrom === null || availableAtOrFrom === void 0 ? void 0 : availableAtOrFrom.id) === null || _a === void 0 ? void 0 : _a.$eq) !== 'string' || availableAtOrFrom.id.$eq === '') {
31
- throw new factory.errors.ArgumentNull('availableAtOrFrom.id.$eq');
32
- }
33
- const matchStages = [
34
- { $match: { 'project.id': { $eq: conditions.project.id.$eq } } },
35
- { $match: { 'offers.seller.makesOffer.availableAtOrFrom.id': { $exists: true, $eq: availableAtOrFrom.id.$eq } } }
36
- ];
37
- const reservationForIdIn = conditions.itemOffered.serviceOutput.reservationFor.id.$in;
38
- if (Array.isArray(reservationForIdIn)) {
39
- matchStages.push({ $match: { _id: { $in: reservationForIdIn } } });
40
- }
41
- const aggregate = this.eventModel.aggregate([
42
- { $unwind: '$offers.seller.makesOffer' },
43
- ...matchStages,
44
- { $sort: { _id: factory.sortType.Ascending } },
45
- {
46
- $project: {
47
- _id: 0,
48
- availabilityEnds: '$offers.seller.makesOffer.availabilityEnds',
49
- availabilityStarts: '$offers.seller.makesOffer.availabilityStarts',
50
- validFrom: '$offers.seller.makesOffer.validFrom',
51
- validThrough: '$offers.seller.makesOffer.validThrough',
52
- itemOffered: {
53
- serviceOutput: {
54
- reservationFor: {
55
- id: { $toString: '$_id' }
56
- }
57
- }
58
- }
59
- }
44
+ const { offers, itemOffered, project } = params;
45
+ const updateQuery = {
46
+ $set: {
47
+ 'offers.seller.makesOffer': offers
60
48
  }
61
- ]);
62
- if (typeof conditions.limit === 'number' && conditions.limit > 0) {
63
- const page = (typeof conditions.page === 'number' && conditions.page > 0) ? conditions.page : 1;
64
- aggregate.limit(conditions.limit * page)
65
- .skip(conditions.limit * (page - 1));
66
- }
67
- return aggregate
68
- .option({ maxTimeMS: settings_1.MONGO_MAX_TIME_MS })
49
+ };
50
+ const updateFilter = {
51
+ _id: { $eq: itemOffered.id },
52
+ 'project.id': { $eq: project.id }
53
+ };
54
+ const queryOptions = { upsert: false, new: false, projection: { _id: 1 } };
55
+ const doc = yield this.eventModel.findOneAndUpdate(updateFilter, updateQuery, queryOptions)
56
+ .lean()
69
57
  .exec();
58
+ if (doc === null) {
59
+ throw new factory.errors.NotFound(this.eventModel.modelName);
60
+ }
70
61
  });
71
62
  }
72
63
  }
@@ -100,9 +100,9 @@ function fixEvent(params) {
100
100
  // additionalProperty, // discontinue(2024-07-20~)
101
101
  'name', 'doorTime', 'endDate', 'eventStatus',
102
102
  'location', 'startDate', 'superEvent',
103
- 'offers', 'maximumPhysicalAttendeeCapacity'
103
+ 'offers', 'maximumPhysicalAttendeeCapacity',
104
+ 'identifier' // support identifier(2025-10-24~)
104
105
  // 'coaInfo', // discontinue(2024-07-24~)
105
- // 'identifier' // discontinue(2024-07-24~)
106
106
  ]);
107
107
  const offeredThroughIdentifier = (_b = event.offers.offeredThrough) === null || _b === void 0 ? void 0 : _b.identifier;
108
108
  if (offeredThroughIdentifier === factory.service.webAPI.Identifier.COA) {
@@ -0,0 +1,15 @@
1
+ import * as factory from '../../../../factory';
2
+ import { IMinimizedIndividualEvent } from '../../../../factory/event';
3
+ import type { IssuerRepo } from '../../../../repo/issuer';
4
+ /**
5
+ * オファートークン検証(2025-10-21~)
6
+ */
7
+ declare function validateIssuedOfferIfExists(params: {
8
+ event: Pick<IMinimizedIndividualEvent, 'offers' | 'id' | 'project' | 'identifier'>;
9
+ now: Date;
10
+ object: factory.assetTransaction.reserve.IObjectWithoutDetail;
11
+ makesOfferOnApplication: factory.event.screeningEvent.ISellerMakesOffer;
12
+ }): (repos: {
13
+ issuer: IssuerRepo;
14
+ }) => Promise<void>;
15
+ export { validateIssuedOfferIfExists };