nexusflex-mcp 3.69.0 → 3.70.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/docs.mjs +339 -373
- package/package.json +1 -1
- package/server.mjs +53 -50
package/docs.mjs
CHANGED
|
@@ -1,542 +1,508 @@
|
|
|
1
1
|
// ============================================================================
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
// ⚠️ ESPEJO: este archivo está DUPLICADO en `backend/src/services/mcp-docs.ts`
|
|
7
|
-
// (el conector remoto se deploya sin la carpeta mcp/). Si editás uno, editá el
|
|
8
|
-
// otro — igual que MCP_VERSION/NOVEDADES. Mantené el contenido idéntico.
|
|
2
|
+
// ⚠️ ARCHIVO GENERADO — NO EDITAR A MANO.
|
|
3
|
+
// Fuente: backend/src/services/mcp-docs.ts → regenerar con `cd backend && npm run mcp:docs`.
|
|
4
|
+
// El test backend/src/coherencia.test.ts falla si este archivo no coincide con la fuente.
|
|
9
5
|
// ============================================================================
|
|
10
|
-
|
|
11
|
-
// Tópicos transversales (no son tools) — se consultan con `ayuda tema:<clave>`.
|
|
12
|
-
export const TOPICS = {
|
|
6
|
+
const TOPICS = {
|
|
13
7
|
facturacion_marketplace: [
|
|
14
|
-
"
|
|
8
|
+
"FACTURACI\xD3N DEL MARKETPLACE DE RUTAS P\xDABLICAS",
|
|
15
9
|
"",
|
|
16
10
|
"Adjudicar una ruta (ruta_adjudicar) es OPERATIVO: cierra la subasta, marca el",
|
|
17
|
-
"nodo ganador (nodoToma) y deja registrada la
|
|
18
|
-
"(precioAcordado). NO crea
|
|
11
|
+
"nodo ganador (nodoToma) y deja registrada la OBLIGACI\xD3N al precio de la oferta",
|
|
12
|
+
"(precioAcordado). NO crea ning\xFAn asiento autom\xE1tico de facturaci\xF3n semanal, ni",
|
|
19
13
|
"en rendiciones, ni en comisiones de afiliado, ni en el clearing entre nodos.",
|
|
20
14
|
"El marketplace NO mueve dinero.",
|
|
21
15
|
"",
|
|
22
|
-
"Es decir: adjudicar
|
|
16
|
+
"Es decir: adjudicar \u2260 colecta. Una colecta entre nodos s\xED genera un \xEDtem de",
|
|
23
17
|
"clearing; una ruta adjudicada, NO. El pago entre el nodo que publica y el que",
|
|
24
|
-
"toma se acuerda y se salda MANUALMENTE (efectivo con el cadete, o
|
|
18
|
+
"toma se acuerda y se salda MANUALMENTE (efectivo con el cadete, o descont\xE1ndolo",
|
|
25
19
|
"de lo que un nodo ya le debe al otro por otros conceptos).",
|
|
26
20
|
"",
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
21
|
+
"C\xF3mo verificarlo desde el MCP:",
|
|
22
|
+
" \u2022 mis_rutas \u2192 estado 'adjudicada', nodoToma y precioAcordado de cada ruta tuya.",
|
|
23
|
+
" \u2022 rendiciones / comisiones_afiliado_ver \u2192 NO listar\xE1n la ruta adjudicada.",
|
|
30
24
|
"",
|
|
31
|
-
"
|
|
25
|
+
"Qu\xE9 falta (roadmap, todav\xEDa NO implementado): un settlement autom\xE1tico que,",
|
|
32
26
|
"al adjudicar, cargue el precioAcordado en la cuenta corriente entre los dos",
|
|
33
|
-
"nodos. Mientras no exista,
|
|
27
|
+
"nodos. Mientras no exista, trat\xE1 el pago como manual y avis\xE1selo al usuario."
|
|
34
28
|
].join("\n"),
|
|
35
|
-
|
|
36
29
|
dinero: [
|
|
37
|
-
"DINERO
|
|
30
|
+
"DINERO \u2014 QU\xC9 NO HACE NUNCA EL MCP",
|
|
38
31
|
"",
|
|
39
32
|
"El MCP nunca mueve plata: no registra pagos de vendedores, no factura, no",
|
|
40
33
|
"concilia caja, no imputa cobros/haberes en cuentas corrientes. Hay una denylist",
|
|
41
|
-
"de dinero (mcpMoneyGuard) heredada del backend. Las
|
|
34
|
+
"de dinero (mcpMoneyGuard) heredada del backend. Las \xFAnicas escrituras 'con",
|
|
42
35
|
"olor a plata' son configuraciones de TARIFA (colecta_configurar, precio_",
|
|
43
|
-
"actualizar, afiliacion_crear) o el REGISTRO de una
|
|
36
|
+
"actualizar, afiliacion_crear) o el REGISTRO de una obligaci\xF3n (comision_liquidar",
|
|
44
37
|
"marca comisiones ya devengadas como pagadas; ruta_adjudicar deja el precio",
|
|
45
|
-
"acordado). Ver tema facturacion_marketplace."
|
|
38
|
+
"acordado). Ver tema facturacion_marketplace."
|
|
46
39
|
].join("\n"),
|
|
47
|
-
|
|
48
40
|
aislamiento: [
|
|
49
41
|
"AISLAMIENTO ENTRE NODOS",
|
|
50
42
|
"",
|
|
51
43
|
"Cada token de MCP pertenece a un usuario. Todos los tools llaman a la API REST",
|
|
52
|
-
"del backend con ese token,
|
|
44
|
+
"del backend con ese token, as\xED que heredan el MISMO gateo que la web:",
|
|
53
45
|
"requireAuth + requirePermiso + scope por nodo/idCliente. Un vendedor solo ve",
|
|
54
|
-
"SUS
|
|
55
|
-
"tool puede leer ni escribir datos de otro nodo (salvo lo que es
|
|
56
|
-
"
|
|
57
|
-
"aislamiento del backend, no un bug."
|
|
58
|
-
].join("\n")
|
|
46
|
+
"SUS env\xEDos/stock; un operador solo su nodo; el admin global ve la red. Ning\xFAn",
|
|
47
|
+
"tool puede leer ni escribir datos de otro nodo (salvo lo que es p\xFAblico por",
|
|
48
|
+
"dise\xF1o, como el marketplace de rutas abiertas). Si un tool devuelve 403 es el",
|
|
49
|
+
"aislamiento del backend, no un bug."
|
|
50
|
+
].join("\n")
|
|
59
51
|
};
|
|
60
|
-
|
|
61
|
-
// Guías de arranque por rol (onboarding). Se muestran al conectar (server
|
|
62
|
-
// `instructions`) y con el tool `guia`. Metodología para empezar a usar el sistema
|
|
63
|
-
// rápido y bien, con las herramientas concretas de cada paso.
|
|
64
|
-
export const GUIAS = {
|
|
52
|
+
const GUIAS = {
|
|
65
53
|
mensajero: [
|
|
66
|
-
"
|
|
54
|
+
"GU\xCDA DEL MENSAJERO \u2014 registrar lo que colect\xE1s, en el momento",
|
|
67
55
|
"",
|
|
68
|
-
"La idea: cuando
|
|
69
|
-
"
|
|
56
|
+
"La idea: cuando pas\xE1s a colectar a un cliente, en vez de anotar a mano, me",
|
|
57
|
+
"mand\xE1s las FOTOS y yo cargo los env\xEDos por vos. Paso a paso:",
|
|
70
58
|
"",
|
|
71
|
-
"1)
|
|
59
|
+
"1) Sac\xE1 una FOTO de cada paquete que agarr\xE1s: la etiqueta (Flex/Mercado Libre",
|
|
72
60
|
" o la que sea) y, si tiene QR, que se vea. Si el paquete NO tiene etiqueta,",
|
|
73
|
-
"
|
|
74
|
-
"2)
|
|
75
|
-
"
|
|
76
|
-
"
|
|
61
|
+
" sac\xE1 foto igual (datos del paquete: a qui\xE9n va, direcci\xF3n, tel\xE9fono).",
|
|
62
|
+
"2) Mand\xE1melas todas juntas (un grupo de fotos). Yo leo cada una y registro el",
|
|
63
|
+
" env\xEDo del cliente que est\xE1s colectando:",
|
|
64
|
+
" \u2022 Con etiqueta ML / QR \u2192 lo registro con `envio_desde_etiqueta_ml`",
|
|
77
65
|
" (guardo el QR real, la etiqueta queda reimprimible).",
|
|
78
|
-
"
|
|
66
|
+
" \u2022 Sin etiqueta, con datos \u2192 lo registro con `envio_cargar` como pedido",
|
|
79
67
|
" manual y se le puede generar una etiqueta NUEVA para pegar.",
|
|
80
|
-
"3) IMPORTANTE (aislamiento): SOLO
|
|
68
|
+
"3) IMPORTANTE (aislamiento): SOLO pod\xE9s registrar env\xEDos de clientes de TU",
|
|
81
69
|
" nodo, o de un cliente que tengas COLECTADO (incluye colectas tomadas del",
|
|
82
70
|
" marketplace de colectas). De otros clientes, no.",
|
|
83
|
-
"4) Cada
|
|
71
|
+
"4) Cada env\xEDo queda 'A retirar', atribuido a vos, con un LINK de etiqueta",
|
|
84
72
|
" imprimible. El vendedor lo ve al toque en su cuenta.",
|
|
85
|
-
"5) Al llegar al nodo, el centro procesa los
|
|
86
|
-
" etiqueta se les pega una y salen normal.
|
|
73
|
+
"5) Al llegar al nodo, el centro procesa los env\xEDos; a los que cargaste sin",
|
|
74
|
+
" etiqueta se les pega una y salen normal. Despu\xE9s se escanean, aparecen en",
|
|
87
75
|
" el mapa y se te suma la tarifa como cualquier reparto.",
|
|
88
76
|
"",
|
|
89
|
-
"Tips: si una etiqueta se
|
|
90
|
-
"y
|
|
91
|
-
"ruta con `mi_ruta` y tus colectas con `mis_colectas`."
|
|
92
|
-
"(Próximamente: aviso en la app para imprimir de una todas las etiquetas que",
|
|
93
|
-
"cargaste por acá.)",
|
|
77
|
+
"Tips: si una etiqueta se rompi\xF3 o no se lee, carg\xE1 el env\xEDo con `envio_cargar`",
|
|
78
|
+
"y gener\xE1s una nueva. Consult\xE1 el estado de un env\xEDo con `envio_consultar`, tu",
|
|
79
|
+
"ruta con `mi_ruta` y tus colectas con `mis_colectas`."
|
|
94
80
|
].join("\n"),
|
|
95
|
-
|
|
96
81
|
cliente: [
|
|
97
|
-
"
|
|
82
|
+
"GU\xCDA DEL VENDEDOR \u2014 carg\xE1 tus ventas y segu\xED tu operaci\xF3n desde ac\xE1",
|
|
98
83
|
"",
|
|
99
|
-
"1) Cargar una venta/
|
|
100
|
-
"
|
|
84
|
+
"1) Cargar una venta/env\xEDo: `envio_cargar` con destinatario, tel\xE9fono,",
|
|
85
|
+
" direcci\xF3n y localidad (montoCobro si cobr\xE1s contra entrega). Te devuelvo",
|
|
101
86
|
" el tracking + un link de etiqueta para imprimir + un link para subir una",
|
|
102
87
|
" foto del paquete.",
|
|
103
|
-
"2)
|
|
88
|
+
"2) \xBFVend\xE9s por Mercado Libre? Mandame la foto de la etiqueta y la registro",
|
|
104
89
|
" con `envio_desde_etiqueta_ml` (queda con el QR real).",
|
|
105
|
-
"3) Colecta (que te retiren): `mi_colecta` para ver
|
|
106
|
-
" para prender/apagar la
|
|
90
|
+
"3) Colecta (que te retiren): `mi_colecta` para ver c\xF3mo est\xE1s, `colecta_auto`",
|
|
91
|
+
" para prender/apagar la autom\xE1tica, `colecta_solicitar` para una por \xFAnica vez.",
|
|
107
92
|
"4) Tu negocio: `mi_stock` / `mi_disponible` (para no sobrevender), ",
|
|
108
93
|
" `mi_rentabilidad`, `mis_top_productos`, `mis_kpis`. Sucursales de retiro con",
|
|
109
94
|
" `mis_sucursales` / `sucursal_guardar`.",
|
|
110
95
|
"",
|
|
111
|
-
"Todo lo tuyo es solo tuyo (aislamiento). Nunca toco dinero por ac
|
|
96
|
+
"Todo lo tuyo es solo tuyo (aislamiento). Nunca toco dinero por ac\xE1."
|
|
112
97
|
].join("\n"),
|
|
113
|
-
|
|
114
98
|
nodo: [
|
|
115
|
-
"
|
|
99
|
+
"GU\xCDA DEL NODO (operador/admin) \u2014 implementar y operar Nexus Flex r\xE1pido",
|
|
116
100
|
"",
|
|
117
101
|
"Puesta a punto:",
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
102
|
+
" \u2022 Vendedores: `cliente_crear` / `cliente_editar` (asign\xE1 su lista de precio).",
|
|
103
|
+
" \u2022 Choferes: `chofer_crear` (te devuelvo una clave temporal para pasarle).",
|
|
104
|
+
" \u2022 Colecta: `colecta_configurar` (pago del nodo/mensajero, cobro por vendedor).",
|
|
105
|
+
" \u2022 Zonas: `asignar_mensajero_zona` (mensajero\u2194metazona), `asignar_nodo_zona`",
|
|
122
106
|
" (un nodo de tu grupo cubre una localidad).",
|
|
123
107
|
"",
|
|
124
|
-
"El
|
|
125
|
-
"
|
|
108
|
+
"El d\xEDa a d\xEDa:",
|
|
109
|
+
" \u2022 `colecta_pendientes` (hoy + ma\xF1ana) y `colecta_asignar` (que Fulano levante",
|
|
126
110
|
" a tal cliente).",
|
|
127
|
-
"
|
|
128
|
-
" los ves 'A retirar'.
|
|
111
|
+
" \u2022 Env\xEDos: los cadetes pueden cargar lo que colectan por MCP (foto\u2192env\xEDo); vos",
|
|
112
|
+
" los ves 'A retirar'. Consult\xE1 con `envio_consultar`, correg\xED con",
|
|
129
113
|
" `cobro_corregir` / `envio_reasignar_cliente`.",
|
|
130
|
-
"
|
|
114
|
+
" \u2022 Rendiciones: `rendiciones` (qu\xE9 falta recuperar/rendir).",
|
|
131
115
|
"",
|
|
132
116
|
"Clearing entre nodos (eficiente):",
|
|
133
|
-
"
|
|
134
|
-
"
|
|
117
|
+
" \u2022 Metazonas + grupos log\xEDsticos rutean los env\xEDos al nodo que cubre la zona.",
|
|
118
|
+
" Recib\xEDs lo que te rutean con `envios_por_zona` \u2192 `procesar_zona` (aceptar) o",
|
|
135
119
|
" `rechazar_zona`. El clearing sale de la config de tarifas por grupo.",
|
|
136
|
-
"
|
|
137
|
-
" subasta abierta entre nodos. OJO: adjudicar NO factura
|
|
120
|
+
" \u2022 Marketplace de rutas (`rutas_publicas`, `ruta_publicar`/`ofertar`/`adjudicar`):",
|
|
121
|
+
" subasta abierta entre nodos. OJO: adjudicar NO factura autom\xE1tico \u2014 el pago",
|
|
138
122
|
" entre nodos se salda a mano (ver `ayuda tema:facturacion_marketplace`).",
|
|
139
|
-
"
|
|
123
|
+
" \u2022 N\xFAmeros: `kpi_nodo` (P&L, top clientes), `metricas_por_tipo`.",
|
|
140
124
|
"",
|
|
141
|
-
"Aislamiento: todo lo que ves/
|
|
142
|
-
].join("\n")
|
|
125
|
+
"Aislamiento: todo lo que ves/hac\xE9s es de TU nodo (o tu grupo cuando corresponde)."
|
|
126
|
+
].join("\n")
|
|
143
127
|
};
|
|
144
|
-
|
|
145
|
-
// Intro motivador (engancha antes de la guía del rol): que den ganas de hacerlo.
|
|
146
128
|
const INTRO = [
|
|
147
|
-
"
|
|
129
|
+
"\u{1F680} Bienvenido a Nexus Flex \u2014 tu operaci\xF3n entera desde el chat.",
|
|
148
130
|
"",
|
|
149
|
-
"Esto no es un
|
|
150
|
-
"clientes y choferes, cargar
|
|
151
|
-
"plata al
|
|
152
|
-
"planillas, sin clicks eternos. Cada cosa que
|
|
131
|
+
"Esto no es un men\xFA m\xE1s: le habl\xE1s y se hace. En 5 minutos pod\xE9s dar de alta",
|
|
132
|
+
"clientes y choferes, cargar env\xEDos sacando una FOTO (yo leo la etiqueta), ver tu",
|
|
133
|
+
"plata al d\xEDa, armar zonas, y hasta tomar rutas de otros nodos de la red. Sin",
|
|
134
|
+
"planillas, sin clicks eternos. Cada cosa que hac\xE9s ac\xE1 queda LIVE al instante y",
|
|
153
135
|
"aislada a lo tuyo (nadie ve lo de otro nodo).",
|
|
154
136
|
"",
|
|
155
|
-
"
|
|
156
|
-
"todo lo que
|
|
157
|
-
"",
|
|
158
|
-
"════════════════════════════════════════",
|
|
137
|
+
"Hac\xE9 la prueba: segu\xED los pasos de abajo, son 3 minutos y te va a quedar clar\xEDsimo",
|
|
138
|
+
"todo lo que pod\xE9s automatizar. \xBFListo? Arrancamos \u{1F447}",
|
|
159
139
|
"",
|
|
140
|
+
"\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550",
|
|
141
|
+
""
|
|
160
142
|
].join("\n");
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
export function guiaOnboarding(rol) {
|
|
164
|
-
const cuerpo =
|
|
165
|
-
rol === "mensajero" ? GUIAS.mensajero :
|
|
166
|
-
rol === "cliente" ? GUIAS.cliente :
|
|
167
|
-
rol === "operador" || rol === "admin" ? GUIAS.nodo :
|
|
168
|
-
[GUIAS.cliente, "", "— — —", "", GUIAS.nodo].join("\n");
|
|
143
|
+
function guiaOnboarding(rol) {
|
|
144
|
+
const cuerpo = rol === "mensajero" ? GUIAS.mensajero : rol === "cliente" ? GUIAS.cliente : rol === "operador" || rol === "admin" ? GUIAS.nodo : [GUIAS.cliente, "", "\u2014 \u2014 \u2014", "", GUIAS.nodo].join("\n");
|
|
169
145
|
return INTRO + cuerpo;
|
|
170
146
|
}
|
|
171
|
-
|
|
172
|
-
// Orden y agrupación para el índice (solo se muestran los que el usuario tiene).
|
|
173
|
-
export const GROUPS = [
|
|
147
|
+
const GROUPS = [
|
|
174
148
|
{ titulo: "General", tools: ["mis_datos", "guia", "flujo", "flujo_registrar", "ayuda", "mcp_version", "sugerencia_crear", "mis_sugerencias"] },
|
|
175
|
-
{ titulo: "Vendedor
|
|
176
|
-
{ titulo: "Vendedor
|
|
149
|
+
{ titulo: "Vendedor \u2014 mi operaci\xF3n", tools: ["mis_envios", "envio_consultar", "mis_sucursales", "sucursal_guardar", "mi_colecta", "colecta_solicitar", "colecta_auto"] },
|
|
150
|
+
{ titulo: "Vendedor \u2014 mi stock y n\xFAmeros", tools: ["mi_stock", "mi_disponible", "mi_rentabilidad", "mis_productos", "mis_top_productos", "mis_kpis"] },
|
|
177
151
|
{ titulo: "Mensajero", tools: ["mi_ruta", "mis_colectas"] },
|
|
178
|
-
{ titulo: "
|
|
179
|
-
{ titulo: "Colecta y zonas (staff)", tools: ["colecta_ver", "colecta_pendientes", "colecta_historial", "colecta_configurar", "colecta_fija", "colecta_asignar", "
|
|
152
|
+
{ titulo: "Env\xEDos (staff)", tools: ["envio_cargar", "envio_desde_etiqueta_ml", "envio_procesar", "envio_entregar", "envio_estado", "envios_trabados", "planilla_reporte", "envio_asignar_grupo", "nodo_provisorio_crear", "provisorio_conciliar", "envio_reasignar_cliente", "envio_mensajero_externo", "envio_editar_zona", "envio_editar_fecha", "cobro_corregir", "sin_vendedor", "asignar_sin_vendedor", "envio_completar_ciclo", "envio_pago_mensajero", "envio_corregir_estado", "envio_asignar_mensajero"] },
|
|
153
|
+
{ titulo: "Colecta y zonas (staff)", tools: ["colecta_ver", "colecta_pendientes", "colecta_historial", "colecta_configurar", "colecta_fija", "colecta_asignar", "colecta_desasignar", "zonas_reparto", "zona_barrios", "zonas_simetria", "asignar_mensajero_zona", "asignar_nodo_zona", "envios_por_zona", "procesar_zona", "rechazar_zona", "grupos_tarifas", "nodo_alias_poner", "zona_dejar", "nodo_link_confirmacion", "zonas_grupo", "zona_mover_metazona", "zona_componer_grupo", "grupo_tarifa_set", "retiros_cargar"] },
|
|
180
154
|
{ titulo: "Rendiciones y reclamos", tools: ["rendiciones", "rendicion_revertir", "reclamos_listar"] },
|
|
181
155
|
{ titulo: "Marketplace de rutas", tools: ["rutas_publicas", "mis_rutas", "ruta_ofertas", "ruta_publicar", "ruta_ofertar", "ruta_adjudicar"] },
|
|
182
156
|
{ titulo: "Afiliados", tools: ["afiliacion_listar", "comisiones_afiliado_ver", "afiliado_crear", "afiliacion_crear", "afiliacion_editar", "comision_liquidar"] },
|
|
183
|
-
{ titulo: "
|
|
157
|
+
{ titulo: "M\xE9tricas / KPIs", tools: ["kpi_nodo", "kpi_red", "metricas_por_tipo", "top_productos"] },
|
|
184
158
|
{ titulo: "WMS del nodo", tools: ["stock_nodo", "productos_nodo", "producto_crear"] },
|
|
185
|
-
{ titulo: "
|
|
186
|
-
{ titulo: "Marketing /
|
|
187
|
-
{ titulo: "Liquidaciones (consulta)", tools: ["liquidacion_buscar", "liquidacion_detalle", "liquidaciones_sin_recibir"] },
|
|
159
|
+
{ titulo: "Gesti\xF3n del nodo", tools: ["clientes_del_nodo", "cliente_crear", "cliente_editar", "sucursales_cliente", "sucursal_perfil", "precios_ver", "precio_actualizar", "cuentas_vinculadas", "generar_enlace_vinculacion", "facturacion_estado", "facturacion_preparar_cliente"] },
|
|
160
|
+
{ titulo: "Marketing / atribuci\xF3n", tools: ["marketing_config_ver", "marketing_config_guardar"] },
|
|
161
|
+
{ titulo: "Liquidaciones (consulta)", tools: ["liquidacion_buscar", "liquidacion_detalle", "liquidaciones_sin_recibir", "liquidacion_excluir_envio", "liquidacion_reincluir_envio", "cuenta_semanal_nodos"] },
|
|
188
162
|
{ titulo: "Usuarios / choferes", tools: ["chofer_listar", "chofer_crear", "chofer_editar", "usuario_editar", "operador_crear", "cliente_generar_usuario", "cliente_resetear_clave", "usuario_habilitar_reparto"] },
|
|
189
|
-
{ titulo: "
|
|
163
|
+
{ titulo: "Administraci\xF3n (red)", tools: ["nodos_listar", "nodo_crear", "usuario_habilitar_rol", "grupo_crear", "logo_subir", "sugerencias_listar", "cierre_semanal_links", "nodo_renombrar", "grupo_miembros", "grupo_sumar_nodo", "grupo_expulsar_nodo", "grupo_admin_permiso"] }
|
|
190
164
|
];
|
|
191
|
-
|
|
192
|
-
//
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
165
|
+
const TOOL_DOCS = {
|
|
166
|
+
// Fichas agregadas 23/09 (esos tools no tenían ayuda; ahora lo exige src/coherencia.test.ts).
|
|
167
|
+
sin_vendedor: { "que": "Muestra las cuentas de Mercado Libre y env\xEDos cargados con foto que tu nodo tiene sin vendedor.", "uso": "Sin par\xE1metros obligatorios. Devuelve cuentas (cu\xE1ntos env\xEDos, ejemplos de destinatarios, si ya est\xE1 vinculada), env\xEDos (los cargados con foto), y clientes del nodo (con si tienen usuario). Admin global: pas\xE1 `nodo` para elegir/acotar el nodo.", "ej": "sin_vendedor nodo:6 \u2192 ves las cuentas y env\xEDos hu\xE9rfanos del nodo 6 para asignarlos con asignar_sin_vendedor.", "no": "No asigna (para eso us\xE1 asignar_sin_vendedor); no mueve dinero." },
|
|
168
|
+
asignar_sin_vendedor: { "que": "Asigna a UN vendedor las cuentas de Mercado Libre y env\xEDos sin vendedor de tu nodo, en un paso, y devuelve enlaces de vinculaci\xF3n.", "uso": "Pas\xE1 idCliente (vendedor existente) O nuevoVendedor (nombre, se crea); cuentasML (array de n\xFAmeros de usuario ML) y/o envioIds (ids de sin_vendedor); opcionales usuarioEmail/usuarioNombre/usuarioApellido para crearle usuario si no tiene. Admin global: `nodo` para elegir/acotar el nodo.", "ej": "asignar_sin_vendedor idCliente:130 cuentasML:['123456','789012'] envioIds:[1,2,3] \u2192 le pasa las cuentas y env\xEDos, devuelve los enlaces de vinculaci\xF3n.", "no": "No vincula las cuentas por s\xED solo: devuelve el enlace para que el vendedor lo autorice en 48 hs; no mueve dinero." },
|
|
169
|
+
liquidacion_excluir_envio: { "que": "Saca un env\xEDo del cobro de una liquidaci\xF3n YA emitida y re-suma el total.", "uso": "id (liquidaci\xF3n), tracking (del env\xEDo a excluir), motivo (obligatorio, m\xEDnimo 10 caracteres, lo ve el vendedor). Requiere permiso finanzas. Si esa liquidaci\xF3n ya est\xE1 en una factura ARCA emitida, la rechaza (har\xEDa falta nota de cr\xE9dito).", "ej": "liquidacion_excluir_envio id:1234 tracking:'NFABC123' motivo:'el nodo no lo entreg\xF3, qued\xF3 en el centro'.", "no": "No emite nota de cr\xE9dito: si la liquidaci\xF3n ya est\xE1 en una factura de ARCA emitida, lo rechaza. Re-suma la liquidaci\xF3n y ajusta la cuenta corriente del vendedor (no es un pago ni un cobro)." },
|
|
170
|
+
liquidacion_reincluir_envio: { "que": "Lo inverso de liquidacion_excluir_envio: devuelve al cobro un env\xEDo que se hab\xEDa excluido.", "uso": "id (liquidaci\xF3n), tracking (del env\xEDo a reincluir), motivo (obligatorio, m\xEDnimo 10 caracteres, ej. 'el nodo s\xED lo entreg\xF3, hay foto'). Requiere permiso finanzas. Mismo guard de factura emitida.", "ej": "liquidacion_reincluir_envio id:1234 tracking:'NFABC123' motivo:'verif con el nodo, s\xED lo entreg\xF3'.", "no": "Mismo cuidado que excluir: si la liquidaci\xF3n ya est\xE1 facturada en ARCA, lo rechaza. Re-suma y ajusta la cuenta corriente; no es un pago ni un cobro." },
|
|
171
|
+
cuenta_semanal_nodos: { "que": "La cuenta de TU nodo con cada nodo con el que se pasaron paquetes por un grupo (de lunes a s\xE1bado que se congela el mi\xE9rcoles siguiente).", "uso": "Sin par\xE1metros lista lo que est\xE1 EN VIVO, a\xFAn no cerrado. Con `cierre` (id): ese cierre congelado. Con `lista:true`: tus cierres semanales con su neto. Admin global: `nodo` para elegir/acotar el nodo.", "ej": "cuenta_semanal_nodos lista:true \u2192 ves tus cierres; cuenta_semanal_nodos cierre:100 \u2192 ese cierre congelado con el detalle por nodo.", "no": "No cierra semanas (se cierran solas); no mueve dinero." },
|
|
172
|
+
cierre_semanal_links: { "que": "Para cada nodo de un cierre semanal, el link SIN LOGIN donde ve su cuenta y la baja en PDF.", "uso": "Opcional cierre (id del cierre; default: el \xFAltimo). Devuelve primero los nodos SIN usuario: a esos pas\xE1selo por WhatsApp. Solo admin global.", "ej": "cierre_semanal_links cierre:100 \u2192 recib\xEDs los links de todos los nodos para mandarles por WhatsApp.", "no": "No env\xEDa por WhatsApp (solo genera el link); solo lectura." },
|
|
173
|
+
nodo_renombrar: { "que": "Cambia la raz\xF3n social (nombre real) de un nodo \u2014 lo ve TODO el mundo.", "uso": "nodo (nombre actual o tu apodo), nombreNuevo (nombre nuevo). Solo admin global. No toca dinero.", "ej": "nodo_renombrar nodo:'FastCorreo' nombreNuevo:'FastCorreo Log\xEDstica'.", "no": "No es un apodo personal (para eso us\xE1 nodo_alias_poner); la cambio es global." },
|
|
174
|
+
grupos_tarifas: { "que": "Los grupos log\xEDsticos de tu nodo (admin global: todos) con los nodos que los integran y la TARIFA de clearing por zona de cada uno.", "uso": "Sin par\xE1metros. Admin global: cualquier nodo; operador: sus grupos. Es lo que mir\xE1s para auditar por qu\xE9 un traspaso entre nodos se cobr\xF3 lo que se cobr\xF3.", "ej": "grupos_tarifas \u2192 ves Bonorino, Portela, etc. con sus nodos y cu\xE1nto cobra cada zona.", "no": "No modifica tarifas (para eso us\xE1 grupo_tarifa_set); solo lectura." },
|
|
175
|
+
nodo_alias_poner: { "que": "Le pon\xE9s TU propio apodo a un nodo para reconocerlo m\xE1s f\xE1cil \u2014 es personal.", "uso": "nodo (nombre actual o tu apodo), alias (el apodo nuevo; vac\xEDo para sacarlo). Pod\xE9s usar ese apodo en cualquier herramienta que pida un nodo.", "ej": `nodo_alias_poner nodo:'Log\xEDstica Portela' alias:'RL Zona Sur' \u2192 de ah\xED en m\xE1s pod\xE9s decir 'asignar_nodo_zona nodo:"RL Zona Sur"'.`, "no": "No es un cambio global (nodo_renombrar s\xED); solo te lo ve a vos." },
|
|
176
|
+
zona_dejar: { "que": "Te sac\xE1s (a tu nodo) de una zona de un grupo log\xEDstico que ten\xEDas asignada \u2014 self-service.", "uso": "grupo (nombre o id), metazona (nombre/localidad que dej\xE1s). Si eras el \xFAnico responsable, la zona pasa a LIBERADA y se avisa al grupo.", "ej": "zona_dejar grupo:'Portela' metazona:'Ensenada' \u2192 te sac\xE1s de esa zona.", "no": "Solo te saca a VOS (no a otro nodo) y no reasigna la zona: la libera (deja de cubrirla tu nodo) y, si eras el \xFAnico, solo la comisi\xF3n la vuelve a asignar. No mueve dinero." },
|
|
177
|
+
nodo_link_confirmacion: { "que": "Devuelve el link FIJO (sin login) donde un nodo sin usuarios propios ve sus responsabilidades de zona y las confirma.", "uso": "nodo (nombre o tu apodo del nodo). El link es el mismo siempre para ese nodo.", "ej": "nodo_link_confirmacion nodo:'Feeder Sur' \u2192 recib\xEDs el link para mandarle por WhatsApp a ese nodo que no tiene tel\xE9fono cargado.", "no": "No entra en el link por vos; solo devuelve la URL." },
|
|
178
|
+
zonas_grupo: { "que": "Lista las zonas de un grupo log\xEDstico con el nodo responsable de cada una, marcando las LIBERADAS y si pod\xE9s reasignarlas.", "uso": "grupo (nombre o id). Visible a cualquier miembro del grupo. Solo lectura.", "ej": "zonas_grupo grupo:'Bonorino' \u2192 ves qu\xE9 nodo cubre cada zona y cu\xE1les est\xE1n libres (sin responsable).", "no": "No asigna (us\xE1 asignar_nodo_zona + `grupo`)." },
|
|
179
|
+
zona_mover_metazona: { "que": "Reclasifica una metazona/localidad: la saca de la zona de grupo que la contiene y la mete en OTRA zona del MISMO grupo.", "uso": "grupo, metazona (a mover), zonaDestino (nombre, id, o una metazona que ya tenga). Solo comisi\xF3n (admin) del grupo o admin global.", "ej": "zona_mover_metazona grupo:'Portela' metazona:'El Palomar' zonaDestino:'Tres de Febrero' \u2192 paso El Palomar de Mor\xF3n a Tres de Febrero.", "no": "No cambia el nodo responsable (solo reclasifica de zona); no mueve dinero." },
|
|
180
|
+
zona_componer_grupo: { "que": "Crea o edita una zona de un grupo log\xEDstico: la ubica por nombre/id, le puede sumar un nodo responsable y agrega/quita metazonas de su composici\xF3n.", "uso": "grupo, zona (nombre o id; se crea si no existe), nodo (responsable, opcional), agregar (array de metazonas a sumar), quitar (array a quitar). Solo comisi\xF3n del grupo o admin global.", "ej": "zona_componer_grupo grupo:'Portela' zona:'Flores' nodo:'FastCorreo' agregar:['CABA \xB7 Flores','Flores'] \u2192 crea/edita la zona y la suma las metazonas.", "no": "No mueve dinero; importante: el ruteo matchea EXACTAMENTE por metazona, as\xED que una zona CABA necesita 'CABA \xB7 Barrio' Y 'Barrio' separadas." },
|
|
181
|
+
grupo_tarifa_set: { "que": "Fija la tarifa de clearing por zona (cercana/media/lejana/muyLejana) de TODO un grupo en una sola llamada.", "uso": "grupo, y opcionalmente los montos (cercana, media, lejana, muyLejana). Con `soloDef:true`: solo el default del grupo, sin tocar los nodos miembro. Solo comisi\xF3n (admin) del grupo o admin global.", "ej": "grupo_tarifa_set grupo:'Portela' cercana:2700 media:3200 lejana:4500 muyLejana:6000 \u2192 todos los nodos del grupo quedan en esa tarifa.", "no": "No mueve dinero; es config del clearing." },
|
|
182
|
+
envio_completar_ciclo: { "que": "Rellena los pasos que le FALTAN a un env\xEDo ya cerrado: Colectado, En centro y En camino, cada uno a nombre de quien lo hizo.", "uso": "trackings (array; ej. ['NFABC123','TN-2057600163']), fecha (d\xEDa real en que se hicieron los pasos, dd/mm/aaaa), y por cada paso: colectado, procesado, enCamino (nombre o id). Si no pas\xE1s una persona, ese paso no se agrega.", "ej": "envio_completar_ciclo trackings:['NFABC123','TN-456'] fecha:'14/09/2026' colectado:'Maxi' procesado:'Ana' enCamino:'Juan' \u2192 les agrega los pasos faltantes con las personas que los hicieron.", "no": "No duplica pasos ya existentes; no inventa autores; no cambia el estado actual del env\xEDo ni mueve dinero." },
|
|
183
|
+
envio_pago_mensajero: { "que": "Carga lo que se le paga a quien reparti\xF3 cada env\xEDo y, si falta el nombre del mensajero, lo completa.", "uso": "trackings (array), valor (pesos por env\xEDo), mensajero (opcional: nombre o id, para asignar y pagar en un paso), incluirNoEntregados (opcional: true para pagar tambi\xE9n Cancelados/Devueltos).", "ej": "envio_pago_mensajero trackings:['NFABC','TN-456'] valor:2500 mensajero:'Maxi' \u2192 los paga a Maxi a $2500 cada uno.", "no": "No paga: escribe valor + nombre, y con eso el env\xEDo entra al resumen de pago del cadete. Por defecto NO toca env\xEDos no entregados; no mueve dinero." },
|
|
184
|
+
envio_corregir_estado: { "que": "Corrige el ESTADO de un env\xEDo ya cargado para deshacer algo que qued\xF3 mal.", "uso": "tracking, estado (destino: ej. 'Cancelado', 'En camino', 'Entregado'), motivo (obligatorio, m\xEDnimo 10 caracteres, queda en el historial). Acepta estados terminales ('Cancelado', 'Rechazado por el comprador').", "ej": "envio_corregir_estado tracking:'NFABC123' estado:'Cancelado' motivo:'error del sistema, se marc\xF3 entregado sin serlo'.", "no": "No toca banderas de devoluci\xF3n ni cobro; no mueve dinero; el motivo es obligatorio." },
|
|
185
|
+
envio_asignar_mensajero: { "que": "Asigna \u2014o QUITA con `quitar:true`\u2014 el MENSAJERO de env\xEDos ya cargados.", "uso": "trackings (array), mensajero (nombre o id; busca entre TODOS los que pueden repartir, no solo 'mensajero'). Con `quitar:true` lo deja SIN mensajero. Si el nombre matchea a varios, devuelve los candidatos con su id.", "ej": "envio_asignar_mensajero trackings:['NFABC','TN-456'] mensajero:7 \u2192 les asigna al mensajero con id 7. / envio_asignar_mensajero trackings:['NFABC'] quitar:true \u2192 lo deja SIN mensajero.", "no": "No mueve dinero (el pago al cadete se liquida por NOMBRE); no entra en el clearing." },
|
|
186
|
+
retiros_cargar: { "que": "Carga de una vez la LISTA DE RETIROS del d\xEDa (la ronda de paradas donde el cadete va a BUSCAR). Reemplaza la carga por Excel Maestro.", "uso": "cliente + direcciones[] (una por parada, pueden venir numeradas '1. Helguera 936, CABA': el n\xFAmero se toma como orden de ruta) + zona ('Retiro en CABA' o 'Retiro en GBA', la que cobra y paga) + mensajero para toda la ronda + fecha si no es hoy.", "ej": "retiros_cargar cliente:'Fast Correo' mensajero:'Maxi' direcciones:['1. Helguera 936, CABA','2. Nepper 1273, CABA'].", "no": "NO es colecta_asignar (eso es levantarle los paquetes a un vendedor). No mueve dinero. Repetir la misma direcci\xF3n el mismo d\xEDa no duplica." },
|
|
187
|
+
facturacion_estado: { que: "Diagn\xF3stico de facturaci\xF3n ARCA: emisores del nodo y si est\xE1n completos, cuentas de dinero sin emisor propio, y por cada cliente qu\xE9 dato le falta para poder facturarle.", uso: "Sin argumentos = los clientes YA habilitados. cliente:<nombre|id> = ese cliente, aunque todav\xEDa no est\xE9 habilitado.", ej: "facturacion_estado cliente:Segucentro \u2192 te dice si le falta CUIT, raz\xF3n social, condici\xF3n IVA, emisor o la habilitaci\xF3n.", no: "No devuelve importes ni factura nada. Es estado de configuraci\xF3n." },
|
|
188
|
+
facturacion_preparar_cliente: { que: "Deja un cliente listo para facturar: CUIT, raz\xF3n social (el titular del CUIT), condici\xF3n IVA, cuenta donde cobra (define QUI\xC9N factura), frecuencia y corte.", uso: "cliente, cuit, razonSocial y condicionIVA son obligatorios; cuentaCobro, frecuencia (Semanal|Mensual) y desde (YYYY-MM-DD) son opcionales. El corte por defecto es HOY.", ej: "facturacion_preparar_cliente cliente:'Digital Store' cuit:30714508160 razonSocial:'DIGITAL STORE' condicionIVA:RI cuentaCobro:'UALA ElMaxzito' frecuencia:Semanal", no: "NO emite comprobantes (el MCP no factura) ni hace el tr\xE1mite en ARCA: eso necesita la Clave Fiscal de esa persona y se hace en la web de ARCA." },
|
|
189
|
+
ayuda: { que: "Devuelve esta documentaci\xF3n: \xEDndice de herramientas o la ficha completa de una (qu\xE9 hace, params, ejemplo, qu\xE9 NO hace) y t\xF3picos transversales.", uso: "Sin argumentos = \xEDndice. `tool:<nombre>` = ficha de esa herramienta. `tema:<clave>` = t\xF3pico (facturacion_marketplace, dinero, aislamiento).", ej: "ayuda tool:ruta_adjudicar \u2192 te explica c\xF3mo adjudicar y aclara que no mueve dinero.", no: "No ejecuta nada ni consulta datos; es solo lectura de documentaci\xF3n est\xE1tica." },
|
|
190
|
+
guia: { que: "Gu\xEDa de ARRANQUE para tu rol: la metodolog\xEDa para empezar a usar Nexus Flex r\xE1pido, con las herramientas de cada paso (mensajero: foto\u2192env\xEDo al colectar; vendedor: cargar ventas; nodo: implementar + operar + clearing).", uso: "Sin argumentos = tu gu\xEDa seg\xFAn tu rol. `rol:<mensajero|cliente|nodo>` para ver otra.", ej: "Reci\xE9n conect\xE1s como mensajero \u2192 guia \u2192 te explico c\xF3mo registrar lo que colect\xE1s sacando fotos.", no: "No ejecuta acciones; es la metodolog\xEDa. Para el detalle de una herramienta us\xE1 `ayuda tool:<x>`." },
|
|
191
|
+
flujo: { que: "Paso a paso de un OBJETIVO para completarlo sin dejar nada incompleto (ej. alta de cliente con su lista de precios). Sirve para guiar a alguien que no sabe qu\xE9 datos faltan.", uso: "Sin argumento = lista los flujos. `objetivo:<alta_cliente|alta_operador|alta_chofer|control_por_foto|alta_planilla_ml|facturacion>` = el paso a paso.", ej: "flujo alta_cliente \u2192 te digo que despu\xE9s de crearlo hay que preguntar qu\xE9 lista de precios le cobr\xE1s.", no: "No ejecuta las acciones; te da la secuencia. Cada paso usa su propia herramienta." },
|
|
192
|
+
mis_datos: { que: "Tu usuario, rol y nodo/cliente: define tu ALCANCE (qu\xE9 pod\xE9s ver/hacer).", uso: "Sin par\xE1metros.", ej: "Antes de operar, mis_datos \u2192 confirm\xE1s que sos operador del nodo 6 y qu\xE9 permisos ten\xE9s.", no: "No lista otros usuarios ni cambia nada." },
|
|
193
|
+
mcp_version: { que: "Versi\xF3n del MCP corriendo, por qu\xE9 v\xEDa (remoto/npx) y las novedades recientes.", uso: "Sin par\xE1metros.", ej: "El usuario pregunta 'tengo lo \xFAltimo' \u2192 mcp_version.", no: "No actualiza el MCP." },
|
|
201
194
|
sugerencia_crear: { que: "Registra una sugerencia/mejora/bug del usuario (queda para el equipo).", uso: "mensaje (obligatorio); categoria opcional (funcionalidad|mejora|bug|otro). Se adjunta tu usuario/rol/nodo solo.", ej: "sugerencia_crear mensaje:'Sumar recordatorio de colecta' categoria:mejora.", no: "No abre tickets externos ni notifica por mail." },
|
|
202
|
-
mis_sugerencias: { que: "Tus PROPIAS sugerencias/pedidos de mejora y en
|
|
203
|
-
flujo_registrar: { que: "Registra un 'flujo aprendido': cuando el asistente tuvo que hacer VARIAS preguntas para descubrir
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
colecta_configurar: { que: "Setea un valor de colecta según alcance.", uso: "alcance: 'nodo' (pago default por colecta), 'mensajero' (default de ese cadete), 'cliente' (cuánto se le COBRA a ese vendedor; idCliente + valor, minEnvios opcional), 'par' (pago pactado a un mensajero por un cliente puntual; idCliente + mensajero + valor). Scopeado a tu nodo. Admin global: `nodo` para elegir/acotar el nodo.", ej: "colecta_configurar alcance:cliente idCliente:'130' valor:2500 minEnvios:5 → gratis desde 5 envíos, sino $2500.", no: "No mueve dinero: es config de tarifa (el cobro se aplica al liquidar)." },
|
|
241
|
-
colecta_fija: { que: "Días en que se va a buscar SIEMPRE a un vendedor, tenga o no envíos cargados (colecta fija).", uso: "idCliente + dias (números 0-6 o nombres). dias:[] la quita. Requiere permiso gestion.", ej: "colecta_fija idCliente:\"130\" dias:[1,3,5] → lunes, miércoles y viernes.", no: "No mueve dinero (el cobro/pago de la colecta es colecta_configurar); no crea la colecta del día, hace que aparezca en el panel." },
|
|
242
|
-
colecta_asignar: { que: "Asigna la colecta de un cliente a un mensajero (ambos por nombre de tu nodo) y avisa al cadete.", uso: "cliente + mensajero (nombres). Sirve TAMBIÉN para clientes SIN envíos cargados: la colecta se crea vacía y el cadete escanea los paquetes en la puerta (se crean solos a nombre del vendedor, sin duplicar el mismo QR). Si el corte venció, la programa para el próximo día hábil. Admin global: `nodo` para elegir/acotar el nodo.", ej: "colecta_asignar cliente:'Distri Sur' mensajero:'Maxi'.", no: "No mueve dinero; no cruza nodos." },
|
|
243
|
-
retiros_cargar: { que: "Carga de una vez la LISTA DE RETIROS del día (la ronda de paradas donde el cadete va a BUSCAR). Reemplaza la carga por Excel Maestro.", uso: "cliente + direcciones[] (una por parada, pueden venir numeradas '1. Helguera 936, CABA': el número se toma como orden de ruta) + zona ('Retiro en CABA' o 'Retiro en GBA', la que cobra y paga) + mensajero para toda la ronda + fecha si no es hoy.", ej: "retiros_cargar cliente:'Fast Correo' mensajero:'Maxi' direcciones:['1. Helguera 936, CABA','2. Nepper 1273, CABA'].", no: "NO es colecta_asignar (eso es levantarle los paquetes a un vendedor). No mueve dinero. Repetir la misma dirección el mismo día no duplica." },
|
|
244
|
-
colecta_desasignar: { que: "Quita la asignación de una colecta (los envíos vuelven a 'sin colecta').", uso: "colectaId (lo devuelve colecta_pendientes). Admin global: `nodo` para elegir/acotar el nodo. Solo colectas de tu nodo.", ej: "colecta_desasignar colectaId:44.", no: "No borra los envíos; no mueve dinero." },
|
|
245
|
-
zonas_reparto: { que: "Zonas de reparto del nodo con sus metazonas y qué mensajeros tiene cada una.", uso: "Sin parámetros.", ej: "zonas_reparto → ver quién cubre Palermo.", no: "No asigna (asignar_mensajero_zona / asignar_nodo_zona)." },
|
|
195
|
+
mis_sugerencias: { que: "Tus PROPIAS sugerencias/pedidos de mejora y en qu\xE9 estado est\xE1n (Recibida / En evaluaci\xF3n / \u2705 Implementada / Descartada). Cada usuario ve solo las suyas.", uso: "Sin argumentos.", ej: "mis_sugerencias \u2192 ves cu\xE1les de tus pedidos ya se aplicaron.", no: "No muestra las de otros usuarios (eso es `sugerencias_listar`, solo superadmin); no cambia su estado." },
|
|
196
|
+
flujo_registrar: { que: "Registra un 'flujo aprendido': cuando el asistente tuvo que hacer VARIAS preguntas para descubrir qu\xE9 quer\xEDas (no lo pediste directo), guarda el objetivo + los pasos que lo aclararon, para armar un flujo directo.", uso: "objetivo (lo que terminaste queriendo) + pasos (las preguntas/decisiones + herramientas usadas). Lo llama el asistente solo cuando corresponde.", ej: "flujo_registrar objetivo:'cargar 5 paquetes ML de un nodo nuevo' pasos:'pregunt\xF3 de qui\xE9n eran \u2192 nodo no estaba \u2192 cre\xF3 provisorio \u2192 carg\xF3 reusando QR'.", no: "No crea el flujo autom\xE1ticamente (lo revisa el equipo); no mueve dinero." },
|
|
197
|
+
mis_envios: { que: "Tus env\xEDos/paquetes (solo los tuyos).", uso: "estado opcional (filtra por estado).", ej: "mis_envios estado:'En camino' \u2192 los que est\xE1n en reparto.", no: "No muestra env\xEDos de otros vendedores; no los edita." },
|
|
198
|
+
envio_consultar: { que: "Busca UN env\xEDo por tracking/c\xF3digo y devuelve estado, historial, destino y datos de cobro/cambio.", uso: "codigo (tracking o c\xF3digo). Vendedor: entre SUS env\xEDos; staff: dentro de su nodo. Si hay varios matches, pas\xE1 el tracking completo.", ej: "El vendedor pregunta '\xBFd\xF3nde est\xE1 44000...?' \u2192 envio_consultar codigo:'44000123'.", no: "No cambia el estado del env\xEDo; no busca fuera de tu alcance." },
|
|
199
|
+
envio_estado: { que: "Narrativa de estado + ETA de un env\xEDo para responder '\xBFcu\xE1ndo llega?': mensajero asignado, cu\xE1ntos env\xEDos lleva en la ruta, en qu\xE9 posici\xF3n va este y un estimado (posici\xF3n \xD7 min/parada). Marca problemas (nunca despachado, sin mensajero, mensajero detenido).", uso: "tracking. Staff y mensajero, scopeado a tu nodo. Es una estimaci\xF3n explicable, no exacta.", ej: "El vendedor pregunta '\xBFcu\xE1ndo entregan NFABC?' \u2192 envio_estado tracking:'NFABC' \u2192 'En camino con Maxi, 8 env\xEDos en ruta, este va 3\xBA, ~24 min'.", no: "No cambia nada; la ETA es orientativa." },
|
|
200
|
+
envios_trabados: { que: "Lista los env\xEDos TRABADOS de tu nodo con el motivo: estancado (mucho tiempo sin avanzar), sin_mensajero (en el centro sin asignar), mensajero_detenido (en camino, sin reportar ubicaci\xF3n) o en_camino_sin_cerrar (en camino +24h sin cerrarse: candidato a cerrar; confirm\xE1 con el usuario antes de marcarlo entregado).", uso: "Sin par\xE1metros. Staff. Ordenados por severidad. Misma detecci\xF3n que el aviso proactivo a operativos y admins del nodo.", ej: "El jefe pregunta '\xBFqu\xE9 qued\xF3 trabado / por cerrar hoy?' \u2192 envios_trabados.", no: "Solo lo detecta/lista; no lo destraba ni lo marca entregado (eso lo hac\xE9s en la app / esc\xE1ner)." },
|
|
201
|
+
planilla_reporte: { que: "Resumen de los env\xEDos cargados por el m\xE9todo de planilla/control por foto (ml_manual): total + desglose por cliente, zona y estado + suma de valor declarado y de monto a cobrar.", uso: "Opcional desde/hasta (YYYY-MM-DD). Staff, scopeado a tu nodo.", ej: "planilla_reporte desde:'2026-09-01' \u2192 cu\xE1ntos cargaste hoy, por cliente/zona/estado.", no: "No es el clearing plata-por-nodo (para eso el reporte de clearing); solo cuenta/valores de la planilla." },
|
|
202
|
+
mis_sucursales: { que: "Tus sucursales / puntos de retiro (la principal = tu direcci\xF3n de retiro), con horario de corte y ventanas.", uso: "Sin par\xE1metros.", ej: "mis_sucursales \u2192 confirm\xE1s desde d\xF3nde te colectan.", no: "No las edita (para eso, sucursal_guardar)." },
|
|
203
|
+
sucursal_guardar: { que: "Crea o edita una sucursal tuya (punto de retiro). Geocodifica la direcci\xF3n sola.", uso: "id vac\xEDo = nueva; nombre obligatorio; principal:true la vuelve tu direcci\xF3n de retiro; horarioCorte HH:MM y ventanas opcionales.", ej: "Cambiar tu retiro: sucursal_guardar id:<principal> direccion:'Av. Rivadavia 5000, CABA' principal:true.", no: "No mueve dinero; el detalle de piso/depto/timbre va aparte, no al geocoder." },
|
|
204
|
+
mi_colecta: { que: "Estado de tu colecta (retiro): si la autom\xE1tica est\xE1 prendida, si pediste una por \xFAnica vez y el aviso de costo.", uso: "Sin par\xE1metros.", ej: "mi_colecta \u2192 ver si ma\xF1ana te pasan a buscar.", no: "No la prende/apaga (colecta_auto) ni la solicita (colecta_solicitar)." },
|
|
205
|
+
colecta_solicitar: { que: "Ped\xEDs que te retiren los env\xEDos POR \xDANICA VEZ, aunque tengas la autom\xE1tica apagada.", uso: "Sin par\xE1metros. Devuelve el aviso de costo si aplica.", ej: "colecta_solicitar \u2192 aparec\xE9s en el panel de colecta del nodo.", no: "No prende la colecta autom\xE1tica permanente; no mueve dinero." },
|
|
206
|
+
colecta_auto: { que: "Prende (true) o apaga (false) tu colecta AUTOM\xC1TICA.", uso: "activa (bool).", ej: "colecta_auto activa:false \u2192 dej\xE1s de que te retiren; llev\xE1s vos al dep\xF3sito.", no: "No agenda una colecta puntual (para eso colecta_solicitar)." },
|
|
207
|
+
mi_stock: { que: "Tu stock f\xEDsico (solo tus productos).", uso: "Sin par\xE1metros.", ej: "mi_stock \u2192 ver unidades por SKU.", no: "No muestra disponible-para-vender (us\xE1 mi_disponible)." },
|
|
208
|
+
mi_disponible: { que: "Disponible por SKU = f\xEDsico \u2212 comprometido; marca \u26A0\uFE0F si est\xE1 bajo el m\xEDnimo.", uso: "Sin par\xE1metros.", ej: "mi_disponible \u2192 cu\xE1ntas unidades pod\xE9s seguir vendiendo sin sobrevender.", no: "No repone stock." },
|
|
209
|
+
mi_rentabilidad: { que: "Margen por SKU (precio \u2212 flete real \u2212 COGS).", uso: "desde/hasta YYYY-MM-DD (default: mes en curso).", ej: "mi_rentabilidad desde:2026-08-01 \u2192 margen del mes.", no: "No incluye gastos fijos del negocio; es por SKU." },
|
|
210
|
+
mis_productos: { que: "Tu cat\xE1logo de productos.", uso: "Sin par\xE1metros.", ej: "mis_productos \u2192 ver SKUs cargados.", no: "No da de alta (producto_crear, si el nodo tiene WMS)." },
|
|
211
|
+
mis_top_productos: { que: "Ranking de tus productos m\xE1s despachados.", uso: "desde/hasta YYYY-MM-DD (default: mes).", ej: "mis_top_productos \u2192 qu\xE9 se vende m\xE1s.", no: "No muestra rentabilidad (us\xE1 mi_rentabilidad)." },
|
|
212
|
+
mis_kpis: { que: "Tus m\xE9tricas + benchmark an\xF3nimo de tu nodo.", uso: "desde/hasta opcionales.", ej: "mis_kpis \u2192 tu tasa de entrega vs. el promedio del nodo.", no: "No revela datos de otros vendedores (el benchmark es an\xF3nimo)." },
|
|
213
|
+
mi_ruta: { que: "Tus entregas asignadas: las paradas de tu ruta del d\xEDa.", uso: "Sin par\xE1metros.", ej: "mi_ruta \u2192 orden de reparto de hoy.", no: "No marca entregas (eso se hace escaneando en la app)." },
|
|
214
|
+
mis_colectas: { que: "Las colectas/retiros que ten\xE9s asignados.", uso: "Sin par\xE1metros.", ej: "mis_colectas \u2192 a qu\xE9 vendedores ten\xE9s que ir a buscar.", no: "No las completa/confirma desde ac\xE1." },
|
|
215
|
+
envio_cargar: { que: "Registra un env\xEDo nuevo (queda 'A retirar') y devuelve tracking + link de etiqueta + link para subir foto.", uso: "Obligatorios: destinatario, telefono, direccion, localidad. Staff pasa `cliente` (nombre del vendedor de su nodo); el vendedor no. montoCobro = cobro contra entrega (opcional). `fecha` (solo staff, dd/mm/aaaa) si el env\xEDo NO es de hoy: es la que define en qu\xE9 semana se liquida; no se admite futura.", ej: "Staff: envio_cargar cliente:'Distri Sur' destinatario:'Ana' telefono:'11...' direccion:'Belgrano 100' localidad:'Lan\xFAs' montoCobro:15000.", no: "No mueve dinero (montoCobro es el cobro a destino, no un asiento); no imprime, devuelve el link. Un vendedor/cadete NO puede pasar `fecha` (mover\xEDa sus paquetes de per\xEDodo de liquidaci\xF3n)." },
|
|
216
|
+
envio_entregar: { que: "Marca como ENTREGADO uno o varios env\xEDos que YA est\xE1n cargados, por tracking \u2014 y con `fecha`, el d\xEDa REAL en que se entreg\xF3.", uso: "trackings: ['TN-123', 'NFABC123'] + fecha (opcional, dd/mm/aaaa). Usalo cuando no est\xE1s cargando desde una etiqueta (para eso est\xE1 `envio_desde_etiqueta_ml` con `avanzarA`). Sin `fecha` el historial dice que se entreg\xF3 ahora, que es mentira cuando la tanda se controla por foto d\xEDas despu\xE9s; sobre un env\xEDo que YA figura entregado, `fecha` CORRIGE el cierre ya registrado (vuelve en `fechaCorregida`). Entrega solo con los datos (sin foto ni firma). Scopeado a tu nodo.", ej: "envio_entregar trackings:['TN-2057600163'] fecha:'02/09/2026' \u2192 lo cierra con el d\xEDa en que sali\xF3 y sella la log\xEDstica de entrega para el clearing.", no: "No mueve dinero; `fecha` toca el evento 'Entregado' del historial, NO la semana en que se liquida (eso es envio_editar_fecha); no pide foto ni firma (para eso est\xE1 la entrega del cadete en la PWA); no revierte una entrega." },
|
|
217
|
+
envio_procesar: { que: "Marca un env\xEDo como PROCESADO / recibido en el centro de distribuci\xF3n (queda 'En centro de distribuci\xF3n') por su tracking, sin escanear.", uso: "tracking del env\xEDo. Scopeado a tu nodo/grupo (solo proces\xE1s lo que te corresponde). Es la misma acci\xF3n 'procesar' del esc\xE1ner.", ej: "envio_procesar tracking:'NFABC123' \u2192 lo marca recibido en el centro.", no: "No mueve dinero (registra el tramo de clearing del grupo, como procesar_zona); no lo entrega ni lo asigna a un cadete." },
|
|
218
|
+
envio_desde_etiqueta_ml: { que: "Registra un env\xEDo a partir de lo que VOS (Claude) le\xEDste de la foto de una etiqueta de Mercado Libre.", uso: "Le\xE9 la etiqueta: mlShipmentId + (si pod\xE9s) mlQr crudo, mlSenderId del vendedor y el destino. El vendedor se mapea por mlSenderId (cuenta vinculada) o `cliente` por nombre. Una llamada por etiqueta. Si la planilla es de d\xEDas anteriores, pas\xE1 `fecha` (solo staff, dd/mm/aaaa): fecha el env\xEDo Y toda la cadena de `avanzarA` (cada estado con su hora de ESE d\xEDa: Colectado 9, En centro 12, En camino 15, Entregado 18). Sin eso todo queda con la hora del control y se liquida en la semana equivocada. Si el env\xEDo YA estaba cargado tambi\xE9n le mueve la fecha, salvo que ese per\xEDodo ya est\xE9 liquidado (ah\xED rechaza nombrando la liquidaci\xF3n).", ej: "envio_desde_etiqueta_ml mlSenderId:'123456' mlShipmentId:'44000...' destinatario:'Juan' direccion:'...' localidad:'Avellaneda'.", no: "No mueve dinero; si no reconoce el vendedor por mlSenderId ten\xE9s que pasar `cliente`." },
|
|
219
|
+
envio_reasignar_cliente: { que: "Mueve UN env\xEDo (por tracking) a otro cliente/vendedor de tu nodo cuando se carg\xF3 mal.", uso: "tracking + cliente (nombre o id destino, de tu nodo). Queda en el historial.", ej: "envio_reasignar_cliente tracking:'44000...' cliente:'Comercial Norte'.", no: "No cruza nodos; no cambia el estado del env\xEDo." },
|
|
220
|
+
envio_mensajero_externo: { que: "Registra env\xEDos hechos por un mensajero EXTERNO (alguien de afuera, sin usuario en la plataforma).", uso: "envioIds[] + nombre + valorPorEnvio (opcional). Quedan En camino a su nombre y entran en la liquidaci\xF3n de mensajeros. Sin valor, figuran FALTA VALOR.", ej: 'envio_mensajero_externo envioIds:[123,124] nombre:"Juan (moto)" valorPorEnvio:3000.', no: "No reasigna env\xEDos ya entregados; no paga (registra el valor)." },
|
|
221
|
+
envio_editar_zona: { que: "Corrige la localidad/zona/partido/CP de UN env\xEDo (por tracking) cargado con el destino mal, para que vuelva a ser cobrable/ruteable. Recalcula la zona y deja registro.", uso: "tracking + al menos uno de localidad/zona/partido/cp. Si no pas\xE1s zona, se deriva de la localidad. El cp se guarda solo con d\xEDgitos ('1.832,00' \u2192 '1832'). Staff: solo env\xEDos de tu nodo; admin global: cualquiera.", ej: "La etiqueta tra\xEDa 'san martin - Lan\xFAs' pisadas \u2192 envio_editar_zona tracking:'NFD5L122' localidad:'Lan\xFAs'. CP con la altura de la calle \u2192 envio_editar_zona tracking:'25001' cp:'1712'.", no: "No reasigna de cliente (para eso envio_reasignar_cliente); no crea un alias global (arregla SOLO ese env\xEDo); no mueve dinero." },
|
|
222
|
+
envio_editar_fecha: { que: "Corrige la FECHA de UN env\xEDo ya cargado (por tracking): el que se subi\xF3 atrasado sin `fecha` qued\xF3 con el d\xEDa del alta. Es la fecha que define en qu\xE9 SEMANA se le liquida al vendedor.", uso: "tracking + fecha (dd/mm/aaaa o aaaa-mm-dd). No se admite futura. Si ese per\xEDodo ya est\xE1 liquidado, lo rechaza nombrando la liquidaci\xF3n (rehacerla la decid\xEDs vos). El primer estado del historial se mueve con el env\xEDo; los dem\xE1s quedan como se registraron. Staff: solo env\xEDos de tu nodo; admin global: cualquiera.", ej: "Subiste el martes reci\xE9n el viernes y todo qued\xF3 con fecha del viernes \u2192 envio_editar_fecha tracking:'47904719712' fecha:'01/09/2026'.", no: "No corrige el destino (para eso envio_editar_zona) ni reasigna de cliente (envio_reasignar_cliente); no rehace la liquidaci\xF3n; no mueve dinero." },
|
|
223
|
+
envio_asignar_grupo: { que: "Asigna/rutea UN env\xEDo (por tracking) a un GRUPO log\xEDstico tuyo (por nombre o id) y, si todav\xEDa no sali\xF3, lo DESPACHA \u2014 igual que 'Asignar grupo' del esc\xE1ner.", uso: "tracking + grupo (nombre o id de TUS grupos, ej. 'Portela'). Define con qu\xE9 grupo sali\xF3 (tarifa del clearing). Si el env\xEDo est\xE1 'A retirar'/'En centro' lo pasa a 'En camino'; si YA est\xE1 'Entregado'/'En camino' NO le toca el estado (solo le queda el grupo \u2192 sirve para corregir el clearing de una planilla vieja). Solo tus grupos y env\xEDos de tu nodo (admin global, cualquiera).", ej: "envio_asignar_grupo tracking:'NFABC123' grupo:'Bonorino' \u2192 lo despacha por ese grupo (o solo le setea el grupo si ya estaba entregado).", no: "No mueve dinero (el clearing es config); no lo entrega ni lo asigna a un cadete puntual." },
|
|
224
|
+
cobro_corregir: { que: "Ajusta el monto a cobrar contra entrega de un env\xEDo (se cobr\xF3 de m\xE1s/de menos), guardando el original en el historial.", uso: "envioId + monto nuevo; motivo opcional.", ej: "cobro_corregir envioId:987 monto:12000 motivo:'lista vieja'.", no: "No mueve dinero en cuentas: corrige el DATO del env\xEDo." },
|
|
225
|
+
colecta_ver: { que: "Resumen de valores de colecta del nodo: pago default, cobros por cliente y pagos pactados por cliente+mensajero.", uso: "Sin par\xE1metros.", ej: "colecta_ver \u2192 cu\xE1nto se paga/cobra por colecta.", no: "No cambia tarifas (colecta_configurar)." },
|
|
226
|
+
colecta_historial: { que: "Paquetes colectados por d\xEDa y por cliente en una fecha o rango (hist\xF3rico, hasta 62 d\xEDas), con qui\xE9n los colect\xF3.", uso: "desde (aaaa-mm-dd), hasta opcional, cliente opcional (nombre o id). Solo tu nodo.", ej: "colecta_historial desde:2026-09-08 cliente:Libero \u2192 cu\xE1ntos paquetes se le levantaron ese d\xEDa.", no: "No es el panel de hoy (colecta_pendientes) ni cobra/paga colectas." },
|
|
227
|
+
colecta_pendientes: { que: "Panel de colectas del nodo: `items` = a retirar HOY (por cliente, con corte y mensajero asignado); `itemsManana` = clientes cuyos env\xEDos entraron despu\xE9s del corte \u2192 van a ma\xF1ana; `clientesSinEnvios` = vendedores sin env\xEDos cargados a los que igual se los puede mandar a colectar.", uso: "Sin par\xE1metros. Trae el colectaId para desasignar.", ej: "'\xBFQui\xE9n levanta a Distri Sur?' \u2192 colecta_pendientes y mir\xE1s items.", no: "No asigna (colecta_asignar) ni configura tarifas." },
|
|
228
|
+
colecta_configurar: { que: "Setea un valor de colecta seg\xFAn alcance.", uso: "alcance: 'nodo' (pago default por colecta), 'mensajero' (default de ese cadete), 'cliente' (cu\xE1nto se le COBRA a ese vendedor; idCliente + valor, minEnvios opcional), 'par' (pago pactado a un mensajero por un cliente puntual; idCliente + mensajero + valor). Scopeado a tu nodo. Admin global: `nodo` para elegir/acotar el nodo.", ej: "colecta_configurar alcance:cliente idCliente:'130' valor:2500 minEnvios:5 \u2192 gratis desde 5 env\xEDos, sino $2500.", no: "No mueve dinero: es config de tarifa (el cobro se aplica al liquidar)." },
|
|
229
|
+
colecta_fija: { que: "D\xEDas en que se va a buscar SIEMPRE a un vendedor, tenga o no env\xEDos cargados (colecta fija).", uso: "idCliente + dias (n\xFAmeros 0-6 o nombres). dias:[] la quita. Requiere permiso gestion.", ej: 'colecta_fija idCliente:"130" dias:[1,3,5] \u2192 lunes, mi\xE9rcoles y viernes.', no: "No mueve dinero (el cobro/pago de la colecta es colecta_configurar); no crea la colecta del d\xEDa, hace que aparezca en el panel." },
|
|
230
|
+
colecta_asignar: { que: "Asigna la colecta de un cliente a un mensajero (ambos por nombre de tu nodo) y avisa al cadete.", uso: "cliente + mensajero (nombres). Sirve TAMBI\xC9N para clientes SIN env\xEDos cargados: la colecta se crea vac\xEDa y el cadete escanea los paquetes en la puerta (se crean solos a nombre del vendedor, sin duplicar el mismo QR). Si el corte venci\xF3, la programa para el pr\xF3ximo d\xEDa h\xE1bil. Admin global: `nodo` para elegir/acotar el nodo.", ej: "colecta_asignar cliente:'Distri Sur' mensajero:'Maxi'.", no: "No mueve dinero; no cruza nodos." },
|
|
231
|
+
colecta_desasignar: { que: "Quita la asignaci\xF3n de una colecta (los env\xEDos vuelven a 'sin colecta').", uso: "colectaId (lo devuelve colecta_pendientes). Admin global: `nodo` para elegir/acotar el nodo. Solo colectas de tu nodo.", ej: "colecta_desasignar colectaId:44.", no: "No borra los env\xEDos; no mueve dinero." },
|
|
232
|
+
zonas_reparto: { que: "Zonas de reparto del nodo con sus metazonas y qu\xE9 mensajeros tiene cada una.", uso: "Sin par\xE1metros.", ej: "zonas_reparto \u2192 ver qui\xE9n cubre Palermo.", no: "No asigna (asignar_mensajero_zona / asignar_nodo_zona)." },
|
|
246
233
|
zonas_simetria: { que: "Avisa cuando la distancia entre zonas NO es reciproca (desde A, B es cercana; pero desde B, A es lejana).", uso: "Sin parametros. Cada grupo debe declarar su 'perfil de origen' para entrar al chequeo. Devuelve asimetricos, incompletos y perfiles sin lugar.", ej: "zonas_simetria -> revisar los pares que no cierran antes de liquidar.", no: "NO corrige ni auto-completa: puede haber asimetrias legitimas (autopista, rio); la decision es humana." },
|
|
247
|
-
zona_barrios: { que: "
|
|
234
|
+
zona_barrios: { que: "Qu\xE9 localidades y BARRIOS componen una zona con nombre (ej. 'Matanza Norte', 'CABA'), con su tramo por perfil. Consulta r\xE1pida por nombre.", uso: "zona (nombre). Devuelve las zonas visibles (propias, globales o de tus grupos log\xEDsticos) que matchean.", ej: "zona_barrios zona:'Matanza Norte' \u2192 los barrios de esa zona.", no: "No edita la zona (eso es la config de metazonas/grupos); solo lectura." },
|
|
248
235
|
asignar_mensajero_zona: { que: "Asigna un mensajero de tu nodo a una metazona; si la zona existe le suma el cadete, si no la crea.", uso: "mensajero + metazona; nombre opcional. Admin global: `nodo` para elegir/acotar el nodo.", ej: "asignar_mensajero_zona mensajero:'Maxi' metazona:'Palermo'.", no: "No cruza nodos." },
|
|
249
|
-
asignar_nodo_zona: { que: "Asigna un NODO COMPLETO (de tu grupo
|
|
250
|
-
envios_por_zona: { que: "
|
|
251
|
-
procesar_zona: { que: "ACEPTA (recibe en tu nodo)
|
|
252
|
-
rechazar_zona: { que: "RECHAZA
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
stock_nodo: { que: "Stock del depósito del nodo (WMS).", uso: "cliente opcional para filtrar.", ej: "stock_nodo cliente:'Distri Sur'.", no: "Requiere WMS activo; no repone." },
|
|
278
|
-
productos_nodo: { que: "Catálogo del depósito del nodo (WMS).", uso: "cliente opcional.", ej: "productos_nodo.", no: "Requiere WMS activo." },
|
|
279
|
-
producto_crear: { que: "Alta de producto en el depósito (WMS).", uso: "nombre + sku/codigoBarra/peso/volumen opcionales; staff pasa idCliente dueño. Admin global: `nodo` para elegir/acotar el nodo.", ej: "producto_crear nombre:'Remera M' sku:'REM-M' idCliente:'130'.", no: "No mueve dinero; requiere WMS activo." },
|
|
280
|
-
|
|
281
|
-
clientes_del_nodo: { que: "Clientes/vendedores del nodo con su lista de precio.", uso: "Sin parámetros. Scopeado a tu nodo.", ej: "clientes_del_nodo → ver a quién facturás y con qué lista.", no: "No los crea/edita (cliente_crear/editar)." },
|
|
236
|
+
asignar_nodo_zona: { que: "Asigna un NODO COMPLETO (de tu grupo log\xEDstico) a una metazona, cuando ese nodo cubre toda la localidad.", uso: "nodo (nombre, debe compartir grupo log\xEDstico) + metazona; nombre opcional. Sin `grupo`: el nodo cubre toda esa localidad de tu zona (se suma como opci\xF3n). Con `grupo` (nombre o id): MODO COMISI\xD3N, la zona es del grupo y esto reasigna su responsable; solo un admin de ese grupo o el admin global. Admin global sin `grupo`: `logisticaId` para elegir el nodo due\xF1o de la zona.", ej: "asignar_nodo_zona nodo:'RL' metazona:'Portela'. / asignar_nodo_zona nodo:'FastCorreo' metazona:'Ensenada' grupo:'Portela'.", no: "No suma nodos fuera de tu grupo log\xEDstico; con `grupo`, un miembro que no es admin del grupo recibe error. No mueve dinero." },
|
|
237
|
+
envios_por_zona: { que: "Env\xEDos que OTROS nodos te rutearon por zona de reparto, agrupados por zona (para aceptar/rechazar).", uso: "Sin par\xE1metros. Cada env\xEDo trae su id (para procesar_zona/rechazar_zona).", ej: "envios_por_zona \u2192 ver qu\xE9 te mandaron por la zona Sur.", no: "No los acepta solo: us\xE1 procesar_zona o rechazar_zona." },
|
|
238
|
+
procesar_zona: { que: "ACEPTA (recibe en tu nodo) env\xEDos ruteados por zona.", uso: "envioIds (de envios_por_zona); mensajeroId opcional para asignarlos. Admin global: `nodo` para elegir/acotar el nodo.", ej: "procesar_zona envioIds:[101,102] mensajeroId:7.", no: "No mueve dinero (el clearing es config)." },
|
|
239
|
+
rechazar_zona: { que: "RECHAZA env\xEDos ruteados por zona: dejan de aparecerte y quedan para origen u otros nodos de la zona.", uso: "envioIds (de envios_por_zona); motivo opcional. Admin global: `nodo` para elegir/acotar el nodo.", ej: "rechazar_zona envioIds:[103] motivo:'fuera de mi cobertura'.", no: "No cambia el estado del env\xEDo." },
|
|
240
|
+
rendiciones: { que: "Estado de rendiciones: cobros/cambios/devoluciones a recuperar o rendir, con totales y qui\xE9n tiene cada uno.", uso: "Sin par\xE1metros. Scopeado a tu alcance (vendedor: lo tuyo; nodo: tu nodo; mensajero: lo suyo).", ej: "rendiciones \u2192 cu\xE1nto falta que rinda cada cadete.", no: "No confirma ni revierte (rendicion_revertir); NO incluye rutas de marketplace adjudicadas (ver ayuda tema:facturacion_marketplace)." },
|
|
241
|
+
rendicion_revertir: { que: "Revierte un cobro/cambio marcado como 'rendido' por error \u2192 vuelve a 'a rendir'.", uso: "envioId + tipo (cobro|cambio); motivo opcional. Deja registro.", ej: "rendicion_revertir envioId:987 tipo:cobro motivo:'se marc\xF3 sin recibir'.", no: "No mueve dinero en cuentas; corrige el estado de la rendici\xF3n." },
|
|
242
|
+
reclamos_listar: { que: "Reclamos abiertos de clientes ligados a liquidaciones/rendiciones (tipo, estado, trackings en disputa).", uso: "estado opcional (abierto|resuelto). Vendedor: lo suyo; operador: su nodo.", ej: "reclamos_listar estado:abierto \u2192 qu\xE9 cobros est\xE1n en disputa.", no: "No resuelve reclamos desde ac\xE1." },
|
|
243
|
+
rutas_publicas: { que: "Publicaciones ABIERTAS de toda la red que tu nodo puede tomar (con cu\xE1ntas ofertas tiene cada una). Marca las tuyas con esMia.", uso: "Sin par\xE1metros.", ej: "rutas_publicas \u2192 ver qu\xE9 rutas hay para ofertar.", no: "No oferta (ruta_ofertar)." },
|
|
244
|
+
mis_rutas: { que: "Tus publicaciones (con estado/adjudicaci\xF3n: nodoToma y precioAcordado) y las ofertas que hiciste a otros.", uso: "Sin par\xE1metros.", ej: "mis_rutas \u2192 ver si tu ruta se adjudic\xF3 y a qui\xE9n.", no: "El precioAcordado es la obligaci\xF3n registrada, NO un asiento de facturaci\xF3n (ver ayuda tema:facturacion_marketplace)." },
|
|
245
|
+
ruta_ofertas: { que: "Ofertas recibidas en una publicaci\xF3n TUYA, de la m\xE1s barata a la m\xE1s cara. Solo el que public\xF3.", uso: "publicacionId. Los ids de oferta sirven para adjudicar.", ej: "ruta_ofertas publicacionId:12 \u2192 eleg\xEDs la mejor y su ofertaId.", no: "No adjudica (ruta_adjudicar)." },
|
|
246
|
+
ruta_publicar: { que: "Public\xE1s una ruta/colecta/viaje para que cualquier nodo la tome (subasta abierta). VOS le pag\xE1s al que la toma.", uso: "titulo (obligatorio); tipo (ruta|colecta|viaje), descripcion, zona, precioMax (tope que ofrec\xE9s pagar) opcionales.", ej: "ruta_publicar titulo:'Reparto zona Oeste 40 paquetes' tipo:ruta precioMax:20000.", no: "No mueve dinero: la obligaci\xF3n reci\xE9n se registra al adjudicar; el pago es manual." },
|
|
247
|
+
ruta_ofertar: { que: "Ofert\xE1s por una publicaci\xF3n de OTRO nodo. precio = lo que cobr\xE1s por hacerla (m\xE1s barato = mejor para el que publica).", uso: "publicacionId + precio; nota opcional. Si ya ofertaste, la actualiza.", ej: "ruta_ofertar publicacionId:12 precio:18000 nota:'salgo 8am'.", no: "No pod\xE9s ofertar en tu propia publicaci\xF3n." },
|
|
248
|
+
ruta_adjudicar: { que: "Eleg\xEDs la oferta ganadora de una publicaci\xF3n TUYA y cerr\xE1s la subasta: el nodo ganador la toma a su precio y queda registrada la obligaci\xF3n.", uso: "publicacionId + ofertaId (de ruta_ofertas).", ej: "ruta_adjudicar publicacionId:12 ofertaId:34 \u2192 gana el nodo de esa oferta a $18000.", no: "NO crea asiento de facturaci\xF3n/rendici\xF3n/comisi\xF3n ni clearing autom\xE1tico: el pago entre nodos se salda MANUALMENTE (ver ayuda tema:facturacion_marketplace)." },
|
|
249
|
+
afiliacion_listar: { que: "Afiliaciones (afiliado\u2194entidad referida) con su comisi\xF3n por env\xEDo, vigencia y estado.", uso: "afiliado y/o entidad opcionales para filtrar. Scopeado a tu nodo.", ej: "afiliacion_listar afiliado:'Nodo RL'.", no: "No muestra comisiones devengadas (comisiones_afiliado_ver)." },
|
|
250
|
+
comisiones_afiliado_ver: { que: "Comisiones devengadas por env\xEDo (pendiente/liquidada) con totales.", uso: "afiliado, desde, hasta (YYYY-MM-DD) opcionales. Scopeado a tu nodo.", ej: "comisiones_afiliado_ver afiliado:'Nodo RL' desde:2026-08-01.", no: "No las paga (comision_liquidar); NO incluye rutas de marketplace." },
|
|
251
|
+
afiliado_crear: { que: "Alta de un afiliado (quien trae volumen nuevo a la red).", uso: "nombre + tipo (nodo|mensajero|externo); refId = id del nodo/mensajero (null si externo).", ej: "afiliado_crear nombre:'Juan Ref' tipo:externo.", no: "No crea la afiliaci\xF3n/comisi\xF3n (afiliacion_crear); no toca dinero." },
|
|
252
|
+
afiliacion_crear: { que: "Vincula un afiliado con una entidad referida (nodo o cliente) y su comisi\xF3n RECURRENTE por env\xEDo.", uso: "afiliado + entidadTipo (nodo|cliente) + entidad + tipoComision (porcentaje|montoFijo) + valorComision; fechaExpiracion opcional. Una entidad = un afiliado activo.", ej: "afiliacion_crear afiliado:'Juan Ref' entidadTipo:cliente entidad:'Distri Sur' tipoComision:montoFijo valorComision:50.", no: "No paga (comision_liquidar); es config, no mueve dinero." },
|
|
253
|
+
afiliacion_editar: { que: "Edita una afiliaci\xF3n: valorComision, fechaExpiracion (renovar/extender) y/o activa.", uso: "id + los campos a cambiar.", ej: "afiliacion_editar id:5 activa:false \u2192 la das de baja.", no: "No toca dinero." },
|
|
254
|
+
comision_liquidar: { que: "Marca comisiones devengadas como LIQUIDADAS (registra el pago al afiliado).", uso: "ids = lista de comisiones (de comisiones_afiliado_ver). Requiere permiso de finanzas. Scopeado a tu nodo.", ej: "comision_liquidar ids:[10,11,12].", no: "No calcula comisiones (se devengan solas por env\xEDo); no factura." },
|
|
255
|
+
kpi_nodo: { que: "Tablero del nodo: P&L, top clientes, ca\xEDdas.", uso: "desde/hasta opcionales; nodo solo para admin.", ej: "kpi_nodo desde:2026-08-01 \u2192 resultado del mes.", no: "No baja a un vendedor puntual; solo tu nodo (salvo admin)." },
|
|
256
|
+
kpi_red: { que: "KPIs globales de la red.", uso: "Sin par\xE1metros. Solo admin global.", ej: "kpi_red \u2192 panorama SaaS de toda la red.", no: "No desglosa por nodo (us\xE1 kpi_nodo con nodo)." },
|
|
257
|
+
metricas_por_tipo: { que: "M\xE9tricas por TIPO de env\xEDo (flex/tienda/manual): total, entregados, tasa y % entregado antes de las 21hs. Para admin desglosa por log\xEDstica.", uso: "desde/hasta YYYY-MM-DD (default 30 d\xEDas); nodo solo admin.", ej: "metricas_por_tipo \u2192 ver si los Flex se entregan a tiempo.", no: "No es por cliente." },
|
|
258
|
+
top_productos: { que: "Ranking de productos m\xE1s despachados del nodo (WMS).", uso: "desde/hasta y cliente opcionales.", ej: "top_productos cliente:'Distri Sur'.", no: "Requiere WMS activo en el nodo." },
|
|
259
|
+
stock_nodo: { que: "Stock del dep\xF3sito del nodo (WMS).", uso: "cliente opcional para filtrar.", ej: "stock_nodo cliente:'Distri Sur'.", no: "Requiere WMS activo; no repone." },
|
|
260
|
+
productos_nodo: { que: "Cat\xE1logo del dep\xF3sito del nodo (WMS).", uso: "cliente opcional.", ej: "productos_nodo.", no: "Requiere WMS activo." },
|
|
261
|
+
producto_crear: { que: "Alta de producto en el dep\xF3sito (WMS).", uso: "nombre + sku/codigoBarra/peso/volumen opcionales; staff pasa idCliente due\xF1o. Admin global: `nodo` para elegir/acotar el nodo.", ej: "producto_crear nombre:'Remera M' sku:'REM-M' idCliente:'130'.", no: "No mueve dinero; requiere WMS activo." },
|
|
262
|
+
clientes_del_nodo: { que: "Clientes/vendedores del nodo con su lista de precio.", uso: "Sin par\xE1metros. Scopeado a tu nodo.", ej: "clientes_del_nodo \u2192 ver a qui\xE9n factur\xE1s y con qu\xE9 lista.", no: "No los crea/edita (cliente_crear/editar)." },
|
|
282
263
|
cliente_crear: { que: "Alta de cliente/vendedor en tu nodo.", uso: "nombre obligatorio; telefono/dni/direccion/idLista opcionales. Admin global: `nodo` para elegir/acotar el nodo.", ej: "cliente_crear nombre:'Nueva Distri' idLista:'ID12'.", no: "No toca dinero; no cruza nodos." },
|
|
283
|
-
cliente_editar: { que: "Edita un cliente de tu nodo cambiando SOLO los campos que
|
|
284
|
-
sucursales_cliente: { que: "Lista las sucursales (puntos de retiro) de un cliente de tu nodo con su id, nombre,
|
|
285
|
-
sucursal_perfil: { que: "Setea (o limpia) el perfil de zona de UNA sucursal: la
|
|
286
|
-
precios_ver: { que: "Listas de precios por zona de tu nodo.", uso: "Sin
|
|
287
|
-
precio_actualizar: { que: "Cambia precios de una lista creando una
|
|
288
|
-
cuentas_vinculadas: { que: "
|
|
289
|
-
generar_enlace_vinculacion: { que: "Genera el enlace para vincular una tienda; se lo
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
liquidaciones_sin_recibir: { que: "Liquidaciones de clientes con saldo deudor (aprox. por cliente: el pago todavía no entró).", uso: "Opcional cliente y nodo (nodo solo admin global). Requiere permiso finanzas.", ej: "liquidaciones_sin_recibir → ver quién debe pagar.", no: "Es aproximado a nivel cliente (los pagos son FIFO por cuenta, no por liquidación); no reclama ni cobra." },
|
|
297
|
-
|
|
298
|
-
chofer_listar: { que: "Usuarios de tu nodo, incluidos los choferes (rol mensajero): id, nombre, teléfono, activo.", uso: "Sin parámetros. Requiere permiso 'usuarios'.", ej: "chofer_listar → ver tus cadetes.", no: "No crea/edita (chofer_crear/editar)." },
|
|
264
|
+
cliente_editar: { que: "Edita un cliente de tu nodo cambiando SOLO los campos que pas\xE1s (lista de precio, tel\xE9fono, email con el que entra, DNI, direcci\xF3n, nombre de pago, activo).", uso: 'id + los campos a cambiar. Lo que no pas\xE1s queda igual; "" vac\xEDa el campo. `email` = el del usuario del cliente (requiere permiso de usuarios). Admin global: `nodo` mueve el cliente a ese nodo.', ej: "cliente_editar id:130 idLista:'ID12' \xB7 cliente_editar id:50 email:'nuevo@mail.com'.", no: "No toca dinero ni la clave (cliente_resetear_clave)." },
|
|
265
|
+
sucursales_cliente: { que: "Lista las sucursales (puntos de retiro) de un cliente de tu nodo con su id, nombre, direcci\xF3n y perfil de zona.", uso: "cliente (id, de clientes_del_nodo). Requiere permiso 'gestion'.", ej: "sucursales_cliente cliente:130 \u2192 ver las sucursales y sus perfiles.", no: "No las crea/edita (eso lo hace el vendedor en su portal); solo el PERFIL lo setea el staff con sucursal_perfil." },
|
|
266
|
+
sucursal_perfil: { que: "Setea (o limpia) el perfil de zona de UNA sucursal: la liquidaci\xF3n cotiza los env\xEDos que salen de ah\xED seg\xFAn SU distancia, no la del cliente.", uso: "sucursalId (de sucursales_cliente) + perfilZona (vac\xEDo = hereda el del cliente). Requiere permiso 'gestion'. Config de staff (el vendedor NO lo toca).", ej: "sucursal_perfil sucursalId:12 perfilZona:'MORENO'.", no: "No mueve dinero, pero afecta el tramo/precio; no crea la sucursal." },
|
|
267
|
+
precios_ver: { que: "Listas de precios por zona de tu nodo.", uso: "Sin par\xE1metros. Requiere permiso 'precios'.", ej: "precios_ver \u2192 ver tarifas por zona.", no: "No las edita (precio_actualizar)." },
|
|
268
|
+
precio_actualizar: { que: "Cambia precios de una lista creando una VERSI\xD3N nueva (hist\xF3rico intacto).", uso: "idLista + los tramos (cercana/media/lejana/muyLejana); referencia/vigenciaDesde opcionales. Requiere permiso 'precios' (y que el conector lo permita). Admin global: `nodo` para elegir/acotar el nodo.", ej: "precio_actualizar idLista:'ID12' cercana:1500 media:2000 lejana:2800.", no: "No mueve dinero; puede estar deshabilitado por el conector (ALLOW_PRECIOS)." },
|
|
269
|
+
cuentas_vinculadas: { que: "Cu\xE1ntas cuentas de tienda hay vinculadas, por proveedor (ML / TiendaNube / TiendaNegocio).", uso: "nodo opcional (solo admin, baja al desglose por cliente).", ej: "cuentas_vinculadas \u2192 cu\xE1ntos vendedores tienen ML conectado.", no: "No vincula (generar_enlace_vinculacion)." },
|
|
270
|
+
generar_enlace_vinculacion: { que: "Genera el enlace para vincular una tienda; se lo mand\xE1s al cliente para que autorice.", uso: "proveedor (ml|tiendanube|tiendanegocio); staff pasa `cliente` (nombre o id del cliente de su nodo). El enlace vence en 48 hs.", ej: "generar_enlace_vinculacion proveedor:ml cliente:'Distri Sur'.", no: "No completa la vinculaci\xF3n (la autoriza el due\xF1o de la tienda); no toca dinero." },
|
|
271
|
+
marketing_config_ver: { que: "Muestra los p\xEDxeles/config de marketing (Meta Pixel, GA4, GTM y si hay tokens de la Conversions API / API secret cargados) de tu alcance.", uso: "nodo opcional (solo admin global). Vendedor: la suya; operador: la de su nodo (el backend resuelve el alcance).", ej: "marketing_config_ver \u2192 ver qu\xE9 Meta Pixel / GA4 ten\xE9s configurado.", no: "No devuelve los tokens/secrets en claro (solo si est\xE1n cargados); no los edita (marketing_config_guardar)." },
|
|
272
|
+
marketing_config_guardar: { que: "Guarda los p\xEDxeles/config de marketing de tu alcance (vendedor: la suya; operador: la de su nodo).", uso: "Campos opcionales: metaPixelId, ga4MeasurementId, gtmId, metaConvApiToken, metaTestEventCode, ga4ApiSecret, activo, nodo (solo admin). String vac\xEDo BORRA ese campo; omitido = queda igual.", ej: "marketing_config_guardar metaPixelId:'123456789' ga4MeasurementId:'G-ABC123'.", no: "No mueve dinero; no verifica que el p\xEDxel exista en Meta/GA4." },
|
|
273
|
+
liquidacion_buscar: { que: "Busca liquidaciones por cliente (nombre o id base) y/o rango de monto. Trae el saldo de cta cte del cliente y la marca sinRecibir.", uso: "Filtros opcionales: cliente, montoMin, montoMax, sinRecibir. `nodo` solo lo usa el admin global (acota a un nodo); el admin de nodo queda en el suyo. Requiere permiso finanzas.", ej: "liquidacion_buscar cliente:'Roger' montoMin:50000 \u2192 sus liquidaciones de $50.000+.", no: "No edita ni paga; el detalle de env\xEDos es liquidacion_detalle." },
|
|
274
|
+
liquidacion_detalle: { que: "Snapshot completo de una liquidaci\xF3n: detalle de los env\xEDos, resumen y comisiones.", uso: "id de la liquidaci\xF3n (de liquidacion_buscar). Scopeada: no abre la de otro nodo.", ej: "liquidacion_detalle id:1234 \u2192 ver los env\xEDos que la componen.", no: "No la modifica; no factura." },
|
|
275
|
+
liquidaciones_sin_recibir: { que: "Liquidaciones de clientes con saldo deudor (aprox. por cliente: el pago todav\xEDa no entr\xF3).", uso: "Opcional cliente y nodo (nodo solo admin global). Requiere permiso finanzas.", ej: "liquidaciones_sin_recibir \u2192 ver qui\xE9n debe pagar.", no: "Es aproximado a nivel cliente (los pagos son FIFO por cuenta, no por liquidaci\xF3n); no reclama ni cobra." },
|
|
276
|
+
chofer_listar: { que: "Usuarios de tu nodo, incluidos los choferes (rol mensajero): id, nombre, tel\xE9fono, activo.", uso: "Sin par\xE1metros. Requiere permiso 'usuarios'.", ej: "chofer_listar \u2192 ver tus cadetes.", no: "No crea/edita (chofer_crear/editar)." },
|
|
299
277
|
chofer_crear: { que: "Da de alta un chofer (mensajero) en tu nodo con una CLAVE TEMPORAL que devuelve el server.", uso: "nombre + apellido (obligatorios, por separado) + telefono + email; mensajeroNombre opcional (macheo con su cta cte). Admin global: `nodo` para elegir/acotar el nodo. Pasale la clave; la cambia al primer ingreso.", ej: "chofer_crear nombre:'Maxi' apellido:'Sagarzazu' telefono:'11...' email:'maxi@...'.", no: "Claude nunca inventa la clave; el server la genera." },
|
|
300
|
-
chofer_editar: { que: "Edita un chofer de tu nodo: nombre, apellido,
|
|
301
|
-
usuario_editar: { que: "Corrige nombre, apellido,
|
|
302
|
-
operador_crear: { que: "Da de alta un OPERADOR (staff que administra el nodo: recibe/escanea/despacha, liquida, etc.) en tu nodo, con una CLAVE TEMPORAL que devuelve el server.", uso: "nombre + apellido + email + telefono; permisos opcional (default 'logistica'): gestion, finanzas, mensajeros, reportes, logistica, wms, precios, usuarios. El admin global elige el nodo con `nodo`. Requiere permiso 'usuarios'. Pasale la clave; la cambia al primer ingreso.", ej: "operador_crear nombre:'Ana' apellido:'
|
|
303
|
-
cliente_generar_usuario: { que: "Le crea las credenciales de login a un cliente/vendedor YA EXISTENTE de tu nodo (para que entre a su portal) y devuelve una CLAVE TEMPORAL.", uso: "cliente (nombre o id, de clientes_del_nodo) + email para loguear + nombre y apellido de la PERSONA que entra (obligatorios; no el de la tienda); telefono opcional. Requiere permiso 'usuarios'. Admin global: `nodo` para elegir/acotar el nodo. Si el cliente ya tiene usuario, avisa (no lo pisa).", ej: "cliente_generar_usuario cliente:'Distri Sur' email:'ventas@distrisur.com' nombre:'Juan' apellido:'
|
|
304
|
-
cliente_resetear_clave: { que: "Genera una CLAVE TEMPORAL NUEVA para un cliente/vendedor de tu nodo que YA tiene usuario pero
|
|
305
|
-
usuario_habilitar_reparto: { que: "Marca a un operador/admin de tu nodo como
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
grupo_miembros: { que: "Lista los nodos de un grupo, marcando quién es admin de grupo y si vos lo sos.", uso: "grupo (id). El id lo ves en mis_datos o al vincular por QR. Solo miembros del grupo.", ej: "grupo_miembros grupo:21.", no: "No modifica; solo lectura." },
|
|
278
|
+
chofer_editar: { que: "Edita un chofer de tu nodo: nombre, apellido, tel\xE9fono, mensajeroNombre y/o activo.", uso: "id + los campos a cambiar.", ej: "chofer_editar id:7 activo:false \u2192 lo desactiv\xE1s.", no: "No toca credenciales/clave." },
|
|
279
|
+
usuario_editar: { que: "Corrige nombre, apellido, tel\xE9fono y/o email de un usuario de tu nodo.", uso: "id + los campos a cambiar. Si el usuario todav\xEDa no tiene nombre y apellido separados, pas\xE1 los dos. Requiere permiso 'usuarios'.", ej: "usuario_editar id:7 nombre:'Sol' apellido:'Mart\xEDnez'.", no: "No toca rol, permisos ni clave. No cambia el nombre con el que se le paga al cadete." },
|
|
280
|
+
operador_crear: { que: "Da de alta un OPERADOR (staff que administra el nodo: recibe/escanea/despacha, liquida, etc.) en tu nodo, con una CLAVE TEMPORAL que devuelve el server.", uso: "nombre + apellido + email + telefono; permisos opcional (default 'logistica'): gestion, finanzas, mensajeros, reportes, logistica, wms, precios, usuarios. El admin global elige el nodo con `nodo`. Requiere permiso 'usuarios'. Pasale la clave; la cambia al primer ingreso.", ej: "operador_crear nombre:'Ana' apellido:'G\xF3mez' email:'ana@nodo.com' telefono:'11...' permisos:['logistica','gestion'].", no: "No es un vendedor (cliente_generar_usuario) ni un chofer (chofer_crear); no otorga admin de nodo (usuario_habilitar_rol); Claude nunca inventa la clave; no toca dinero." },
|
|
281
|
+
cliente_generar_usuario: { que: "Le crea las credenciales de login a un cliente/vendedor YA EXISTENTE de tu nodo (para que entre a su portal) y devuelve una CLAVE TEMPORAL.", uso: "cliente (nombre o id, de clientes_del_nodo) + email para loguear + nombre y apellido de la PERSONA que entra (obligatorios; no el de la tienda); telefono opcional. Requiere permiso 'usuarios'. Admin global: `nodo` para elegir/acotar el nodo. Si el cliente ya tiene usuario, avisa (no lo pisa).", ej: "cliente_generar_usuario cliente:'Distri Sur' email:'ventas@distrisur.com' nombre:'Juan' apellido:'P\xE9rez'.", no: "No da de alta el PERFIL del cliente (eso es cliente_crear); Claude nunca inventa la clave; no toca dinero." },
|
|
282
|
+
cliente_resetear_clave: { que: "Genera una CLAVE TEMPORAL NUEVA para un cliente/vendedor de tu nodo que YA tiene usuario pero perdi\xF3 el acceso.", uso: "cliente (nombre o id, de clientes_del_nodo). Requiere permiso 'usuarios'. Admin global: `nodo` para elegir/acotar el nodo.", ej: "cliente_resetear_clave cliente:'Distri Sur' \u2192 nueva clave temporal.", no: "Si el cliente todav\xEDa no tiene usuario, avisa y sugiere cliente_generar_usuario; no crea uno nuevo; no toca dinero." },
|
|
283
|
+
usuario_habilitar_reparto: { que: "Marca a un operador/admin de tu nodo como TAMBI\xC9N mensajero (puede escanear, autoasignarse y entregar).", uso: "id + activo (default true).", ej: "usuario_habilitar_reparto id:4 \u2192 ese comisionista ya puede repartir.", no: "No toca credenciales." },
|
|
284
|
+
nodos_listar: { que: "Todas las log\xEDsticas (nodos) de la red.", uso: "Sin par\xE1metros. Solo admin global.", ej: "nodos_listar \u2192 id/nombre de cada nodo.", no: "No los crea (nodo_crear)." },
|
|
285
|
+
nodo_crear: { que: "Alta de una log\xEDstica/nodo.", uso: "nombre + telefono opcional. Solo admin global.", ej: "nodo_crear nombre:'Nodo Oeste' telefono:'11...'.", no: "No toca dinero." },
|
|
286
|
+
nodo_provisorio_crear: { que: "Crea al vuelo un nodo PROVISORIO (placeholder para el clearing) dentro de un grupo, cuando te bajan paquetes de un nodo que todav\xEDa no est\xE1 dado de alta.", uso: "nombre + grupoId (de tus grupos). Staff: solo en grupos de TU nodo; admin global: cualquiera.", ej: "nodo_provisorio_crear nombre:'Nodo Avellaneda prov.' grupoId:3.", no: "No tiene login hasta conciliarlo con el nodo real; no mueve dinero." },
|
|
287
|
+
provisorio_conciliar: { que: "Fusiona un nodo PROVISORIO con el nodo REAL cuando este ya est\xE1 dado de alta: reatribuye sus env\xEDos y su membres\xEDa de grupo al nodo real y marca el provisorio como resuelto.", uso: "provisorioId (lo devolvi\xF3 `nodo_provisorio_crear`, o lo ves en `grupos_tarifas`) + nodoReal (nombre o id). Como operador solo concili\xE1s los provisorios que cre\xF3 tu nodo y contra un nodo que YA opera en el grupo; el admin global puede adem\xE1s pasar `tarifa` (bandas) si el nodo real todav\xEDa no est\xE1 en el grupo.", ej: "provisorio_conciliar provisorioId:42 nodoReal:'Nodo Avellaneda'.", no: "No mueve dinero (reordena el clearing: esos env\xEDos pasan a la tarifa del nodo real)." },
|
|
288
|
+
usuario_habilitar_rol: { que: "Habilita o deshabilita a un usuario como superoperador (global) y/o admin de nodo.", uso: "id + al menos uno de esSuperoperador/esAdminNodo (true = habilitar, false = quitar). Solo admin global; otorgar superoperador exige un superadmin real.", ej: "usuario_habilitar_rol id:12 esAdminNodo:true \u2192 lo hac\xE9s admin de su nodo.", no: "No crea el usuario; no toca credenciales ni dinero." },
|
|
289
|
+
grupo_crear: { que: "Crea un grupo log\xEDstico nuevo (para el clearing entre nodos).", uso: "nombre. Solo admin global. Los nodos se agregan/tarifan despu\xE9s.", ej: "grupo_crear nombre:'Grupo Sur'.", no: "No agrega ni tarifa nodos; no toca dinero." },
|
|
290
|
+
grupo_miembros: { que: "Lista los nodos de un grupo, marcando qui\xE9n es admin de grupo y si vos lo sos.", uso: "grupo (id). El id del grupo sale de `grupos_tarifas`. Solo miembros del grupo.", ej: "grupo_miembros grupo:21.", no: "No modifica; solo lectura." },
|
|
314
291
|
grupo_sumar_nodo: { que: "Agrega un nodo al grupo (entra como miembro normal, sin admin).", uso: "grupo + nodo (ids). Solo un ADMIN del grupo (o admin global).", ej: "grupo_sumar_nodo grupo:21 nodo:5.", no: "No lo hace admin; no toca dinero." },
|
|
315
|
-
grupo_expulsar_nodo: { que: "Saca un nodo del grupo.", uso: "grupo + nodo (ids). Solo un ADMIN del grupo. No se puede expulsar al
|
|
316
|
-
grupo_admin_permiso: { que: "Da o saca el permiso de admin de grupo a un nodo (para que otros hereden la
|
|
292
|
+
grupo_expulsar_nodo: { que: "Saca un nodo del grupo.", uso: "grupo + nodo (ids). Solo un ADMIN del grupo. No se puede expulsar al \xFAltimo admin.", ej: "grupo_expulsar_nodo grupo:21 nodo:5.", no: "No deja el grupo sin admin; no toca dinero." },
|
|
293
|
+
grupo_admin_permiso: { que: "Da o saca el permiso de admin de grupo a un nodo (para que otros hereden la administraci\xF3n).", uso: "grupo + nodo (ids) + admin (true=dar, false=sacar). Solo un ADMIN del grupo. No se puede sacar al \xFAltimo admin.", ej: "grupo_admin_permiso grupo:21 nodo:5 admin:true.", no: "No toca dinero." },
|
|
317
294
|
logo_subir: { que: "Sube/actualiza el logo y la marca (marca blanca) de un nodo.", uso: "nodo (id) + logo (data-URI base64, ej. data:image/png;base64,...); marca/slug/color opcionales. Solo admin global.", ej: "logo_subir nodo:6 logo:'data:image/png;base64,iVBOR...' marca:'FastCorreo'.", no: "No toca dinero; el logo va como data-URI base64." },
|
|
318
|
-
sugerencias_listar: { que: "
|
|
295
|
+
sugerencias_listar: { que: "Solo superadmin: todas las sugerencias de la red (funciones/mejoras/bugs) con usuario, rol, nodo, estado.", uso: "rol y/o estado opcionales.", ej: "sugerencias_listar estado:nueva.", no: "No las implementa; es lectura." }
|
|
319
296
|
};
|
|
320
|
-
|
|
321
|
-
// Renderiza la ayuda. q = nombre de tool o clave de tema (opcional).
|
|
322
|
-
// ctx = { version, disponibles: Set<string> } — disponibles filtra el índice a lo
|
|
323
|
-
// que ese usuario realmente tiene (según su rol/permisos).
|
|
324
|
-
export function renderAyuda(q, ctx = {}) {
|
|
297
|
+
function renderAyuda(q, ctx = {}) {
|
|
325
298
|
const version = ctx.version ?? "";
|
|
326
299
|
const disponibles = ctx.disponibles instanceof Set ? ctx.disponibles : null;
|
|
327
300
|
const clave = String(q ?? "").trim().toLowerCase().replace(/[^a-z_]/g, "");
|
|
328
|
-
|
|
329
301
|
if (!clave) return indice(version, disponibles);
|
|
302
|
+
if (TOPICS[clave]) return TOPICS[clave] + `
|
|
330
303
|
|
|
331
|
-
|
|
332
|
-
|
|
304
|
+
(Consult\xE1 una herramienta con: ayuda tool:<nombre>)`;
|
|
333
305
|
const d = TOOL_DOCS[clave];
|
|
334
306
|
if (d) {
|
|
335
307
|
const tiene = !disponibles || disponibles.has(clave);
|
|
336
|
-
const nota = tiene ? "" : "\n\n(
|
|
308
|
+
const nota = tiene ? "" : "\n\n(\u26A0\uFE0F Con tu rol/permiso actual esta herramienta no est\xE1 disponible.)";
|
|
337
309
|
return [
|
|
338
|
-
|
|
310
|
+
`\u{1F527} ${clave}`,
|
|
339
311
|
"",
|
|
340
|
-
`
|
|
341
|
-
`
|
|
312
|
+
`Qu\xE9 hace: ${d.que}`,
|
|
313
|
+
`C\xF3mo usar: ${d.uso}`,
|
|
342
314
|
`Ejemplo: ${d.ej}`,
|
|
343
|
-
`
|
|
315
|
+
`Qu\xE9 NO hace: ${d.no}`
|
|
344
316
|
].join("\n") + nota;
|
|
345
317
|
}
|
|
346
|
-
|
|
347
|
-
// No matcheó: sugerir por prefijo/substring.
|
|
348
318
|
const cerca = Object.keys(TOOL_DOCS).filter((n) => n.includes(clave)).slice(0, 8);
|
|
349
319
|
const temas = Object.keys(TOPICS);
|
|
350
320
|
return [
|
|
351
|
-
`No
|
|
352
|
-
cerca.length ?
|
|
321
|
+
`No encontr\xE9 una herramienta o tema llamado "${clave}".`,
|
|
322
|
+
cerca.length ? `\xBFQuisiste decir?: ${cerca.join(", ")}` : "",
|
|
353
323
|
`Temas disponibles: ${temas.join(", ")}`,
|
|
354
|
-
`Sin argumentos, ayuda te da el
|
|
324
|
+
`Sin argumentos, ayuda te da el \xEDndice completo.`
|
|
355
325
|
].filter(Boolean).join("\n");
|
|
356
326
|
}
|
|
357
|
-
|
|
358
327
|
function indice(version, disponibles) {
|
|
359
328
|
const out = [
|
|
360
329
|
`AYUDA DEL MCP NEXUS FLEX${version ? ` (v${version})` : ""}`,
|
|
361
330
|
"",
|
|
362
|
-
"
|
|
363
|
-
"
|
|
331
|
+
"Ped\xED el detalle de una herramienta con: ayuda tool:<nombre>",
|
|
332
|
+
"Ped\xED un tema transversal con: ayuda tema:<clave>",
|
|
364
333
|
`Temas: ${Object.keys(TOPICS).join(", ")}`,
|
|
365
334
|
"",
|
|
366
|
-
"Herramientas" + (disponibles ? " disponibles para vos" : "") + ":"
|
|
335
|
+
"Herramientas" + (disponibles ? " disponibles para vos" : "") + ":"
|
|
367
336
|
];
|
|
368
337
|
for (const g of GROUPS) {
|
|
369
338
|
const items = g.tools.filter((t) => TOOL_DOCS[t] && (!disponibles || disponibles.has(t)));
|
|
370
339
|
if (!items.length) continue;
|
|
371
|
-
out.push("",
|
|
372
|
-
for (const t of items) out.push(`
|
|
340
|
+
out.push("", `\u25B8 ${g.titulo}`);
|
|
341
|
+
for (const t of items) out.push(` \u2022 ${t} \u2014 ${TOOL_DOCS[t].que}`);
|
|
373
342
|
}
|
|
374
|
-
// Tools registradas que no estén en ningún grupo (por si se agrega una y se olvida).
|
|
375
343
|
if (disponibles) {
|
|
376
344
|
const enGrupos = new Set(GROUPS.flatMap((g) => g.tools));
|
|
377
345
|
const sueltas = [...disponibles].filter((t) => TOOL_DOCS[t] && !enGrupos.has(t));
|
|
378
346
|
if (sueltas.length) {
|
|
379
|
-
out.push("", "
|
|
380
|
-
for (const t of sueltas) out.push(`
|
|
347
|
+
out.push("", "\u25B8 Otras");
|
|
348
|
+
for (const t of sueltas) out.push(` \u2022 ${t} \u2014 ${TOOL_DOCS[t].que}`);
|
|
381
349
|
}
|
|
382
350
|
}
|
|
383
351
|
return out.join("\n");
|
|
384
352
|
}
|
|
385
|
-
|
|
386
|
-
// ============================================================================
|
|
387
|
-
// FLUJOS GUIADOS (Fase A, ver docs/Plan-MCP-Flujo-Guiado.md). ⚠️ ESPEJO en
|
|
388
|
-
// backend/src/services/mcp-docs.ts. Paso a paso por objetivo para no dejar
|
|
389
|
-
// nada incompleto; el tool `flujo` los devuelve y el LLM guía con esto.
|
|
390
|
-
// ============================================================================
|
|
391
353
|
const CONTROL_POR_FOTO = [
|
|
392
|
-
"FLUJO
|
|
393
|
-
"
|
|
394
|
-
"a una cuenta ML (un cliente/nodo te los
|
|
395
|
-
"Sirve para registrar
|
|
354
|
+
"FLUJO \u2014 CONTROL POR FOTO Y CARGA DE PLANILLA V\xCDA MCP",
|
|
355
|
+
"Qu\xE9 es: cargar paquetes que YA vienen con etiqueta de Mercado Libre pero NO est\xE1n vinculados",
|
|
356
|
+
"a una cuenta ML (un cliente/nodo te los baj\xF3 etiquetados y te dej\xF3 las fotos en una CARPETA).",
|
|
357
|
+
"Sirve para registrar r\xE1pido el movimiento y el CLEARING entre nodos, sin escanear.",
|
|
396
358
|
"",
|
|
397
|
-
"
|
|
398
|
-
" responsable) o `asignar_mensajero_zona`.
|
|
359
|
+
"PREPARACI\xD3N (una vez): defin\xED qui\xE9n reparte cada zona con `asignar_nodo_zona` (nodo",
|
|
360
|
+
" responsable) o `asignar_mensajero_zona`. As\xED el auto-ruteo sabe a qui\xE9n mandar cada paquete.",
|
|
399
361
|
"",
|
|
400
|
-
"POR CADA FOTO de la carpeta
|
|
401
|
-
"
|
|
402
|
-
"
|
|
362
|
+
"POR CADA FOTO de la carpeta \u2192 `envio_desde_etiqueta_ml`:",
|
|
363
|
+
" \u2022 cliente (o mlSenderId): de qui\xE9n es el paquete (detecta al vendedor de ML);",
|
|
364
|
+
" \u2022 mlShipmentId + mlQr crudos + `reusarEtiqueta: true` \u2192 REUSA el tracking/QR/etiqueta ya",
|
|
403
365
|
" impreso (no genera uno nuevo), 'ml_manual', IDEMPOTENTE (recargar no duplica);",
|
|
404
|
-
"
|
|
405
|
-
"
|
|
406
|
-
" (ej. 'Aguirre 31**')
|
|
366
|
+
" \u2022 destino (destinatario, direcci\xF3n, localidad, CP);",
|
|
367
|
+
" \u2022 D\xCDGITOS/LETRAS ILEGIBLES: carg\xE1 la parte legible + un '*' por cada car\xE1cter que NO se lee",
|
|
368
|
+
" (ej. 'Aguirre 31**') \u2014 NO inventes \u2014 y pas\xE1 `fotoRuta` = la RUTA LOCAL de la foto en la",
|
|
407
369
|
" compu (ej. 'C:\\\\Users\\\\...\\\\Desktop\\\\etiquetas\\\\ml_123.jpg') para reencontrarla;",
|
|
408
|
-
"
|
|
409
|
-
" 'entregado' recorre TODOS los estados de una: A retirar
|
|
410
|
-
"
|
|
411
|
-
" queda registrado con
|
|
412
|
-
"
|
|
413
|
-
"
|
|
414
|
-
" que el
|
|
370
|
+
" \u2022 CIERRE DEL CICLO en un paso con `avanzarA`: 'colectado' / 'procesado' / 'entregado'.",
|
|
371
|
+
" 'entregado' recorre TODOS los estados de una: A retirar \u2192 Colectado \u2192 Procesado (En centro)",
|
|
372
|
+
" \u2192 [si pas\xE1s `grupo`, ej. 'Bonorino': En camino, con su integrante] \u2192 Entregado. Cada estado",
|
|
373
|
+
" queda registrado con QUI\xC9N lo hizo (vos, el usuario MCP) \u2014 es la v\xEDa r\xE1pida del clearing;",
|
|
374
|
+
" \u2022 `autoRutear: true`: adem\xE1s, manda el paquete al nodo/mensajero responsable de su zona.",
|
|
375
|
+
" \u2022 `nodoEntrega`: el nodo que RECIBI\xD3 y entreg\xF3 el paquete (ej. 'FastCorreo'). Es lo que hace",
|
|
376
|
+
" que el env\xEDo entre al CIERRE SEMANAL entre nodos (origen = nodo del cliente \u2192 entrega =",
|
|
415
377
|
" este nodo). Sin `grupo` se deduce: cliente del mismo nodo = paquete propio (sin traspaso);",
|
|
416
|
-
" de otro nodo = el grupo que comparten. Decilo siempre que sepas
|
|
378
|
+
" de otro nodo = el grupo que comparten. Decilo siempre que sepas qui\xE9n lo entreg\xF3;",
|
|
417
379
|
"",
|
|
418
|
-
"TANDA DE UN CADETE (lo
|
|
419
|
-
" de otros nodos mezclados): por cada foto
|
|
420
|
-
" reusarEtiqueta:true, fecha:<el
|
|
380
|
+
"TANDA DE UN CADETE (lo m\xE1s com\xFAn: una carpeta por d\xEDa y por cadete, con paquetes propios y",
|
|
381
|
+
" de otros nodos mezclados): por cada foto \u2192 mlQr crudo (+ destino le\xEDdo de la etiqueta),",
|
|
382
|
+
" reusarEtiqueta:true, fecha:<el d\xEDa>, avanzarA:'entregado', mensajero:<el cadete>,",
|
|
421
383
|
" nodoEntrega:<nuestro nodo>. El vendedor y su nodo salen del QR; si ya estaba cargado no se",
|
|
422
|
-
" duplica (se completa y se avanza). Si contesta que no conoce la cuenta de ML,
|
|
423
|
-
"
|
|
384
|
+
" duplica (se completa y se avanza). Si contesta que no conoce la cuenta de ML, PREGUNT\xC1 de",
|
|
385
|
+
" qu\xE9 nodo/cliente es y repet\xED con `cliente` \u2014 no adivines. Al final: conteo propios vs. de",
|
|
424
386
|
" cada nodo, los que no se reconocieron y las advertencias.",
|
|
425
|
-
"
|
|
426
|
-
"
|
|
387
|
+
" \u2022 PLANILLA ATRASADA: `fecha` = el d\xEDa real (dd/mm/aaaa). Ej.: 5 env\xEDos de un cliente de",
|
|
388
|
+
" Env\xEDos Frank que entreg\xF3 FastCorreo el lunes 14 \u2192 cliente, fecha:'14/09/2026',",
|
|
427
389
|
" avanzarA:'entregado', grupo:'Portela', nodoEntrega:'FastCorreo'. Si esa semana ya",
|
|
428
|
-
" cerr
|
|
390
|
+
" cerr\xF3, entra en el cierre siguiente marcado como tarde, con su fecha real.",
|
|
429
391
|
"",
|
|
430
|
-
"AL TERMINAR:
|
|
431
|
-
" responsable de zona (
|
|
432
|
-
" ABSORBER este historial (conciliar el provisorio) o descartarlo
|
|
392
|
+
"AL TERMINAR: devolv\xE9 el CONTEO total + desglose por cliente/zona/estado + qu\xE9 qued\xF3 sin",
|
|
393
|
+
" responsable de zona (avis\xE1 para configurarla). Cuando el nodo real se d\xE9 de alta puede",
|
|
394
|
+
" ABSORBER este historial (conciliar el provisorio) o descartarlo \u2014 no bloquea nada."
|
|
433
395
|
].join("\n");
|
|
434
|
-
|
|
435
|
-
export const FLUJOS = {
|
|
396
|
+
const FLUJOS = {
|
|
436
397
|
alta_cliente: [
|
|
437
|
-
"FLUJO
|
|
438
|
-
"
|
|
398
|
+
"FLUJO \u2014 ALTA DE CLIENTE (vendedor) COMPLETA",
|
|
399
|
+
"Gui\xE1 paso a paso; NO lo des por terminado hasta el paso 4.",
|
|
439
400
|
"",
|
|
440
|
-
"1) Datos
|
|
441
|
-
"
|
|
442
|
-
"2) LISTA DE PRECIOS (
|
|
443
|
-
"
|
|
444
|
-
"
|
|
445
|
-
"
|
|
446
|
-
"3) PERFIL DE ZONA:
|
|
447
|
-
" Ej.: cliente de CABA que usa las zonas de todos
|
|
401
|
+
"1) Datos b\xE1sicos: nombre (obligatorio), tel\xE9fono/WhatsApp, direcci\xF3n, DNI/CUIT si tiene.",
|
|
402
|
+
" \u2192 `cliente_crear`.",
|
|
403
|
+
"2) LISTA DE PRECIOS (pregunt\xE1 SIEMPRE \xAB\xBFqu\xE9 le cobr\xE1s a este cliente?\xBB):",
|
|
404
|
+
" \u2022 Oficial de Flex (la que usan todos) o un PRECIO PROPIO (mir\xE1 `precios_ver`, el nombre",
|
|
405
|
+
" est\xE1 en 'referencia'; si es nueva, se crea con nombre para reusarla).",
|
|
406
|
+
" \u2192 asign\xE1s con `cliente_editar idLista:<id>`.",
|
|
407
|
+
"3) PERFIL DE ZONA: pregunt\xE1 \xAB\xBFusa la zonificaci\xF3n COM\xDAN o necesita un perfil aparte?\xBB.",
|
|
408
|
+
" Ej.: cliente de CABA que usa las zonas de todos \u2192 perfil GENERAL; si opera distinto",
|
|
448
409
|
" (otras metazonas / precios por zona) asignale un perfil de zona propio.",
|
|
449
|
-
"4) COLECTA (
|
|
450
|
-
" timbre/piso/referencia y que quede GEOPOSICIONADA;
|
|
451
|
-
"5)
|
|
452
|
-
"6)
|
|
453
|
-
" colecta
|
|
410
|
+
"4) COLECTA (\xBFle retir\xE1s la mercader\xEDa?): si s\xED, ped\xED la DIRECCI\xD3N de retiro con",
|
|
411
|
+
" timbre/piso/referencia y que quede GEOPOSICIONADA; defin\xED si la colecta tiene cargo.",
|
|
412
|
+
"5) \xBFVende por Mercado Libre / Tienda? Ofrec\xE9 vincular con `generar_enlace_vinculacion`.",
|
|
413
|
+
"6) CONFIRM\xC1 (`clientes_del_nodo`): debe estar con su LISTA. Si le falta lista, zona o",
|
|
414
|
+
" colecta seg\xFAn lo que dijo, el alta est\xE1 INCOMPLETA \u2192 volv\xE9 al paso que falte."
|
|
454
415
|
].join("\n"),
|
|
455
|
-
|
|
456
416
|
control_por_foto: CONTROL_POR_FOTO,
|
|
457
|
-
alta_planilla_ml: CONTROL_POR_FOTO,
|
|
458
|
-
|
|
417
|
+
alta_planilla_ml: CONTROL_POR_FOTO,
|
|
418
|
+
// alias histórico
|
|
459
419
|
facturacion: [
|
|
460
|
-
"FLUJO
|
|
420
|
+
"FLUJO \u2014 PONER A FACTURAR (ARCA) DE CERO",
|
|
461
421
|
"",
|
|
462
422
|
"IDEA CENTRAL: quien COBRA es quien FACTURA. Cada cuenta de dinero puede tener su",
|
|
463
423
|
"propio emisor; lo que un cliente transfiere a esa cuenta se factura con el CUIT del",
|
|
464
|
-
"
|
|
424
|
+
"due\xF1o de esa cuenta. Las cuentas sin emisor propio facturan con el CUIT de la empresa.",
|
|
465
425
|
"",
|
|
466
|
-
"
|
|
426
|
+
"\u26A0\uFE0F LO QUE YO NO PUEDO HACER: el tr\xE1mite en ARCA (certificado, relaci\xF3n con el web",
|
|
467
427
|
" service, punto de venta) necesita la Clave Fiscal de esa persona y un navegador.",
|
|
468
428
|
" Yo no entro a ARCA ni manejo claves fiscales. Tampoco emito comprobantes: eso se",
|
|
469
|
-
" hace desde la PWA o desde el portal del cliente.
|
|
470
|
-
" configurado y te digo exactamente
|
|
429
|
+
" hace desde la PWA o desde el portal del cliente. S\xED dejo TODO lo de Nexus Flex",
|
|
430
|
+
" configurado y te digo exactamente qu\xE9 falta.",
|
|
471
431
|
"",
|
|
472
|
-
"PASO 0
|
|
473
|
-
" Te dice
|
|
474
|
-
" cliente.
|
|
432
|
+
"PASO 0 \u2014 \xBFD\xF3nde est\xE1s parado? \u2192 `facturacion_estado`.",
|
|
433
|
+
" Te dice qu\xE9 emisores hay, qu\xE9 cuentas no tienen emisor y qu\xE9 le falta a cada",
|
|
434
|
+
" cliente. Arranc\xE1 SIEMPRE por ac\xE1 y volv\xE9 al final para confirmar.",
|
|
475
435
|
"",
|
|
476
|
-
"PASO 1
|
|
477
|
-
" a) Registro
|
|
478
|
-
"
|
|
479
|
-
"
|
|
480
|
-
"
|
|
481
|
-
" b)
|
|
436
|
+
"PASO 1 \u2014 EL EMISOR (una vez por persona/CUIT que cobre). Lo hace ESA persona:",
|
|
437
|
+
" a) Registro \xDAnico Tributario \u2192 Puntos de venta \u2192 dar de alta uno de tipo",
|
|
438
|
+
" \xABFactura Electr\xF3nica - Monotributo - Web Services\xBB (monotributo) o",
|
|
439
|
+
" \xABRECE para aplicativo y web services\xBB (responsable inscripto).",
|
|
440
|
+
" \u26A0\uFE0F El de \xABFactura en L\xEDnea\xBB NO sirve. Anot\xE1 el n\xFAmero.",
|
|
441
|
+
" b) Administraci\xF3n de Certificados Digitales \u2192 agregar el servicio \u2192 subir un CSR",
|
|
482
442
|
" y descargar el certificado.",
|
|
483
|
-
" c) Administrador de Relaciones
|
|
484
|
-
"
|
|
485
|
-
" d) En la PWA,
|
|
486
|
-
"
|
|
487
|
-
"
|
|
488
|
-
"
|
|
443
|
+
" c) Administrador de Relaciones \u2192 Nueva Relaci\xF3n \u2192 ARCA \u2192 WebServices \u2192",
|
|
444
|
+
" \xABFacturaci\xF3n Electr\xF3nica\xBB \u2192 representante = ese certificado.",
|
|
445
|
+
" d) En la PWA, Configuraci\xF3n \u2192 \u{1F9FE} Facturaci\xF3n ARCA \u2192 \xAB+ Emisor para una cuenta\xBB:",
|
|
446
|
+
" eleg\xEDs la cuenta de dinero, carg\xE1s CUIT, raz\xF3n social (el TITULAR del CUIT),",
|
|
447
|
+
" condici\xF3n IVA, punto de venta, certificado y clave, y \xABProbar conexi\xF3n\xBB.",
|
|
448
|
+
" Empez\xE1 en HOMOLOGACI\xD3N; pas\xE1 a producci\xF3n cuando la prueba d\xE9 OK.",
|
|
489
449
|
"",
|
|
490
|
-
"PASO 2
|
|
491
|
-
"
|
|
492
|
-
"
|
|
493
|
-
" mensual.
|
|
494
|
-
" El corte queda en HOY: lo anterior no se factura desde el sistema (ya se
|
|
495
|
-
" por fuera y emitirlo de nuevo
|
|
450
|
+
"PASO 2 \u2014 LOS CLIENTES a los que le va a facturar \u2192 `facturacion_preparar_cliente`.",
|
|
451
|
+
" Necesit\xE1s de cada uno: CUIT, raz\xF3n social (como figura en ARCA, NO el nombre de",
|
|
452
|
+
" fantas\xEDa), condici\xF3n frente al IVA, en qu\xE9 cuenta cobra, y si factura semanal o",
|
|
453
|
+
" mensual. Pregunt\xE1 TODO eso antes de ejecutar; no inventes ninguno.",
|
|
454
|
+
" El corte queda en HOY: lo anterior no se factura desde el sistema (ya se factur\xF3",
|
|
455
|
+
" por fuera y emitirlo de nuevo ser\xEDa un duplicado).",
|
|
496
456
|
"",
|
|
497
|
-
"PASO 3
|
|
498
|
-
" tiene CUIT,
|
|
499
|
-
" habilitado. Si falta algo, el estado te dice
|
|
457
|
+
"PASO 3 \u2014 CONFIRMAR \u2192 `facturacion_estado` de nuevo. Un cliente est\xE1 listo cuando",
|
|
458
|
+
" tiene CUIT, raz\xF3n social, condici\xF3n IVA, cuenta de cobro con emisor y est\xE1",
|
|
459
|
+
" habilitado. Si falta algo, el estado te dice cu\xE1l.",
|
|
500
460
|
"",
|
|
501
|
-
"
|
|
502
|
-
"
|
|
503
|
-
" cerrado y toca
|
|
504
|
-
" reclamos abiertos, no
|
|
505
|
-
"
|
|
506
|
-
" el staff la corrige; el
|
|
507
|
-
"
|
|
461
|
+
"C\xD3MO SE FACTURA DESPU\xC9S (no por ac\xE1):",
|
|
462
|
+
" \u2022 El cliente entra a su portal (Mi Cuenta \u2192 \u{1F9FE} Tus facturas), revisa el per\xEDodo",
|
|
463
|
+
" cerrado y toca \xABEmitir factura\xBB. Solo aparece si: el per\xEDodo cerr\xF3, no tiene",
|
|
464
|
+
" reclamos abiertos, no est\xE1 facturado y NO tiene saldo pendiente.",
|
|
465
|
+
" \u2022 Si el importe no coincide con lo acordado, el cliente RECLAMA la liquidaci\xF3n y",
|
|
466
|
+
" el staff la corrige; el bot\xF3n usa siempre lo liquidado, nunca un n\xFAmero a mano.",
|
|
467
|
+
" \u2022 El staff puede emitir desde la PWA (Liquidaciones Anteriores \u2192 Facturar)."
|
|
508
468
|
].join("\n"),
|
|
509
|
-
|
|
510
469
|
alta_operador: [
|
|
511
|
-
"FLUJO
|
|
512
|
-
"1) Datos: email (con el que loguea), nombre y apellido (obligatorios),
|
|
513
|
-
"2) Permisos:
|
|
514
|
-
" reportes, datos). Si es el
|
|
515
|
-
"
|
|
516
|
-
"3)
|
|
517
|
-
"4) Pasale la clave temporal por un canal seguro. Nunca la inventes vos."
|
|
470
|
+
"FLUJO \u2014 ALTA DE UN OPERADOR DE NODO (staff que administra)",
|
|
471
|
+
"1) Datos: email (con el que loguea), nombre y apellido (obligatorios), tel\xE9fono.",
|
|
472
|
+
"2) Permisos: qu\xE9 secciones va a manejar (gesti\xF3n, finanzas, mensajeros, precios, wms,",
|
|
473
|
+
" reportes, datos). Si es el due\xF1o del nodo, despu\xE9s habilitalo como admin de nodo.",
|
|
474
|
+
" \u2192 `operador_crear` (te devuelve una CLAVE TEMPORAL para pasarle; la cambia al entrar).",
|
|
475
|
+
"3) \xBFEs due\xF1o/mano derecha? `usuario_habilitar_rol` para admin de nodo (solo admin global).",
|
|
476
|
+
"4) Pasale la clave temporal por un canal seguro. Nunca la inventes vos."
|
|
518
477
|
].join("\n"),
|
|
519
|
-
|
|
520
478
|
alta_chofer: [
|
|
521
|
-
"FLUJO
|
|
522
|
-
"1) Datos: nombre y apellido (obligatorios),
|
|
523
|
-
"2) Si
|
|
479
|
+
"FLUJO \u2014 ALTA DE UN CHOFER (mensajero/cadete)",
|
|
480
|
+
"1) Datos: nombre y apellido (obligatorios), tel\xE9fono, email. \u2192 `chofer_crear` (devuelve CLAVE TEMPORAL).",
|
|
481
|
+
"2) Si adem\xE1s cobra su ganancia contra su cuenta, pas\xE1 `mensajeroNombre` (el nombre con",
|
|
524
482
|
" el que figura en el Maestro) para el macheo.",
|
|
525
|
-
"3) Zona: asignale su metazona con `asignar_mensajero_zona` para que le lleguen
|
|
526
|
-
"4) Pasale la clave temporal; la cambia al primer ingreso."
|
|
527
|
-
].join("\n")
|
|
483
|
+
"3) Zona: asignale su metazona con `asignar_mensajero_zona` para que le lleguen env\xEDos.",
|
|
484
|
+
"4) Pasale la clave temporal; la cambia al primer ingreso."
|
|
485
|
+
].join("\n")
|
|
528
486
|
};
|
|
529
|
-
|
|
530
|
-
/** Devuelve el paso a paso de un objetivo, o el índice de flujos disponibles. */
|
|
531
|
-
export function renderFlujo(q) {
|
|
487
|
+
function renderFlujo(q) {
|
|
532
488
|
const key = (q ?? "").toLowerCase().trim().replace(/[\s-]+/g, "_");
|
|
533
489
|
if (key && FLUJOS[key]) return FLUJOS[key];
|
|
534
490
|
const found = key ? Object.keys(FLUJOS).find((k) => k.includes(key) || key.includes(k)) : null;
|
|
535
491
|
if (found) return FLUJOS[found];
|
|
536
492
|
return [
|
|
537
493
|
"FLUJOS GUIADOS disponibles (paso a paso para no dejar nada a medias):",
|
|
538
|
-
...Object.keys(FLUJOS).map((k) => `
|
|
494
|
+
...Object.keys(FLUJOS).map((k) => ` \u2022 ${k}`),
|
|
539
495
|
"",
|
|
540
|
-
"
|
|
496
|
+
"Ped\xED uno, ej.: flujo alta_cliente"
|
|
541
497
|
].join("\n");
|
|
542
498
|
}
|
|
499
|
+
export {
|
|
500
|
+
FLUJOS,
|
|
501
|
+
GROUPS,
|
|
502
|
+
GUIAS,
|
|
503
|
+
TOOL_DOCS,
|
|
504
|
+
TOPICS,
|
|
505
|
+
guiaOnboarding,
|
|
506
|
+
renderAyuda,
|
|
507
|
+
renderFlujo
|
|
508
|
+
};
|