fix: decir una categoria a secas devolvia el menu principal

Los submenus estaban marcados nlu_skip para que la IA no ruteara a navegacion,
pero eso dejo solo las hojas en el catalogo: "ausentismo" tenia cuatro
candidatos y ninguno se llamaba asi, "sanidad" ninguno, "produccion" dos. Como
no podia elegir, caia al fallback y aparecia el menu principal, que se siente
como que ignoro el mensaje.

Las cuatro categorias vuelven a ser ruteables. Para que el filtro de permisos
las alcance —por tipo un menu no es ni subida ni descarga— se agrega nlu_dir,
con lo que cat 1 solo ve registrar y cat 2 solo consultar, y la ambiguedad se
resuelve sola. Cat 3 ve las dos, asi que tiene un menu que pregunta cual.

Cuando aun asi no rutea, ahora avisa antes de mostrar el menu.

Se quita el aprendizaje por usuario: el orden por uso lo resuelve Palmas360
sobre los registros reales, y dos criterios compitiendo sobraba.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-08-05 23:20:25 -05:00
co-authored by Claude Sonnet 4.6
parent 2d92867431
commit 6a6f2ef44a
4 changed files with 82 additions and 68 deletions
+41 -22
View File
@@ -462,33 +462,52 @@ check('el POST manda un array de ids', array_map('strval', array_keys($alternar(
check('accesible desde enviar información', $enMenu($config, '3', 'registrar_ciclo'), true);
echo "\nMotivos más usados primero\n";
echo "\nCategorías ruteables por el NLU\n";
check('el motivo aprende del uso', $campos['novedad_id']['frecuentes'] ?? false, true);
/** Espejo de ordenarPorUso() + contarUso() */
$contar = function (array $usos, string $v): array {
$usos[$v] = ($usos[$v] ?? 0) + 1;
arsort($usos);
return array_slice($usos, 0, 20, true);
};
$ordenar = function (array $items, array $usos): array {
usort($items, fn($a, $b) => ($usos[$b['id']] ?? 0) <=> ($usos[$a['id']] ?? 0));
return array_column($items, 'id');
/** Espejo de buildFlowCatalog(): qué ve la IA según la categoría del usuario */
$catalogo = function (array $config, int $perm): array {
$out = [];
foreach (flowsDe($config, (string)$perm) as $k => $f) {
$tipo = $f['type'] ?? 'text';
$dir = $f['nlu_dir'] ?? '';
$sube = in_array($tipo, ['collect_and_post', 'collect_for_each', 'submit_form'], true) || $dir === 'subida';
$baja = ($tipo === 'function' && ($f['function'] ?? '') === 'api_report') || $dir === 'descarga';
if ($sube && !in_array($perm, [1, 3], true)) continue;
if ($baja && !in_array($perm, [2, 3], true)) continue;
if (!empty($f['nlu_skip'])) continue;
if (($f['nlu_description'] ?? '') === '') continue;
$out[] = $k;
}
return $out;
};
$catalogo = [['id' => '25'], ['id' => '34'], ['id' => '35'], ['id' => '41']];
check('sin historial respeta el catálogo', $ordenar($catalogo, []), ['25', '34', '35', '41']);
// Los tres casos que reporto la clienta: decir la categoria a secas
foreach (['submenu_ausentismos', 'submenu_produccion', 'submenu_ciclos_sanidad', 'submenu_ciclos'] as $k) {
check("la IA puede rutear a {$k}", in_array($k, $catalogo($config, 2), true), true);
}
$usos = [];
foreach (['35', '35', '35', '41'] as $v) $usos = $contar($usos, $v);
check('cuenta cada elección', $usos, ['35' => 3, '41' => 1]);
check('sube los más usados y desempata alfabético',
$ordenar($catalogo, $usos), ['35', '41', '25', '34']);
// El filtro de permisos resuelve la ambiguedad en cat 1 y cat 2
$c1 = $catalogo($config, 1);
$c2 = $catalogo($config, 2);
check('cat 1 solo ve registrar ausentismo',
[in_array('registrar_ausentismo', $c1, true), in_array('submenu_ausentismos', $c1, true)], [true, false]);
check('cat 2 solo ve consultar ausentismos',
[in_array('registrar_ausentismo', $c2, true), in_array('submenu_ausentismos', $c2, true)], [true === false, true]);
// El contador vive en el metadata, que se limpia tras cada registro
check('los usos sobreviven al reset',
in_array('__usos', ['finca', 'grupo_mant', '__saludo', '__usos'], true), true);
// Cat 3 ve las dos, por eso necesita desambiguar
$c3 = $catalogo($config, 3);
check('cat 3 ve consultar y registrar',
[in_array('registrar_ausentismo', $c3, true), in_array('submenu_ausentismos', $c3, true)], [true, true]);
check('y tiene el menu que pregunta cual', in_array('ausentismo', $c3, true), true);
// La navegacion pura sigue oculta: rutear ahi no aporta nada
foreach (['show_main_menu', 'descargar_informes', 'enviar_informacion'] as $k) {
check("{$k} sigue oculto al NLU", in_array($k, $catalogo($config, 3), true), false);
}
// El orden por uso lo resuelve Palmas360, no el bot
check('el bot ya no reordena por su cuenta',
isset(flowsDe($config, '3')['registrar_ausentismo']['fields'][1]['frecuentes']), false);
echo "\nask_finca\n";
$af = $flows['ask_finca'];