hvp-shared 13.11.0 → 13.12.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.
package/dist/constants/index.js
CHANGED
|
@@ -45,3 +45,4 @@ __exportStar(require("./client-billing.enums"), exports);
|
|
|
45
45
|
__exportStar(require("./sat-income-invoice"), exports);
|
|
46
46
|
__exportStar(require("./global-invoice.enums"), exports);
|
|
47
47
|
__exportStar(require("./google-calendar.constants"), exports);
|
|
48
|
+
__exportStar(require("./performance-metrics.constants"), exports);
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance dashboard — canonical metric registry (single source of truth).
|
|
3
|
+
*
|
|
4
|
+
* Consumed by: backend (label, lowerIsBetter for the API), frontend (weight, unit),
|
|
5
|
+
* and the catalog generator. DO NOT duplicate this metadata in consumers.
|
|
6
|
+
*
|
|
7
|
+
* AUTO-GENERATED seed (hvp-backend/scripts/gen-performance-registry.ts).
|
|
8
|
+
* 76 metrics · type {"indicator":38,"support":38} · weight {"critical":10,"important":17,"complementary":11} · status {"implemented":70,"proposed":6}
|
|
9
|
+
*/
|
|
10
|
+
export declare enum MetricWeight {
|
|
11
|
+
CRITICAL = "critical",
|
|
12
|
+
IMPORTANT = "important",
|
|
13
|
+
COMPLEMENTARY = "complementary"
|
|
14
|
+
}
|
|
15
|
+
export type MetricType = "indicator" | "support";
|
|
16
|
+
export type MetricUnit = "currency" | "percent" | "number";
|
|
17
|
+
export type MetricPillar = "P1" | "P2" | "P3";
|
|
18
|
+
export type MetricEndpoint = "growth" | "cooperation" | "fidelity" | "visits" | "others" | "operative" | "sales";
|
|
19
|
+
export type MetricStatus = "implemented" | "proposed";
|
|
20
|
+
export interface PerformanceMetricMeta {
|
|
21
|
+
/** Stable metric key (matches the API response `metrics[].key`). */
|
|
22
|
+
key: string;
|
|
23
|
+
/** Spanish display label (the one the API sends today). */
|
|
24
|
+
label: string;
|
|
25
|
+
/** indicator = tracked KPI · support = numerator/denominator/context. */
|
|
26
|
+
type: MetricType;
|
|
27
|
+
/** Only indicators have a weight. */
|
|
28
|
+
weight?: MetricWeight;
|
|
29
|
+
unit: MetricUnit;
|
|
30
|
+
/** True when a lower value is better (default false). */
|
|
31
|
+
lowerIsBetter?: boolean;
|
|
32
|
+
/** Which dashboard endpoint produces it. */
|
|
33
|
+
endpoint: MetricEndpoint;
|
|
34
|
+
pillar: MetricPillar;
|
|
35
|
+
status: MetricStatus;
|
|
36
|
+
}
|
|
37
|
+
export declare const PERFORMANCE_METRICS: Record<string, PerformanceMetricMeta>;
|
|
38
|
+
/** Labels for a given endpoint (replaces the per-endpoint *_METRIC_LABELS maps). */
|
|
39
|
+
export declare function performanceLabelsByEndpoint(endpoint: MetricEndpoint): Record<string, string>;
|
|
40
|
+
/** Keys where a lower value is better, for a given endpoint. */
|
|
41
|
+
export declare function performanceLowerIsBetter(endpoint: MetricEndpoint): Set<string>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Performance dashboard — canonical metric registry (single source of truth).
|
|
4
|
+
*
|
|
5
|
+
* Consumed by: backend (label, lowerIsBetter for the API), frontend (weight, unit),
|
|
6
|
+
* and the catalog generator. DO NOT duplicate this metadata in consumers.
|
|
7
|
+
*
|
|
8
|
+
* AUTO-GENERATED seed (hvp-backend/scripts/gen-performance-registry.ts).
|
|
9
|
+
* 76 metrics · type {"indicator":38,"support":38} · weight {"critical":10,"important":17,"complementary":11} · status {"implemented":70,"proposed":6}
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.PERFORMANCE_METRICS = exports.MetricWeight = void 0;
|
|
13
|
+
exports.performanceLabelsByEndpoint = performanceLabelsByEndpoint;
|
|
14
|
+
exports.performanceLowerIsBetter = performanceLowerIsBetter;
|
|
15
|
+
var MetricWeight;
|
|
16
|
+
(function (MetricWeight) {
|
|
17
|
+
MetricWeight["CRITICAL"] = "critical";
|
|
18
|
+
MetricWeight["IMPORTANT"] = "important";
|
|
19
|
+
MetricWeight["COMPLEMENTARY"] = "complementary";
|
|
20
|
+
})(MetricWeight || (exports.MetricWeight = MetricWeight = {}));
|
|
21
|
+
exports.PERFORMANCE_METRICS = {
|
|
22
|
+
"assistancesGiven": { key: "assistancesGiven", label: "Asistencias prestadas", type: "indicator", weight: MetricWeight.CRITICAL, unit: "number", endpoint: "cooperation", pillar: "P1", status: "implemented" },
|
|
23
|
+
"mentorshipsAsMentor": { key: "mentorshipsAsMentor", label: "Mentorías como mentor", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "number", endpoint: "cooperation", pillar: "P1", status: "implemented" },
|
|
24
|
+
"mentorshipsAsMentoree": { key: "mentorshipsAsMentoree", label: "Mentorías como mentoree", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "number", endpoint: "cooperation", pillar: "P1", status: "implemented" },
|
|
25
|
+
"allConsultations": { key: "allConsultations", label: "Consultas", type: "indicator", weight: MetricWeight.CRITICAL, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
26
|
+
"allHospitalizations": { key: "allHospitalizations", label: "Hospitalizaciones y emergencias", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
27
|
+
"allLabWork": { key: "allLabWork", label: "Laboratorio", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
28
|
+
"allPreventive": { key: "allPreventive", label: "Vacunas y desparasitaciones", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
29
|
+
"allSurgeries": { key: "allSurgeries", label: "Cirugías", type: "indicator", weight: MetricWeight.CRITICAL, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
30
|
+
"allSurgeryAssistances": { key: "allSurgeryAssistances", label: "Asistencias de cirugía", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
31
|
+
"chemistryPanels": { key: "chemistryPanels", label: "Químicas sanguíneas", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
32
|
+
"commissionAmount": { key: "commissionAmount", label: "Monto de comisiones", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "currency", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
33
|
+
"commissionCount": { key: "commissionCount", label: "Comisiones recibidas", type: "indicator", weight: MetricWeight.CRITICAL, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
34
|
+
"complexSurgeries": { key: "complexSurgeries", label: "Cirugías complejas", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
35
|
+
"consultations": { key: "consultations", label: "Consultas generales", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
36
|
+
"dewormings": { key: "dewormings", label: "Desparasitaciones", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
37
|
+
"diagnosticTests": { key: "diagnosticTests", label: "Tests diagnósticos", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
38
|
+
"emergencies": { key: "emergencies", label: "Emergencias", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
39
|
+
"englishConsultations": { key: "englishConsultations", label: "Consultas en inglés", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
40
|
+
"hemograms": { key: "hemograms", label: "Hemogramas", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
41
|
+
"hospitalizations": { key: "hospitalizations", label: "Hospitalizaciones", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
42
|
+
"revisions": { key: "revisions", label: "Revisiones", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
43
|
+
"specialistConsultations": { key: "specialistConsultations", label: "Consultas de especialista", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
44
|
+
"specialistRevisions": { key: "specialistRevisions", label: "Revisiones de especialista", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
45
|
+
"surgeries": { key: "surgeries", label: "Cirugías estándar", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
46
|
+
"surgeryAssistances": { key: "surgeryAssistances", label: "Asistencias (anestesista/1er ayudante)", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
47
|
+
"totalServices": { key: "totalServices", label: "Total servicios", type: "indicator", weight: MetricWeight.CRITICAL, unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
48
|
+
"vaccines": { key: "vaccines", label: "Vacunas", type: "support", unit: "number", endpoint: "growth", pillar: "P1", status: "implemented" },
|
|
49
|
+
"commissionConsultations": { key: "commissionConsultations", label: "Consultas y vacunas comisionadas", type: "support", unit: "number", endpoint: "others", pillar: "P1", status: "implemented" },
|
|
50
|
+
"matchedConsultations": { key: "matchedConsultations", label: "Consultas y vacunas comisionadas con visita registrada", type: "support", unit: "number", endpoint: "others", pillar: "P1", status: "implemented" },
|
|
51
|
+
"matchRate": { key: "matchRate", label: "% de consultas y vacunas comisionadas con visita registrada", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", endpoint: "others", pillar: "P1", status: "implemented" },
|
|
52
|
+
"avgVisitLength": { key: "avgVisitLength", label: "Extensión promedio (caracteres)", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "number", endpoint: "visits", pillar: "P1", status: "implemented" },
|
|
53
|
+
"visitCount": { key: "visitCount", label: "Visitas registradas", type: "indicator", weight: MetricWeight.CRITICAL, unit: "number", endpoint: "visits", pillar: "P1", status: "implemented" },
|
|
54
|
+
"newClients": { key: "newClients", label: "Clientes nuevos", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "number", endpoint: "fidelity", pillar: "P2", status: "implemented" },
|
|
55
|
+
"vetRequestedTotal": { key: "vetRequestedTotal", label: "Veterinario solicitado (total)", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "number", endpoint: "fidelity", pillar: "P2", status: "implemented" },
|
|
56
|
+
"avgTicketOverall": { key: "avgTicketOverall", label: "Ticket promedio general", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "currency", endpoint: "sales", pillar: "P2", status: "proposed" },
|
|
57
|
+
"consultations_avgTicket": { key: "consultations_avgTicket", label: "Consultas — prom. ticket", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "currency", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
58
|
+
"consultations_extraPct": { key: "consultations_extraPct", label: "Consultas — extra %", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "percent", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
59
|
+
"consultations_tickets": { key: "consultations_tickets", label: "Consultas — tickets", type: "support", unit: "number", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
60
|
+
"emergencies_avgTicket": { key: "emergencies_avgTicket", label: "Emergencias y hospitalizaciones — prom. ticket", type: "support", unit: "currency", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
61
|
+
"emergencies_extraPct": { key: "emergencies_extraPct", label: "Emergencias y hospitalizaciones — extra %", type: "support", unit: "percent", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
62
|
+
"emergencies_tickets": { key: "emergencies_tickets", label: "Emergencias y hospitalizaciones — tickets", type: "support", unit: "number", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
63
|
+
"generatedRevenue": { key: "generatedRevenue", label: "Facturación generada", type: "indicator", weight: MetricWeight.CRITICAL, unit: "currency", endpoint: "sales", pillar: "P2", status: "proposed" },
|
|
64
|
+
"pharmacyProductSales": { key: "pharmacyProductSales", label: "Venta de farmacia / productos", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "currency", endpoint: "sales", pillar: "P2", status: "proposed" },
|
|
65
|
+
"surgeries_avgTicket": { key: "surgeries_avgTicket", label: "Cirugías — prom. ticket", type: "support", unit: "currency", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
66
|
+
"surgeries_extraPct": { key: "surgeries_extraPct", label: "Cirugías — extra %", type: "support", unit: "percent", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
67
|
+
"surgeries_tickets": { key: "surgeries_tickets", label: "Cirugías — tickets", type: "support", unit: "number", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
68
|
+
"vaccines_avgTicket": { key: "vaccines_avgTicket", label: "Vacunas y desparasitaciones — prom. ticket", type: "support", unit: "currency", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
69
|
+
"vaccines_extraPct": { key: "vaccines_extraPct", label: "Vacunas y desparasitaciones — extra %", type: "support", unit: "percent", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
70
|
+
"vaccines_tickets": { key: "vaccines_tickets", label: "Vacunas y desparasitaciones — tickets", type: "support", unit: "number", endpoint: "sales", pillar: "P2", status: "implemented" },
|
|
71
|
+
"absenceRate": { key: "absenceRate", label: "% faltas", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
72
|
+
"absences": { key: "absences", label: "Faltas", type: "support", unit: "number", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
73
|
+
"attendanceCount": { key: "attendanceCount", label: "Registros de asistencia", type: "support", unit: "number", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
74
|
+
"cashFlowCount": { key: "cashFlowCount", label: "Entradas/salidas de caja", type: "support", unit: "number", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
75
|
+
"cashFlowValidRate": { key: "cashFlowValidRate", label: "% E/S caja bien hechas", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "percent", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
76
|
+
"closingsCount": { key: "closingsCount", label: "Cierres de caja", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "number", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
77
|
+
"closingSuccessRate": { key: "closingSuccessRate", label: "% cierres bien hechos", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
78
|
+
"collectionsAmount": { key: "collectionsAmount", label: "Monto de cobros", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "currency", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
79
|
+
"collectionsTickets": { key: "collectionsTickets", label: "Tickets cobrados", type: "support", unit: "number", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
80
|
+
"cvGlobalPct": { key: "cvGlobalPct", label: "% Clientes Varios (monto total)", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "percent", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
81
|
+
"cvMedicalPct": { key: "cvMedicalPct", label: "% Clientes Varios (servicios médicos)", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
82
|
+
"docsReadRate": { key: "docsReadRate", label: "% documentación interna leída", type: "indicator", weight: MetricWeight.CRITICAL, unit: "percent", endpoint: "operative", pillar: "P3", status: "proposed" },
|
|
83
|
+
"farCheckInRate": { key: "farCheckInRate", label: "% check-ins fuera", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "percent", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
84
|
+
"farCheckIns": { key: "farCheckIns", label: "Check-ins fuera de sucursal", type: "support", unit: "number", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
85
|
+
"goodSchedulingRate": { key: "goodSchedulingRate", label: "% agendas bien hechas", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", endpoint: "operative", pillar: "P3", status: "proposed" },
|
|
86
|
+
"internalLabRate": { key: "internalLabRate", label: "% químicas y hemogramas internos", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", endpoint: "operative", pillar: "P3", status: "proposed" },
|
|
87
|
+
"invalidClosings": { key: "invalidClosings", label: "Cierres inválidos", type: "support", unit: "number", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
88
|
+
"lateCount": { key: "lateCount", label: "Retardos (>10 min)", type: "support", unit: "number", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
89
|
+
"lateRate": { key: "lateRate", label: "% retardos", type: "indicator", weight: MetricWeight.CRITICAL, unit: "percent", lowerIsBetter: true, endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
90
|
+
"memosRead": { key: "memosRead", label: "Memorandums leídos", type: "support", unit: "number", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
91
|
+
"memosReadRate": { key: "memosReadRate", label: "% lectura de memorandums", type: "indicator", weight: MetricWeight.CRITICAL, unit: "percent", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
92
|
+
"salesAmount": { key: "salesAmount", label: "Monto de ventas", type: "indicator", weight: MetricWeight.COMPLEMENTARY, unit: "currency", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
93
|
+
"salesCount": { key: "salesCount", label: "Tickets vendidos", type: "support", unit: "number", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
94
|
+
"sellerMatchRate": { key: "sellerMatchRate", label: "% de cobros con el vendedor correcto", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
95
|
+
"verifiedTickets": { key: "verifiedTickets", label: "Tickets médicos verificados", type: "support", unit: "number", endpoint: "operative", pillar: "P3", status: "implemented" },
|
|
96
|
+
"ownSaleConsultations": { key: "ownSaleConsultations", label: "Consultas y vacunas comisionadas en las que aparezco como vendedor", type: "support", unit: "number", endpoint: "others", pillar: "P3", status: "implemented" },
|
|
97
|
+
"ownSaleRate": { key: "ownSaleRate", label: "% de consultas y vacunas comisionadas en las que aparezco como vendedor", type: "indicator", weight: MetricWeight.IMPORTANT, unit: "percent", endpoint: "others", pillar: "P3", status: "implemented" },
|
|
98
|
+
};
|
|
99
|
+
/** Labels for a given endpoint (replaces the per-endpoint *_METRIC_LABELS maps). */
|
|
100
|
+
function performanceLabelsByEndpoint(endpoint) {
|
|
101
|
+
const out = {};
|
|
102
|
+
for (const m of Object.values(exports.PERFORMANCE_METRICS)) {
|
|
103
|
+
if (m.endpoint === endpoint)
|
|
104
|
+
out[m.key] = m.label;
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
/** Keys where a lower value is better, for a given endpoint. */
|
|
109
|
+
function performanceLowerIsBetter(endpoint) {
|
|
110
|
+
return new Set(Object.values(exports.PERFORMANCE_METRICS)
|
|
111
|
+
.filter((m) => m.endpoint === endpoint && m.lowerIsBetter)
|
|
112
|
+
.map((m) => m.key));
|
|
113
|
+
}
|