hvp-shared 13.4.0 → 13.5.0

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.
@@ -22,11 +22,25 @@ import type { AppointmentBranch, AppointmentStandard } from "../contracts/google
22
22
  * Weights sum to 100. An event is "compliant" when its score >= 80.
23
23
  */
24
24
  export declare const STANDARD_V2: AppointmentStandard;
25
+ /**
26
+ * Multi-factor appointment standard v3.
27
+ *
28
+ * Twelve dimensions. Compared to V2:
29
+ * - `title` is split into 3 dimensions: `title_service_code`, `title_pet_name`,
30
+ * `title_format` — so each aspect of "well-formed title" gets its own weight.
31
+ * - `discount_format` added: auto-passes when no discount mentioned, but if
32
+ * a `%` is present in the description, must follow `\d+% <razón>` format.
33
+ * - Weights rebalanced: title + branch weighted higher (12 each); owner +
34
+ * context downgraded to 8; raza/edad downgraded to 4. Discount = 4.
35
+ *
36
+ * Weights sum to 100. An event is "compliant" when its score >= 80.
37
+ */
38
+ export declare const STANDARD_V3: AppointmentStandard;
25
39
  /**
26
40
  * Backward-compatible alias for existing code/tests that imported `STANDARD_V1`.
27
- * Always points to the current standard.
41
+ * Always points to the current standard (V3 as of 13.5.0).
28
42
  *
29
- * @deprecated Use `STANDARD_V2` (or whatever the current version is) explicitly.
43
+ * @deprecated Use `STANDARD_V3` (or whatever the current version is) explicitly.
30
44
  */
31
45
  export declare const STANDARD_V1: AppointmentStandard;
32
46
  /**
@@ -13,7 +13,7 @@
13
13
  * runs remain reproducible.
14
14
  */
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
- exports.HVP_EVENT_PROP_KEYS = exports.KNOWN_BREEDS = exports.PET_AGE_REGEX = exports.SCHEDULER_WITH_DATE_REGEX = exports.SCHEDULER_REGEX = exports.PHONE_REGEX = exports.QVET_ID_REGEX = exports.CANCELLED_TITLE_REGEX = exports.REMINDER_TITLE_REGEX = exports.PREFERRED_VET_REGEX = exports.EXCLUDED_TITLE_PREFIXES = exports.SERVICE_CODE_SYNONYMS = exports.CANONICAL_SERVICE_CODES = exports.EXCLUDED_COLOR_IDS = exports.CANCELLED_COLOR_ID = exports.COLOR_ID_TO_BRANCH = exports.BRANCH_COLOR_IDS = exports.STANDARD_V1 = exports.STANDARD_V2 = void 0;
16
+ exports.HVP_EVENT_PROP_KEYS = exports.KNOWN_BREEDS = exports.PET_AGE_REGEX = exports.SCHEDULER_WITH_DATE_REGEX = exports.SCHEDULER_REGEX = exports.PHONE_REGEX = exports.QVET_ID_REGEX = exports.CANCELLED_TITLE_REGEX = exports.REMINDER_TITLE_REGEX = exports.PREFERRED_VET_REGEX = exports.EXCLUDED_TITLE_PREFIXES = exports.SERVICE_CODE_SYNONYMS = exports.CANONICAL_SERVICE_CODES = exports.EXCLUDED_COLOR_IDS = exports.CANCELLED_COLOR_ID = exports.COLOR_ID_TO_BRANCH = exports.BRANCH_COLOR_IDS = exports.STANDARD_V1 = exports.STANDARD_V3 = exports.STANDARD_V2 = void 0;
17
17
  // ─── Standard v1 ─────────────────────────────────────────────────────────────
