paperclip-plugin-autopilot-ops 0.1.61 → 0.1.62

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/manifest.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // src/manifest.ts
2
2
  var PLUGIN_ID = "alephoo.autopilot-ops";
3
- var PLUGIN_VERSION = "0.1.61";
3
+ var PLUGIN_VERSION = "0.1.62";
4
4
  var DB_NAMESPACE_SLUG = "autopilot_ops";
5
5
  var PAGE_ROUTE = "autopilot";
6
6
  var TOOL_NAMES = {
package/dist/ui/index.js CHANGED
@@ -8,7 +8,7 @@ import {
8
8
 
9
9
  // src/manifest.ts
10
10
  var PLUGIN_ID = "alephoo.autopilot-ops";
11
- var PLUGIN_VERSION = "0.1.61";
11
+ var PLUGIN_VERSION = "0.1.62";
12
12
  var DB_NAMESPACE_SLUG = "autopilot_ops";
13
13
  var PAGE_ROUTE = "autopilot";
14
14
  var TOOL_NAMES = {
package/dist/worker.js CHANGED
@@ -39932,7 +39932,7 @@ function startWorkerRpcHost(options) {
39932
39932
 
39933
39933
  // src/manifest.ts
39934
39934
  var PLUGIN_ID = "alephoo.autopilot-ops";
39935
- var PLUGIN_VERSION = "0.1.61";
39935
+ var PLUGIN_VERSION = "0.1.62";
39936
39936
  var DB_NAMESPACE_SLUG = "autopilot_ops";
39937
39937
  var PAGE_ROUTE = "autopilot";
39938
39938
  var TOOL_NAMES = {
@@ -44708,7 +44708,7 @@ function evaluarRentabilidad(input2) {
44708
44708
  if (i >= 0) avisos.splice(i, 1);
44709
44709
  }
44710
44710
  if (valor > 0 && (insumos / valor * 100 > INSUMOS_A_VERIFICAR_PCT || honorarioMax !== null && honorarioMax > valor)) avisos.push("dato_a_verificar");
44711
- const impacto = impactoPromedio !== null && impactoPromedio >= 0 && perdidaProfesionales !== null ? perdidaProfesionales : impactoPromedio;
44711
+ const impacto = impactoPromedio !== null && perdidaProfesionales !== null ? Math.min(impactoPromedio, perdidaProfesionales) : impactoPromedio;
44712
44712
  const reparto = valor > 0 ? conHonorario.map((h) => {
44713
44713
  const m = redondear5(valor - descuento - insumos - indUsado - h.honorario);
44714
44714
  return { profesional_id: h.profesional_id, profesional: h.profesional, honorario: h.honorario, margen: m, volumen: h.volumen, por_mes: h.volumen !== null ? porMes(m, h.volumen) : null };
@@ -44729,9 +44729,12 @@ function evaluarRentabilidad(input2) {
44729
44729
  }
44730
44730
  const honorarioPct = !conHonorario.length ? 0 : segunQuien ? conHonorario.reduce((a, h) => a + h.pct * h.volumen, 0) / totalVol : conHonorario.reduce((m, h) => h.honorario === honorarioMax ? Math.max(m, h.pct) : m, 0);
44731
44731
  const indirectosPct = medidoCon === "total" && valor > 0 ? ind.detalle.filter((d) => (input2.indirectos ?? []).some((c) => c.id === d.id && c.reparto === "porcentaje")).reduce((a, d) => a + d.monto, 0) / valor : 0;
44732
- const fijos = honorarioBase !== null ? honorarioBase - honorarioPct * valor + insumos + (indUsado - indirectosPct * valor) : null;
44733
- const libre = 1 - (umbral + descuentoPct) / 100 - honorarioPct - indirectosPct;
44734
- const valorObjetivo = fijos !== null && libre > 0.05 ? Math.ceil(fijos / libre) : null;
44732
+ const peorDebajo = debajoProf.length ? debajoProf.reduce((a, x) => x.h.honorario > a.h.honorario ? x : a).h : null;
44733
+ const [honObj, pctObj] = peorDebajo ? [peorDebajo.honorario, peorDebajo.pct] : [honorarioBase, honorarioPct];
44734
+ const fijos = honObj !== null ? honObj - pctObj * valor + insumos + (indUsado - indirectosPct * valor) : null;
44735
+ const libre = 1 - (umbral + descuentoPct) / 100 - pctObj - indirectosPct;
44736
+ const objetivoCalculado = fijos !== null && libre > 0.05 ? Math.ceil(fijos / libre) : null;
44737
+ const valorObjetivo = objetivoCalculado !== null && objetivoCalculado > valor ? objetivoCalculado : null;
44735
44738
  const honorarioObjetivo = valor > 0 ? Math.max(0, Math.floor(valor * (1 - umbral / 100) - descuento - insumos - indUsado)) : null;
44736
44739
  const insumosObjetivo = valor > 0 && honorarioBase !== null ? Math.max(0, Math.floor(valor * (1 - umbral / 100) - descuento - honorarioBase - indUsado)) : null;
44737
44740
  const e = {
@@ -44819,6 +44822,8 @@ function oracionRentabilidad(l, e) {
44819
44822
  const porque = porqueRentabilidad(l, e);
44820
44823
  const total = e.medido_con === "total" ? " despu\xE9s de los costos indirectos" : "";
44821
44824
  if (e.clase === "perdida") return `${practica} da p\xE9rdida${total}.${porque ? ` ${porque}` : ""}${mensual}`;
44825
+ const prof = e.causa === "honorario_profesional" ? e.causa_profesionales[0] : void 0;
44826
+ if (e.clase === "margen_bajo" && prof && e.valor > 0) return `${practica}: con ${prof.profesional} deja un margen de ${porcentaje(Math.round(prof.margen / e.valor * 1e3) / 10)}${total}, debajo del ${porcentaje(e.umbral)} de la instituci\xF3n.${porque ? ` ${porque}` : ""}${mensual}`;
44822
44827
  if (e.clase === "margen_bajo") return `${practica} deja un margen de ${porcentaje(e.margen_pct)}${total}, debajo del ${porcentaje(e.umbral)} de la instituci\xF3n.${porque ? ` ${porque}` : ""}${mensual}`;
44823
44828
  return `${practica} deja un margen de ${porcentaje(e.margen_pct)}${total}.`;
44824
44829
  }
@@ -45237,6 +45242,7 @@ ON CONFLICT (company_id) DO UPDATE SET bases = EXCLUDED.bases, practicas = EXCLU
45237
45242
  return bases;
45238
45243
  }
45239
45244
  async function guardarMediciones(ctx, companyId, items, quitar = []) {
45245
+ await ctx.db.execute(`DELETE FROM ${t3(ctx, "rentabilidad_medicion")} WHERE company_id = $1 AND medido_el < now() - interval '45 days'`, [companyId]);
45240
45246
  for (const referencia of quitar) await ctx.db.execute(`DELETE FROM ${t3(ctx, "rentabilidad_medicion")} WHERE company_id = $1 AND referencia = $2`, [companyId, referencia]);
45241
45247
  for (const { lectura: l, evaluacion } of items) {
45242
45248
  await ctx.db.execute(
@@ -45288,7 +45294,7 @@ function decidirApertura(e, ultimo, hoy, piso = 0) {
45288
45294
  if (antes !== null && antes >= 0 && ahora !== null && ahora < 0) return { abrir: true, motivo: "aceptada cuando dejaba margen, ahora da p\xE9rdida" };
45289
45295
  const mismoCalculo = !ultimo.calculo_aceptado || !e.calculo || ultimo.calculo_aceptado === e.calculo;
45290
45296
  const [a0, a1] = mismoCalculo ? [antes, ahora] : [ultimo.peor_aceptada ?? null, e.impacto_peor ?? null];
45291
- if (a0 !== null && a1 !== null && a1 < 0 && a0 - a1 > Math.max(Math.abs(a0) * CRECIMIENTO_QUE_REABRE, piso)) return { abrir: true, motivo: "la p\xE9rdida por mes creci\xF3 m\xE1s de un 20 % desde que la acept\xF3 la direcci\xF3n" };
45297
+ if (a0 !== null && a1 !== null && (a1 < 0 || e.clase === "margen_bajo") && a0 - a1 > Math.max(Math.abs(a0) * CRECIMIENTO_QUE_REABRE, piso)) return { abrir: true, motivo: a1 < 0 ? "la p\xE9rdida por mes creci\xF3 m\xE1s de un 20 % desde que la acept\xF3 la direcci\xF3n" : "lo que deja por mes cay\xF3 m\xE1s de un 20 % desde que la acept\xF3 la direcci\xF3n" };
45292
45298
  if (!ultimo.aceptada_hasta && antes === null) return { abrir: false, motivo: "la direcci\xF3n la acept\xF3 as\xED" };
45293
45299
  return { abrir: false, motivo: `aceptada por la direcci\xF3n${ultimo.aceptada_hasta ? ` hasta el ${ultimo.aceptada_hasta}` : ""}` };
45294
45300
  }
@@ -45730,6 +45736,17 @@ function pareceNoProfesional(nombre) {
45730
45736
  const [apellido = "", nombres = ""] = n2.split(",").map((x) => x.trim().toLowerCase());
45731
45737
  return /^[^a-záéíóúñü]/i.test(n2) || /\d/.test(n2) || apellido !== "" && apellido === nombres || /\b(admin|administrador|prueba|test|sistema|usuario)\b/i.test(n2);
45732
45738
  }
45739
+ function imputarMinutos(lecturas) {
45740
+ const mediana2 = (xs) => {
45741
+ const o = [...xs].sort((a, b) => a - b);
45742
+ return o.length ? o[Math.floor(o.length / 2)] : null;
45743
+ };
45744
+ const conDuracion = lecturas.filter((l) => l.minutos !== null);
45745
+ const general = mediana2(conDuracion.map((l) => l.minutos));
45746
+ const porTipo = /* @__PURE__ */ new Map();
45747
+ for (const l of conDuracion) porTipo.set(l.tipo ?? "", [...porTipo.get(l.tipo ?? "") ?? [], l.minutos]);
45748
+ for (const l of lecturas) if (l.minutos === null) l.minutos = mediana2(porTipo.get(l.tipo ?? "") ?? []) ?? general;
45749
+ }
45733
45750
  function resultadoPedido(d, e) {
45734
45751
  const accion = str2(d.accion) ?? "pedir_aumento";
45735
45752
  const pedido = typeof d.precio_propuesto === "number" ? d.precio_propuesto : null;
@@ -45737,8 +45754,9 @@ function resultadoPedido(d, e) {
45737
45754
  if (accion === "revisar_honorario") {
45738
45755
  const previo = d.evaluacion && typeof d.evaluacion === "object" ? d.evaluacion : {};
45739
45756
  const objetivo = typeof previo.honorario_objetivo === "number" ? previo.honorario_objetivo : null;
45740
- const prof = Array.isArray(previo.causa_profesionales) ? previo.causa_profesionales[0] : void 0;
45741
- const ahora = prof ? e.reparto.find((r) => r.profesional_id === prof.profesional_id)?.honorario ?? null : null;
45757
+ const profs = Array.isArray(previo.causa_profesionales) ? previo.causa_profesionales : [];
45758
+ const honorarios = profs.map((p) => e.reparto.find((r) => r.profesional_id === p.profesional_id)?.honorario ?? null);
45759
+ const ahora = honorarios.length && honorarios.every((h) => h !== null) ? Math.max(...honorarios) : null;
45742
45760
  return { accion, pedido: objetivo, ahora, cumple: objetivo !== null && ahora !== null ? ahora <= objetivo + 0.5 : null };
45743
45761
  }
45744
45762
  return { accion, pedido: null, ahora: null, cumple: e.clase === "rentable" ? true : null };
@@ -45755,6 +45773,7 @@ async function evaluarRentabilidades(ctx, companyId, lecturas) {
45755
45773
  const leidas = lecturas.map((x) => leerLecturaRentabilidad(x));
45756
45774
  const validas = leidas.flatMap((l) => "error" in l ? [] : [l.lectura]);
45757
45775
  for (const l of validas) conInsumosDeOpera(l, insumos);
45776
+ imputarMinutos(validas);
45758
45777
  const anteriores = new Map((await listarMediciones(ctx, companyId)).map((m) => [m.referencia, m]));
45759
45778
  const completa = validas.length > 0 && validas.length >= anteriores.size * 0.8;
45760
45779
  const bases = completa ? await guardarBases(ctx, companyId, validas, opciones.indirectos) : await leerBases(ctx, companyId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "paperclip-plugin-autopilot-ops",
3
- "version": "0.1.61",
3
+ "version": "0.1.62",
4
4
  "type": "module",
5
5
  "description": "Autopilot Care · operación autónoma gobernada para instituciones de salud: workflows determinísticos, validaciones, registro de negocio, políticas (observa/propone/ejecuta/corte) y tablero del director, como plugin de Paperclip.",
6
6
  "files": [