@runnerpro/backend 1.21.12 → 1.21.14
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/achievements/catalog.js +204 -0
- package/lib/cjs/achievements/index.js +805 -0
- package/lib/cjs/achievements/streak.js +126 -0
- package/lib/cjs/chat/api/conversation.js +21 -29
- package/lib/cjs/chat/exposed/conversation.js +0 -7
- package/lib/cjs/chat/index.js +0 -7
- package/lib/cjs/index.js +34 -5
- package/lib/cjs/locale/en.js +0 -4
- package/lib/cjs/locale/es.js +0 -4
- package/lib/cjs/locale/fr.js +0 -4
- package/lib/cjs/locale/it.js +0 -4
- package/lib/cjs/prompt/azureModel.js +7 -35
- package/lib/cjs/prompt/constants.js +12 -67
- package/lib/cjs/prompt/googleModel.js +6 -11
- package/lib/cjs/prompt/index.js +1 -4
- package/lib/cjs/prompt/modelPricing.js +1 -22
- package/lib/cjs/sendNotification/index.js +4 -88
- package/lib/cjs/types/achievements/catalog.d.ts +104 -0
- package/lib/cjs/types/achievements/catalog.d.ts.map +1 -0
- package/lib/cjs/types/achievements/index.d.ts +41 -0
- package/lib/cjs/types/achievements/index.d.ts.map +1 -0
- package/lib/cjs/types/achievements/streak.d.ts +20 -0
- package/lib/cjs/types/achievements/streak.d.ts.map +1 -0
- package/lib/cjs/types/chat/api/conversation.d.ts.map +1 -1
- package/lib/cjs/types/chat/exposed/conversation.d.ts.map +1 -1
- package/lib/cjs/types/chat/index.d.ts.map +1 -1
- package/lib/cjs/types/index.d.ts +4 -2
- package/lib/cjs/types/index.d.ts.map +1 -1
- package/lib/cjs/types/locale/en.d.ts +0 -4
- package/lib/cjs/types/locale/en.d.ts.map +1 -1
- package/lib/cjs/types/locale/es.d.ts +0 -4
- package/lib/cjs/types/locale/es.d.ts.map +1 -1
- package/lib/cjs/types/locale/fr.d.ts +0 -4
- package/lib/cjs/types/locale/fr.d.ts.map +1 -1
- package/lib/cjs/types/locale/it.d.ts +0 -4
- package/lib/cjs/types/locale/it.d.ts.map +1 -1
- package/lib/cjs/types/prompt/azureModel.d.ts.map +1 -1
- package/lib/cjs/types/prompt/constants.d.ts +7 -28
- package/lib/cjs/types/prompt/constants.d.ts.map +1 -1
- package/lib/cjs/types/prompt/googleModel.d.ts.map +1 -1
- package/lib/cjs/types/prompt/index.d.ts +2 -2
- package/lib/cjs/types/prompt/index.d.ts.map +1 -1
- package/lib/cjs/types/prompt/modelPricing.d.ts.map +1 -1
- package/lib/cjs/types/sendNotification/index.d.ts +1 -20
- package/lib/cjs/types/sendNotification/index.d.ts.map +1 -1
- package/lib/cjs/types/workout/planificacionPrueba7dias/index.d.ts.map +1 -1
- package/lib/cjs/types/workout/saveWorkoutAplication.d.ts.map +1 -1
- package/lib/cjs/workout/planificacionPrueba7dias/index.js +7 -3
- package/lib/cjs/workout/saveWorkoutAplication.js +10 -0
- package/package.json +1 -1
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Catálogo de REGLAS de logros (umbrales). Vive en el paquete compartido para
|
|
4
|
+
* que lo usen tanto los hooks de evento (saveWorkoutAplication.postHooks y los
|
|
5
|
+
* eventos de Cliente-backend) como el backfill.
|
|
6
|
+
*
|
|
7
|
+
* Los `id` deben coincidir EXACTAMENTE con el catálogo de PRESENTACIÓN del
|
|
8
|
+
* frontend (Cliente-app/src/screens/PlanMap/utils/achievementCatalog.js).
|
|
9
|
+
* Frontend = labels/iconos/colores; aquí = umbrales/reglas.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.BRICK_TYPES = exports.RECOVERY_RUN_ZONE = exports.RECOVERY_RUN_DAYS = exports.STRENGTH_HABIT_WEEKS = exports.STRENGTH_WINDOWS = exports.PLAN_RACE_PACE_MIN_DISTANCE = exports.PLAN_RACE_PACE_TOLERANCE = exports.PLAN_LONG_RUN_MIN_DURATION = exports.PLAN_LONG_RUN_MIN_DISTANCE = exports.PLAN_RUN_TYPES = exports.PLAN_RACE_WEEK_DAYS = exports.PLAN_COMPLETE_ADHERENCE = exports.PLAN_BLOCK_ADHERENCE = exports.PLAN_ADHERENCE_82 = exports.PLAN_SESSION_TYPES = exports.WEARABLE_APPS = exports.NUTRITION_DAYS_THRESHOLD = exports.NUTRITION_MEALS = exports.CHAT_MSG = exports.TRI_SWIM_DISTANCE = exports.TRAIL_ELEVATION = exports.TRAIL_DISTANCE = exports.SWIM_DISTANCE = exports.CYCLING_VOLUME = exports.CYCLING_DISTANCE = exports.RACE_COUNT = exports.STRENGTH_COUNT = exports.PR_DISTANCE_BADGE = exports.PR_MANUAL_FLOOR = exports.PR_NO_STREAM_MARGIN = exports.TIME_PR = exports.PACE = exports.PR_DISTANCES = exports.RUNNING_TYPES = exports.VOLUME = exports.DISTANCE = exports.CONSISTENCY = void 0;
|
|
13
|
+
// ── Consistencia (racha por semanas, contra `longest`) ──────────────────────
|
|
14
|
+
exports.CONSISTENCY = [
|
|
15
|
+
{ id: 'consistency_1w', weeks: 1 },
|
|
16
|
+
{ id: 'consistency_2w', weeks: 2 },
|
|
17
|
+
{ id: 'consistency_4w', weeks: 4 },
|
|
18
|
+
{ id: 'consistency_8w', weeks: 8 },
|
|
19
|
+
{ id: 'consistency_12w', weeks: 12 },
|
|
20
|
+
{ id: 'consistency_26w', weeks: 26 },
|
|
21
|
+
{ id: 'consistency_52w', weeks: 52 },
|
|
22
|
+
{ id: 'consistency_104w', weeks: 104 },
|
|
23
|
+
{ id: 'consistency_156w', weeks: 156 },
|
|
24
|
+
];
|
|
25
|
+
// ── Distancia (máx distancia de un entreno de carrera, metros; cascada) ─────
|
|
26
|
+
exports.DISTANCE = [
|
|
27
|
+
{ id: 'dist_1k', meters: 1000 },
|
|
28
|
+
{ id: 'dist_2k', meters: 2000 },
|
|
29
|
+
{ id: 'dist_3k', meters: 3000 },
|
|
30
|
+
{ id: 'dist_5k', meters: 5000 },
|
|
31
|
+
{ id: 'dist_7k', meters: 7000 },
|
|
32
|
+
{ id: 'dist_10k', meters: 10000 },
|
|
33
|
+
{ id: 'dist_15k', meters: 15000 },
|
|
34
|
+
{ id: 'dist_21k', meters: 21000 },
|
|
35
|
+
{ id: 'dist_25k', meters: 25000 },
|
|
36
|
+
{ id: 'dist_30k', meters: 30000 },
|
|
37
|
+
{ id: 'dist_35k', meters: 35000 },
|
|
38
|
+
{ id: 'dist_42k', meters: 42000 },
|
|
39
|
+
{ id: 'dist_50k', meters: 50000 },
|
|
40
|
+
{ id: 'dist_100k', meters: 100000 },
|
|
41
|
+
];
|
|
42
|
+
// ── Volumen acumulado (suma km corridos desde el ancla) ─────────────────────
|
|
43
|
+
exports.VOLUME = [
|
|
44
|
+
{ id: 'vol_50', km: 50 },
|
|
45
|
+
{ id: 'vol_100', km: 100 },
|
|
46
|
+
{ id: 'vol_250', km: 250 },
|
|
47
|
+
{ id: 'vol_500', km: 500 },
|
|
48
|
+
{ id: 'vol_1000', km: 1000 },
|
|
49
|
+
{ id: 'vol_2500', km: 2500 },
|
|
50
|
+
{ id: 'vol_5000', km: 5000 },
|
|
51
|
+
{ id: 'vol_10000', km: 10000 },
|
|
52
|
+
{ id: 'vol_25000', km: 25000 },
|
|
53
|
+
];
|
|
54
|
+
// Tipos que cuentan como "carrera a pie" (mismos equivalentes que saveWorkoutAplication).
|
|
55
|
+
exports.RUNNING_TYPES = ['CORRER', 'TRAIL', 'COMPETICION'];
|
|
56
|
+
// ── Ritmo / PRs ─────────────────────────────────────────────────────────────
|
|
57
|
+
exports.PR_DISTANCES = [1000, 5000, 10000, 21097, 42195];
|
|
58
|
+
exports.PACE = [
|
|
59
|
+
{ id: 'pace_sub8', maxSecPerKm: 8 * 60 },
|
|
60
|
+
{ id: 'pace_sub7', maxSecPerKm: 7 * 60 },
|
|
61
|
+
{ id: 'pace_sub630', maxSecPerKm: 6 * 60 + 30 },
|
|
62
|
+
{ id: 'pace_sub6', maxSecPerKm: 6 * 60 },
|
|
63
|
+
{ id: 'pace_sub530', maxSecPerKm: 5 * 60 + 30 },
|
|
64
|
+
{ id: 'pace_sub5', maxSecPerKm: 5 * 60 },
|
|
65
|
+
];
|
|
66
|
+
exports.TIME_PR = [
|
|
67
|
+
{ id: 'pr_5k_sub30', distance: 5000, maxSeconds: 30 * 60 },
|
|
68
|
+
{ id: 'pr_5k_sub25', distance: 5000, maxSeconds: 25 * 60 },
|
|
69
|
+
{ id: 'pr_5k_sub20', distance: 5000, maxSeconds: 20 * 60 },
|
|
70
|
+
{ id: 'pr_10k_sub60', distance: 10000, maxSeconds: 60 * 60 },
|
|
71
|
+
{ id: 'pr_10k_sub50', distance: 10000, maxSeconds: 50 * 60 },
|
|
72
|
+
{ id: 'pr_10k_sub45', distance: 10000, maxSeconds: 45 * 60 },
|
|
73
|
+
{ id: 'pr_21k_sub2h', distance: 21097, maxSeconds: 120 * 60 },
|
|
74
|
+
{ id: 'pr_21k_sub145', distance: 21097, maxSeconds: 105 * 60 },
|
|
75
|
+
{ id: 'pr_21k_sub130', distance: 21097, maxSeconds: 90 * 60 },
|
|
76
|
+
{ id: 'pr_42k_sub4h', distance: 42195, maxSeconds: 240 * 60 },
|
|
77
|
+
{ id: 'pr_42k_sub330', distance: 42195, maxSeconds: 210 * 60 },
|
|
78
|
+
{ id: 'pr_42k_sub3h', distance: 42195, maxSeconds: 180 * 60 },
|
|
79
|
+
];
|
|
80
|
+
// Sin stream: cuenta como esfuerzo de X solo si distancia total ∈ [X, X*margen].
|
|
81
|
+
exports.PR_NO_STREAM_MARGIN = 1.05;
|
|
82
|
+
// Entrada MANUAL (sin stream): la app guarda la media/maratón redondeadas
|
|
83
|
+
// (21000/42000), no la distancia oficial (21097/42195). Sin esto, una media
|
|
84
|
+
// manual quedaría justo por debajo del oficial y NO contaría como PR. Este mapa
|
|
85
|
+
// "oficial → suelo manual aceptado" hace que se dé por hecho que 21000 = media y
|
|
86
|
+
// 42000 = maratón. NO afecta al camino con stream (Strava/Garmin), que sigue
|
|
87
|
+
// usando la distancia oficial con ventana deslizante. Solo aplica sin stream.
|
|
88
|
+
exports.PR_MANUAL_FLOOR = {
|
|
89
|
+
21097: 21000,
|
|
90
|
+
42195: 42000,
|
|
91
|
+
};
|
|
92
|
+
// Dónde se guarda el PR de cada distancia: en los PARAMS del logro de distancia
|
|
93
|
+
// correspondiente (modelo de tabla única). metros → LOGRO ID.
|
|
94
|
+
exports.PR_DISTANCE_BADGE = {
|
|
95
|
+
1000: 'dist_1k',
|
|
96
|
+
5000: 'dist_5k',
|
|
97
|
+
10000: 'dist_10k',
|
|
98
|
+
21097: 'dist_21k',
|
|
99
|
+
42195: 'dist_42k',
|
|
100
|
+
};
|
|
101
|
+
// ── Fuerza (conteo de sesiones FUERZA) ──────────────────────────────────────
|
|
102
|
+
exports.STRENGTH_COUNT = [
|
|
103
|
+
{ id: 'str_first', count: 1 },
|
|
104
|
+
{ id: 'str_10', count: 10 },
|
|
105
|
+
{ id: 'str_25', count: 25 },
|
|
106
|
+
{ id: 'str_50', count: 50 },
|
|
107
|
+
{ id: 'str_100', count: 100 },
|
|
108
|
+
{ id: 'str_250', count: 250 },
|
|
109
|
+
{ id: 'str_500', count: 500 },
|
|
110
|
+
];
|
|
111
|
+
// ── Post-carrera (COMPETICION completadas) ──────────────────────────────────
|
|
112
|
+
exports.RACE_COUNT = [
|
|
113
|
+
{ id: 'pc_finisher', count: 1 },
|
|
114
|
+
{ id: 'pc_10_medallero', count: 10 },
|
|
115
|
+
];
|
|
116
|
+
// ── Ciclismo (BIKE) ─────────────────────────────────────────────────────────
|
|
117
|
+
exports.CYCLING_DISTANCE = [
|
|
118
|
+
{ id: 'bike_20k', meters: 20000 },
|
|
119
|
+
{ id: 'bike_50k', meters: 50000 },
|
|
120
|
+
{ id: 'bike_100k', meters: 100000 },
|
|
121
|
+
{ id: 'bike_200k', meters: 200000 },
|
|
122
|
+
];
|
|
123
|
+
exports.CYCLING_VOLUME = [
|
|
124
|
+
{ id: 'bike_500', km: 500 },
|
|
125
|
+
{ id: 'bike_1000', km: 1000 },
|
|
126
|
+
{ id: 'bike_2500', km: 2500 },
|
|
127
|
+
];
|
|
128
|
+
// ── Natación (SWIM) ─────────────────────────────────────────────────────────
|
|
129
|
+
exports.SWIM_DISTANCE = [
|
|
130
|
+
{ id: 'swim_500m', meters: 500 },
|
|
131
|
+
{ id: 'swim_1k', meters: 1000 },
|
|
132
|
+
{ id: 'swim_2k', meters: 2000 },
|
|
133
|
+
{ id: 'swim_5k', meters: 5000 },
|
|
134
|
+
];
|
|
135
|
+
// ── Trail (TRAIL) ───────────────────────────────────────────────────────────
|
|
136
|
+
exports.TRAIL_DISTANCE = [
|
|
137
|
+
{ id: 'trail_10k', meters: 10000 },
|
|
138
|
+
{ id: 'trail_21k', meters: 21000 },
|
|
139
|
+
{ id: 'trail_30k', meters: 30000 },
|
|
140
|
+
{ id: 'trail_42k', meters: 42000 },
|
|
141
|
+
];
|
|
142
|
+
// Desnivel ACUMULADO (suma de DESNIVEL en metros) de los entrenos de trail.
|
|
143
|
+
exports.TRAIL_ELEVATION = [
|
|
144
|
+
{ id: 'trail_desnivel_1k', meters: 1000 },
|
|
145
|
+
{ id: 'trail_desnivel_5k', meters: 5000 },
|
|
146
|
+
{ id: 'trail_desnivel_10k', meters: 10000 },
|
|
147
|
+
];
|
|
148
|
+
// ── Triatlón (nado: mismos datos SWIM que Natación) ─────────────────────────
|
|
149
|
+
exports.TRI_SWIM_DISTANCE = [
|
|
150
|
+
{ id: 'tri_500m', meters: 500 },
|
|
151
|
+
{ id: 'tri_1k', meters: 1000 },
|
|
152
|
+
{ id: 'tri_2k', meters: 2000 },
|
|
153
|
+
];
|
|
154
|
+
// ── Coach & Chat (mensajes enviados por el usuario) ─────────────────────────
|
|
155
|
+
exports.CHAT_MSG = [
|
|
156
|
+
{ id: 'coach_1er_msg', count: 1 },
|
|
157
|
+
{ id: 'coach_10_msg', count: 10 },
|
|
158
|
+
];
|
|
159
|
+
// ── Nutrición (comidas registradas) ─────────────────────────────────────────
|
|
160
|
+
exports.NUTRITION_MEALS = [
|
|
161
|
+
{ id: 'nut_1a_receta', count: 1 },
|
|
162
|
+
{ id: 'nut_50_comidas', count: 50 },
|
|
163
|
+
];
|
|
164
|
+
exports.NUTRITION_DAYS_THRESHOLD = 7; // nut_7d_plan
|
|
165
|
+
// ── Wearables (conexiones; TIPO APLICATION numérico) ────────────────────────
|
|
166
|
+
exports.WEARABLE_APPS = [
|
|
167
|
+
{ id: 'wear_garmin', tipo: 2 },
|
|
168
|
+
{ id: 'wear_strava', tipo: 1 },
|
|
169
|
+
{ id: 'wear_apple', tipo: 5 },
|
|
170
|
+
];
|
|
171
|
+
// ── Plan + Hitos del Plan (TIER 1) ───────────────────────────────────────────
|
|
172
|
+
// Adherencia al plan = sesiones planificadas (WORKOUT "SHOW CLIENT"=true de un
|
|
173
|
+
// tipo entrenable) completadas / debidas (DATE <= hoy; no penaliza las futuras).
|
|
174
|
+
// Los bloques base/desarrollo/pico/taper salen de CLIENTE."ALGORITMO BLOQUE N
|
|
175
|
+
// INICIO/FIN". La semana de carrera, de la competición alrededor de "GOAL DATE".
|
|
176
|
+
exports.PLAN_SESSION_TYPES = ['CORRER', 'FUERZA', 'SPORT', 'BIKE', 'SWIM', 'TRAIL', 'WALK'];
|
|
177
|
+
exports.PLAN_ADHERENCE_82 = 0.82; // plan_82
|
|
178
|
+
exports.PLAN_BLOCK_ADHERENCE = 0.8; // hito_base/desarrollo/pico/taper (≥80% del bloque)
|
|
179
|
+
exports.PLAN_COMPLETE_ADHERENCE = 0.8; // plan_completado (al alcanzar GOAL DATE)
|
|
180
|
+
exports.PLAN_RACE_WEEK_DAYS = 6; // días antes de GOAL DATE que cuentan como semana de carrera
|
|
181
|
+
// Tipos que cuentan como carrera a pie para tirada larga / ritmo carrera.
|
|
182
|
+
exports.PLAN_RUN_TYPES = ['CORRER', 'TRAIL'];
|
|
183
|
+
// plan_tirada_larga: la tirada larga del plan (la carrera prevista más larga de
|
|
184
|
+
// su semana) completada, si supera un mínimo de volumen.
|
|
185
|
+
exports.PLAN_LONG_RUN_MIN_DISTANCE = 14000; // metros
|
|
186
|
+
exports.PLAN_LONG_RUN_MIN_DURATION = 75 * 60; // segundos
|
|
187
|
+
// plan_ritmo_carrera: carrera planificada hecha cuyo ritmo medio (DURATION/
|
|
188
|
+
// DISTANCE) ≈ ritmo objetivo (GOAL DURATION/GOAL DISTANCE). Solo si hay objetivo.
|
|
189
|
+
exports.PLAN_RACE_PACE_TOLERANCE = 0.04; // ±4%
|
|
190
|
+
exports.PLAN_RACE_PACE_MIN_DISTANCE = 5000; // metros (esfuerzo significativo)
|
|
191
|
+
// ── Fuerza: frecuencia / hábito ──────────────────────────────────────────────
|
|
192
|
+
// Sobre las fechas de las sesiones de FUERZA completadas (desde el ancla).
|
|
193
|
+
exports.STRENGTH_WINDOWS = [
|
|
194
|
+
{ id: 'str_racha7d', sessions: 3, days: 7 }, // ≥3 sesiones en 7 días
|
|
195
|
+
{ id: 'str_racha30d', sessions: 10, days: 30 }, // ≥10 sesiones en 30 días
|
|
196
|
+
];
|
|
197
|
+
exports.STRENGTH_HABIT_WEEKS = 4; // str_habito: 4 semanas ISO consecutivas con ≥1 sesión
|
|
198
|
+
// ── Post-carrera: recovery run ────────────────────────────────────────────────
|
|
199
|
+
// pc_recovery: rodaje suave (zona) en los N días siguientes a una COMPETICION hecha.
|
|
200
|
+
exports.RECOVERY_RUN_DAYS = 3;
|
|
201
|
+
exports.RECOVERY_RUN_ZONE = 2;
|
|
202
|
+
// ── Triatlón: brick ───────────────────────────────────────────────────────────
|
|
203
|
+
// tri_brick: una BIKE y una CORRER completadas el mismo día.
|
|
204
|
+
exports.BRICK_TYPES = ['BIKE', 'CORRER'];
|