18
18
  /**
19
19
  * Multi-factor appointment standard v2.
@@ -32,71 +32,162 @@ exports.STANDARD_V2 = {
32
32
  id: "branch",
33
33
  weight: 10,
34
34
  label: "Sucursal",
35
- description: "El evento tiene un color asignado (Urban=rojo, Harbor=azul, Montejo=morado). Sin color, no se puede asignar carga ni recursos por sucursal.",
35
+ description: 'Sucursal detectada por colorId del evento: 11 (Tomato/rojo) = Urban, 9 (Blueberry/azul) = Harbor, 3 (Grape/morado) = Montejo. Si el evento usa el color por defecto, falla esta dimensión. Atención: hay tonos parecidos en GCal — fíjate en el colorId exacto en el drawer si dudas.',
36
36
  },
37
37
  {
38
38
  id: "title",
39
39
  weight: 10,
40
40
  label: "Título bien formado",
41
- description: "El título empieza con un código de servicio del diccionario (C, V, SC, CS, CX, USG, CERT, etc.).",
41
+ description: 'El título empieza con un código de servicio reconocible del diccionario: C (consulta), SC (sin cita), CS (consulta seguimiento), V/VAC (vacuna), CX (cirugía), CERT (certificado), USG, RX, ECO, OVH, TM (toma de muestras), AP/APL/AM (aplicación), D (desparasitación), etc.',
42
42
  },
43
43
  {
44
44
  id: "pet_name",
45
45
  weight: 10,
46
46
  label: "Nombre de la mascota",
47
- description: "Nombre de la mascota detectable en el título.",
47
+ description: 'Nombre de la mascota detectable en el título (después del código de servicio y antes de las iniciales del vet). Ej: "C. MILO RGL*" → mascota = MILO.',
48
48
  },
49
49
  {
50
50
  id: "pet_age",
51
51
  weight: 8,
52
52
  label: "Edad de la mascota",
53
- description: 'Edad anotada en la descripción (ej. "4 meses", "1 año", "8 semanas"). Importante para vacunación, dosis y diagnóstico.',
53
+ description: 'Edad anotada en la descripción: "4 meses", "1 año y 4 meses", "8 semanas", "2 años". Importante para vacunación, dosis y diagnóstico — sin edad, no se puede protocolizar.',
54
54
  },
55
55
  {
56
56
  id: "pet_breed",
57
57
  weight: 8,
58
58
  label: "Raza de la mascota",
59
- description: 'Raza detectada en la descripción (ej. "Yorkie", "Shih Tzu", "Cocker Spaniel"). Útil para protocolos clínicos.',
59
+ description: 'Raza detectada en la descripción contra un diccionario de razas comunes: Yorkie, Shih Tzu, Cocker Spaniel, French Bulldog, Chihuahua, Schnauzer, Golden Retriever, Labrador, Persa, Siamés, mestizo, etc. Útil para protocolos clínicos y dosificación.',
60
60
  },
61
61
  {
62
62
  id: "owner_name",
63
63
  weight: 12,
64
64
  label: "Nombre del tutor",
65
- description: "Nombre del cliente/tutor detectable en la descripción, o linkeable a QVET vía Q{id} (auto-pasa).",
65
+ description: 'Nombre del cliente/tutor. Auto-pasa si hay Q{id} en la descripción (cliente linkeado a QVET) o si el teléfono matchea un cliente QVET existente. Si no, busca nombre completo del tutor en la descripción (mínimo 2 palabras, mayúsculas/minúsculas con letras).',
66
66
  },
67
67
  {
68
68
  id: "owner_phone",
69
69
  weight: 12,
70
70
  label: "Teléfono del tutor",
71
- description: "Teléfono del tutor en la descripción (cualquier formato común). Necesario para confirmar y avisar de cambios.",
71
+ description: 'Teléfono del tutor en cualquier formato común (con o sin +52, con o sin separadores). Auto-pasa si hay Q{id} (sabemos el teléfono del registro QVET). Necesario para confirmar la cita y avisar de cambios.',
72
72
  },
73
73
  {
74
74
  id: "context",
75
75
  weight: 10,
76
76
  label: "Motivo / contexto",
77
- description: 'Descripción tiene contexto clínico relevante (motivo, síntomas, antecedentes). >20 caracteres tras descontar nombre/teléfono/Q{id}.',
77
+ description: 'La descripción tiene contexto clínico relevante (motivo de la visita, síntomas, antecedentes) más allá del nombre y teléfono. Mínimo 20 caracteres tras descontar nombre, teléfono y Q{id}.',
78
78
  },
79
79
  {
80
80
  id: "scheduler",
81
81
  weight: 10,
82
82
  label: "Iniciales de quien agendó",
83
- description: 'Iniciales del colaborador que agendó la cita ("AGENDO XZA", "AG YMP"). Permite reporte de productividad por persona.',
83
+ description: 'Iniciales (col_code) del colaborador que agendó la cita, dentro de la descripción. Formatos válidos: "AGENDO XZA", "AG YMP", "AGENDADO POR SLR". Permite reportar productividad por persona.',
84
84
  },
85
85
  {
86
86
  id: "scheduling_date",
87
87
  weight: 10,
88
88
  label: "Fecha en que se agendó",
89
- description: 'Fecha de la anotación de quién agendó (ej. "AGENDO XZA 16 MAYO"). Permite medir lead time entre agendado y atención.',
89
+ description: 'Fecha de la anotación de quién agendó, junto a sus iniciales. Ejemplos: "AGENDO XZA 16 MAYO", "AG YMP 14.05.26", "AGENDADO POR SLR 02/12/25". Permite medir el lead time entre cuándo se agendó y cuándo es la cita.',
90
+ },
91
+ ],
92
+ };
93
+ /**
94
+ * Multi-factor appointment standard v3.
95
+ *
96
+ * Twelve dimensions. Compared to V2:
97
+ * - `title` is split into 3 dimensions: `title_service_code`, `title_pet_name`,
98
+ * `title_format` — so each aspect of "well-formed title" gets its own weight.
99
+ * - `discount_format` added: auto-passes when no discount mentioned, but if
100
+ * a `%` is present in the description, must follow `\d+% <razón>` format.
101
+ * - Weights rebalanced: title + branch weighted higher (12 each); owner +
102
+ * context downgraded to 8; raza/edad downgraded to 4. Discount = 4.
103
+ *
104
+ * Weights sum to 100. An event is "compliant" when its score >= 80.
105
+ */
106
+ exports.STANDARD_V3 = {
107
+ version: "3.0",
108
+ minimumCompliantScore: 80,
109
+ dimensions: [
110
+ {
111
+ id: "branch",
112
+ weight: 12,
113
+ label: "Sucursal",
114
+ description: 'Sucursal detectada por colorId del evento: 11 (Tomato/rojo) = Urban, 9 (Blueberry/azul) = Harbor, 3 (Grape/morado) = Montejo. Si el evento usa el color por defecto, falla esta dimensión. Atención: hay tonos parecidos en GCal — fíjate en el colorId exacto en el drawer si dudas.',
115
+ },
116
+ {
117
+ id: "title_service_code",
118
+ weight: 12,
119
+ label: "Código de servicio",
120
+ description: 'El título empieza con un código del diccionario: C (consulta), SC (sin cita), CS (consulta seguimiento), V/VAC (vacuna), CX (cirugía), CERT (certificado), USG, RX, ECO, OVH, TM (toma de muestras), AM/AP/APL (aplicación de medicamento), D (desparasitación), MC (microchip), CU (corte de uñas), PROFILAXIS, etc.',
121
+ },
122
+ {
123
+ id: "title_pet_name",
124
+ weight: 12,
125
+ label: "Nombre de la mascota (título)",
126
+ description: 'Nombre de la mascota detectable en el título (después del código de servicio, antes de iniciales del vet). Ej: "C MILO RGL*" → mascota = MILO. Soporta multi-mascota: "V CUBA, TEQUILA Y WHISKY".',
127
+ },
128
+ {
129
+ id: "title_format",
130
+ weight: 12,
131
+ label: "Formato del título",
132
+ description: 'Longitud ≤ 40 caracteres, sin info clínica verbosa, asterisco solo al final (médico preferido — nunca doble ni en medio), iniciales del vet al final si están presentes. "MANEJO INTRAHOSPITALARIO MINNIE" o "DUTTON FPO**" fallan.',
133
+ },
134
+ {
135
+ id: "scheduling_date",
136
+ weight: 8,
137
+ label: "Fecha en que se agendó",
138
+ description: 'Fecha de la anotación de quién agendó, junto a sus iniciales. Ejemplos: "AGENDO XZA 16 MAYO", "AG YMP 14.05.26", "AGENDADO POR SLR 02/12/25". Permite medir el lead time entre cuándo se agendó y cuándo es la cita.',
139
+ },
140
+ {
141
+ id: "scheduler",
142
+ weight: 8,
143
+ label: "Iniciales de quien agendó",
144
+ description: 'Iniciales (col_code) del colaborador que agendó la cita, dentro de la descripción. Formatos válidos: "AGENDO XZA", "AG YMP", "AGENDADO POR SLR". Permite reportar productividad por persona.',
145
+ },
146
+ {
147
+ id: "context",
148
+ weight: 8,
149
+ label: "Motivo / contexto",
150
+ description: 'La descripción tiene contexto clínico relevante (motivo de la visita, síntomas, antecedentes) más allá del nombre y teléfono. Mínimo 20 caracteres tras descontar nombre, teléfono y Q{id}.',
151
+ },
152
+ {
153
+ id: "owner_name",
154
+ weight: 8,
155
+ label: "Nombre del tutor",
156
+ description: 'Nombre del cliente/tutor. Auto-pasa si hay Q{id} en la descripción (cliente linkeado a QVET) o si el teléfono matchea un cliente QVET existente. Si no, busca nombre completo del tutor en la descripción (mínimo 2 palabras, mayúsculas/minúsculas con letras).',
157
+ },
158
+ {
159
+ id: "owner_phone",
160
+ weight: 8,
161
+ label: "Teléfono del tutor",
162
+ description: 'Teléfono del tutor en cualquier formato común (con o sin +52, con o sin separadores). Auto-pasa si hay Q{id} (sabemos el teléfono del registro QVET). Necesario para confirmar la cita y avisar de cambios.',
163
+ },
164
+ {
165
+ id: "pet_age",
166
+ weight: 4,
167
+ label: "Edad de la mascota",
168
+ description: 'Edad anotada en la descripción: "4 meses", "1 año y 4 meses", "8 semanas", "2 años". Importante para vacunación, dosis y diagnóstico.',
169
+ },
170
+ {
171
+ id: "pet_breed",
172
+ weight: 4,
173
+ label: "Raza de la mascota",
174
+ description: 'Raza detectada en la descripción contra un diccionario de razas comunes: Yorkie, Shih Tzu, Cocker Spaniel, French Bulldog, Chihuahua, Schnauzer, Golden Retriever, Labrador, Persa, Siamés, mestizo, etc. Útil para protocolos clínicos y dosificación.',
175
+ },
176
+ {
177
+ id: "discount_format",
178
+ weight: 4,
179
+ label: "Formato de descuento",
180
+ description: 'Si la descripción menciona un descuento (contiene un patrón \\d+%), debe seguir el formato "<porcentaje>% <razón>" — ejemplos: "15% recordatorio", "10% nuevo cliente", "30% primera vez", "50% cortesía". Si no hay descuento mencionado, esta dimensión pasa automáticamente.',
90
181
  },
91
182
  ],
92
183
  };
