@lyxa.ai/core 1.4.323 → 1.4.324
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/dist/libraries/google-location/google-location.service.js +15 -13
- package/dist/libraries/google-location/google-location.service.js.map +1 -1
- package/dist/libraries/llm/providers/openai-provider.js +15 -5
- package/dist/libraries/llm/providers/openai-provider.js.map +1 -1
- package/dist/libraries/mongo/models/user-shop-history.model.d.ts +6 -1
- package/dist/libraries/mongo/models/user-shop-history.model.js +22 -3
- package/dist/libraries/mongo/models/user-shop-history.model.js.map +1 -1
- package/dist/libraries/socket/events/chatroom-message-send.socket.event.d.ts +25 -25
- package/dist/libraries/socket/events/order-actions.socket.event.d.ts +32 -32
- package/dist/libraries/socket/events/rider-location-update.socket.event.d.ts +8 -8
- package/dist/libraries/socket/events/ticket-actions.socket.event.d.ts +8 -8
- package/dist/libraries/socket/events/ticket-assign.socket.event.d.ts +28 -28
- package/dist/types/README.md +1 -1
- package/dist/types/package.json +1 -1
- package/package.json +1 -1
|
@@ -35,13 +35,7 @@ let GoogleLocationService = class GoogleLocationService {
|
|
|
35
35
|
this.logger.logger.info('Google Autocomplete skipped: empty input provided');
|
|
36
36
|
return { predictions: [], status: 'OK' };
|
|
37
37
|
}
|
|
38
|
-
const
|
|
39
|
-
if (sessionToken)
|
|
40
|
-
queryParams.sessiontoken = sessionToken;
|
|
41
|
-
const querySummary = Object.entries(queryParams)
|
|
42
|
-
.map(([k, v]) => `${k}:${v}`)
|
|
43
|
-
.join('|');
|
|
44
|
-
const cacheKey = `maps:autocomplete:${this.redisService.sanitizeKey(querySummary)}`;
|
|
38
|
+
const cacheKey = `maps:autocomplete:${this.redisService.sanitizeKey(searchText.trim().toLowerCase())}`;
|
|
45
39
|
try {
|
|
46
40
|
const cached = await this.redisService.getCachedObject(cacheKey);
|
|
47
41
|
if (cached !== undefined) {
|
|
@@ -54,9 +48,12 @@ let GoogleLocationService = class GoogleLocationService {
|
|
|
54
48
|
this.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');
|
|
55
49
|
throw new Error('GOOGLE_MAPS_API_KEY is not configured');
|
|
56
50
|
}
|
|
51
|
+
const queryParams = { input: searchText, ...otherParams };
|
|
52
|
+
if (sessionToken)
|
|
53
|
+
queryParams.sessiontoken = sessionToken;
|
|
57
54
|
const result = await this.client.callGoogleMapsAPI('place/autocomplete', apiKey, queryParams);
|
|
58
55
|
if (result.status === 'OK') {
|
|
59
|
-
await this.redisService.cacheObject(cacheKey, result,
|
|
56
|
+
await this.redisService.cacheObject(cacheKey, result, 604800);
|
|
60
57
|
this.logger.logger.info('Google Autocomplete response cached successfully', {
|
|
61
58
|
cacheKey,
|
|
62
59
|
predictionCount: result.predictions?.length ?? 0,
|
|
@@ -128,6 +125,16 @@ let GoogleLocationService = class GoogleLocationService {
|
|
|
128
125
|
const roundedLng = parseFloat(longitude).toFixed(4);
|
|
129
126
|
const cacheKey = `maps:geocode:${roundedLat}:${roundedLng}`;
|
|
130
127
|
try {
|
|
128
|
+
const cached = await this.redisService.getCachedObject(cacheKey);
|
|
129
|
+
if (cached !== undefined) {
|
|
130
|
+
this.logger.logger.info('Google Reverse Geocode Cache HIT', { cacheKey, roundedLat, roundedLng });
|
|
131
|
+
return cached;
|
|
132
|
+
}
|
|
133
|
+
this.logger.logger.info('Google Reverse Geocode Cache MISS - Calling API', {
|
|
134
|
+
cacheKey,
|
|
135
|
+
latitude,
|
|
136
|
+
longitude,
|
|
137
|
+
});
|
|
131
138
|
const apiKey = await this.secretManager.getKey('GOOGLE_MAPS_API_KEY');
|
|
132
139
|
if (!apiKey) {
|
|
133
140
|
this.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');
|
|
@@ -136,11 +143,6 @@ let GoogleLocationService = class GoogleLocationService {
|
|
|
136
143
|
const params = { latlng: `${latitude},${longitude}` };
|
|
137
144
|
const result = await this.client.callGoogleMapsAPI('geocode', apiKey, params);
|
|
138
145
|
if (result.status === 'OK') {
|
|
139
|
-
await this.redisService.cacheObject(cacheKey, result, 259200);
|
|
140
|
-
this.logger.logger.info('Google Reverse Geocode cached successfully', {
|
|
141
|
-
cacheKey,
|
|
142
|
-
resultsCount: result.results?.length ?? 0,
|
|
143
|
-
});
|
|
144
146
|
}
|
|
145
147
|
else {
|
|
146
148
|
this.logger.logger.warn('Google Reverse Geocode returned non-OK status', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google-location.service.js","sourceRoot":"/","sources":["libraries/google-location/google-location.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Service } from 'typedi';\nimport { GoogleLocationClient } from './google-location.client';\nimport { SecretManagerService } from '../secrets';\nimport { RedisService } from '../redis';\nimport { LyxaLogger } from '../logger';\nimport {\n\tGoogleAutocompleteInputDTO,\n\tGoogleAutocompleteResponse,\n\tGooglePlaceDetailsInputDTO,\n\tGooglePlaceDetailsResponse,\n\tGoogleReverseGeocodeInputDTO,\n\tGoogleReverseGeocodeResponse,\n} from './google-location.dto';\n\n@Service()\nexport class GoogleLocationService {\n\tconstructor(\n\t\t@Inject() private readonly client: GoogleLocationClient,\n\t\t@Inject() private readonly secretManager: SecretManagerService,\n\t\t@Inject() private readonly redisService: RedisService,\n\t\t@Inject() private readonly logger: LyxaLogger\n\t) {}\n\n\tpublic async getAutocomplete(input: GoogleAutocompleteInputDTO): Promise<GoogleAutocompleteResponse> {\n\t\tconst { searchText, sessionToken, ...otherParams } = input;\n\n\t\tif (!searchText?.trim()) {\n\t\t\tthis.logger.logger.info('Google Autocomplete skipped: empty input provided');\n\t\t\treturn { predictions: [], status: 'OK' };\n\t\t}\n\n\t\tconst queryParams: Record<string, string> = { input: searchText, ...otherParams };\n\t\tif (sessionToken) queryParams.sessiontoken = sessionToken;\n\n\t\tconst querySummary = Object.entries(queryParams)\n\t\t\t.map(([k, v]) => `${k}:${v}`)\n\t\t\t.join('|');\n\t\tconst cacheKey = `maps:autocomplete:${this.redisService.sanitizeKey(querySummary)}`;\n\n\t\ttry {\n\t\t\tconst cached = await this.redisService.getCachedObject<GoogleAutocompleteResponse>(cacheKey);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tthis.logger.logger.info('Google Autocomplete Cache HIT', { cacheKey, input });\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tthis.logger.logger.info('Google Autocomplete Cache MISS - Calling API', { cacheKey, input });\n\n\t\t\tconst apiKey = await this.secretManager.getKey('GOOGLE_MAPS_API_KEY');\n\t\t\tif (!apiKey) {\n\t\t\t\tthis.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');\n\t\t\t\tthrow new Error('GOOGLE_MAPS_API_KEY is not configured');\n\t\t\t}\n\n\t\t\tconst result = await this.client.callGoogleMapsAPI('place/autocomplete', apiKey, queryParams);\n\n\t\t\tif (result.status === 'OK') {\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, 86400);\n\t\t\t\tthis.logger.logger.info('Google Autocomplete response cached successfully', {\n\t\t\t\t\tcacheKey,\n\t\t\t\t\tpredictionCount: result.predictions?.length ?? 0,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.logger.logger.warn('Google Autocomplete returned non-OK status', {\n\t\t\t\t\tstatus: result.status,\n\t\t\t\t\terrorMessage: result.error_message,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result as GoogleAutocompleteResponse;\n\t\t} catch (error) {\n\t\t\tthis.logger.logger.error('Google Autocomplete failed', { input, error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async getPlaceDetails(input: GooglePlaceDetailsInputDTO): Promise<GooglePlaceDetailsResponse> {\n\t\tconst { placeId, sessionToken } = input;\n\t\tif (!placeId) {\n\t\t\tthis.logger.logger.error('Google Place Details failed: missing placeId');\n\t\t\tthrow new Error('Missing place_id');\n\t\t}\n\n\t\tconst cacheKey = `maps:details:${placeId}`;\n\n\t\ttry {\n\t\t\tconst cached = await this.redisService.getCachedObject<GooglePlaceDetailsResponse>(cacheKey);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tthis.logger.logger.info('Google Place Details Cache HIT', { cacheKey, placeId });\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tthis.logger.logger.info('Google Place Details Cache MISS - Calling API', { cacheKey, placeId });\n\n\t\t\tconst apiKey = await this.secretManager.getKey('GOOGLE_MAPS_API_KEY');\n\t\t\tif (!apiKey) {\n\t\t\t\tthis.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');\n\t\t\t\tthrow new Error('GOOGLE_MAPS_API_KEY is not configured');\n\t\t\t}\n\n\t\t\tconst params: Record<string, string> = {\n\t\t\t\tplace_id: placeId,\n\t\t\t\tfields: 'name,formatted_address,geometry,address_component',\n\t\t\t};\n\t\t\tif (sessionToken) params.sessiontoken = sessionToken;\n\n\t\t\tconst result = await this.client.callGoogleMapsAPI('place/details', apiKey, params);\n\n\t\t\tif (result.status === 'OK') {\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, 604800);\n\t\t\t\tthis.logger.logger.info('Google Place Details cached successfully', { cacheKey, placeId });\n\t\t\t} else {\n\t\t\t\tthis.logger.logger.warn('Google Place Details returned non-OK status', {\n\t\t\t\t\tstatus: result.status,\n\t\t\t\t\terrorMessage: result.error_message,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result as GooglePlaceDetailsResponse;\n\t\t} catch (error) {\n\t\t\tthis.logger.logger.error('Google Place Details failed', { input, error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async getReverseGeocode(input: GoogleReverseGeocodeInputDTO): Promise<GoogleReverseGeocodeResponse> {\n\t\tconst { latitude, longitude } = input;\n\t\tif (!latitude || !longitude) {\n\t\t\tthis.logger.logger.error('Google Reverse Geocode failed: missing coordinates', { latitude, longitude });\n\t\t\tthrow new Error('Missing latitude or longitude');\n\t\t}\n\n\t\tconst roundedLat = parseFloat(latitude).toFixed(4);\n\t\tconst roundedLng = parseFloat(longitude).toFixed(4);\n\t\tconst cacheKey = `maps:geocode:${roundedLat}:${roundedLng}`;\n\n\t\ttry {\n\t\t\t/*\n\t\t\tRedis Cache logic \n\t\t\t*/\n\n\t\t\t// const cached = await this.redisService.getCachedObject<GoogleReverseGeocodeResponse>(cacheKey);\n\t\t\t// if (cached !== undefined) {\n\t\t\t// \tthis.logger.logger.info('Google Reverse Geocode Cache HIT', { cacheKey, roundedLat, roundedLng });\n\t\t\t// \treturn cached;\n\t\t\t// }\n\n\t\t\t// this.logger.logger.info('Google Reverse Geocode Cache MISS - Calling API', {\n\t\t\t// \tcacheKey,\n\t\t\t// \tlatitude,\n\t\t\t// \tlongitude,\n\t\t\t// });\n\n\t\t\tconst apiKey = await this.secretManager.getKey('GOOGLE_MAPS_API_KEY');\n\t\t\tif (!apiKey) {\n\t\t\t\tthis.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');\n\t\t\t\tthrow new Error('GOOGLE_MAPS_API_KEY is not configured');\n\t\t\t}\n\n\t\t\tconst params = { latlng: `${latitude},${longitude}` };\n\n\t\t\tconst result = await this.client.callGoogleMapsAPI('geocode', apiKey, params);\n\n\t\t\tif (result.status === 'OK') {\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, 259200);\n\t\t\t\tthis.logger.logger.info('Google Reverse Geocode cached successfully', {\n\t\t\t\t\tcacheKey,\n\t\t\t\t\tresultsCount: result.results?.length ?? 0,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.logger.logger.warn('Google Reverse Geocode returned non-OK status', {\n\t\t\t\t\tstatus: result.status,\n\t\t\t\t\terrorMessage: result.error_message,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result as GoogleReverseGeocodeResponse;\n\t\t} catch (error) {\n\t\t\tthis.logger.logger.error('Google Reverse Geocode failed', { input, error });\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"google-location.service.js","sourceRoot":"/","sources":["libraries/google-location/google-location.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Inject, Service } from 'typedi';\nimport { GoogleLocationClient } from './google-location.client';\nimport { SecretManagerService } from '../secrets';\nimport { RedisService } from '../redis';\nimport { LyxaLogger } from '../logger';\nimport {\n\tGoogleAutocompleteInputDTO,\n\tGoogleAutocompleteResponse,\n\tGooglePlaceDetailsInputDTO,\n\tGooglePlaceDetailsResponse,\n\tGoogleReverseGeocodeInputDTO,\n\tGoogleReverseGeocodeResponse,\n} from './google-location.dto';\n\n@Service()\nexport class GoogleLocationService {\n\tconstructor(\n\t\t@Inject() private readonly client: GoogleLocationClient,\n\t\t@Inject() private readonly secretManager: SecretManagerService,\n\t\t@Inject() private readonly redisService: RedisService,\n\t\t@Inject() private readonly logger: LyxaLogger\n\t) {}\n\n\tpublic async getAutocomplete(input: GoogleAutocompleteInputDTO): Promise<GoogleAutocompleteResponse> {\n\t\tconst { searchText, sessionToken, ...otherParams } = input;\n\n\t\tif (!searchText?.trim()) {\n\t\t\tthis.logger.logger.info('Google Autocomplete skipped: empty input provided');\n\t\t\treturn { predictions: [], status: 'OK' };\n\t\t}\n\n\t\tconst cacheKey = `maps:autocomplete:${this.redisService.sanitizeKey(searchText.trim().toLowerCase())}`;\n\n\t\ttry {\n\t\t\tconst cached = await this.redisService.getCachedObject<GoogleAutocompleteResponse>(cacheKey);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tthis.logger.logger.info('Google Autocomplete Cache HIT', { cacheKey, input });\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tthis.logger.logger.info('Google Autocomplete Cache MISS - Calling API', { cacheKey, input });\n\n\t\t\tconst apiKey = await this.secretManager.getKey('GOOGLE_MAPS_API_KEY');\n\t\t\tif (!apiKey) {\n\t\t\t\tthis.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');\n\t\t\t\tthrow new Error('GOOGLE_MAPS_API_KEY is not configured');\n\t\t\t}\n\n\t\t\tconst queryParams: Record<string, string> = { input: searchText, ...otherParams };\n\t\t\tif (sessionToken) queryParams.sessiontoken = sessionToken;\n\n\t\t\tconst result = await this.client.callGoogleMapsAPI('place/autocomplete', apiKey, queryParams);\n\n\t\t\tif (result.status === 'OK') {\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, 604800);\n\t\t\t\tthis.logger.logger.info('Google Autocomplete response cached successfully', {\n\t\t\t\t\tcacheKey,\n\t\t\t\t\tpredictionCount: result.predictions?.length ?? 0,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis.logger.logger.warn('Google Autocomplete returned non-OK status', {\n\t\t\t\t\tstatus: result.status,\n\t\t\t\t\terrorMessage: result.error_message,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result as GoogleAutocompleteResponse;\n\t\t} catch (error) {\n\t\t\tthis.logger.logger.error('Google Autocomplete failed', { input, error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async getPlaceDetails(input: GooglePlaceDetailsInputDTO): Promise<GooglePlaceDetailsResponse> {\n\t\tconst { placeId, sessionToken } = input;\n\t\tif (!placeId) {\n\t\t\tthis.logger.logger.error('Google Place Details failed: missing placeId');\n\t\t\tthrow new Error('Missing place_id');\n\t\t}\n\n\t\tconst cacheKey = `maps:details:${placeId}`;\n\n\t\ttry {\n\t\t\tconst cached = await this.redisService.getCachedObject<GooglePlaceDetailsResponse>(cacheKey);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tthis.logger.logger.info('Google Place Details Cache HIT', { cacheKey, placeId });\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tthis.logger.logger.info('Google Place Details Cache MISS - Calling API', { cacheKey, placeId });\n\n\t\t\tconst apiKey = await this.secretManager.getKey('GOOGLE_MAPS_API_KEY');\n\t\t\tif (!apiKey) {\n\t\t\t\tthis.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');\n\t\t\t\tthrow new Error('GOOGLE_MAPS_API_KEY is not configured');\n\t\t\t}\n\n\t\t\tconst params: Record<string, string> = {\n\t\t\t\tplace_id: placeId,\n\t\t\t\tfields: 'name,formatted_address,geometry,address_component',\n\t\t\t};\n\t\t\tif (sessionToken) params.sessiontoken = sessionToken;\n\n\t\t\tconst result = await this.client.callGoogleMapsAPI('place/details', apiKey, params);\n\n\t\t\tif (result.status === 'OK') {\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, 604800);\n\t\t\t\tthis.logger.logger.info('Google Place Details cached successfully', { cacheKey, placeId });\n\t\t\t} else {\n\t\t\t\tthis.logger.logger.warn('Google Place Details returned non-OK status', {\n\t\t\t\t\tstatus: result.status,\n\t\t\t\t\terrorMessage: result.error_message,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result as GooglePlaceDetailsResponse;\n\t\t} catch (error) {\n\t\t\tthis.logger.logger.error('Google Place Details failed', { input, error });\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async getReverseGeocode(input: GoogleReverseGeocodeInputDTO): Promise<GoogleReverseGeocodeResponse> {\n\t\tconst { latitude, longitude } = input;\n\t\tif (!latitude || !longitude) {\n\t\t\tthis.logger.logger.error('Google Reverse Geocode failed: missing coordinates', { latitude, longitude });\n\t\t\tthrow new Error('Missing latitude or longitude');\n\t\t}\n\n\t\tconst roundedLat = parseFloat(latitude).toFixed(4);\n\t\tconst roundedLng = parseFloat(longitude).toFixed(4);\n\t\tconst cacheKey = `maps:geocode:${roundedLat}:${roundedLng}`;\n\n\t\ttry {\n\t\t\tconst cached = await this.redisService.getCachedObject<GoogleReverseGeocodeResponse>(cacheKey);\n\t\t\tif (cached !== undefined) {\n\t\t\t\tthis.logger.logger.info('Google Reverse Geocode Cache HIT', { cacheKey, roundedLat, roundedLng });\n\t\t\t\treturn cached;\n\t\t\t}\n\n\t\t\tthis.logger.logger.info('Google Reverse Geocode Cache MISS - Calling API', {\n\t\t\t\tcacheKey,\n\t\t\t\tlatitude,\n\t\t\t\tlongitude,\n\t\t\t});\n\n\t\t\tconst apiKey = await this.secretManager.getKey('GOOGLE_MAPS_API_KEY');\n\t\t\tif (!apiKey) {\n\t\t\t\tthis.logger.logger.error('GOOGLE_MAPS_API_KEY is missing in SecretManager');\n\t\t\t\tthrow new Error('GOOGLE_MAPS_API_KEY is not configured');\n\t\t\t}\n\n\t\t\tconst params = { latlng: `${latitude},${longitude}` };\n\n\t\t\tconst result = await this.client.callGoogleMapsAPI('geocode', apiKey, params);\n\n\t\t\tif (result.status === 'OK') {\n\t\t\t\t/* redis cache create\n\t\t\t\tawait this.redisService.cacheObject(cacheKey, result, 259200);\n\t\t\t\tthis.logger.logger.info('Google Reverse Geocode cached successfully', {\n\t\t\t\t\tcacheKey,\n\t\t\t\t\tresultsCount: result.results?.length ?? 0,\n\t\t\t\t});\n\t\t\t\t*/\n\t\t\t} else {\n\t\t\t\tthis.logger.logger.warn('Google Reverse Geocode returned non-OK status', {\n\t\t\t\t\tstatus: result.status,\n\t\t\t\t\terrorMessage: result.error_message,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn result as GoogleReverseGeocodeResponse;\n\t\t} catch (error) {\n\t\t\tthis.logger.logger.error('Google Reverse Geocode failed', { input, error });\n\t\t\tthrow error;\n\t\t}\n\t}\n}\n"]}
|
|
@@ -48,9 +48,9 @@ class OpenAICompletionProvider {
|
|
|
48
48
|
}
|
|
49
49
|
async generateSearchVariantsChunksInBatch(items, model, instructions, options) {
|
|
50
50
|
const finalModel = model ?? this.model;
|
|
51
|
-
const chunkSize = options?.chunkSize ??
|
|
51
|
+
const chunkSize = options?.chunkSize ?? 25;
|
|
52
52
|
const maxArabic = options?.maxArabic ?? 1;
|
|
53
|
-
const maxArabizi = options?.maxArabizi ??
|
|
53
|
+
const maxArabizi = options?.maxArabizi ?? 1;
|
|
54
54
|
const maxTransliteration = options?.maxTransliteration ?? 1;
|
|
55
55
|
const itemsToSend = items.filter(i => !i.skipAutoTranslation);
|
|
56
56
|
const skippedItems = items.filter(i => i.skipAutoTranslation);
|
|
@@ -109,6 +109,7 @@ class OpenAICompletionProvider {
|
|
|
109
109
|
const outputByChunk = await this.readJsonlFile(batch.output_file_id);
|
|
110
110
|
const errorsByChunk = await this.readJsonlFile(batch.error_file_id);
|
|
111
111
|
const resultsById = new Map();
|
|
112
|
+
let chunkParseFailures = 0;
|
|
112
113
|
for (const [chunkId, record] of outputByChunk.entries()) {
|
|
113
114
|
const body = record?.response?.body;
|
|
114
115
|
const outputText = body?.output_text ??
|
|
@@ -140,10 +141,19 @@ class OpenAICompletionProvider {
|
|
|
140
141
|
});
|
|
141
142
|
}
|
|
142
143
|
}
|
|
143
|
-
catch {
|
|
144
|
-
|
|
144
|
+
catch (parseErr) {
|
|
145
|
+
chunkParseFailures++;
|
|
146
|
+
console.error(`generateSearchVariantsChunksInBatch: failed to parse output for ${chunkId}`, {
|
|
147
|
+
error: parseErr,
|
|
148
|
+
outputTextLength: outputText.length,
|
|
149
|
+
outputTextPreview: outputText.slice(0, 2000),
|
|
150
|
+
outputTextTail: outputText.slice(-500),
|
|
151
|
+
});
|
|
145
152
|
}
|
|
146
153
|
}
|
|
154
|
+
if (chunkParseFailures) {
|
|
155
|
+
console.error(`generateSearchVariantsChunksInBatch: ${chunkParseFailures}/${chunks.length} chunks failed to parse entirely — every item in those chunks will show as missing from LLM output below.`);
|
|
156
|
+
}
|
|
147
157
|
const missingIds = itemsToSend.filter(i => !resultsById.has(i.id)).map(i => i.id);
|
|
148
158
|
if (missingIds.length) {
|
|
149
159
|
console.error(`generateSearchVariantsChunksInBatch: ${missingIds.length}/${itemsToSend.length} items missing from LLM output`, missingIds);
|
|
@@ -152,7 +162,7 @@ class OpenAICompletionProvider {
|
|
|
152
162
|
const r = resultsById.get(id);
|
|
153
163
|
if (!r) {
|
|
154
164
|
console.error(`generateSearchVariantsChunksInBatch: no result for itemId=${id}`);
|
|
155
|
-
return { id, original: text,
|
|
165
|
+
return { id, original: text, isProcessingFailed: true, isEmpty: true };
|
|
156
166
|
}
|
|
157
167
|
return { id, original: text, ...r };
|
|
158
168
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-provider.js","sourceRoot":"/","sources":["libraries/llm/providers/openai-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenAI, { toFile } from 'openai';\nimport { IAICompletionProvider, ItemTextInput, TextVariantResult } from '../interfaces/common-llm-interfaces';\n\nexport class OpenAICompletionProvider implements IAICompletionProvider {\n\tprivate readonly client: OpenAI;\n\tprivate readonly model: string;\n\tprivate readonly ARABIC_CHAR_REGEX = /[\\u0600-\\u06FF]/;\n\n\tconstructor(apiKey: string | undefined, model: string = 'gpt-5-nano') {\n\t\tif (!apiKey) {\n\t\t\tthrow new Error('OPENAI_API_KEY is required to construct OpenAICompletionProvider');\n\t\t}\n\t\tthis.client = new OpenAI({ apiKey });\n\t\tthis.model = model;\n\t}\n\n\t// ── Cost-optimized batch path ────────────────────────────────────\n\t// Implements everything discussed:\n\t// 1. Chunking — groups items (default 200/chunk) into one line per\n\t// chunk, so `instructions` is billed once per chunk instead of\n\t// once per item (biggest single cost lever).\n\t// 2. Short output keys — model emits {id, ar, az, tr} instead of\n\t// {id, arabic, arabizi, arabicTransliteration}; mapped back\n\t// to full field names locally, at zero token cost.\n\t// 3. Capped array lengths — schema enforces maxItems (not just a\n\t// prose suggestion), so the model can't drift to longer arrays.\n\t// 4. No echoed fields — model never re-emits id/original text;\n\t// both are re-attached locally from the input you already have.\n\tasync generateSearchVariantsChunksInBatch(\n\t\titems: ItemTextInput[],\n\t\tmodel?: string,\n\t\tinstructions?: string,\n\t\toptions?: {\n\t\t\tchunkSize?: number;\n\t\t\tmaxArabic?: number;\n\t\t\tmaxArabizi?: number;\n\t\t\tmaxTransliteration?: number;\n\t\t\tpollIntervalMs?: number;\n\t\t\tmaxWaitMs?: number;\n\t\t}\n\t): Promise<TextVariantResult[]> {\n\t\tconst finalModel = model ?? this.model;\n\t\tconst chunkSize = options?.chunkSize ?? 200;\n\t\tconst maxArabic = options?.maxArabic ?? 1;\n\t\tconst maxArabizi = options?.maxArabizi ?? 2;\n\t\tconst maxTransliteration = options?.maxTransliteration ?? 1;\n\n\t\t// Items explicitly opted out — never sent to the model, just passed through.\n\t\tconst itemsToSend = items.filter(i => !i.skipAutoTranslation);\n\t\tconst skippedItems = items.filter(i => i.skipAutoTranslation);\n\n\t\tif (skippedItems.length) {\n\t\t\tconsole.log(\n\t\t\t\t`generateSearchVariantsChunksInBatch: skipping ${skippedItems.length}/${items.length} items due to skipAutoTranslation=true`\n\t\t\t);\n\t\t}\n\n\t\t// Nothing left to actually send — short-circuit before touching the OpenAI API at all.\n\t\tif (!itemsToSend.length) {\n\t\t\t// return skippedItems.map(({ id, text }) => ({ id, original: text, skipped: true }));\n\t\t\treturn [];\n\t\t}\n\n\t\ttry {\n\t\t\tconst finalInstructions =\n\t\t\t\tinstructions ?? this.buildOptimizedInstructions({ maxArabic, maxArabizi, maxTransliteration });\n\n\t\t\tconst chunkSchema = this.buildOptimizedChunkSchema({ maxArabic, maxArabizi, maxTransliteration });\n\n\t\t\tconst chunks = this.chunkItems(itemsToSend, chunkSize);\n\n\t\t\tif (chunks.length > 50_000) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Too many chunks (${chunks.length}) for a single batch file — increase chunkSize or split into multiple batch submissions.`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`generateSearchVariantsChunksInBatch: model=${finalModel} items=${itemsToSend.length} (${skippedItems.length} skipped) chunkSize=${chunkSize} chunks=${chunks.length}`\n\t\t\t);\n\n\t\t\t// 1. Build JSONL — ONE line per chunk, not per item\n\t\t\tconst jsonl = chunks\n\t\t\t\t.map((chunkItems, i) =>\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\tcustom_id: `chunk-${i}`,\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\turl: '/v1/responses',\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tmodel: finalModel,\n\t\t\t\t\t\t\tinstructions: finalInstructions,\n\t\t\t\t\t\t\tinput: JSON.stringify(chunkItems.map(({ id, text }) => ({ id: id, text }))),\n\t\t\t\t\t\t\ttext: {\n\t\t\t\t\t\t\t\tformat: {\n\t\t\t\t\t\t\t\t\ttype: 'json_schema',\n\t\t\t\t\t\t\t\t\tname: 'text_variants_batch',\n\t\t\t\t\t\t\t\t\tschema: chunkSchema,\n\t\t\t\t\t\t\t\t\tstrict: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t\t.join('\\n');\n\n\t\t\t// 2. Upload input file\n\t\t\tconst inputFile = await this.client.files.create({\n\t\t\t\tfile: await toFile(Buffer.from(jsonl, 'utf-8'), 'batch-input-optimized.jsonl'),\n\t\t\t\tpurpose: 'batch',\n\t\t\t});\n\n\t\t\t// 3. Create batch job\n\t\t\tlet batch = await this.client.batches.create({\n\t\t\t\tinput_file_id: inputFile.id,\n\t\t\t\tendpoint: '/v1/responses',\n\t\t\t\tcompletion_window: '24h',\n\t\t\t});\n\n\t\t\t// 4. Poll until done\n\t\t\tbatch = await this.pollBatch(batch.id, options?.pollIntervalMs, options?.maxWaitMs);\n\n\t\t\tconsole.log({\n\t\t\t\tstatus: batch.status,\n\t\t\t\trequest_counts: batch.request_counts,\n\t\t\t\terrors: batch.errors,\n\t\t\t});\n\n\t\t\tif (batch.status !== 'completed') {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Batch ${batch.id} ended with status \"${batch.status}\" (${batch.request_counts?.failed ?? 0} failed)`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// 5. Parse output\n\t\t\tconst outputByChunk = await this.readJsonlFile(batch.output_file_id);\n\t\t\tconst errorsByChunk = await this.readJsonlFile(batch.error_file_id);\n\n\t\t\t// 6. Flatten chunk results into a per-itemId map\n\t\t\tconst resultsById = new Map<string, Partial<TextVariantResult>>();\n\n\t\t\tfor (const [chunkId, record] of outputByChunk.entries()) {\n\t\t\t\tconst body = record?.response?.body;\n\t\t\t\tconst outputText =\n\t\t\t\t\tbody?.output_text ??\n\t\t\t\t\tbody?.output\n\t\t\t\t\t\t?.find((o: any) => o.type === 'message')\n\t\t\t\t\t\t?.content?.find((c: any) => c.type === 'output_text')?.text;\n\n\t\t\t\tif (!outputText) {\n\t\t\t\t\tconst err = errorsByChunk.get(chunkId);\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`generateSearchVariantsChunksInBatch: no output for ${chunkId}`,\n\t\t\t\t\t\terr ?? record?.error\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst parsed = JSON.parse(outputText) as {\n\t\t\t\t\t\tresults: Array<{ id: string; ar: string[]; az: string[]; tr: string[] }>;\n\t\t\t\t\t};\n\t\t\t\t\tfor (const r of parsed.results) {\n\t\t\t\t\t\tconst ar = this.sanitizeArabicArray(r.ar);\n\t\t\t\t\t\tconst tr = this.sanitizeArabicArray(r.tr);\n\t\t\t\t\t\tconst az = this.sanitizeLatinArray(r.az);\n\n\t\t\t\t\t\tconst isEmpty = this.isEmptyValue(r.ar) || this.isEmptyValue(r.az) || this.isEmptyValue(r.tr);\n\t\t\t\t\t\tconst isProcessingFailed = (!ar.length && !tr.length) || !az.length;\n\n\t\t\t\t\t\tif (isProcessingFailed) {\n\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t`generateSearchVariantsChunksInBatch: marking id=${r.id} as processingFailed — ar=${JSON.stringify(r.ar)} az=${JSON.stringify(r.az)} tr=${JSON.stringify(r.tr)}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresultsById.set(r.id, {\n\t\t\t\t\t\t\tarabic: ar,\n\t\t\t\t\t\t\tarabizi: az,\n\t\t\t\t\t\t\tarabicTransliteration: tr,\n\t\t\t\t\t\t\tisProcessingFailed,\n\t\t\t\t\t\t\tisEmpty,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`generateSearchVariantsChunksInBatch: failed to parse output for ${chunkId}`,\n\t\t\t\t\t\toutputText\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// 7. Surface items the model silently dropped (only checked against what we actually sent)\n\t\t\tconst missingIds = itemsToSend.filter(i => !resultsById.has(i.id)).map(i => i.id);\n\t\t\tif (missingIds.length) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`generateSearchVariantsChunksInBatch: ${missingIds.length}/${itemsToSend.length} items missing from LLM output`,\n\t\t\t\t\tmissingIds\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// 8. Merge back with the FULL original item list — skipped items pass through untouched,\n\t\t\t// everything else is looked up in resultsById.\n\t\t\treturn items.map(({ id, text }) => {\n\t\t\t\tconst r = resultsById.get(id);\n\t\t\t\tif (!r) {\n\t\t\t\t\tconsole.error(`generateSearchVariantsChunksInBatch: no result for itemId=${id}`);\n\t\t\t\t\treturn { id, original: text, processingFailed: true, isEmpty: true };\n\t\t\t\t}\n\t\t\t\treturn { id, original: text, ...r } as TextVariantResult;\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error('generateSearchVariantsChunksInBatch failed', {\n\t\t\t\terror,\n\t\t\t\titemCount: itemsToSend.length,\n\t\t\t\tmodel: finalModel,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// ── Helpers ──────────────────────────────────────────────────────\n\n\t// Keeps only entries that actually contain Arabic-script characters — used for `ar`/`tr`,\n\t// which must never contain the raw English/Latin text the model was given.\n\tprivate sanitizeArabicArray(values: string[] | undefined): string[] {\n\t\treturn (values ?? []).filter(v => typeof v === 'string' && v.trim() && this.ARABIC_CHAR_REGEX.test(v));\n\t}\n\n\t// Keeps only entries that do NOT contain Arabic-script characters — used for `az`\n\t// (Latin/Arabizi variants), which must never contain Arabic script.\n\tprivate sanitizeLatinArray(values: string[] | undefined): string[] {\n\t\treturn (values ?? []).filter(v => typeof v === 'string' && v.trim() && !this.ARABIC_CHAR_REGEX.test(v));\n\t}\n\n\t// Compact instructions for the optimized path: short-key output format,\n\t// explicit array caps stated in prose (schema also enforces them),\n\t// and an explicit \"no commentary inside values\" rule to stop the model\n\t// padding fields with parenthetical notes.\n\tprivate buildOptimizedInstructions(caps: {\n\t\tmaxArabic: number;\n\t\tmaxArabizi: number;\n\t\tmaxTransliteration: number;\n\t}): string {\n\t\treturn [\n\t\t\t'You generate search-name variants for a food delivery app product/shop name.',\n\t\t\t'You will receive a JSON array of items, each with \"id\" and \"text\".',\n\t\t\t'For EACH item, return an object with:',\n\t\t\t`- id: the exact id provided (unchanged)`,\n\t\t\t`- ar: Arabic translation(s) in Arabic script, max ${caps.maxArabic}.`,\n\t\t\t`- az: Arabizi spelling(s) (Latin script/numerals, e.g. \"zaytoon\"), max ${caps.maxArabizi}.`,\n\t\t\t`- tr: Arabic-script transliteration(s) of the original word (not translated), max ${caps.maxTransliteration}.`,\n\t\t\t'Return one result per input item, same order, no items skipped or merged.',\n\t\t\t'Values must contain only the term itself — no parenthetical notes, no commentary.',\n\t\t\t'Return strict JSON matching the schema. No extra commentary, no extra fields.',\n\t\t].join('\\n');\n\t}\n\n\t// Schema for the OPTIMIZED chunk path: wraps a `results` array (one\n\t// entry per item in the chunk), short keys, and hard maxItems caps.\n\tprivate buildOptimizedChunkSchema(caps: {\n\t\tmaxArabic: number;\n\t\tmaxArabizi: number;\n\t\tmaxTransliteration: number;\n\t}) {\n\t\treturn {\n\t\t\ttype: 'object',\n\t\t\tproperties: {\n\t\t\t\tresults: {\n\t\t\t\t\ttype: 'array',\n\t\t\t\t\titems: {\n\t\t\t\t\t\ttype: 'object',\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tid: { type: 'string' },\n\t\t\t\t\t\t\tar: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: caps.maxArabic },\n\t\t\t\t\t\t\taz: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: caps.maxArabizi },\n\t\t\t\t\t\t\ttr: {\n\t\t\t\t\t\t\t\ttype: 'array',\n\t\t\t\t\t\t\t\titems: { type: 'string' },\n\t\t\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\t\t\tmaxItems: caps.maxTransliteration,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequired: ['id', 'ar', 'az', 'tr'],\n\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\trequired: ['results'],\n\t\t\tadditionalProperties: false,\n\t\t};\n\t}\n\n\tprivate chunkItems<T>(items: T[], size: number): T[][] {\n\t\tconst out: T[][] = [];\n\t\tfor (let i = 0; i < items.length; i += size) {\n\t\t\tout.push(items.slice(i, i + size));\n\t\t}\n\t\treturn out;\n\t}\n\n\tprivate async pollBatch(\n\t\tbatchId: string,\n\t\tintervalMs = 5000,\n\t\tmaxWaitMs = 24 * 60 * 60 * 1000\n\t): Promise<OpenAI.Batches.Batch> {\n\t\tconst terminal = new Set(['completed', 'failed', 'expired', 'cancelled']);\n\t\tconst start = Date.now();\n\n\t\twhile (true) {\n\t\t\tconst batch = await this.client.batches.retrieve(batchId);\n\t\t\tconsole.log(\n\t\t\t\t`pollBatch: ${batchId} status=${batch.status} elapsed=${Math.round((Date.now() - start) / 1000)}s`\n\t\t\t);\n\t\t\tif (terminal.has(batch.status)) return batch;\n\n\t\t\tif (Date.now() - start > maxWaitMs) {\n\t\t\t\tthrow new Error(`Batch ${batchId} did not finish within ${maxWaitMs}ms (status: ${batch.status})`);\n\t\t\t}\n\n\t\t\tawait new Promise(resolve => setTimeout(resolve, intervalMs));\n\t\t}\n\t}\n\n\tprivate async readJsonlFile(fileId: string | null | undefined): Promise<Map<string, any>> {\n\t\tconst result = new Map<string, any>();\n\t\tif (!fileId) return result;\n\n\t\tconst fileResponse = await this.client.files.content(fileId);\n\t\tconst text = await fileResponse.text();\n\n\t\tfor (const line of text.split('\\n').filter(Boolean)) {\n\t\t\tconst record = JSON.parse(line);\n\t\t\tresult.set(record.custom_id, record);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// Checks whether ar/az/tr came back empty in any sense the model might produce:\n\t// missing entirely (null/undefined), an empty array, or an array whose entries\n\t// are just empty/whitespace strings.\n\tprivate isEmptyValue(values: string[] | null | undefined): boolean {\n\t\tif (!values || values.length === 0) return true;\n\t\treturn values.every(v => typeof v !== 'string' || !v.trim());\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"openai-provider.js","sourceRoot":"/","sources":["libraries/llm/providers/openai-provider.ts"],"names":[],"mappings":"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","sourcesContent":["import OpenAI, { toFile } from 'openai';\nimport { IAICompletionProvider, ItemTextInput, TextVariantResult } from '../interfaces/common-llm-interfaces';\n\nexport class OpenAICompletionProvider implements IAICompletionProvider {\n\tprivate readonly client: OpenAI;\n\tprivate readonly model: string;\n\tprivate readonly ARABIC_CHAR_REGEX = /[\\u0600-\\u06FF]/;\n\n\tconstructor(apiKey: string | undefined, model: string = 'gpt-5-nano') {\n\t\tif (!apiKey) {\n\t\t\tthrow new Error('OPENAI_API_KEY is required to construct OpenAICompletionProvider');\n\t\t}\n\t\tthis.client = new OpenAI({ apiKey });\n\t\tthis.model = model;\n\t}\n\n\t// ── Cost-optimized batch path ────────────────────────────────────\n\t// Implements everything discussed:\n\t// 1. Chunking — groups items (default 25/chunk — kept small so a single\n\t// malformed/truncated model response only takes out a small slice of\n\t// items instead of ~100+ at once) into one line per chunk, so\n\t// `instructions` is billed once per chunk instead of once per item.\n\t// 2. Short output keys — model emits {id, ar, az, tr} instead of\n\t// {id, arabic, arabizi, arabicTransliteration}; mapped back\n\t// to full field names locally, at zero token cost.\n\t// 3. Capped array lengths — schema enforces maxItems (not just a\n\t// prose suggestion), so the model can't drift to longer arrays.\n\t// 4. No echoed fields — model never re-emits id/original text;\n\t// both are re-attached locally from the input you already have.\n\tasync generateSearchVariantsChunksInBatch(\n\t\titems: ItemTextInput[],\n\t\tmodel?: string,\n\t\tinstructions?: string,\n\t\toptions?: {\n\t\t\tchunkSize?: number;\n\t\t\tmaxArabic?: number;\n\t\t\tmaxArabizi?: number;\n\t\t\tmaxTransliteration?: number;\n\t\t\tpollIntervalMs?: number;\n\t\t\tmaxWaitMs?: number;\n\t\t}\n\t): Promise<TextVariantResult[]> {\n\t\tconst finalModel = model ?? this.model;\n\t\t// Kept intentionally small — large chunks (100+) risk the model truncating or\n\t\t// malforming output for the WHOLE chunk, which drops every item in it at once.\n\t\tconst chunkSize = options?.chunkSize ?? 25;\n\t\tconst maxArabic = options?.maxArabic ?? 1;\n\t\t// Reduced from 2 → 1 by default: fewer required strings per item means less total\n\t\t// output per chunk, which lowers the chance of hitting a truncation/formatting issue.\n\t\tconst maxArabizi = options?.maxArabizi ?? 1;\n\t\tconst maxTransliteration = options?.maxTransliteration ?? 1;\n\n\t\t// Items explicitly opted out — never sent to the model, just passed through.\n\t\tconst itemsToSend = items.filter(i => !i.skipAutoTranslation);\n\t\tconst skippedItems = items.filter(i => i.skipAutoTranslation);\n\n\t\tif (skippedItems.length) {\n\t\t\tconsole.log(\n\t\t\t\t`generateSearchVariantsChunksInBatch: skipping ${skippedItems.length}/${items.length} items due to skipAutoTranslation=true`\n\t\t\t);\n\t\t}\n\n\t\t// Nothing left to actually send — short-circuit before touching the OpenAI API at all.\n\t\tif (!itemsToSend.length) {\n\t\t\treturn [];\n\t\t}\n\n\t\ttry {\n\t\t\tconst finalInstructions =\n\t\t\t\tinstructions ?? this.buildOptimizedInstructions({ maxArabic, maxArabizi, maxTransliteration });\n\n\t\t\tconst chunkSchema = this.buildOptimizedChunkSchema({ maxArabic, maxArabizi, maxTransliteration });\n\n\t\t\tconst chunks = this.chunkItems(itemsToSend, chunkSize);\n\n\t\t\tif (chunks.length > 50_000) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Too many chunks (${chunks.length}) for a single batch file — increase chunkSize or split into multiple batch submissions.`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconsole.log(\n\t\t\t\t`generateSearchVariantsChunksInBatch: model=${finalModel} items=${itemsToSend.length} (${skippedItems.length} skipped) chunkSize=${chunkSize} chunks=${chunks.length}`\n\t\t\t);\n\n\t\t\t// 1. Build JSONL — ONE line per chunk, not per item\n\t\t\tconst jsonl = chunks\n\t\t\t\t.map((chunkItems, i) =>\n\t\t\t\t\tJSON.stringify({\n\t\t\t\t\t\tcustom_id: `chunk-${i}`,\n\t\t\t\t\t\tmethod: 'POST',\n\t\t\t\t\t\turl: '/v1/responses',\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tmodel: finalModel,\n\t\t\t\t\t\t\tinstructions: finalInstructions,\n\t\t\t\t\t\t\tinput: JSON.stringify(chunkItems.map(({ id, text }) => ({ id: id, text }))),\n\t\t\t\t\t\t\ttext: {\n\t\t\t\t\t\t\t\tformat: {\n\t\t\t\t\t\t\t\t\ttype: 'json_schema',\n\t\t\t\t\t\t\t\t\tname: 'text_variants_batch',\n\t\t\t\t\t\t\t\t\tschema: chunkSchema,\n\t\t\t\t\t\t\t\t\tstrict: true,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t\t.join('\\n');\n\n\t\t\t// 2. Upload input file\n\t\t\tconst inputFile = await this.client.files.create({\n\t\t\t\tfile: await toFile(Buffer.from(jsonl, 'utf-8'), 'batch-input-optimized.jsonl'),\n\t\t\t\tpurpose: 'batch',\n\t\t\t});\n\n\t\t\t// 3. Create batch job\n\t\t\tlet batch = await this.client.batches.create({\n\t\t\t\tinput_file_id: inputFile.id,\n\t\t\t\tendpoint: '/v1/responses',\n\t\t\t\tcompletion_window: '24h',\n\t\t\t});\n\n\t\t\t// 4. Poll until done\n\t\t\tbatch = await this.pollBatch(batch.id, options?.pollIntervalMs, options?.maxWaitMs);\n\n\t\t\tconsole.log({\n\t\t\t\tstatus: batch.status,\n\t\t\t\trequest_counts: batch.request_counts,\n\t\t\t\terrors: batch.errors,\n\t\t\t});\n\n\t\t\tif (batch.status !== 'completed') {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Batch ${batch.id} ended with status \"${batch.status}\" (${batch.request_counts?.failed ?? 0} failed)`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// 5. Parse output\n\t\t\tconst outputByChunk = await this.readJsonlFile(batch.output_file_id);\n\t\t\tconst errorsByChunk = await this.readJsonlFile(batch.error_file_id);\n\n\t\t\t// 6. Flatten chunk results into a per-itemId map\n\t\t\tconst resultsById = new Map<string, Partial<TextVariantResult>>();\n\t\t\tlet chunkParseFailures = 0;\n\n\t\t\tfor (const [chunkId, record] of outputByChunk.entries()) {\n\t\t\t\tconst body = record?.response?.body;\n\t\t\t\tconst outputText =\n\t\t\t\t\tbody?.output_text ??\n\t\t\t\t\tbody?.output\n\t\t\t\t\t\t?.find((o: any) => o.type === 'message')\n\t\t\t\t\t\t?.content?.find((c: any) => c.type === 'output_text')?.text;\n\n\t\t\t\tif (!outputText) {\n\t\t\t\t\tconst err = errorsByChunk.get(chunkId);\n\t\t\t\t\tconsole.error(\n\t\t\t\t\t\t`generateSearchVariantsChunksInBatch: no output for ${chunkId}`,\n\t\t\t\t\t\terr ?? record?.error\n\t\t\t\t\t);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\ttry {\n\t\t\t\t\tconst parsed = JSON.parse(outputText) as {\n\t\t\t\t\t\tresults: Array<{ id: string; ar: string[]; az: string[]; tr: string[] }>;\n\t\t\t\t\t};\n\t\t\t\t\tfor (const r of parsed.results) {\n\t\t\t\t\t\tconst ar = this.sanitizeArabicArray(r.ar);\n\t\t\t\t\t\tconst tr = this.sanitizeArabicArray(r.tr);\n\t\t\t\t\t\tconst az = this.sanitizeLatinArray(r.az);\n\n\t\t\t\t\t\tconst isEmpty = this.isEmptyValue(r.ar) || this.isEmptyValue(r.az) || this.isEmptyValue(r.tr);\n\t\t\t\t\t\tconst isProcessingFailed = (!ar.length && !tr.length) || !az.length;\n\n\t\t\t\t\t\tif (isProcessingFailed) {\n\t\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t\t`generateSearchVariantsChunksInBatch: marking id=${r.id} as processingFailed — ar=${JSON.stringify(r.ar)} az=${JSON.stringify(r.az)} tr=${JSON.stringify(r.tr)}`\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tresultsById.set(r.id, {\n\t\t\t\t\t\t\tarabic: ar,\n\t\t\t\t\t\t\tarabizi: az,\n\t\t\t\t\t\t\tarabicTransliteration: tr,\n\t\t\t\t\t\t\tisProcessingFailed,\n\t\t\t\t\t\t\tisEmpty,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} catch (parseErr) {\n\t\t\t\t\tchunkParseFailures++;\n\t\t\t\t\t// Log a preview + length of the raw output so you can tell WHY it failed —\n\t\t\t\t\t// truncated mid-JSON (hit output length) vs. malformed/extra text vs. something else.\n\t\t\t\t\tconsole.error(`generateSearchVariantsChunksInBatch: failed to parse output for ${chunkId}`, {\n\t\t\t\t\t\terror: parseErr,\n\t\t\t\t\t\toutputTextLength: outputText.length,\n\t\t\t\t\t\toutputTextPreview: outputText.slice(0, 2000),\n\t\t\t\t\t\toutputTextTail: outputText.slice(-500),\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (chunkParseFailures) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`generateSearchVariantsChunksInBatch: ${chunkParseFailures}/${chunks.length} chunks failed to parse entirely — every item in those chunks will show as missing from LLM output below.`\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// 7. Surface items the model silently dropped (only checked against what we actually sent)\n\t\t\tconst missingIds = itemsToSend.filter(i => !resultsById.has(i.id)).map(i => i.id);\n\t\t\tif (missingIds.length) {\n\t\t\t\tconsole.error(\n\t\t\t\t\t`generateSearchVariantsChunksInBatch: ${missingIds.length}/${itemsToSend.length} items missing from LLM output`,\n\t\t\t\t\tmissingIds\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// 8. Merge back with the FULL original item list — skipped items pass through untouched,\n\t\t\t// everything else is looked up in resultsById.\n\t\t\treturn items.map(({ id, text }) => {\n\t\t\t\tconst r = resultsById.get(id);\n\t\t\t\tif (!r) {\n\t\t\t\t\tconsole.error(`generateSearchVariantsChunksInBatch: no result for itemId=${id}`);\n\t\t\t\t\t// NOTE: key must be isProcessingFailed (matches the shape set above and what\n\t\t\t\t\t// hasAnyFailedField/isFieldUsable check downstream) — a prior version of this\n\t\t\t\t\t// fallback used `processingFailed` (wrong key), which meant callers saw\n\t\t\t\t\t// isProcessingFailed=undefined for every dropped item instead of true.\n\t\t\t\t\treturn { id, original: text, isProcessingFailed: true, isEmpty: true };\n\t\t\t\t}\n\t\t\t\treturn { id, original: text, ...r } as TextVariantResult;\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tconsole.error('generateSearchVariantsChunksInBatch failed', {\n\t\t\t\terror,\n\t\t\t\titemCount: itemsToSend.length,\n\t\t\t\tmodel: finalModel,\n\t\t\t});\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\t// ── Helpers ──────────────────────────────────────────────────────\n\n\t// Keeps only entries that actually contain Arabic-script characters — used for `ar`/`tr`,\n\t// which must never contain the raw English/Latin text the model was given.\n\tprivate sanitizeArabicArray(values: string[] | undefined): string[] {\n\t\treturn (values ?? []).filter(v => typeof v === 'string' && v.trim() && this.ARABIC_CHAR_REGEX.test(v));\n\t}\n\n\t// Keeps only entries that do NOT contain Arabic-script characters — used for `az`\n\t// (Latin/Arabizi variants), which must never contain Arabic script.\n\tprivate sanitizeLatinArray(values: string[] | undefined): string[] {\n\t\treturn (values ?? []).filter(v => typeof v === 'string' && v.trim() && !this.ARABIC_CHAR_REGEX.test(v));\n\t}\n\n\t// Compact instructions for the optimized path: short-key output format,\n\t// explicit array caps stated in prose (schema also enforces them),\n\t// and an explicit \"no commentary inside values\" rule to stop the model\n\t// padding fields with parenthetical notes.\n\tprivate buildOptimizedInstructions(caps: {\n\t\tmaxArabic: number;\n\t\tmaxArabizi: number;\n\t\tmaxTransliteration: number;\n\t}): string {\n\t\treturn [\n\t\t\t'You generate search-name variants for a food delivery app product/shop name.',\n\t\t\t'You will receive a JSON array of items, each with \"id\" and \"text\".',\n\t\t\t'For EACH item, return an object with:',\n\t\t\t`- id: the exact id provided (unchanged)`,\n\t\t\t`- ar: Arabic translation(s) in Arabic script, max ${caps.maxArabic}.`,\n\t\t\t`- az: Arabizi spelling(s) (Latin script/numerals, e.g. \"zaytoon\"), max ${caps.maxArabizi}.`,\n\t\t\t`- tr: Arabic-script transliteration(s) of the original word (not translated), max ${caps.maxTransliteration}.`,\n\t\t\t'Return one result per input item, same order, no items skipped or merged.',\n\t\t\t'Values must contain only the term itself — no parenthetical notes, no commentary.',\n\t\t\t'Return strict JSON matching the schema. No extra commentary, no extra fields.',\n\t\t].join('\\n');\n\t}\n\n\t// Schema for the OPTIMIZED chunk path: wraps a `results` array (one\n\t// entry per item in the chunk), short keys, and hard maxItems caps.\n\tprivate buildOptimizedChunkSchema(caps: {\n\t\tmaxArabic: number;\n\t\tmaxArabizi: number;\n\t\tmaxTransliteration: number;\n\t}) {\n\t\treturn {\n\t\t\ttype: 'object',\n\t\t\tproperties: {\n\t\t\t\tresults: {\n\t\t\t\t\ttype: 'array',\n\t\t\t\t\titems: {\n\t\t\t\t\t\ttype: 'object',\n\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\tid: { type: 'string' },\n\t\t\t\t\t\t\tar: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: caps.maxArabic },\n\t\t\t\t\t\t\taz: { type: 'array', items: { type: 'string' }, minItems: 1, maxItems: caps.maxArabizi },\n\t\t\t\t\t\t\ttr: {\n\t\t\t\t\t\t\t\ttype: 'array',\n\t\t\t\t\t\t\t\titems: { type: 'string' },\n\t\t\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\t\t\tmaxItems: caps.maxTransliteration,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\trequired: ['id', 'ar', 'az', 'tr'],\n\t\t\t\t\t\tadditionalProperties: false,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\trequired: ['results'],\n\t\t\tadditionalProperties: false,\n\t\t};\n\t}\n\n\tprivate chunkItems<T>(items: T[], size: number): T[][] {\n\t\tconst out: T[][] = [];\n\t\tfor (let i = 0; i < items.length; i += size) {\n\t\t\tout.push(items.slice(i, i + size));\n\t\t}\n\t\treturn out;\n\t}\n\n\tprivate async pollBatch(\n\t\tbatchId: string,\n\t\tintervalMs = 5000,\n\t\tmaxWaitMs = 24 * 60 * 60 * 1000\n\t): Promise<OpenAI.Batches.Batch> {\n\t\tconst terminal = new Set(['completed', 'failed', 'expired', 'cancelled']);\n\t\tconst start = Date.now();\n\n\t\twhile (true) {\n\t\t\tconst batch = await this.client.batches.retrieve(batchId);\n\t\t\tconsole.log(\n\t\t\t\t`pollBatch: ${batchId} status=${batch.status} elapsed=${Math.round((Date.now() - start) / 1000)}s`\n\t\t\t);\n\t\t\tif (terminal.has(batch.status)) return batch;\n\n\t\t\tif (Date.now() - start > maxWaitMs) {\n\t\t\t\tthrow new Error(`Batch ${batchId} did not finish within ${maxWaitMs}ms (status: ${batch.status})`);\n\t\t\t}\n\n\t\t\tawait new Promise(resolve => setTimeout(resolve, intervalMs));\n\t\t}\n\t}\n\n\tprivate async readJsonlFile(fileId: string | null | undefined): Promise<Map<string, any>> {\n\t\tconst result = new Map<string, any>();\n\t\tif (!fileId) return result;\n\n\t\tconst fileResponse = await this.client.files.content(fileId);\n\t\tconst text = await fileResponse.text();\n\n\t\tfor (const line of text.split('\\n').filter(Boolean)) {\n\t\t\tconst record = JSON.parse(line);\n\t\t\tresult.set(record.custom_id, record);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// Checks whether ar/az/tr came back empty in any sense the model might produce:\n\t// missing entirely (null/undefined), an empty array, or an array whose entries\n\t// are just empty/whitespace strings.\n\tprivate isEmptyValue(values: string[] | null | undefined): boolean {\n\t\tif (!values || values.length === 0) return true;\n\t\treturn values.every(v => typeof v !== 'string' || !v.trim());\n\t}\n}\n"]}
|
|
@@ -2,7 +2,12 @@ import { Ref } from '@typegoose/typegoose';
|
|
|
2
2
|
import { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';
|
|
3
3
|
import { User } from './user.model';
|
|
4
4
|
import { Shop } from './shop.model';
|
|
5
|
+
export declare class ShopOrderCount {
|
|
6
|
+
shop: Ref<Shop>;
|
|
7
|
+
count: number;
|
|
8
|
+
lastOrderedAt: Date;
|
|
9
|
+
}
|
|
5
10
|
export declare class UserShopHistory extends TimeStamps {
|
|
6
11
|
user: Ref<User>;
|
|
7
|
-
shops
|
|
12
|
+
shops: ShopOrderCount[];
|
|
8
13
|
}
|
|
@@ -9,11 +9,29 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.UserShopHistory = void 0;
|
|
12
|
+
exports.UserShopHistory = exports.ShopOrderCount = void 0;
|
|
13
13
|
const typegoose_1 = require("@typegoose/typegoose");
|
|
14
14
|
const defaultClasses_1 = require("@typegoose/typegoose/lib/defaultClasses");
|
|
15
15
|
const user_model_1 = require("./user.model");
|
|
16
16
|
const shop_model_1 = require("./shop.model");
|
|
17
|
+
class ShopOrderCount {
|
|
18
|
+
shop;
|
|
19
|
+
count;
|
|
20
|
+
lastOrderedAt;
|
|
21
|
+
}
|
|
22
|
+
exports.ShopOrderCount = ShopOrderCount;
|
|
23
|
+
__decorate([
|
|
24
|
+
(0, typegoose_1.prop)({ required: true, ref: () => shop_model_1.Shop }),
|
|
25
|
+
__metadata("design:type", Object)
|
|
26
|
+
], ShopOrderCount.prototype, "shop", void 0);
|
|
27
|
+
__decorate([
|
|
28
|
+
(0, typegoose_1.prop)({ required: true, type: Number, default: 1 }),
|
|
29
|
+
__metadata("design:type", Number)
|
|
30
|
+
], ShopOrderCount.prototype, "count", void 0);
|
|
31
|
+
__decorate([
|
|
32
|
+
(0, typegoose_1.prop)({ required: true, type: Date, default: Date.now }),
|
|
33
|
+
__metadata("design:type", Date)
|
|
34
|
+
], ShopOrderCount.prototype, "lastOrderedAt", void 0);
|
|
17
35
|
let UserShopHistory = class UserShopHistory extends defaultClasses_1.TimeStamps {
|
|
18
36
|
user;
|
|
19
37
|
shops;
|
|
@@ -24,11 +42,12 @@ __decorate([
|
|
|
24
42
|
__metadata("design:type", Object)
|
|
25
43
|
], UserShopHistory.prototype, "user", void 0);
|
|
26
44
|
__decorate([
|
|
27
|
-
(0, typegoose_1.prop)({
|
|
45
|
+
(0, typegoose_1.prop)({ type: () => [ShopOrderCount], default: [] }),
|
|
28
46
|
__metadata("design:type", Array)
|
|
29
47
|
], UserShopHistory.prototype, "shops", void 0);
|
|
30
48
|
exports.UserShopHistory = UserShopHistory = __decorate([
|
|
31
49
|
(0, typegoose_1.modelOptions)({ schemaOptions: { collection: 'userShopHistories' } }),
|
|
32
|
-
(0, typegoose_1.index)({ user: 1 }, { unique: true })
|
|
50
|
+
(0, typegoose_1.index)({ user: 1 }, { unique: true }),
|
|
51
|
+
(0, typegoose_1.index)({ 'shops.shop': 1 })
|
|
33
52
|
], UserShopHistory);
|
|
34
53
|
//# sourceMappingURL=user-shop-history.model.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-shop-history.model.js","sourceRoot":"/","sources":["libraries/mongo/models/user-shop-history.model.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAsE;AACtE,4EAAqE;AACrE,6CAAoC;AACpC,6CAAoC;
|
|
1
|
+
{"version":3,"file":"user-shop-history.model.js","sourceRoot":"/","sources":["libraries/mongo/models/user-shop-history.model.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,oDAAsE;AACtE,4EAAqE;AACrE,6CAAoC;AACpC,6CAAoC;AAEpC,MAAa,cAAc;IAEnB,IAAI,CAAa;IAGjB,KAAK,CAAU;IAGf,aAAa,CAAQ;CAC5B;AATD,wCASC;AAPO;IADN,IAAA,gBAAI,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,iBAAI,EAAE,CAAC;;4CAClB;AAGjB;IADN,IAAA,gBAAI,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;;6CAC7B;AAGf;IADN,IAAA,gBAAI,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;8BACjC,IAAI;qDAAC;AAStB,IAAM,eAAe,GAArB,MAAM,eAAgB,SAAQ,2BAAU;IAEvC,IAAI,CAAa;IAGjB,KAAK,CAAoB;CAChC,CAAA;AANY,0CAAe;AAEpB;IADN,IAAA,gBAAI,EAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,iBAAI,EAAE,CAAC;;6CAClB;AAGjB;IADN,IAAA,gBAAI,EAAC,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;;8CACpB;0BALpB,eAAe;IAH3B,IAAA,wBAAY,EAAC,EAAE,aAAa,EAAE,EAAE,UAAU,EAAE,mBAAmB,EAAE,EAAE,CAAC;IACpE,IAAA,iBAAK,EAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACpC,IAAA,iBAAK,EAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;GACd,eAAe,CAM3B","sourcesContent":["import { index, modelOptions, prop, Ref } from '@typegoose/typegoose';\nimport { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses';\nimport { User } from './user.model';\nimport { Shop } from './shop.model';\n\nexport class ShopOrderCount {\n\t@prop({ required: true, ref: () => Shop })\n\tpublic shop!: Ref<Shop>;\n\n\t@prop({ required: true, type: Number, default: 1 })\n\tpublic count!: number;\n\n\t@prop({ required: true, type: Date, default: Date.now })\n\tpublic lastOrderedAt!: Date;\n}\n\n/**\n * UserShopHistory model - Tracks the shops a user is associated with (eligible/ordered-from shops)\n */\n@modelOptions({ schemaOptions: { collection: 'userShopHistories' } })\n@index({ user: 1 }, { unique: true })\n@index({ 'shops.shop': 1 })\nexport class UserShopHistory extends TimeStamps {\n\t@prop({ required: true, ref: () => User })\n\tpublic user!: Ref<User>;\n\n\t@prop({ type: () => [ShopOrderCount], default: [] })\n\tpublic shops!: ShopOrderCount[];\n}\n"]}
|
|
@@ -20,13 +20,13 @@ export declare const ChatroomMessageSendOutputSchema: z.ZodObject<{
|
|
|
20
20
|
name: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
21
21
|
type: z.ZodNativeEnum<typeof UserRef>;
|
|
22
22
|
}, "strip", z.ZodTypeAny, {
|
|
23
|
-
type: UserRef;
|
|
24
23
|
name: string;
|
|
25
24
|
id: import("mongoose").Types.ObjectId;
|
|
26
|
-
}, {
|
|
27
25
|
type: UserRef;
|
|
26
|
+
}, {
|
|
28
27
|
name: string;
|
|
29
28
|
id: import("mongoose").Types.ObjectId;
|
|
29
|
+
type: UserRef;
|
|
30
30
|
}>;
|
|
31
31
|
content: z.ZodOptional<z.ZodString> | z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
32
32
|
media: z.ZodArray<z.ZodObject<{
|
|
@@ -36,14 +36,14 @@ export declare const ChatroomMessageSendOutputSchema: z.ZodObject<{
|
|
|
36
36
|
thumbnailUrl: z.ZodOptional<z.ZodString> | z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
37
37
|
name: z.ZodOptional<z.ZodString> | z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
38
38
|
}, "strip", z.ZodTypeAny, {
|
|
39
|
-
mediaUrl: string;
|
|
40
39
|
mediaType: MediaType;
|
|
40
|
+
mediaUrl: string;
|
|
41
41
|
mimeType: string;
|
|
42
42
|
name?: string | undefined;
|
|
43
43
|
thumbnailUrl?: string | undefined;
|
|
44
44
|
}, {
|
|
45
|
-
mediaUrl: string;
|
|
46
45
|
mediaType: MediaType;
|
|
46
|
+
mediaUrl: string;
|
|
47
47
|
mimeType: string;
|
|
48
48
|
name?: string | undefined;
|
|
49
49
|
thumbnailUrl?: string | undefined;
|
|
@@ -63,17 +63,17 @@ export declare const ChatroomMessageSendOutputSchema: z.ZodObject<{
|
|
|
63
63
|
orderId: z.ZodOptional<z.ZodEffects<z.ZodType<import("mongoose").Types.ObjectId, z.ZodTypeDef, import("mongoose").Types.ObjectId>, import("mongoose").Types.ObjectId, import("mongoose").Types.ObjectId>>;
|
|
64
64
|
createdAt: z.ZodEffects<z.ZodEffects<z.ZodDate, Date, Date>, Date, Date>;
|
|
65
65
|
}, "strip", z.ZodTypeAny, {
|
|
66
|
-
_id: import("mongoose").Types.ObjectId;
|
|
67
66
|
createdAt: Date;
|
|
67
|
+
_id: import("mongoose").Types.ObjectId;
|
|
68
68
|
sender: {
|
|
69
|
-
type: UserRef;
|
|
70
69
|
name: string;
|
|
71
70
|
id: import("mongoose").Types.ObjectId;
|
|
71
|
+
type: UserRef;
|
|
72
72
|
};
|
|
73
73
|
senderType: UserRef;
|
|
74
74
|
media: {
|
|
75
|
-
mediaUrl: string;
|
|
76
75
|
mediaType: MediaType;
|
|
76
|
+
mediaUrl: string;
|
|
77
77
|
mimeType: string;
|
|
78
78
|
name?: string | undefined;
|
|
79
79
|
thumbnailUrl?: string | undefined;
|
|
@@ -89,17 +89,17 @@ export declare const ChatroomMessageSendOutputSchema: z.ZodObject<{
|
|
|
89
89
|
content?: string | undefined;
|
|
90
90
|
chatroomId?: import("mongoose").Types.ObjectId | undefined;
|
|
91
91
|
}, {
|
|
92
|
-
_id: import("mongoose").Types.ObjectId;
|
|
93
92
|
createdAt: Date;
|
|
93
|
+
_id: import("mongoose").Types.ObjectId;
|
|
94
94
|
sender: {
|
|
95
|
-
type: UserRef;
|
|
96
95
|
name: string;
|
|
97
96
|
id: import("mongoose").Types.ObjectId;
|
|
97
|
+
type: UserRef;
|
|
98
98
|
};
|
|
99
99
|
senderType: UserRef;
|
|
100
100
|
media: {
|
|
101
|
-
mediaUrl: string;
|
|
102
101
|
mediaType: MediaType;
|
|
102
|
+
mediaUrl: string;
|
|
103
103
|
mimeType: string;
|
|
104
104
|
name?: string | undefined;
|
|
105
105
|
thumbnailUrl?: string | undefined;
|
|
@@ -124,14 +124,14 @@ export declare const ChatroomMessageSendPushOutputSchema: z.ZodObject<{
|
|
|
124
124
|
}, "strip", z.ZodTypeAny, {
|
|
125
125
|
type: ChatroomType;
|
|
126
126
|
orderId?: import("mongoose").Types.ObjectId | undefined;
|
|
127
|
-
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
128
127
|
lastMessage?: string | undefined;
|
|
128
|
+
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
129
129
|
chatroomId?: import("mongoose").Types.ObjectId | undefined;
|
|
130
130
|
}, {
|
|
131
131
|
type: ChatroomType;
|
|
132
132
|
orderId?: import("mongoose").Types.ObjectId | undefined;
|
|
133
|
-
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
134
133
|
lastMessage?: string | undefined;
|
|
134
|
+
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
135
135
|
chatroomId?: import("mongoose").Types.ObjectId | undefined;
|
|
136
136
|
}>;
|
|
137
137
|
export type ChatlistMessageSendPushOutputDTO = DTO<typeof ChatroomMessageSendPushOutputSchema>;
|
|
@@ -156,13 +156,13 @@ export declare class ChatroomMessageSendSocketEvent extends BaseSocketEvent<type
|
|
|
156
156
|
name: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
157
157
|
type: z.ZodNativeEnum<typeof UserRef>;
|
|
158
158
|
}, "strip", z.ZodTypeAny, {
|
|
159
|
-
type: UserRef;
|
|
160
159
|
name: string;
|
|
161
160
|
id: import("mongoose").Types.ObjectId;
|
|
162
|
-
}, {
|
|
163
161
|
type: UserRef;
|
|
162
|
+
}, {
|
|
164
163
|
name: string;
|
|
165
164
|
id: import("mongoose").Types.ObjectId;
|
|
165
|
+
type: UserRef;
|
|
166
166
|
}>;
|
|
167
167
|
content: z.ZodOptional<z.ZodString> | z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
168
168
|
media: z.ZodArray<z.ZodObject<{
|
|
@@ -172,14 +172,14 @@ export declare class ChatroomMessageSendSocketEvent extends BaseSocketEvent<type
|
|
|
172
172
|
thumbnailUrl: z.ZodOptional<z.ZodString> | z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
173
173
|
name: z.ZodOptional<z.ZodString> | z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
174
174
|
}, "strip", z.ZodTypeAny, {
|
|
175
|
-
mediaUrl: string;
|
|
176
175
|
mediaType: MediaType;
|
|
176
|
+
mediaUrl: string;
|
|
177
177
|
mimeType: string;
|
|
178
178
|
name?: string | undefined;
|
|
179
179
|
thumbnailUrl?: string | undefined;
|
|
180
180
|
}, {
|
|
181
|
-
mediaUrl: string;
|
|
182
181
|
mediaType: MediaType;
|
|
182
|
+
mediaUrl: string;
|
|
183
183
|
mimeType: string;
|
|
184
184
|
name?: string | undefined;
|
|
185
185
|
thumbnailUrl?: string | undefined;
|
|
@@ -199,17 +199,17 @@ export declare class ChatroomMessageSendSocketEvent extends BaseSocketEvent<type
|
|
|
199
199
|
orderId: z.ZodOptional<z.ZodEffects<z.ZodType<import("mongoose").Types.ObjectId, z.ZodTypeDef, import("mongoose").Types.ObjectId>, import("mongoose").Types.ObjectId, import("mongoose").Types.ObjectId>>;
|
|
200
200
|
createdAt: z.ZodEffects<z.ZodEffects<z.ZodDate, Date, Date>, Date, Date>;
|
|
201
201
|
}, "strip", z.ZodTypeAny, {
|
|
202
|
-
_id: import("mongoose").Types.ObjectId;
|
|
203
202
|
createdAt: Date;
|
|
203
|
+
_id: import("mongoose").Types.ObjectId;
|
|
204
204
|
sender: {
|
|
205
|
-
type: UserRef;
|
|
206
205
|
name: string;
|
|
207
206
|
id: import("mongoose").Types.ObjectId;
|
|
207
|
+
type: UserRef;
|
|
208
208
|
};
|
|
209
209
|
senderType: UserRef;
|
|
210
210
|
media: {
|
|
211
|
-
mediaUrl: string;
|
|
212
211
|
mediaType: MediaType;
|
|
212
|
+
mediaUrl: string;
|
|
213
213
|
mimeType: string;
|
|
214
214
|
name?: string | undefined;
|
|
215
215
|
thumbnailUrl?: string | undefined;
|
|
@@ -225,17 +225,17 @@ export declare class ChatroomMessageSendSocketEvent extends BaseSocketEvent<type
|
|
|
225
225
|
content?: string | undefined;
|
|
226
226
|
chatroomId?: import("mongoose").Types.ObjectId | undefined;
|
|
227
227
|
}, {
|
|
228
|
-
_id: import("mongoose").Types.ObjectId;
|
|
229
228
|
createdAt: Date;
|
|
229
|
+
_id: import("mongoose").Types.ObjectId;
|
|
230
230
|
sender: {
|
|
231
|
-
type: UserRef;
|
|
232
231
|
name: string;
|
|
233
232
|
id: import("mongoose").Types.ObjectId;
|
|
233
|
+
type: UserRef;
|
|
234
234
|
};
|
|
235
235
|
senderType: UserRef;
|
|
236
236
|
media: {
|
|
237
|
-
mediaUrl: string;
|
|
238
237
|
mediaType: MediaType;
|
|
238
|
+
mediaUrl: string;
|
|
239
239
|
mimeType: string;
|
|
240
240
|
name?: string | undefined;
|
|
241
241
|
thumbnailUrl?: string | undefined;
|
|
@@ -260,14 +260,14 @@ export declare class ChatroomMessageSendSocketEvent extends BaseSocketEvent<type
|
|
|
260
260
|
}, "strip", z.ZodTypeAny, {
|
|
261
261
|
type: ChatroomType;
|
|
262
262
|
orderId?: import("mongoose").Types.ObjectId | undefined;
|
|
263
|
-
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
264
263
|
lastMessage?: string | undefined;
|
|
264
|
+
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
265
265
|
chatroomId?: import("mongoose").Types.ObjectId | undefined;
|
|
266
266
|
}, {
|
|
267
267
|
type: ChatroomType;
|
|
268
268
|
orderId?: import("mongoose").Types.ObjectId | undefined;
|
|
269
|
-
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
270
269
|
lastMessage?: string | undefined;
|
|
270
|
+
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
271
271
|
chatroomId?: import("mongoose").Types.ObjectId | undefined;
|
|
272
272
|
}>;
|
|
273
273
|
};
|
|
@@ -278,8 +278,8 @@ export declare class ChatroomMessageSendSocketEvent extends BaseSocketEvent<type
|
|
|
278
278
|
getPushNotificationPayload(): {
|
|
279
279
|
type: ChatroomType;
|
|
280
280
|
orderId?: import("mongoose").Types.ObjectId | undefined;
|
|
281
|
-
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
282
281
|
lastMessage?: string | undefined;
|
|
282
|
+
ticketId?: import("mongoose").Types.ObjectId | undefined;
|
|
283
283
|
chatroomId?: import("mongoose").Types.ObjectId | undefined;
|
|
284
284
|
} | undefined;
|
|
285
285
|
protected getIdentifier(): string;
|
|
@@ -16,11 +16,11 @@ export declare const OrderActionsOutputSchema: z.ZodObject<{
|
|
|
16
16
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, import("mongoose").Types.ObjectId, string>, z.ZodType<import("mongoose").Types.ObjectId, z.ZodTypeDef, import("mongoose").Types.ObjectId>]>;
|
|
17
17
|
name: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
18
18
|
}, "strip", z.ZodTypeAny, {
|
|
19
|
-
_id: import("mongoose").Types.ObjectId;
|
|
20
19
|
name: string;
|
|
20
|
+
_id: import("mongoose").Types.ObjectId;
|
|
21
21
|
}, {
|
|
22
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
23
22
|
name: string;
|
|
23
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
24
24
|
}>;
|
|
25
25
|
orderStatus: z.ZodNativeEnum<typeof RegularOrderStatus>;
|
|
26
26
|
orderAction: z.ZodNativeEnum<typeof OrderAction>;
|
|
@@ -39,20 +39,20 @@ export declare const OrderActionsOutputSchema: z.ZodObject<{
|
|
|
39
39
|
riderTips: z.ZodNumber;
|
|
40
40
|
secondaryRiderTips: z.ZodNumber;
|
|
41
41
|
}, "strip", z.ZodTypeAny, {
|
|
42
|
-
total: number;
|
|
43
42
|
deliveryFee: number;
|
|
44
43
|
secondaryDeliveryFee: number;
|
|
45
44
|
riderTips: number;
|
|
46
45
|
secondaryRiderTips: number;
|
|
46
|
+
total: number;
|
|
47
47
|
secondaryTotal: number;
|
|
48
48
|
paidAmount: number;
|
|
49
49
|
secondaryPaidAmount: number;
|
|
50
50
|
}, {
|
|
51
|
-
total: number;
|
|
52
51
|
deliveryFee: number;
|
|
53
52
|
secondaryDeliveryFee: number;
|
|
54
53
|
riderTips: number;
|
|
55
54
|
secondaryRiderTips: number;
|
|
55
|
+
total: number;
|
|
56
56
|
secondaryTotal: number;
|
|
57
57
|
paidAmount: number;
|
|
58
58
|
secondaryPaidAmount: number;
|
|
@@ -60,11 +60,11 @@ export declare const OrderActionsOutputSchema: z.ZodObject<{
|
|
|
60
60
|
}, "strip", z.ZodTypeAny, {
|
|
61
61
|
paymentMethod: PaymentMethod;
|
|
62
62
|
pricing: {
|
|
63
|
-
total: number;
|
|
64
63
|
deliveryFee: number;
|
|
65
64
|
secondaryDeliveryFee: number;
|
|
66
65
|
riderTips: number;
|
|
67
66
|
secondaryRiderTips: number;
|
|
67
|
+
total: number;
|
|
68
68
|
secondaryTotal: number;
|
|
69
69
|
paidAmount: number;
|
|
70
70
|
secondaryPaidAmount: number;
|
|
@@ -73,11 +73,11 @@ export declare const OrderActionsOutputSchema: z.ZodObject<{
|
|
|
73
73
|
}, {
|
|
74
74
|
paymentMethod: PaymentMethod;
|
|
75
75
|
pricing: {
|
|
76
|
-
total: number;
|
|
77
76
|
deliveryFee: number;
|
|
78
77
|
secondaryDeliveryFee: number;
|
|
79
78
|
riderTips: number;
|
|
80
79
|
secondaryRiderTips: number;
|
|
80
|
+
total: number;
|
|
81
81
|
secondaryTotal: number;
|
|
82
82
|
paidAmount: number;
|
|
83
83
|
secondaryPaidAmount: number;
|
|
@@ -88,59 +88,59 @@ export declare const OrderActionsOutputSchema: z.ZodObject<{
|
|
|
88
88
|
triggerAt: z.ZodEffects<z.ZodEffects<z.ZodDate, Date, Date>, Date, Date>;
|
|
89
89
|
orderActionType: z.ZodNativeEnum<typeof OrderAction>;
|
|
90
90
|
}, "strip", z.ZodTypeAny, {
|
|
91
|
-
_id: import("mongoose").Types.ObjectId;
|
|
92
91
|
createdAt: Date;
|
|
92
|
+
_id: import("mongoose").Types.ObjectId;
|
|
93
|
+
shopId: import("mongoose").Types.ObjectId;
|
|
93
94
|
user: {
|
|
94
|
-
_id: import("mongoose").Types.ObjectId;
|
|
95
95
|
name: string;
|
|
96
|
+
_id: import("mongoose").Types.ObjectId;
|
|
96
97
|
};
|
|
97
98
|
orderId: string;
|
|
98
|
-
shopId: import("mongoose").Types.ObjectId;
|
|
99
|
-
paymentMethod: PaymentMethod;
|
|
100
99
|
triggerAt: Date;
|
|
101
100
|
adjustedFinance: {
|
|
102
101
|
paymentMethod: PaymentMethod;
|
|
103
102
|
pricing: {
|
|
104
|
-
total: number;
|
|
105
103
|
deliveryFee: number;
|
|
106
104
|
secondaryDeliveryFee: number;
|
|
107
105
|
riderTips: number;
|
|
108
106
|
secondaryRiderTips: number;
|
|
107
|
+
total: number;
|
|
109
108
|
secondaryTotal: number;
|
|
110
109
|
paidAmount: number;
|
|
111
110
|
secondaryPaidAmount: number;
|
|
112
111
|
};
|
|
113
112
|
shopProfit: number;
|
|
114
113
|
};
|
|
114
|
+
paymentMethod: PaymentMethod;
|
|
115
115
|
orderActionType: OrderAction;
|
|
116
116
|
orderStatus: RegularOrderStatus;
|
|
117
117
|
orderAction: OrderAction;
|
|
118
118
|
preparationTimeMinutes: number;
|
|
119
119
|
}, {
|
|
120
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
121
120
|
createdAt: Date;
|
|
121
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
122
|
+
shopId: string | import("mongoose").Types.ObjectId;
|
|
122
123
|
user: {
|
|
123
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
124
124
|
name: string;
|
|
125
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
125
126
|
};
|
|
126
127
|
orderId: string;
|
|
127
|
-
shopId: string | import("mongoose").Types.ObjectId;
|
|
128
|
-
paymentMethod: PaymentMethod;
|
|
129
128
|
triggerAt: Date;
|
|
130
129
|
adjustedFinance: {
|
|
131
130
|
paymentMethod: PaymentMethod;
|
|
132
131
|
pricing: {
|
|
133
|
-
total: number;
|
|
134
132
|
deliveryFee: number;
|
|
135
133
|
secondaryDeliveryFee: number;
|
|
136
134
|
riderTips: number;
|
|
137
135
|
secondaryRiderTips: number;
|
|
136
|
+
total: number;
|
|
138
137
|
secondaryTotal: number;
|
|
139
138
|
paidAmount: number;
|
|
140
139
|
secondaryPaidAmount: number;
|
|
141
140
|
};
|
|
142
141
|
shopProfit: number;
|
|
143
142
|
};
|
|
143
|
+
paymentMethod: PaymentMethod;
|
|
144
144
|
orderActionType: OrderAction;
|
|
145
145
|
orderStatus: RegularOrderStatus;
|
|
146
146
|
orderAction: OrderAction;
|
|
@@ -160,11 +160,11 @@ export declare class OrderActionsSocketEvent extends BaseSocketEvent<typeof Orde
|
|
|
160
160
|
_id: z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, import("mongoose").Types.ObjectId, string>, z.ZodType<import("mongoose").Types.ObjectId, z.ZodTypeDef, import("mongoose").Types.ObjectId>]>;
|
|
161
161
|
name: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
162
162
|
}, "strip", z.ZodTypeAny, {
|
|
163
|
-
_id: import("mongoose").Types.ObjectId;
|
|
164
163
|
name: string;
|
|
164
|
+
_id: import("mongoose").Types.ObjectId;
|
|
165
165
|
}, {
|
|
166
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
167
166
|
name: string;
|
|
167
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
168
168
|
}>;
|
|
169
169
|
orderStatus: z.ZodNativeEnum<typeof RegularOrderStatus>;
|
|
170
170
|
orderAction: z.ZodNativeEnum<typeof OrderAction>;
|
|
@@ -183,20 +183,20 @@ export declare class OrderActionsSocketEvent extends BaseSocketEvent<typeof Orde
|
|
|
183
183
|
riderTips: z.ZodNumber;
|
|
184
184
|
secondaryRiderTips: z.ZodNumber;
|
|
185
185
|
}, "strip", z.ZodTypeAny, {
|
|
186
|
-
total: number;
|
|
187
186
|
deliveryFee: number;
|
|
188
187
|
secondaryDeliveryFee: number;
|
|
189
188
|
riderTips: number;
|
|
190
189
|
secondaryRiderTips: number;
|
|
190
|
+
total: number;
|
|
191
191
|
secondaryTotal: number;
|
|
192
192
|
paidAmount: number;
|
|
193
193
|
secondaryPaidAmount: number;
|
|
194
194
|
}, {
|
|
195
|
-
total: number;
|
|
196
195
|
deliveryFee: number;
|
|
197
196
|
secondaryDeliveryFee: number;
|
|
198
197
|
riderTips: number;
|
|
199
198
|
secondaryRiderTips: number;
|
|
199
|
+
total: number;
|
|
200
200
|
secondaryTotal: number;
|
|
201
201
|
paidAmount: number;
|
|
202
202
|
secondaryPaidAmount: number;
|
|
@@ -204,11 +204,11 @@ export declare class OrderActionsSocketEvent extends BaseSocketEvent<typeof Orde
|
|
|
204
204
|
}, "strip", z.ZodTypeAny, {
|
|
205
205
|
paymentMethod: PaymentMethod;
|
|
206
206
|
pricing: {
|
|
207
|
-
total: number;
|
|
208
207
|
deliveryFee: number;
|
|
209
208
|
secondaryDeliveryFee: number;
|
|
210
209
|
riderTips: number;
|
|
211
210
|
secondaryRiderTips: number;
|
|
211
|
+
total: number;
|
|
212
212
|
secondaryTotal: number;
|
|
213
213
|
paidAmount: number;
|
|
214
214
|
secondaryPaidAmount: number;
|
|
@@ -217,11 +217,11 @@ export declare class OrderActionsSocketEvent extends BaseSocketEvent<typeof Orde
|
|
|
217
217
|
}, {
|
|
218
218
|
paymentMethod: PaymentMethod;
|
|
219
219
|
pricing: {
|
|
220
|
-
total: number;
|
|
221
220
|
deliveryFee: number;
|
|
222
221
|
secondaryDeliveryFee: number;
|
|
223
222
|
riderTips: number;
|
|
224
223
|
secondaryRiderTips: number;
|
|
224
|
+
total: number;
|
|
225
225
|
secondaryTotal: number;
|
|
226
226
|
paidAmount: number;
|
|
227
227
|
secondaryPaidAmount: number;
|
|
@@ -232,59 +232,59 @@ export declare class OrderActionsSocketEvent extends BaseSocketEvent<typeof Orde
|
|
|
232
232
|
triggerAt: z.ZodEffects<z.ZodEffects<z.ZodDate, Date, Date>, Date, Date>;
|
|
233
233
|
orderActionType: z.ZodNativeEnum<typeof OrderAction>;
|
|
234
234
|
}, "strip", z.ZodTypeAny, {
|
|
235
|
-
_id: import("mongoose").Types.ObjectId;
|
|
236
235
|
createdAt: Date;
|
|
236
|
+
_id: import("mongoose").Types.ObjectId;
|
|
237
|
+
shopId: import("mongoose").Types.ObjectId;
|
|
237
238
|
user: {
|
|
238
|
-
_id: import("mongoose").Types.ObjectId;
|
|
239
239
|
name: string;
|
|
240
|
+
_id: import("mongoose").Types.ObjectId;
|
|
240
241
|
};
|
|
241
242
|
orderId: string;
|
|
242
|
-
shopId: import("mongoose").Types.ObjectId;
|
|
243
|
-
paymentMethod: PaymentMethod;
|
|
244
243
|
triggerAt: Date;
|
|
245
244
|
adjustedFinance: {
|
|
246
245
|
paymentMethod: PaymentMethod;
|
|
247
246
|
pricing: {
|
|
248
|
-
total: number;
|
|
249
247
|
deliveryFee: number;
|
|
250
248
|
secondaryDeliveryFee: number;
|
|
251
249
|
riderTips: number;
|
|
252
250
|
secondaryRiderTips: number;
|
|
251
|
+
total: number;
|
|
253
252
|
secondaryTotal: number;
|
|
254
253
|
paidAmount: number;
|
|
255
254
|
secondaryPaidAmount: number;
|
|
256
255
|
};
|
|
257
256
|
shopProfit: number;
|
|
258
257
|
};
|
|
258
|
+
paymentMethod: PaymentMethod;
|
|
259
259
|
orderActionType: OrderAction;
|
|
260
260
|
orderStatus: RegularOrderStatus;
|
|
261
261
|
orderAction: OrderAction;
|
|
262
262
|
preparationTimeMinutes: number;
|
|
263
263
|
}, {
|
|
264
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
265
264
|
createdAt: Date;
|
|
265
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
266
|
+
shopId: string | import("mongoose").Types.ObjectId;
|
|
266
267
|
user: {
|
|
267
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
268
268
|
name: string;
|
|
269
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
269
270
|
};
|
|
270
271
|
orderId: string;
|
|
271
|
-
shopId: string | import("mongoose").Types.ObjectId;
|
|
272
|
-
paymentMethod: PaymentMethod;
|
|
273
272
|
triggerAt: Date;
|
|
274
273
|
adjustedFinance: {
|
|
275
274
|
paymentMethod: PaymentMethod;
|
|
276
275
|
pricing: {
|
|
277
|
-
total: number;
|
|
278
276
|
deliveryFee: number;
|
|
279
277
|
secondaryDeliveryFee: number;
|
|
280
278
|
riderTips: number;
|
|
281
279
|
secondaryRiderTips: number;
|
|
280
|
+
total: number;
|
|
282
281
|
secondaryTotal: number;
|
|
283
282
|
paidAmount: number;
|
|
284
283
|
secondaryPaidAmount: number;
|
|
285
284
|
};
|
|
286
285
|
shopProfit: number;
|
|
287
286
|
};
|
|
287
|
+
paymentMethod: PaymentMethod;
|
|
288
288
|
orderActionType: OrderAction;
|
|
289
289
|
orderStatus: RegularOrderStatus;
|
|
290
290
|
orderAction: OrderAction;
|
|
@@ -19,18 +19,18 @@ export declare const RiderLocationUpdateSocketOutputSchema: z.ZodObject<{
|
|
|
19
19
|
bearing: z.ZodOptional<z.ZodNumber>;
|
|
20
20
|
updatedAt: z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, Date, string>, z.ZodDate]>, Date, string | Date>, Date, string | Date>;
|
|
21
21
|
}, "strip", z.ZodTypeAny, {
|
|
22
|
-
_id: import("mongoose").Types.ObjectId;
|
|
23
22
|
updatedAt: Date;
|
|
23
|
+
_id: import("mongoose").Types.ObjectId;
|
|
24
|
+
riderId: import("mongoose").Types.ObjectId;
|
|
24
25
|
latitude: number;
|
|
25
26
|
longitude: number;
|
|
26
|
-
riderId: import("mongoose").Types.ObjectId;
|
|
27
27
|
bearing?: number | undefined;
|
|
28
28
|
}, {
|
|
29
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
30
29
|
updatedAt: string | Date;
|
|
30
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
31
|
+
riderId: string | import("mongoose").Types.ObjectId;
|
|
31
32
|
latitude: number;
|
|
32
33
|
longitude: number;
|
|
33
|
-
riderId: string | import("mongoose").Types.ObjectId;
|
|
34
34
|
bearing?: number | undefined;
|
|
35
35
|
}>;
|
|
36
36
|
export type RiderLocationUpdateSocketInputDTO = DTO<typeof RiderLocationUpdateSocketInputSchema>;
|
|
@@ -55,18 +55,18 @@ export declare class RiderLocationUpdateSocketEvent extends BaseSocketEvent<type
|
|
|
55
55
|
bearing: z.ZodOptional<z.ZodNumber>;
|
|
56
56
|
updatedAt: z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, Date, string>, z.ZodDate]>, Date, string | Date>, Date, string | Date>;
|
|
57
57
|
}, "strip", z.ZodTypeAny, {
|
|
58
|
-
_id: import("mongoose").Types.ObjectId;
|
|
59
58
|
updatedAt: Date;
|
|
59
|
+
_id: import("mongoose").Types.ObjectId;
|
|
60
|
+
riderId: import("mongoose").Types.ObjectId;
|
|
60
61
|
latitude: number;
|
|
61
62
|
longitude: number;
|
|
62
|
-
riderId: import("mongoose").Types.ObjectId;
|
|
63
63
|
bearing?: number | undefined;
|
|
64
64
|
}, {
|
|
65
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
66
65
|
updatedAt: string | Date;
|
|
66
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
67
|
+
riderId: string | import("mongoose").Types.ObjectId;
|
|
67
68
|
latitude: number;
|
|
68
69
|
longitude: number;
|
|
69
|
-
riderId: string | import("mongoose").Types.ObjectId;
|
|
70
70
|
bearing?: number | undefined;
|
|
71
71
|
}>;
|
|
72
72
|
};
|
|
@@ -13,18 +13,18 @@ export declare const TicketActionsSocketOutputSchema: z.ZodObject<{
|
|
|
13
13
|
silent: z.ZodOptional<z.ZodBoolean>;
|
|
14
14
|
}, "strip", z.ZodTypeAny, {
|
|
15
15
|
status: TicketStatus;
|
|
16
|
-
type: TicketType;
|
|
17
16
|
_id: import("mongoose").Types.ObjectId;
|
|
18
|
-
|
|
17
|
+
type: TicketType;
|
|
19
18
|
title?: string | undefined;
|
|
20
19
|
content?: string | undefined;
|
|
20
|
+
silent?: boolean | undefined;
|
|
21
21
|
}, {
|
|
22
22
|
status: TicketStatus;
|
|
23
|
-
type: TicketType;
|
|
24
23
|
_id: import("mongoose").Types.ObjectId;
|
|
25
|
-
|
|
24
|
+
type: TicketType;
|
|
26
25
|
title?: string | undefined;
|
|
27
26
|
content?: string | undefined;
|
|
27
|
+
silent?: boolean | undefined;
|
|
28
28
|
}>;
|
|
29
29
|
export declare const TicketActionsPushOutputSchema: z.ZodObject<{
|
|
30
30
|
ticketId: z.ZodEffects<z.ZodType<import("mongoose").Types.ObjectId, z.ZodTypeDef, import("mongoose").Types.ObjectId>, import("mongoose").Types.ObjectId, import("mongoose").Types.ObjectId>;
|
|
@@ -60,18 +60,18 @@ export declare class TicketActionsSocketEvent extends BaseSocketEvent<typeof Tic
|
|
|
60
60
|
silent: z.ZodOptional<z.ZodBoolean>;
|
|
61
61
|
}, "strip", z.ZodTypeAny, {
|
|
62
62
|
status: TicketStatus;
|
|
63
|
-
type: TicketType;
|
|
64
63
|
_id: import("mongoose").Types.ObjectId;
|
|
65
|
-
|
|
64
|
+
type: TicketType;
|
|
66
65
|
title?: string | undefined;
|
|
67
66
|
content?: string | undefined;
|
|
67
|
+
silent?: boolean | undefined;
|
|
68
68
|
}, {
|
|
69
69
|
status: TicketStatus;
|
|
70
|
-
type: TicketType;
|
|
71
70
|
_id: import("mongoose").Types.ObjectId;
|
|
72
|
-
|
|
71
|
+
type: TicketType;
|
|
73
72
|
title?: string | undefined;
|
|
74
73
|
content?: string | undefined;
|
|
74
|
+
silent?: boolean | undefined;
|
|
75
75
|
}>;
|
|
76
76
|
pushNotificationOutput: z.ZodObject<{
|
|
77
77
|
ticketId: z.ZodEffects<z.ZodType<import("mongoose").Types.ObjectId, z.ZodTypeDef, import("mongoose").Types.ObjectId>, import("mongoose").Types.ObjectId, import("mongoose").Types.ObjectId>;
|
|
@@ -13,14 +13,14 @@ export declare const TicketAssignSocketOutputSchema: z.ZodObject<{
|
|
|
13
13
|
name: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
14
14
|
profilePhoto: z.ZodNullable<z.ZodString> | z.ZodNullable<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
15
15
|
}, "strip", z.ZodTypeAny, {
|
|
16
|
-
type: UserRef;
|
|
17
|
-
_id: import("mongoose").Types.ObjectId;
|
|
18
16
|
name: string;
|
|
17
|
+
_id: import("mongoose").Types.ObjectId;
|
|
18
|
+
type: UserRef;
|
|
19
19
|
profilePhoto: string | null;
|
|
20
20
|
}, {
|
|
21
|
-
type: UserRef;
|
|
22
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
23
21
|
name: string;
|
|
22
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
23
|
+
type: UserRef;
|
|
24
24
|
profilePhoto: string | null;
|
|
25
25
|
}>;
|
|
26
26
|
createdAt: z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, Date, string>, z.ZodDate]>, Date, string | Date>, Date, string | Date>;
|
|
@@ -40,40 +40,40 @@ export declare const TicketAssignSocketOutputSchema: z.ZodObject<{
|
|
|
40
40
|
unreadCount: z.ZodNumber;
|
|
41
41
|
}, "strip", z.ZodTypeAny, {
|
|
42
42
|
status: TicketStatus;
|
|
43
|
-
type: TicketType;
|
|
44
|
-
_id: import("mongoose").Types.ObjectId;
|
|
45
43
|
createdAt: Date;
|
|
46
44
|
updatedAt: Date;
|
|
45
|
+
_id: import("mongoose").Types.ObjectId;
|
|
46
|
+
type: TicketType;
|
|
47
47
|
lastMessage: {
|
|
48
48
|
createdAt: Date;
|
|
49
49
|
content: string;
|
|
50
50
|
};
|
|
51
|
-
unreadCount: number;
|
|
52
51
|
client: {
|
|
53
|
-
type: UserRef;
|
|
54
|
-
_id: import("mongoose").Types.ObjectId;
|
|
55
52
|
name: string;
|
|
53
|
+
_id: import("mongoose").Types.ObjectId;
|
|
54
|
+
type: UserRef;
|
|
56
55
|
profilePhoto: string | null;
|
|
57
56
|
};
|
|
57
|
+
unreadCount: number;
|
|
58
58
|
chatroomId: import("mongoose").Types.ObjectId;
|
|
59
59
|
orderId?: import("mongoose").Types.ObjectId | undefined;
|
|
60
60
|
}, {
|
|
61
61
|
status: TicketStatus;
|
|
62
|
-
type: TicketType;
|
|
63
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
64
62
|
createdAt: string | Date;
|
|
65
63
|
updatedAt: string | Date;
|
|
64
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
65
|
+
type: TicketType;
|
|
66
66
|
lastMessage: {
|
|
67
67
|
createdAt: string | Date;
|
|
68
68
|
content: string;
|
|
69
69
|
};
|
|
70
|
-
unreadCount: number;
|
|
71
70
|
client: {
|
|
72
|
-
type: UserRef;
|
|
73
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
74
71
|
name: string;
|
|
72
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
73
|
+
type: UserRef;
|
|
75
74
|
profilePhoto: string | null;
|
|
76
75
|
};
|
|
76
|
+
unreadCount: number;
|
|
77
77
|
chatroomId: string | import("mongoose").Types.ObjectId;
|
|
78
78
|
orderId?: string | import("mongoose").Types.ObjectId | undefined;
|
|
79
79
|
}>;
|
|
@@ -91,14 +91,14 @@ export declare class TicketAssignEvent extends BaseSocketEvent<typeof TicketAssi
|
|
|
91
91
|
name: z.ZodString | z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>;
|
|
92
92
|
profilePhoto: z.ZodNullable<z.ZodString> | z.ZodNullable<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
|
|
93
93
|
}, "strip", z.ZodTypeAny, {
|
|
94
|
-
type: UserRef;
|
|
95
|
-
_id: import("mongoose").Types.ObjectId;
|
|
96
94
|
name: string;
|
|
95
|
+
_id: import("mongoose").Types.ObjectId;
|
|
96
|
+
type: UserRef;
|
|
97
97
|
profilePhoto: string | null;
|
|
98
98
|
}, {
|
|
99
|
-
type: UserRef;
|
|
100
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
101
99
|
name: string;
|
|
100
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
101
|
+
type: UserRef;
|
|
102
102
|
profilePhoto: string | null;
|
|
103
103
|
}>;
|
|
104
104
|
createdAt: z.ZodEffects<z.ZodEffects<z.ZodUnion<[z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, Date, string>, z.ZodDate]>, Date, string | Date>, Date, string | Date>;
|
|
@@ -118,40 +118,40 @@ export declare class TicketAssignEvent extends BaseSocketEvent<typeof TicketAssi
|
|
|
118
118
|
unreadCount: z.ZodNumber;
|
|
119
119
|
}, "strip", z.ZodTypeAny, {
|
|
120
120
|
status: TicketStatus;
|
|
121
|
-
type: TicketType;
|
|
122
|
-
_id: import("mongoose").Types.ObjectId;
|
|
123
121
|
createdAt: Date;
|
|
124
122
|
updatedAt: Date;
|
|
123
|
+
_id: import("mongoose").Types.ObjectId;
|
|
124
|
+
type: TicketType;
|
|
125
125
|
lastMessage: {
|
|
126
126
|
createdAt: Date;
|
|
127
127
|
content: string;
|
|
128
128
|
};
|
|
129
|
-
unreadCount: number;
|
|
130
129
|
client: {
|
|
131
|
-
type: UserRef;
|
|
132
|
-
_id: import("mongoose").Types.ObjectId;
|
|
133
130
|
name: string;
|
|
131
|
+
_id: import("mongoose").Types.ObjectId;
|
|
132
|
+
type: UserRef;
|
|
134
133
|
profilePhoto: string | null;
|
|
135
134
|
};
|
|
135
|
+
unreadCount: number;
|
|
136
136
|
chatroomId: import("mongoose").Types.ObjectId;
|
|
137
137
|
orderId?: import("mongoose").Types.ObjectId | undefined;
|
|
138
138
|
}, {
|
|
139
139
|
status: TicketStatus;
|
|
140
|
-
type: TicketType;
|
|
141
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
142
140
|
createdAt: string | Date;
|
|
143
141
|
updatedAt: string | Date;
|
|
142
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
143
|
+
type: TicketType;
|
|
144
144
|
lastMessage: {
|
|
145
145
|
createdAt: string | Date;
|
|
146
146
|
content: string;
|
|
147
147
|
};
|
|
148
|
-
unreadCount: number;
|
|
149
148
|
client: {
|
|
150
|
-
type: UserRef;
|
|
151
|
-
_id: string | import("mongoose").Types.ObjectId;
|
|
152
149
|
name: string;
|
|
150
|
+
_id: string | import("mongoose").Types.ObjectId;
|
|
151
|
+
type: UserRef;
|
|
153
152
|
profilePhoto: string | null;
|
|
154
153
|
};
|
|
154
|
+
unreadCount: number;
|
|
155
155
|
chatroomId: string | import("mongoose").Types.ObjectId;
|
|
156
156
|
orderId?: string | import("mongoose").Types.ObjectId | undefined;
|
|
157
157
|
}>;
|
package/dist/types/README.md
CHANGED
package/dist/types/package.json
CHANGED