@runnerpro/backend 1.21.2 → 1.21.4
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/lib/cjs/translation/index.js +10 -1
- package/lib/cjs/types/translation/index.d.ts.map +1 -1
- package/lib/cjs/types/workout/estructuraWorkout.d.ts.map +1 -1
- package/lib/cjs/types/workout/saveWorkoutAplication.d.ts.map +1 -1
- package/lib/cjs/workout/estructuraWorkout.js +1 -7
- package/lib/cjs/workout/saveWorkoutAplication.js +13 -2
- package/package.json +1 -1
|
@@ -18,10 +18,19 @@ const common_1 = require("@runnerpro/common");
|
|
|
18
18
|
Object.defineProperty(exports, "LANGUAGES", { enumerable: true, get: function () { return common_1.LANGUAGES; } });
|
|
19
19
|
const fs_1 = __importDefault(require("fs"));
|
|
20
20
|
const index_1 = require("../db/index");
|
|
21
|
+
// Cliente singleton: instanciar TranslationServiceClient en cada llamada paga el
|
|
22
|
+
// coste de init (descubrimiento de credenciales/auth) por traducción. Se reutiliza
|
|
23
|
+
// un único cliente por proceso; es thread-safe para llamadas concurrentes.
|
|
24
|
+
let translationClientSingleton = null;
|
|
25
|
+
const getTranslationClient = () => {
|
|
26
|
+
if (!translationClientSingleton)
|
|
27
|
+
translationClientSingleton = new translate_1.TranslationServiceClient();
|
|
28
|
+
return translationClientSingleton;
|
|
29
|
+
};
|
|
21
30
|
const translate = (text, { fromLanguage, toLanguage }) => __awaiter(void 0, void 0, void 0, function* () {
|
|
22
31
|
const projectId = process.env.GCP_PROYECT_ID;
|
|
23
32
|
const location = 'global';
|
|
24
|
-
const translationClient =
|
|
33
|
+
const translationClient = getTranslationClient();
|
|
25
34
|
const request = {
|
|
26
35
|
parent: `projects/${projectId}/locations/${location}`,
|
|
27
36
|
contents: [text],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/translation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAI9C,KAAK,cAAc,GAAG,MAAM,OAAO,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/translation/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAI9C,KAAK,cAAc,GAAG,MAAM,OAAO,SAAS,CAAC;AAW7C,QAAA,MAAM,SAAS,SACP,MAAM;kBACkC,cAAc;gBAAc,cAAc;MACvF,QAAQ,MAAM,CAwBhB,CAAC;AAEF,QAAA,MAAM,cAAc,aAAc,MAAM,QAAQ,MAAM;cAExC,MAAM,iBAAiB,GAAG;CAkBvC,CAAC;AAEF,QAAA,MAAM,gCAAgC;;;;;;EA4BrC,CAAC;AAEF,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,gCAAgC,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"estructuraWorkout.d.ts","sourceRoot":"","sources":["../../../../src/workout/estructuraWorkout.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"estructuraWorkout.d.ts","sourceRoot":"","sources":["../../../../src/workout/estructuraWorkout.ts"],"names":[],"mappings":"AAsCA,QAAA,MAAM,mBAAmB,YAAa,GAAG,cAAc,GAAG,QAiCzD,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,QAAA,MAAM,wBAAwB,cAAqB,GAAG,kBAkBrD,CAAC;AAkPF,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"saveWorkoutAplication.d.ts","sourceRoot":"","sources":["../../../../src/workout/saveWorkoutAplication.ts"],"names":[],"mappings":"AAwPA;;;;;;;;;GASG;AACH,QAAA,MAAM,qBAAqB,SACnB,GAAG,UAED,GAAG,KACV,QAAQ,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"saveWorkoutAplication.d.ts","sourceRoot":"","sources":["../../../../src/workout/saveWorkoutAplication.ts"],"names":[],"mappings":"AAwPA;;;;;;;;;GASG;AACH,QAAA,MAAM,qBAAqB,SACnB,GAAG,UAED,GAAG,KACV,QAAQ,MAAM,GAAG,IAAI,CAsEvB,CAAC;AA+DF,OAAO,EAAE,qBAAqB,EAAE,CAAC"}
|
|
@@ -11,7 +11,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.saveDoneStructuraWorkout = exports.getStructuraWorkout = void 0;
|
|
13
13
|
const db_1 = require("../db");
|
|
14
|
-
const sendMail_1 = require("../sendMail");
|
|
15
14
|
const common_1 = require("@runnerpro/common");
|
|
16
15
|
const calculateZone = (values) => {
|
|
17
16
|
const percentage = Number(values.pacePercentage);
|
|
@@ -127,12 +126,7 @@ const saveDoneStructuraWorkoutWatch = (idWorkout, streamData, laps, workout, est
|
|
|
127
126
|
// Cualquier otra desviación es anómala (faltan laps en medio, doble extra,
|
|
128
127
|
// etc.) y se reporta para auditoría manual.
|
|
129
128
|
if (numPasos !== numLaps && numPasos !== numLaps + 1 && numLaps !== numPasos + 1) {
|
|
130
|
-
return
|
|
131
|
-
title: 'Estructura workout: laps no coinciden con pasos',
|
|
132
|
-
subject: 'Dedup cross-proveedor - Error saving steps structure workout',
|
|
133
|
-
body: JSON.stringify({ idWorkout, laps, estructura }),
|
|
134
|
-
to: ['david.jimenez@runnerpro.app'],
|
|
135
|
-
});
|
|
129
|
+
return;
|
|
136
130
|
}
|
|
137
131
|
for (let i = 0; i < estructura.length; i++) {
|
|
138
132
|
const row = estructura[i];
|
|
@@ -248,6 +248,16 @@ const saveWorkoutAplication = (opts,
|
|
|
248
248
|
_data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
249
249
|
const dateStr = (0, moment_1.default)(opts.date).format('YYYY-MM-DD');
|
|
250
250
|
const pt = predicadoTipo(opts);
|
|
251
|
+
// Traducción FUERA de la sección crítica. getTitleDescriptionTranslated hace
|
|
252
|
+
// una llamada de red a Google Cloud Translation; si se ejecutara dentro de
|
|
253
|
+
// `withTx` retendría el advisory lock durante todo el round-trip (causa de los
|
|
254
|
+
// picos de varios minutos en pg_advisory_xact_lock cuando la API va lenta).
|
|
255
|
+
// Sólo depende de idCliente/title/description —nada de la transacción— así que
|
|
256
|
+
// se calcula antes de abrir la tx. Semántica intacta: si la traducción falla,
|
|
257
|
+
// se propaga el error y el workout no se guarda, igual que antes. En las rutas
|
|
258
|
+
// de merge (1 y 2) el valor se descarta; el único sobrecoste es una traducción
|
|
259
|
+
// extra para clientes no-ES con doble proveedor, a cambio de no bloquear el lock.
|
|
260
|
+
const translated = yield (0, titleDescriptionTranslated_1.getTitleDescriptionTranslated)(opts.idCliente, opts.title, opts.description);
|
|
251
261
|
const idWorkout = yield withTx((q) => __awaiter(void 0, void 0, void 0, function* () {
|
|
252
262
|
// Lock anti-carrera: serializa ingestas del mismo cliente/día/bucket-tipo
|
|
253
263
|
// (Strava-webhook y Garmin-push pueden entrar casi a la vez).
|
|
@@ -276,8 +286,9 @@ _data) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
276
286
|
yield registrarFuente(q, sim.id, opts.aplicationType, opts.aplicationId);
|
|
277
287
|
return sim.id;
|
|
278
288
|
}
|
|
279
|
-
// 3) INSERT nuevo (comportamiento actual).
|
|
280
|
-
|
|
289
|
+
// 3) INSERT nuevo (comportamiento actual). La traducción ya se calculó antes
|
|
290
|
+
// de abrir la tx (ver `translated` arriba) para no retener el advisory lock.
|
|
291
|
+
const { title: titleNoTranslate, description: descriptionNoTranslate, titlePreferredLanguage, descriptionPreferredLanguage } = translated;
|
|
281
292
|
const inserted = yield q(`INSERT INTO "WORKOUT"
|
|
282
293
|
("ID CLIENTE", "DATE", "TITLE", "DESCRIPTION", "TITLE PREFERRED LANGUAGE", "DESCRIPTION PREFERRED LANGUAGE", "TYPE", "DONE", "SHOW CLIENT")
|
|
283
294
|
VALUES (?, ?, ?, ?, ?, ?, ?, TRUE, TRUE) RETURNING "ID"`, [opts.idCliente, dateStr, titleNoTranslate, descriptionNoTranslate, titlePreferredLanguage, descriptionPreferredLanguage, opts.type]);
|