93
184
  /**
94
185
  * Backward-compatible alias for existing code/tests that imported `STANDARD_V1`.
95
- * Always points to the current standard.
186
+ * Always points to the current standard (V3 as of 13.5.0).
96
187
  *
97
- * @deprecated Use `STANDARD_V2` (or whatever the current version is) explicitly.
188
+ * @deprecated Use `STANDARD_V3` (or whatever the current version is) explicitly.
98
189
  */
99
- exports.STANDARD_V1 = exports.STANDARD_V2;
190
+ exports.STANDARD_V1 = exports.STANDARD_V3;
100
191
  // ─── ColorId → Branch mapping ────────────────────────────────────────────────
101
192
  /**
102
193
  * Google Calendar colorId values mapped to HVP branches.
@@ -5,9 +5,15 @@
5
5
  * See: resources/notes/google-calendar/standard-v1.md
6
6
  */
7
7
  /**
8
- * One of the six dimensions of the appointment standard.
8
+ * Dimensions of the appointment standard.
9
+ *
10
+ * V3 (current): 12 dimensions — title split into 3, discount_format added.
11
+ * V2 (frozen): 10 dimensions — `title` and `pet_name` used instead of the V3 split.
12
+ *
13
+ * All IDs from both versions are kept in the union so historical V2 results
14
+ * remain typeable.
9
15
  */
10
- export type AppointmentStandardDimensionId = 'branch' | 'title' | 'pet_name' | 'pet_age' | 'pet_breed' | 'owner_name' | 'owner_phone' | 'context' | 'scheduler' | 'scheduling_date';
16
+ export type AppointmentStandardDimensionId = 'branch' | 'title_format' | 'title_service_code' | 'title_pet_name' | 'title' | 'pet_name' | 'pet_age' | 'pet_breed' | 'owner_name' | 'owner_phone' | 'context' | 'scheduler' | 'scheduling_date' | 'discount_format';
11
17
  /**
12
18
  * One of the three branches.
13
19
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hvp-shared",
3
- "version": "13.4.0",
3
+ "version": "13.5.0",
4
4
  "description": "Shared types and utilities for HVP backend and frontend",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",