From c64e990dfa329e8006bb04cd9c67eef7a699f625 Mon Sep 17 00:00:00 2001 From: Nurfog Date: Tue, 22 Sep 2026 13:54:54 -0300 Subject: [PATCH] feat: tablero de modulo con uso real (equipo helpdesk, pagos validados, inventario API en dashboard) --- src/app/api/portal/helpdesk-stats/route.ts | 13 + src/app/api/portal/helpdesk-team/route.ts | 13 + src/app/api/portal/pagos-validados/route.ts | 44 + src/app/m/[name]/page.tsx | 375 ++- src/components/TableroView.tsx | 124 +- src/lib/api-inventory.ts | 2408 +++++++++++++++++++ src/lib/sam.ts | 110 +- 7 files changed, 2970 insertions(+), 117 deletions(-) create mode 100644 src/app/api/portal/helpdesk-stats/route.ts create mode 100644 src/app/api/portal/helpdesk-team/route.ts create mode 100644 src/app/api/portal/pagos-validados/route.ts create mode 100644 src/lib/api-inventory.ts diff --git a/src/app/api/portal/helpdesk-stats/route.ts b/src/app/api/portal/helpdesk-stats/route.ts new file mode 100644 index 0000000..d61bfb6 --- /dev/null +++ b/src/app/api/portal/helpdesk-stats/route.ts @@ -0,0 +1,13 @@ +// Estadísticas reales de uso de Helpdesk: proxy server-side a +// GET /api/helpdesk/stats con la cuenta de servicio. +// Requiere sesión IT. +import { assertIT, helpdeskFetch, asResponse, errResponse } from "@/lib/correo-server"; + +export async function GET(req: Request): Promise { + try { + await assertIT(req); + return await asResponse(await helpdeskFetch("/api/helpdesk/stats")); + } catch (e) { + return errResponse(e); + } +} diff --git a/src/app/api/portal/helpdesk-team/route.ts b/src/app/api/portal/helpdesk-team/route.ts new file mode 100644 index 0000000..0ebeb64 --- /dev/null +++ b/src/app/api/portal/helpdesk-team/route.ts @@ -0,0 +1,13 @@ +// Equipo real que usa Helpdesk: proxy server-side a +// GET /api/helpdesk/users con la cuenta de servicio +// (HELPDESK_SERVICE_USER/PASS). Requiere sesión IT. +import { assertIT, helpdeskFetch, asResponse, errResponse } from "@/lib/correo-server"; + +export async function GET(req: Request): Promise { + try { + await assertIT(req); + return await asResponse(await helpdeskFetch("/api/helpdesk/users")); + } catch (e) { + return errResponse(e); + } +} diff --git a/src/app/api/portal/pagos-validados/route.ts b/src/app/api/portal/pagos-validados/route.ts new file mode 100644 index 0000000..0fe5b6e --- /dev/null +++ b/src/app/api/portal/pagos-validados/route.ts @@ -0,0 +1,44 @@ +import { NextResponse } from "next/server"; +import { assertIT } from "@/lib/correo-server"; + +// Pagos validados reales: proxy server-side a +// GET /api/Boletas/payments?mes=&year= (endpoint público de SAM.API, +// no requiere Bearer). Requiere sesión IT para verlo en el portal. +const SAM_API_URL = + process.env.SAM_API_URL ?? + process.env.NEXT_PUBLIC_API_URL ?? + "https://api.devops.norteamericano.cl"; + +export async function GET(req: Request): Promise { + try { + await assertIT(req); + const url = new URL(req.url); + const now = new Date(); + const mes = url.searchParams.get("mes") ?? String(now.getMonth() + 1); + const year = url.searchParams.get("year") ?? String(now.getFullYear()); + const m = Number(mes); + const y = Number(year); + if (!Number.isInteger(m) || m < 1 || m > 12 || !Number.isInteger(y) || y < 2000 || y > 2100) { + return NextResponse.json({ error: "mes (1-12) y year válidos requeridos" }, { status: 400 }); + } + const res = await fetch( + `${SAM_API_URL}/api/Boletas/payments?mes=${m}&year=${y}`, + { cache: "no-store" } + ); + const text = await res.text(); + try { + return NextResponse.json(JSON.parse(text), { status: res.status }); + } catch { + return new NextResponse(text, { status: res.status }); + } + } catch (e) { + const status = + typeof e === "object" && e !== null && "status" in e + ? Number((e as { status: unknown }).status) || 500 + : 500; + return NextResponse.json( + { error: e instanceof Error ? e.message : "Error" }, + { status } + ); + } +} diff --git a/src/app/m/[name]/page.tsx b/src/app/m/[name]/page.tsx index 8262216..f467928 100644 --- a/src/app/m/[name]/page.tsx +++ b/src/app/m/[name]/page.tsx @@ -1,14 +1,16 @@ "use client"; import Link from "next/link"; +import { useEffect, useState } from "react"; import SamShell from "@/components/SamShell"; import { useModules, useStats, useMe } from "@/lib/store" import { useParams } from "next/navigation"; import { displayName, envOf, - getModuleFunctions, getStatusInfo, + isPagosModule, + isHelpdeskModule, moduleUrl, } from "@/lib/sam"; import { @@ -36,8 +38,340 @@ function Bar({ value, color }: { value: number; color: string }) { ); } +interface HelpdeskMember { + idUsuario: string; + nombres?: string; + apPaterno?: string; + email?: string; + role?: string; + departmentName?: string; + isActive?: boolean; +} + +interface HelpdeskStats { + totalTickets: number; + openTickets: number; + inProgressTickets: number; + resolvedTickets: number; + closedTickets: number; + unassignedTickets: number; + criticalTickets: number; + dailyCounts: { date: string; count: number }[]; +} + +interface Boleta { + folio: number; + alumnoRut?: string | null; + alumnoNombre?: string | null; + fecha: string; + monto: number; + tipo?: string; + estado?: string; +} + +function HelpdeskUsage() { + const [team, setTeam] = useState(null); + const [stats, setStats] = useState(null); + const [error, setError] = useState(null); + + useEffect(() => { + let cancelled = false; + async function load() { + try { + const [tRes, sRes] = await Promise.all([ + fetch("/api/portal/helpdesk-team", { cache: "no-store" }), + fetch("/api/portal/helpdesk-stats", { cache: "no-store" }), + ]); + if (!tRes.ok || !sRes.ok) { + const t = await tRes.json().catch(() => ({})); + const s = await sRes.json().catch(() => ({})); + throw new Error( + (t as { error?: string }).error || + (s as { error?: string }).error || + `Helpdesk respondió ${tRes.status}/${sRes.status}` + ); + } + const t = (await tRes.json()) as HelpdeskMember[]; + const s = (await sRes.json()) as HelpdeskStats; + if (!cancelled) { + setTeam(Array.isArray(t) ? t : []); + setStats(s); + } + } catch (e) { + if (!cancelled) setError(e instanceof Error ? e.message : "Error al cargar uso"); + } + } + load(); + return () => { + cancelled = true; + }; + }, []); + + if (error) { + return ( +
+ + No se pudo cargar el uso real de Helpdesk: {error} +
+ ); + } + + if (!team || !stats) { + return ( +
+
+

Cargando equipo y estadísticas reales…

+
+ ); + } + + const active = team.filter((m) => m.isActive !== false); + const maxDaily = Math.max(...stats.dailyCounts.map((d) => d.count), 1); + + return ( + <> +
+ Equipo que lo usa ({active.length}) +
+
+
+
+ {active.length === 0 && ( +

Sin integrantes registrados en el equipo.

+ )} +
+ {active.map((m) => ( +
+ + + {[m.nombres, m.apPaterno].filter(Boolean).join(" ") || m.idUsuario} + + {m.idUsuario} + {m.email ? ` · ${m.email}` : ""} + {m.departmentName ? ` · ${m.departmentName}` : ""} + + + {m.role ?? "—"} +
+ ))} +
+ + Fuente: GET /api/helpdesk/users (SAM.API, cuenta de servicio). + +
+
+
+ +
+ Estadísticas de uso +
+
+ {[ + { label: "Total tickets", value: stats.totalTickets }, + { label: "Abiertos", value: stats.openTickets }, + { label: "En progreso", value: stats.inProgressTickets }, + { label: "Resueltos", value: stats.resolvedTickets }, + { label: "Críticos", value: stats.criticalTickets }, + { label: "Sin asignar", value: stats.unassignedTickets }, + ].map((c) => ( +
+
+
{c.value}
+ {c.label} +
+
+ ))} +
+ {stats.dailyCounts.length > 0 && ( +
+
+ + Tickets por día (últimos 14 días) +
+
+
+ {stats.dailyCounts.map((d) => ( +
+ ))} +
+ + Fuente: GET /api/helpdesk/stats (SAM.API). + +
+
+ )} + + ); +} + +function PagosUsage() { + const now = new Date(); + const [mes, setMes] = useState(String(now.getMonth() + 1)); + const [year, setYear] = useState(String(now.getFullYear())); + const [rows, setRows] = useState(null); + const [error, setError] = useState(null); + const [loading, setLoading] = useState(false); + + async function load(m: string, y: string) { + setLoading(true); + setError(null); + try { + const res = await fetch(`/api/portal/pagos-validados?mes=${m}&year=${y}`, { + cache: "no-store", + }); + const data = await res.json().catch(() => null); + if (!res.ok) { + throw new Error( + (data as { error?: string } | null)?.error || `Pagos respondió ${res.status}` + ); + } + setRows(Array.isArray(data) ? data : []); + } catch (e) { + setError(e instanceof Error ? e.message : "Error al cargar pagos"); + setRows(null); + } finally { + setLoading(false); + } + } + + useEffect(() => { + // Carga inicial: fetch async (setState ocurre en callbacks, no sincronico). + // eslint-disable-next-line react-hooks/set-state-in-effect + load(mes, year); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const total = (rows ?? []).reduce((acc, r) => acc + (Number(r.monto) || 0), 0); + + return ( + <> +
+ Pagos validados +
+
+
+
+
{ + e.preventDefault(); + load(mes, year); + }} + > +
+ + +
+
+ + setYear(e.target.value)} + inputMode="numeric" + style={{ width: 100 }} + /> +
+ + {rows && ( + + {rows.length} pagos · Total ${total.toLocaleString("es-CL")} + + )} +
+ + {error && ( +
+ + No se pudieron cargar los pagos validados: {error} +
+ )} + + {!error && loading && ( +
+
+
+ )} + + {!error && !loading && rows && rows.length === 0 && ( +

Sin pagos validados para {mes}/{year}.

+ )} + + {!error && !loading && rows && rows.length > 0 && ( +
+ + + + + + + + + + + + {rows.slice(0, 100).map((r, i) => ( + + + + + + + + ))} + +
FolioAlumnoFechaMontoEstado
{r.folio} + {r.alumnoNombre ?? "—"} + {r.alumnoRut ? ( + {r.alumnoRut} + ) : null} + + {r.fecha ? String(r.fecha).slice(0, 10) : "—"} + ${Number(r.monto || 0).toLocaleString("es-CL")}{r.estado || r.tipo || "—"}
+ {rows.length > 100 && ( + Mostrando 100 de {rows.length}. + )} +
+ )} + + Fuente: GET /api/Boletas/payments?mes=&year= (SAM.API). + +
+
+
+ + ); +} + // Tablero funcional del módulo: estado + carga de trabajo + -// funciones API en el sidebar (plantilla SamShell). +// uso real (equipo + estadísticas). Ya no muestra la lista +// inventada "Funciones disponibles de la API": el uso de la API +// vive solo en el dashboard principal (/tablero). export default function ModuleBoard() { const params = useParams(); const name = Array.isArray(params.name) ? params.name[0] : params.name ?? ""; @@ -49,7 +383,6 @@ export default function ModuleBoard() { const mod = data?.modules.find( (m) => m.name.toLowerCase() === name.toLowerCase() ); - const functions = getModuleFunctions(name); const stat = mod ? statForModule(stats, mod.name) : undefined; const status = mod ? getStatusInfo(mod) : null; const env = mod ? envOf(mod.branch) : null; @@ -58,6 +391,8 @@ export default function ModuleBoard() { const title = mod ? displayName(mod.name) : displayName(name || "Módulo"); const menu = [{ label: "Aplicaciones", icon: "bx-layer", href: "/" }]; + const showHelpdesk = isHelpdeskModule(name); + const showPagos = !showHelpdesk && isPagosModule(name); return (
-
- Funciones disponibles de la API -
-
-
-
-
- {functions.map((f) => ( - - - - {f.label} - {f.desc} - - GET {f.path} - - ))} -
-
+ {showHelpdesk && } + {showPagos && } + {!showHelpdesk && !showPagos && ( +
+ Este módulo aún no expone + estadísticas de uso en el portal. El uso de la API se muestra solo + en el dashboard principal.
-
+ )} )} diff --git a/src/components/TableroView.tsx b/src/components/TableroView.tsx index dbbf060..d3f3760 100644 --- a/src/components/TableroView.tsx +++ b/src/components/TableroView.tsx @@ -1,7 +1,7 @@ "use client"; import Link from "next/link"; -import { useMemo, type CSSProperties } from "react"; +import { useMemo, useState, type CSSProperties } from "react"; import { useModules, useStats } from "@/lib/store"; import { assignColorsForModules, @@ -24,6 +24,11 @@ import { type ContainerStat, } from "@/lib/stats"; import type { ModuleState } from "@/lib/sam"; +import { + API_INVENTORY, + API_TOTAL_CONTROLLERS, + API_TOTAL_ENDPOINTS, +} from "@/lib/api-inventory"; function Donut({ ok, starting, down }: { ok: number; starting: number; down: number }) { const total = ok + starting + down; @@ -180,9 +185,120 @@ function AppCard({ ); } +const SAM_API_URL = + process.env.NEXT_PUBLIC_API_URL || "https://api.devops.norteamericano.cl"; + +function ApiUsage() { + const [q, setQ] = useState(""); + const [expanded, setExpanded] = useState(false); + const filtered = useMemo(() => { + const needle = q.trim().toLowerCase(); + if (!needle) return API_INVENTORY; + return API_INVENTORY.filter( + (c) => + c.controller.toLowerCase().includes(needle) || + c.base.toLowerCase().includes(needle) || + c.endpoints.some((e) => e.path.toLowerCase().includes(needle)) + ); + }, [q]); + const shown = expanded ? filtered : filtered.slice(0, 12); + const getCount = API_INVENTORY.reduce( + (acc, c) => acc + c.endpoints.filter((e) => e.method === "GET").length, + 0 + ); + + return ( + <> +
+ Uso de la API (SAM.API real) +
+
+
+
+
+
+ Endpoints reales + {API_TOTAL_ENDPOINTS} +
+
+ Controladores + {API_TOTAL_CONTROLLERS} +
+
+ Lecturas (GET) + {getCount} +
+ + + Abrir Swagger + +
+
+ setQ(e.target.value)} + /> +
+
+ + + + + + + + + + + {shown.map((c) => { + const methods = Array.from(new Set(c.endpoints.map((e) => e.method))).join(" · "); + return ( + + + + + + + ); + })} + +
ControladorRuta baseEndpointsMétodos
{c.controller} + {c.base} + {c.count}{methods}
+ {filtered.length === 0 && ( +

Sin coincidencias para “{q}”.

+ )} +
+ {filtered.length > 12 && ( + + )} + + Inventario generado desde backend/SAM.API/Controllers/*.cs — no + son funciones inventadas por el portal. El detalle por aplicación vive en su + tablero: Helpdesk muestra equipo + tickets, WebPay/Pagos muestra pagos + validados. + +
+
+
+ + ); +} // Vista del tablero (contenido): tarjeta grande de estado global + -// estado y carga por aplicación. Se usa en /tablero y como -// landing de it.sam.devops.norteamericano.cl +// estado y carga por aplicación + uso real de la API. +// Se usa en /tablero y como landing de it.sam.devops.norteamericano.cl export default function TableroView() { const { data } = useModules(); const stats = useStats(); @@ -292,6 +408,8 @@ export default function TableroView() { )} + +

Auto-actualizado cada 30s · Carga de trabajo en tiempo real (docker stats)

diff --git a/src/lib/api-inventory.ts b/src/lib/api-inventory.ts new file mode 100644 index 0000000..144ccfa --- /dev/null +++ b/src/lib/api-inventory.ts @@ -0,0 +1,2408 @@ +// ============================================================ +// Inventario REAL de SAM.API — generado desde +// backend/SAM.API/Controllers/*.cs ([Route] + [Http*]). +// No inventar endpoints: este archivo se regenera con el script +// del commit (parseo de controladores). El dashboard principal +// lo usa para 'Uso de la API'. Las páginas /m/[name] NO muestran +// funciones: muestran equipo + estadísticas de uso reales. +// ============================================================ + +export interface ApiEndpoint { method: string; path: string; } +export interface ApiControllerInfo { controller: string; base: string; count: number; endpoints: ApiEndpoint[]; } + +export const API_TOTAL_ENDPOINTS = 514; +export const API_TOTAL_CONTROLLERS = 48; + +export const API_INVENTORY: ApiControllerInfo[] = [ + { + "controller": "AlumnoExtra", + "base": "api/alumnos/extra", + "count": 36, + "endpoints": [ + { + "method": "GET", + "path": "api/alumnos/extra/buscar" + }, + { + "method": "GET", + "path": "api/alumnos/extra/empresa/buscar" + }, + { + "method": "GET", + "path": "api/alumnos/extra/datos" + }, + { + "method": "GET", + "path": "api/alumnos/extra/ocupaciones" + }, + { + "method": "GET", + "path": "api/alumnos/extra/lamaisonnnette" + }, + { + "method": "GET", + "path": "api/alumnos/extra/colegios" + }, + { + "method": "GET", + "path": "api/alumnos/extra/profesiones" + }, + { + "method": "GET", + "path": "api/alumnos/extra/comunas" + }, + { + "method": "POST", + "path": "api/alumnos/extra/ingresar-v2" + }, + { + "method": "POST", + "path": "api/alumnos/extra/ingresar-v3" + }, + { + "method": "POST", + "path": "api/alumnos/extra/empresa/ingresar" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/direccion" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/direccion-v2" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/colegio" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/profesion" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/comuna" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/direccion-x" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/empresa" + }, + { + "method": "POST", + "path": "api/alumnos/extra/apoderados" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/apoderados" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/apoderados/direccion-comuna" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/apoderados/contacto" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/apoderados/contacto-v2" + }, + { + "method": "GET", + "path": "api/alumnos/extra/apoderados/por-alumno" + }, + { + "method": "PUT", + "path": "api/alumnos/extra/apoderados/asignar" + }, + { + "method": "GET", + "path": "api/alumnos/extra/{idAlumno}/antiguedad" + }, + { + "method": "GET", + "path": "api/alumnos/extra/{idAlumno}/curso-recuperado" + }, + { + "method": "GET", + "path": "api/alumnos/extra/formas-pago/{boleta}" + }, + { + "method": "GET", + "path": "api/alumnos/extra/{alumnoId}/cursos-renovacion" + }, + { + "method": "GET", + "path": "api/alumnos/extra/{alumnoId}/diagnostico" + }, + { + "method": "GET", + "path": "api/alumnos/extra/{alumnoId}/diagnostico-kid" + }, + { + "method": "POST", + "path": "api/alumnos/extra/asignar-lead-diagnostico" + }, + { + "method": "GET", + "path": "api/alumnos/extra/{alumnoId}/ultimo-nivel" + }, + { + "method": "POST", + "path": "api/alumnos/extra/empresa/asociacion" + }, + { + "method": "GET", + "path": "api/alumnos/extra/empresa/documentos-registro" + }, + { + "method": "POST", + "path": "api/alumnos/extra/empresa/documentos-registro" + } + ] + }, + { + "controller": "Alumnos", + "base": "api/Alumnos", + "count": 22, + "endpoints": [ + { + "method": "GET", + "path": "api/Alumnos" + }, + { + "method": "GET", + "path": "api/Alumnos/search" + }, + { + "method": "PUT", + "path": "api/Alumnos" + }, + { + "method": "GET", + "path": "api/Alumnos/courses" + }, + { + "method": "GET", + "path": "api/Alumnos/contracts" + }, + { + "method": "GET", + "path": "api/Alumnos/certificates" + }, + { + "method": "GET", + "path": "api/Alumnos/history" + }, + { + "method": "GET", + "path": "api/Alumnos/history/finished" + }, + { + "method": "GET", + "path": "api/Alumnos/history/postponed" + }, + { + "method": "GET", + "path": "api/Alumnos/promotions" + }, + { + "method": "GET", + "path": "api/Alumnos/grades" + }, + { + "method": "GET", + "path": "api/Alumnos/attendance" + }, + { + "method": "GET", + "path": "api/Alumnos/blocked" + }, + { + "method": "GET", + "path": "api/Alumnos/seniority" + }, + { + "method": "GET", + "path": "api/Alumnos/logs" + }, + { + "method": "GET", + "path": "api/Alumnos/log-types" + }, + { + "method": "POST", + "path": "api/Alumnos/logs" + }, + { + "method": "GET", + "path": "api/Alumnos/apoderados" + }, + { + "method": "GET", + "path": "api/Alumnos/anexos" + }, + { + "method": "POST", + "path": "api/Alumnos/authorization-requests" + }, + { + "method": "POST", + "path": "api/Alumnos/certificates" + }, + { + "method": "PUT", + "path": "api/Alumnos/certificates" + } + ] + }, + { + "controller": "Apoderados", + "base": "api/apoderados", + "count": 3, + "endpoints": [ + { + "method": "PUT", + "path": "api/apoderados/{rut}" + }, + { + "method": "GET", + "path": "api/apoderados/search" + }, + { + "method": "GET", + "path": "api/apoderados/{rut}" + } + ] + }, + { + "controller": "ArqueoCaja", + "base": "api/ArqueoCaja", + "count": 2, + "endpoints": [ + { + "method": "GET", + "path": "api/ArqueoCaja/hoy" + }, + { + "method": "GET", + "path": "api/ArqueoCaja/ejecutivo/{usuarioId}" + } + ] + }, + { + "controller": "Auth", + "base": "api/Auth", + "count": 4, + "endpoints": [ + { + "method": "POST", + "path": "api/Auth/login" + }, + { + "method": "POST", + "path": "api/Auth/portal-login" + }, + { + "method": "POST", + "path": "api/Auth/it-login" + }, + { + "method": "GET", + "path": "api/Auth/profile" + } + ] + }, + { + "controller": "Boletas", + "base": "api/Boletas", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/Boletas/{folio}" + }, + { + "method": "GET", + "path": "api/Boletas/pending" + }, + { + "method": "GET", + "path": "api/Boletas/payments" + } + ] + }, + { + "controller": "ComercialExtra", + "base": "api/comercial/extra", + "count": 66, + "endpoints": [ + { + "method": "GET", + "path": "api/comercial/extra/nps" + }, + { + "method": "GET", + "path": "api/comercial/extra/ssees" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-alumnos-nuevos" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-alumnos-nuevos-periodo" + }, + { + "method": "GET", + "path": "api/comercial/extra/ventas-mes-actual" + }, + { + "method": "GET", + "path": "api/comercial/extra/ventas-mes" + }, + { + "method": "GET", + "path": "api/comercial/extra/ventas-anual" + }, + { + "method": "GET", + "path": "api/comercial/extra/ventas-anual-x-mes" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-ventas-year" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-ventas-acumulado" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-ventas-anual" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-ventas-empresas" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-ventas-empresas-anual" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-ventas-periodo" + }, + { + "method": "GET", + "path": "api/comercial/extra/informe-mensual-empresas" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-mes" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-mes-detalle" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-year" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-detalle-anual" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-year-detalle" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-ssee" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-ssee-mes" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-ingresos-ssee-year" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-programa" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-programa-mes" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-programa-year" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-pago-mes" + }, + { + "method": "GET", + "path": "api/comercial/extra/resumen-pago-year" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-actual" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-actual-sede" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-sede" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-detallado" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-sede" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-x-dias" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-x-meses" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-tcredito" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-tcredito" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-comunas" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-comunas" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-actual-promos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-promos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-promos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-actual-promos-cursos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-promos-cursos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-promos-cursos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-ejecutivos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-ejecutivos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-mes-vta-cursos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-pc-year-vta-cursos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-prediccion-ingresos" + }, + { + "method": "GET", + "path": "api/comercial/extra/vista-prediccion-ingresos-actual" + }, + { + "method": "GET", + "path": "api/comercial/extra/lead-informe" + }, + { + "method": "GET", + "path": "api/comercial/extra/lead-tipo-contacto" + }, + { + "method": "GET", + "path": "api/comercial/extra/lead-tipo-estado" + }, + { + "method": "GET", + "path": "api/comercial/extra/lead-informe-v2" + }, + { + "method": "GET", + "path": "api/comercial/extra/lead-informe-detalle-ejecutivo" + }, + { + "method": "GET", + "path": "api/comercial/extra/lead-informe-reasignar" + }, + { + "method": "GET", + "path": "api/comercial/extra/usuarios/nombre" + }, + { + "method": "GET", + "path": "api/comercial/extra/periodos-activos-letra" + }, + { + "method": "GET", + "path": "api/comercial/extra/planes-anuales" + }, + { + "method": "GET", + "path": "api/comercial/extra/cursos" + }, + { + "method": "GET", + "path": "api/comercial/extra/sedes" + }, + { + "method": "GET", + "path": "api/comercial/extra/programas" + } + ] + }, + { + "controller": "Contabilidad", + "base": "api/Contabilidad", + "count": 21, + "endpoints": [ + { + "method": "GET", + "path": "api/Contabilidad/asientos" + }, + { + "method": "GET", + "path": "api/Contabilidad/asiento" + }, + { + "method": "GET", + "path": "api/Contabilidad/asientos/detalles" + }, + { + "method": "POST", + "path": "api/Contabilidad/asientos" + }, + { + "method": "POST", + "path": "api/Contabilidad/asientos/detalles" + }, + { + "method": "POST", + "path": "api/Contabilidad/asientos/cerrar" + }, + { + "method": "GET", + "path": "api/Contabilidad/cuentas" + }, + { + "method": "GET", + "path": "api/Contabilidad/cuenta" + }, + { + "method": "POST", + "path": "api/Contabilidad/cuentas" + }, + { + "method": "PUT", + "path": "api/Contabilidad/cuentas" + }, + { + "method": "GET", + "path": "api/Contabilidad/caja/movimientos" + }, + { + "method": "GET", + "path": "api/Contabilidad/caja/saldo" + }, + { + "method": "POST", + "path": "api/Contabilidad/caja/movimientos" + }, + { + "method": "GET", + "path": "api/Contabilidad/libro/diario" + }, + { + "method": "GET", + "path": "api/Contabilidad/libro/mayor" + }, + { + "method": "GET", + "path": "api/Contabilidad/balance/comprobacion" + }, + { + "method": "GET", + "path": "api/Contabilidad/balance/general" + }, + { + "method": "GET", + "path": "api/Contabilidad/periodos" + }, + { + "method": "GET", + "path": "api/Contabilidad/periodo" + }, + { + "method": "POST", + "path": "api/Contabilidad/periodos/cerrar" + }, + { + "method": "POST", + "path": "api/Contabilidad/periodos/abrir" + } + ] + }, + { + "controller": "ContratoExtra", + "base": "api/contratos/extra", + "count": 16, + "endpoints": [ + { + "method": "POST", + "path": "api/contratos/extra/ingresar-detalle" + }, + { + "method": "GET", + "path": "api/contratos/extra/pdf" + }, + { + "method": "GET", + "path": "api/contratos/extra/pdf-jornadas" + }, + { + "method": "GET", + "path": "api/contratos/extra/pdf-programas-cursos" + }, + { + "method": "GET", + "path": "api/contratos/extra/pdf-sedes" + }, + { + "method": "GET", + "path": "api/contratos/extra/pdf-detalle" + }, + { + "method": "GET", + "path": "api/contratos/extra/informacion" + }, + { + "method": "POST", + "path": "api/contratos/extra/empresa/ingresar" + }, + { + "method": "POST", + "path": "api/contratos/extra/empresa/ingresar-firma" + }, + { + "method": "GET", + "path": "api/contratos/extra/empresa/pdf" + }, + { + "method": "POST", + "path": "api/contratos/extra/empresa/ingresar-cerrado" + }, + { + "method": "POST", + "path": "api/contratos/extra/empresa/ingresar-cerrado-por-firmar" + }, + { + "method": "POST", + "path": "api/contratos/extra/empresa/ingresar-anexo-cerrado" + }, + { + "method": "PUT", + "path": "api/contratos/extra/empresa/estado" + }, + { + "method": "PUT", + "path": "api/contratos/extra/empresa/firma" + }, + { + "method": "PUT", + "path": "api/contratos/extra/empresa/detalle-curso-alumno" + } + ] + }, + { + "controller": "Contratos", + "base": "api/Contratos", + "count": 1, + "endpoints": [ + { + "method": "GET", + "path": "api/Contratos/{id}" + } + ] + }, + { + "controller": "CotizacionExtra", + "base": "api/CotizacionExtra", + "count": 26, + "endpoints": [ + { + "method": "POST", + "path": "api/CotizacionExtra/empresa" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/empresa/detalle" + }, + { + "method": "PUT", + "path": "api/CotizacionExtra/tipo-cotizacion" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/tipo-cotizacion" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/pdf" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/cerrada" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/cerrada/detalle" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/direccion" + }, + { + "method": "PUT", + "path": "api/CotizacionExtra/propuesta" + }, + { + "method": "PUT", + "path": "api/CotizacionExtra/descuento" + }, + { + "method": "PATCH", + "path": "api/CotizacionExtra" + }, + { + "method": "PUT", + "path": "api/CotizacionExtra/estado" + }, + { + "method": "PUT", + "path": "api/CotizacionExtra/detalle" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/anexo-sin-curso" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/sin-curso" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/sin-curso-pagadas" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/lead" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/search" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/pdf-detalle" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/pdf-lead" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/detalle-pdf" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/detalle-pdf-sin-curso" + }, + { + "method": "GET", + "path": "api/CotizacionExtra/detalle" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/pago-temporal" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/pago-temporal/grabar" + }, + { + "method": "POST", + "path": "api/CotizacionExtra/pago-final/grabar" + } + ] + }, + { + "controller": "Cotizaciones", + "base": "api/Cotizaciones", + "count": 2, + "endpoints": [ + { + "method": "POST", + "path": "api/Cotizaciones/{id}/pay" + }, + { + "method": "POST", + "path": "api/Cotizaciones/{id}/deactivate" + } + ] + }, + { + "controller": "Cursos", + "base": "api/cursos", + "count": 44, + "endpoints": [ + { + "method": "GET", + "path": "api/cursos/search" + }, + { + "method": "GET", + "path": "api/cursos/opened" + }, + { + "method": "GET", + "path": "api/cursos/by-program" + }, + { + "method": "GET", + "path": "api/cursos/by-teacher" + }, + { + "method": "POST", + "path": "api/cursos/open" + }, + { + "method": "GET", + "path": "api/cursos/sessions" + }, + { + "method": "GET", + "path": "api/cursos/sessions/active" + }, + { + "method": "GET", + "path": "api/cursos/sessions/portal" + }, + { + "method": "PUT", + "path": "api/cursos/sessions/suspend" + }, + { + "method": "GET", + "path": "api/cursos/students" + }, + { + "method": "GET", + "path": "api/cursos/grades" + }, + { + "method": "POST", + "path": "api/cursos/grades" + }, + { + "method": "GET", + "path": "api/cursos/weightings" + }, + { + "method": "POST", + "path": "api/cursos/weightings" + }, + { + "method": "POST", + "path": "api/cursos/attendance" + }, + { + "method": "GET", + "path": "api/cursos/content" + }, + { + "method": "GET", + "path": "api/cursos/log" + }, + { + "method": "POST", + "path": "api/cursos/log" + }, + { + "method": "GET", + "path": "api/cursos/rollbook" + }, + { + "method": "GET", + "path": "api/cursos/closure" + }, + { + "method": "PUT", + "path": "api/cursos/status" + }, + { + "method": "PUT", + "path": "api/cursos/room" + }, + { + "method": "PUT", + "path": "api/cursos/end-date" + }, + { + "method": "GET", + "path": "api/cursos/bbb-room" + }, + { + "method": "POST", + "path": "api/cursos/bbb-room" + }, + { + "method": "GET", + "path": "api/cursos/evaluations" + }, + { + "method": "GET", + "path": "api/cursos/report/nps" + }, + { + "method": "GET", + "path": "api/cursos/report/nps-detail" + }, + { + "method": "GET", + "path": "api/cursos/report/nps-students" + }, + { + "method": "GET", + "path": "api/cursos/report/opref" + }, + { + "method": "GET", + "path": "api/cursos/report/opref-detail" + }, + { + "method": "GET", + "path": "api/cursos/schedules/diurno" + }, + { + "method": "GET", + "path": "api/cursos/schedules/vespertino" + }, + { + "method": "GET", + "path": "api/cursos/schedules/sabatino" + }, + { + "method": "GET", + "path": "api/cursos/substitute-teacher" + }, + { + "method": "GET", + "path": "api/cursos/replacement-sessions" + }, + { + "method": "GET", + "path": "api/cursos/available-rooms" + }, + { + "method": "GET", + "path": "api/cursos/tarifas" + }, + { + "method": "GET", + "path": "api/cursos/promotions" + }, + { + "method": "GET", + "path": "api/cursos/report/period-detail" + }, + { + "method": "GET", + "path": "api/cursos/report/annual" + }, + { + "method": "POST", + "path": "api/cursos/teachers/assign" + }, + { + "method": "POST", + "path": "api/cursos/teachers/replace" + }, + { + "method": "DELETE", + "path": "api/cursos/teachers/titular" + } + ] + }, + { + "controller": "DescuentoExtra", + "base": "api/DescuentoExtra", + "count": 9, + "endpoints": [ + { + "method": "GET", + "path": "api/DescuentoExtra/promo-empresa" + }, + { + "method": "GET", + "path": "api/DescuentoExtra/promo-empresa-v3" + }, + { + "method": "GET", + "path": "api/DescuentoExtra/empresa" + }, + { + "method": "POST", + "path": "api/DescuentoExtra/empresa" + }, + { + "method": "POST", + "path": "api/DescuentoExtra/cotizacion" + }, + { + "method": "GET", + "path": "api/DescuentoExtra/summer" + }, + { + "method": "GET", + "path": "api/DescuentoExtra/lider" + }, + { + "method": "GET", + "path": "api/DescuentoExtra/promocion-consumida/{descuentoId}" + }, + { + "method": "POST", + "path": "api/DescuentoExtra/log-autorizador" + } + ] + }, + { + "controller": "Descuentos", + "base": "api/Descuentos", + "count": 0, + "endpoints": [] + }, + { + "controller": "Diagnosticos", + "base": "api/Diagnosticos", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/Diagnosticos/{id}" + }, + { + "method": "GET", + "path": "api/Diagnosticos/questions/{nivel}" + }, + { + "method": "GET", + "path": "api/Diagnosticos/{id}/result" + } + ] + }, + { + "controller": "Documentos", + "base": "api/Documentos", + "count": 4, + "endpoints": [ + { + "method": "POST", + "path": "api/Documentos/orden-compra/cerrado" + }, + { + "method": "POST", + "path": "api/Documentos/orden-compra/abierto" + }, + { + "method": "POST", + "path": "api/Documentos/sence/abierto" + }, + { + "method": "POST", + "path": "api/Documentos/sence/cerrado" + } + ] + }, + { + "controller": "Dte", + "base": "api/Dte", + "count": 4, + "endpoints": [ + { + "method": "POST", + "path": "api/Dte/emitir" + }, + { + "method": "GET", + "path": "api/Dte/{tipo}/{folio}/pdf" + }, + { + "method": "GET", + "path": "api/Dte/{tipo}/{folio}/estado" + }, + { + "method": "PUT", + "path": "api/Dte/{tipo}/{folio}/anular" + } + ] + }, + { + "controller": "Ejecutivos", + "base": "api/Ejecutivos", + "count": 1, + "endpoints": [ + { + "method": "GET", + "path": "api/Ejecutivos/{usuario}" + } + ] + }, + { + "controller": "Email", + "base": "api/Email", + "count": 8, + "endpoints": [ + { + "method": "POST", + "path": "api/Email/send" + }, + { + "method": "GET", + "path": "api/Email/templates" + }, + { + "method": "POST", + "path": "api/Email/templates" + }, + { + "method": "PUT", + "path": "api/Email/templates/{key}" + }, + { + "method": "GET", + "path": "api/Email/modules" + }, + { + "method": "POST", + "path": "api/Email/modules" + }, + { + "method": "DELETE", + "path": "api/Email/modules/{module}" + }, + { + "method": "GET", + "path": "api/Email/log" + } + ] + }, + { + "controller": "EmpresaExtra", + "base": "api/empresas/extra", + "count": 4, + "endpoints": [ + { + "method": "GET", + "path": "api/empresas/extra/tipos" + }, + { + "method": "POST", + "path": "api/empresas/extra/ingresar-v2" + }, + { + "method": "POST", + "path": "api/empresas/extra/ingresar-v1" + }, + { + "method": "POST", + "path": "api/empresas/extra/ingresar-v4" + } + ] + }, + { + "controller": "Empresas", + "base": "api/Empresas", + "count": 2, + "endpoints": [ + { + "method": "GET", + "path": "api/Empresas/{rut}/proposals" + }, + { + "method": "GET", + "path": "api/Empresas/proposals/{id}" + } + ] + }, + { + "controller": "Feriados", + "base": "api/feriados", + "count": 1, + "endpoints": [ + { + "method": "DELETE", + "path": "api/feriados/{id}" + } + ] + }, + { + "controller": "Helpdesk", + "base": "api/Helpdesk", + "count": 34, + "endpoints": [ + { + "method": "POST", + "path": "api/Helpdesk/login" + }, + { + "method": "GET", + "path": "api/Helpdesk/me" + }, + { + "method": "GET", + "path": "api/Helpdesk/groups" + }, + { + "method": "POST", + "path": "api/Helpdesk/groups" + }, + { + "method": "PUT", + "path": "api/Helpdesk/groups/{id:int}" + }, + { + "method": "DELETE", + "path": "api/Helpdesk/groups/{id:int}" + }, + { + "method": "GET", + "path": "api/Helpdesk/users" + }, + { + "method": "POST", + "path": "api/Helpdesk/users" + }, + { + "method": "PUT", + "path": "api/Helpdesk/users/{id}" + }, + { + "method": "GET", + "path": "api/Helpdesk/sla" + }, + { + "method": "POST", + "path": "api/Helpdesk/sla" + }, + { + "method": "PUT", + "path": "api/Helpdesk/sla/{id:int}" + }, + { + "method": "GET", + "path": "api/Helpdesk/tickets" + }, + { + "method": "GET", + "path": "api/Helpdesk/ticket/{id:int}" + }, + { + "method": "POST", + "path": "api/Helpdesk/tickets" + }, + { + "method": "PUT", + "path": "api/Helpdesk/ticket/{id:int}" + }, + { + "method": "DELETE", + "path": "api/Helpdesk/ticket/{id:int}" + }, + { + "method": "PUT", + "path": "api/Helpdesk/ticket/{id:int}/status" + }, + { + "method": "PUT", + "path": "api/Helpdesk/ticket/{id:int}/assign" + }, + { + "method": "GET", + "path": "api/Helpdesk/comments/{ticketId:int}" + }, + { + "method": "POST", + "path": "api/Helpdesk/comments/{ticketId:int}" + }, + { + "method": "GET", + "path": "api/Helpdesk/kb/published" + }, + { + "method": "GET", + "path": "api/Helpdesk/kb/search" + }, + { + "method": "GET", + "path": "api/Helpdesk/kb/categories" + }, + { + "method": "POST", + "path": "api/Helpdesk/kb/categories" + }, + { + "method": "POST", + "path": "api/Helpdesk/kb/articles" + }, + { + "method": "PUT", + "path": "api/Helpdesk/kb/articles/{id:int}" + }, + { + "method": "GET", + "path": "api/Helpdesk/email/templates" + }, + { + "method": "PUT", + "path": "api/Helpdesk/email/templates/{key}" + }, + { + "method": "GET", + "path": "api/Helpdesk/email/log" + }, + { + "method": "POST", + "path": "api/Helpdesk/email/inbound/sync" + }, + { + "method": "POST", + "path": "api/Helpdesk/email/test" + }, + { + "method": "POST", + "path": "api/Helpdesk/email/send" + }, + { + "method": "GET", + "path": "api/Helpdesk/stats" + } + ] + }, + { + "controller": "Horarios", + "base": "api/horarios", + "count": 6, + "endpoints": [ + { + "method": "GET", + "path": "api/horarios/days" + }, + { + "method": "GET", + "path": "api/horarios/hours" + }, + { + "method": "GET", + "path": "api/horarios/frequencies" + }, + { + "method": "GET", + "path": "api/horarios/day-combinations" + }, + { + "method": "GET", + "path": "api/horarios/blocks" + }, + { + "method": "GET", + "path": "api/horarios/jornadas" + } + ] + }, + { + "controller": "Informes", + "base": "api/Informes", + "count": 8, + "endpoints": [ + { + "method": "GET", + "path": "api/Informes/ventas-ejecutivo" + }, + { + "method": "GET", + "path": "api/Informes/ventas-mes" + }, + { + "method": "GET", + "path": "api/Informes/ventas-cursos-empresa" + }, + { + "method": "GET", + "path": "api/Informes/leads-diarios" + }, + { + "method": "GET", + "path": "api/Informes/documentos" + }, + { + "method": "GET", + "path": "api/Informes/cursos-empresa" + }, + { + "method": "GET", + "path": "api/Informes/general" + }, + { + "method": "GET", + "path": "api/Informes/propuesta-report" + } + ] + }, + { + "controller": "Jornadas", + "base": "api/jornadas", + "count": 1, + "endpoints": [ + { + "method": "GET", + "path": "api/jornadas/buscar" + } + ] + }, + { + "controller": "LeadExtra", + "base": "api/leads/extra", + "count": 51, + "endpoints": [ + { + "method": "POST", + "path": "api/leads/extra/ingresar-v2" + }, + { + "method": "PUT", + "path": "api/leads/extra/producto" + }, + { + "method": "PUT", + "path": "api/leads/extra/estado" + }, + { + "method": "POST", + "path": "api/leads/extra/perdido" + }, + { + "method": "PUT", + "path": "api/leads/extra/contacto" + }, + { + "method": "PUT", + "path": "api/leads/extra/contacto-v2" + }, + { + "method": "POST", + "path": "api/leads/extra/alumno" + }, + { + "method": "POST", + "path": "api/leads/extra/recordatorio" + }, + { + "method": "POST", + "path": "api/leads/extra/cliente" + }, + { + "method": "PUT", + "path": "api/leads/extra/reasignar-diagnostico" + }, + { + "method": "DELETE", + "path": "api/leads/extra/alumno" + }, + { + "method": "POST", + "path": "api/leads/extra/pago" + }, + { + "method": "GET", + "path": "api/leads/extra/pagos" + }, + { + "method": "GET", + "path": "api/leads/extra/nuevos" + }, + { + "method": "GET", + "path": "api/leads/extra/gestion" + }, + { + "method": "GET", + "path": "api/leads/extra/montos" + }, + { + "method": "GET", + "path": "api/leads/extra/contacto" + }, + { + "method": "GET", + "path": "api/leads/extra/buscar-mail" + }, + { + "method": "GET", + "path": "api/leads/extra/buscar-titulo" + }, + { + "method": "GET", + "path": "api/leads/extra/ejecutivo" + }, + { + "method": "GET", + "path": "api/leads/extra/alumno" + }, + { + "method": "GET", + "path": "api/leads/extra/actividad-planificada" + }, + { + "method": "GET", + "path": "api/leads/extra/por-estado" + }, + { + "method": "GET", + "path": "api/leads/extra/por-estado-semana" + }, + { + "method": "GET", + "path": "api/leads/extra/por-estado-todo" + }, + { + "method": "GET", + "path": "api/leads/extra/buscar-filtro" + }, + { + "method": "GET", + "path": "api/leads/extra/buscar-por-programa-diagnostico" + }, + { + "method": "GET", + "path": "api/leads/extra/buscar-por-curso-diagnostico" + }, + { + "method": "GET", + "path": "api/leads/extra/por-actividad" + }, + { + "method": "GET", + "path": "api/leads/extra/por-plan" + }, + { + "method": "GET", + "path": "api/leads/extra/por-ingresos" + }, + { + "method": "GET", + "path": "api/leads/extra/informe" + }, + { + "method": "GET", + "path": "api/leads/extra/informe-mes-actual" + }, + { + "method": "GET", + "path": "api/leads/extra/informe-ejecutivo" + }, + { + "method": "GET", + "path": "api/leads/extra/ganar" + }, + { + "method": "POST", + "path": "api/leads/extra/actividad" + }, + { + "method": "POST", + "path": "api/leads/extra/actividad-plan" + }, + { + "method": "PUT", + "path": "api/leads/extra/actividad-plan" + }, + { + "method": "GET", + "path": "api/leads/extra/motivos-perdido" + }, + { + "method": "GET", + "path": "api/leads/extra/programas" + }, + { + "method": "GET", + "path": "api/leads/extra/tipos-contacto" + }, + { + "method": "GET", + "path": "api/leads/extra/resumen-ejecutivo" + }, + { + "method": "GET", + "path": "api/leads/extra/empresa" + }, + { + "method": "POST", + "path": "api/leads/extra/empresa-actividad" + }, + { + "method": "POST", + "path": "api/leads/extra/empresa-actividad-v2" + }, + { + "method": "PUT", + "path": "api/leads/extra/empresa-estado" + }, + { + "method": "PUT", + "path": "api/leads/extra/empresa-valor" + }, + { + "method": "PUT", + "path": "api/leads/extra/empresa-cotizacion" + }, + { + "method": "PUT", + "path": "api/leads/extra/empresa-propuesta" + }, + { + "method": "POST", + "path": "api/leads/extra/empresa-crear" + }, + { + "method": "GET", + "path": "api/leads/extra/empresa-busqueda" + } + ] + }, + { + "controller": "Leads", + "base": "api/Leads", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/Leads/{id}" + }, + { + "method": "GET", + "path": "api/Leads/{id}/activities" + }, + { + "method": "GET", + "path": "api/Leads/executives" + } + ] + }, + { + "controller": "Libros", + "base": "api/Libros", + "count": 3, + "endpoints": [ + { + "method": "PUT", + "path": "api/Libros/{id}" + }, + { + "method": "POST", + "path": "api/Libros/cursos/{cursoId}" + }, + { + "method": "PUT", + "path": "api/Libros/cursos/{cursoId}" + } + ] + }, + { + "controller": "Notifications", + "base": "api/Notifications", + "count": 4, + "endpoints": [ + { + "method": "POST", + "path": "api/Notifications/send" + }, + { + "method": "GET", + "path": "api/Notifications/unread-count" + }, + { + "method": "PUT", + "path": "api/Notifications/{id:int}/read" + }, + { + "method": "PUT", + "path": "api/Notifications/read-all" + } + ] + }, + { + "controller": "Pagos", + "base": "api/Pagos", + "count": 6, + "endpoints": [ + { + "method": "POST", + "path": "api/Pagos/link" + }, + { + "method": "GET", + "path": "api/Pagos/voucher" + }, + { + "method": "POST", + "path": "api/Pagos/voucher" + }, + { + "method": "PUT", + "path": "api/Pagos/link/estado" + }, + { + "method": "GET", + "path": "api/Pagos/link/buscar" + }, + { + "method": "GET", + "path": "api/Pagos/link" + } + ] + }, + { + "controller": "Periodos", + "base": "api/Periodos", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/Periodos/modalidades" + }, + { + "method": "GET", + "path": "api/Periodos/{id}/modalidad-detalle" + }, + { + "method": "GET", + "path": "api/Periodos/{id}/calendario" + } + ] + }, + { + "controller": "PlacementTest", + "base": "api/placement-test", + "count": 18, + "endpoints": [ + { + "method": "POST", + "path": "api/placement-test/diagnostico" + }, + { + "method": "GET", + "path": "api/placement-test/diagnostico/{id}" + }, + { + "method": "PUT", + "path": "api/placement-test/diagnostico/{id}/estado" + }, + { + "method": "GET", + "path": "api/placement-test/diagnostico/preguntas/{nivel}" + }, + { + "method": "GET", + "path": "api/placement-test/diagnostico/respuestas" + }, + { + "method": "GET", + "path": "api/placement-test/diagnostico/{id}/resultado" + }, + { + "method": "GET", + "path": "api/placement-test/diagnostico/nivel/{cursoId}" + }, + { + "method": "POST", + "path": "api/placement-test/diagnostico/respuesta" + }, + { + "method": "POST", + "path": "api/placement-test/diagnostico/respuesta-empresa" + }, + { + "method": "GET", + "path": "api/placement-test/alumno/{rut}" + }, + { + "method": "POST", + "path": "api/placement-test/alumno" + }, + { + "method": "POST", + "path": "api/placement-test/alumno/empresa" + }, + { + "method": "GET", + "path": "api/placement-test/alumnos" + }, + { + "method": "GET", + "path": "api/placement-test/alumnos/empresa" + }, + { + "method": "PUT", + "path": "api/placement-test/lead/{id}/estado" + }, + { + "method": "POST", + "path": "api/placement-test/lead/actividad" + }, + { + "method": "POST", + "path": "api/placement-test/cotizacion" + }, + { + "method": "DELETE", + "path": "api/placement-test/cotizacion/{id}" + } + ] + }, + { + "controller": "PlanAnual", + "base": "api/plan-anual", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/plan-anual/activos" + }, + { + "method": "GET", + "path": "api/plan-anual/year/{year}" + }, + { + "method": "PUT", + "path": "api/plan-anual/{id}" + } + ] + }, + { + "controller": "PonderacionPortal", + "base": "api/ponderaciones-portal", + "count": 4, + "endpoints": [ + { + "method": "GET", + "path": "api/ponderaciones-portal/tipos-notas" + }, + { + "method": "GET", + "path": "api/ponderaciones-portal/curso" + }, + { + "method": "GET", + "path": "api/ponderaciones-portal/activas" + }, + { + "method": "GET", + "path": "api/ponderaciones-portal/activas-curso" + } + ] + }, + { + "controller": "Ponderaciones", + "base": "api/Ponderaciones", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/Ponderaciones/notas" + }, + { + "method": "PUT", + "path": "api/Ponderaciones/{id}" + }, + { + "method": "DELETE", + "path": "api/Ponderaciones/{id}" + } + ] + }, + { + "controller": "PortalPagos", + "base": "api/portal-pagos", + "count": 25, + "endpoints": [ + { + "method": "GET", + "path": "api/portal-pagos/cotizaciones" + }, + { + "method": "GET", + "path": "api/portal-pagos/cotizaciones/{id}/detalle" + }, + { + "method": "GET", + "path": "api/portal-pagos/cotizaciones/portal" + }, + { + "method": "GET", + "path": "api/portal-pagos/descuentos" + }, + { + "method": "POST", + "path": "api/portal-pagos/cotizaciones/{id}/pagar" + }, + { + "method": "POST", + "path": "api/portal-pagos/cotizaciones/{id}/pagar-temporal" + }, + { + "method": "POST", + "path": "api/portal-pagos/clientes" + }, + { + "method": "POST", + "path": "api/portal-pagos/ventas" + }, + { + "method": "POST", + "path": "api/portal-pagos/pagos/temporal" + }, + { + "method": "POST", + "path": "api/portal-pagos/pagos/finalizar" + }, + { + "method": "POST", + "path": "api/portal-pagos/contratos" + }, + { + "method": "POST", + "path": "api/portal-pagos/contratos/detalle" + }, + { + "method": "GET", + "path": "api/portal-pagos/contratos/{id}/info" + }, + { + "method": "GET", + "path": "api/portal-pagos/alumnos/{id}/bloqueo" + }, + { + "method": "GET", + "path": "api/portal-pagos/alumnos/{id}/antiguedad" + }, + { + "method": "GET", + "path": "api/portal-pagos/apoderados" + }, + { + "method": "GET", + "path": "api/portal-pagos/voucher/{cotizacionId}" + }, + { + "method": "GET", + "path": "api/portal-pagos/usuarios/reasignacion" + }, + { + "method": "GET", + "path": "api/portal-pagos/regiones" + }, + { + "method": "GET", + "path": "api/portal-pagos/comunas" + }, + { + "method": "GET", + "path": "api/portal-pagos/contratos/{id}/pdf" + }, + { + "method": "GET", + "path": "api/portal-pagos/contratos/{id}/pdf-detalle" + }, + { + "method": "GET", + "path": "api/portal-pagos/contratos/{id}/pdf-jornadas" + }, + { + "method": "GET", + "path": "api/portal-pagos/contratos/{id}/pdf-programas" + }, + { + "method": "GET", + "path": "api/portal-pagos/contratos/{id}/pdf-sedes" + } + ] + }, + { + "controller": "ProfesorExtra", + "base": "api/profesores/extra", + "count": 28, + "endpoints": [ + { + "method": "POST", + "path": "api/profesores/extra/reset-password" + }, + { + "method": "PUT", + "path": "api/profesores/extra/{rut}/email" + }, + { + "method": "GET", + "path": "api/profesores/extra/sesion-curso/{cursoId}" + }, + { + "method": "GET", + "path": "api/profesores/extra/sesion-curso-emp/{cursoId}" + }, + { + "method": "POST", + "path": "api/profesores/extra/asistencia" + }, + { + "method": "POST", + "path": "api/profesores/extra/asistencia-emp" + }, + { + "method": "POST", + "path": "api/profesores/extra/asistencia-reemplazo" + }, + { + "method": "POST", + "path": "api/profesores/extra/asistencia-reemplazo-emp" + }, + { + "method": "GET", + "path": "api/profesores/extra/sesiones-pago/{profesorId}" + }, + { + "method": "GET", + "path": "api/profesores/extra/sesiones-pago-emp" + }, + { + "method": "POST", + "path": "api/profesores/extra/contenido" + }, + { + "method": "POST", + "path": "api/profesores/extra/contenido-emp" + }, + { + "method": "GET", + "path": "api/profesores/extra/contenido" + }, + { + "method": "GET", + "path": "api/profesores/extra/contenido-emp" + }, + { + "method": "GET", + "path": "api/profesores/extra/ca-tests/{cursoId}" + }, + { + "method": "GET", + "path": "api/profesores/extra/ca-tests-emp/{cursoId}" + }, + { + "method": "GET", + "path": "api/profesores/extra/notas-ca/{cursoId}" + }, + { + "method": "GET", + "path": "api/profesores/extra/notas-ca-emp/{cursoId}" + }, + { + "method": "POST", + "path": "api/profesores/extra/notas-ca" + }, + { + "method": "POST", + "path": "api/profesores/extra/notas-ca-emp" + }, + { + "method": "POST", + "path": "api/profesores/extra/notas-generales" + }, + { + "method": "POST", + "path": "api/profesores/extra/notas-generales-emp" + }, + { + "method": "GET", + "path": "api/profesores/extra/asistencia-alumnos/{cursoId}" + }, + { + "method": "GET", + "path": "api/profesores/extra/asistencia-alumnos-emp/{cursoId}" + }, + { + "method": "POST", + "path": "api/profesores/extra/asistencia-alumno" + }, + { + "method": "POST", + "path": "api/profesores/extra/asistencia-alumno-emp" + }, + { + "method": "GET", + "path": "api/profesores/extra/ponderacion-aperturado/{cursoId}" + }, + { + "method": "GET", + "path": "api/profesores/extra/ponderacion-aperturado-emp/{cursoId}" + } + ] + }, + { + "controller": "Profesores", + "base": "api/profesores", + "count": 8, + "endpoints": [ + { + "method": "GET", + "path": "api/profesores/{rut}" + }, + { + "method": "PUT", + "path": "api/profesores/{rut}" + }, + { + "method": "PUT", + "path": "api/profesores/{rut}/status" + }, + { + "method": "GET", + "path": "api/profesores/{rut}/sessions" + }, + { + "method": "GET", + "path": "api/profesores/{rut}/history" + }, + { + "method": "GET", + "path": "api/profesores/{rut}/comments" + }, + { + "method": "POST", + "path": "api/profesores/{rut}/comments" + }, + { + "method": "PUT", + "path": "api/profesores/{rut}/password" + } + ] + }, + { + "controller": "Programas", + "base": "api/Programas", + "count": 1, + "endpoints": [ + { + "method": "GET", + "path": "api/Programas/student-types" + } + ] + }, + { + "controller": "PropuestasEmpresa", + "base": "api/propuestas-empresa", + "count": 3, + "endpoints": [ + { + "method": "PUT", + "path": "api/propuestas-empresa/{id}/descuento" + }, + { + "method": "PUT", + "path": "api/propuestas-empresa/{id}/estado" + }, + { + "method": "PUT", + "path": "api/propuestas-empresa/{id}/proceso" + } + ] + }, + { + "controller": "Sedes", + "base": "api/Sedes", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/Sedes/{id}/rooms" + }, + { + "method": "GET", + "path": "api/Sedes/rooms/search" + }, + { + "method": "GET", + "path": "api/Sedes/rooms/{id}/occupancy" + } + ] + }, + { + "controller": "Sence", + "base": "api/Sence", + "count": 2, + "endpoints": [ + { + "method": "PUT", + "path": "api/Sence/{codigo}" + }, + { + "method": "PUT", + "path": "api/Sence/cursos/{cursoId}/asignar" + } + ] + }, + { + "controller": "Tarifas", + "base": "api/Tarifas", + "count": 6, + "endpoints": [ + { + "method": "GET", + "path": "api/Tarifas/sin-filtro" + }, + { + "method": "GET", + "path": "api/Tarifas/promocion" + }, + { + "method": "GET", + "path": "api/Tarifas/promocion-tipo" + }, + { + "method": "GET", + "path": "api/Tarifas/promocion-empresa-v3" + }, + { + "method": "GET", + "path": "api/Tarifas/promocion-empresa" + }, + { + "method": "GET", + "path": "api/Tarifas/sin-filtro-empresa" + } + ] + }, + { + "controller": "Ubicacion", + "base": "api/Ubicacion", + "count": 3, + "endpoints": [ + { + "method": "GET", + "path": "api/Ubicacion/regiones" + }, + { + "method": "GET", + "path": "api/Ubicacion/regiones/{regionId}/comunas" + }, + { + "method": "GET", + "path": "api/Ubicacion/nacionalidades" + } + ] + }, + { + "controller": "Ventas", + "base": "api/Ventas", + "count": 2, + "endpoints": [ + { + "method": "POST", + "path": "api/Ventas/correlativo-prefactura" + }, + { + "method": "PATCH", + "path": "api/Ventas/contrato/{id}" + } + ] + }, + { + "controller": "WebPay", + "base": "api/WebPay", + "count": 4, + "endpoints": [ + { + "method": "POST", + "path": "api/WebPay/create" + }, + { + "method": "POST", + "path": "api/WebPay/commit" + }, + { + "method": "GET", + "path": "api/WebPay/status/{token}" + }, + { + "method": "POST", + "path": "api/WebPay/{token}/refund" + } + ] + } +]; diff --git a/src/lib/sam.ts b/src/lib/sam.ts index 751c396..cc0531c 100644 --- a/src/lib/sam.ts +++ b/src/lib/sam.ts @@ -50,13 +50,6 @@ export interface ApiResponse { modules: ModuleState[]; } -export interface ApiFunction { - label: string; - icon: string; - path: string; - desc: string; -} - export interface MenuItem { label: string; icon: string; @@ -204,88 +197,35 @@ export function onModuleColor(hex: string): string { return lum > 0.62 ? "#212529" : "#ffffff"; } -const A = ( - label: string, - icon: string, - path: string, - desc: string -): ApiFunction => ({ label, icon, path, desc }); +// ============================================================ +// Uso real por módulo (sin funciones inventadas). +// El bloque anterior "Funciones disponibles de la API" (CORE / +// FUNCTION_SETS) se eliminó: listaba rutas que no corresponden +// a la API real. Ahora: +// - El dashboard principal muestra el uso de la API con el +// inventario real (src/lib/api-inventory.ts, generado desde +// backend/SAM.API/Controllers). +// - /m/helpdesk muestra equipo (GET /api/helpdesk/users) + +// estadísticas de uso (GET /api/helpdesk/stats). +// - /m/webpay y /m/pagos muestran pagos validados +// (GET /api/Boletas/payments?mes&year). +// ============================================================ -// --- Conjuntos de funciones por familia de módulo --- -const CORE: ApiFunction[] = [ - A("Alumnos", "bx-group", "api/alumnos", "Ficha, matrícula y sesiones de alumnos"), - A("Cursos", "bx-book", "api/cursos", "Catálogo, apertura y horarios de cursos"), - A("Profesores", "bx-pencil", "api/profesores", "Ficha y periodos de profesores"), - A("Empresas", "bx-buildings", "api/empresas/extra", "Empresas en convenio y propuestas"), - A("Pagos", "bx-money", "api/pagos", "Caja, cotizaciones y vouchers"), - A("Contratos", "bx-file", "api/contratos", "Contratos firmados y por firmar"), - A("Informes", "bx-bar-chart-alt-2", "api/informes", "Reportes académicos y de gestión"), -]; +export type ModuleUsageKind = "helpdesk" | "pagos" | "generic"; -const FUNCTION_SETS: Record = { - academico: [ - A("Cursos", "bx-book", "api/cursos", "Catálogo, apertura y horarios"), - A("Alumnos", "bx-group", "api/alumnos/extra", "Ficha, matrícula y sesiones"), - A("Apoderados", "bx-user", "api/apoderados", "Apoderados y contactos"), - A("Horarios", "bx-time", "api/horarios", "Bloques horarios y salas"), - A("Jornadas", "bx-sun", "api/jornadas", "Jornadas diurno / vespertino"), - A("Feriados", "bx-calendar", "api/feriados", "Calendario de feriados"), - A("Placement Test", "bx-edit", "api/placement-test", "Pruebas de nivel"), - A("Plan Anual", "bx-calendar-alt", "api/plan-anual", "Planificación anual"), - ], - profesores: [ - A("Profesores", "bx-pencil", "api/profesores", "Ficha y periodos"), - A("Funciones Extra", "bx-plus-circle", "api/profesores/extra", "Operaciones extendidas"), - A("Horarios", "bx-time", "api/horarios", "Bloques horarios y salas"), - A("Jornadas", "bx-sun", "api/jornadas", "Jornadas diurno / vespertino"), - ], - empresas: [ - A("Propuestas", "bx-briefcase", "api/propuestas-empresa", "Propuestas a empresas"), - A("Empresas", "bx-buildings", "api/empresas/extra", "Empresas en convenio"), - A("Comercial", "bx-trending-up", "api/comercial/extra", "Gestión comercial"), - A("Contratos", "bx-file", "api/contratos/extra", "Contratos con empresas"), - ], - ventas: [ - A("Comercial", "bx-trending-up", "api/comercial/extra", "Gestión comercial"), - A("Leads", "bx-target-lock", "api/leads/extra", "Prospectos y seguimiento"), - A("Ventas", "bx-cart", "api/ventas", "Ventas y cotizaciones"), - A("Cotizaciones", "bx-receipt", "api/cotizaciones", "Cotizaciones emitidas"), - A("Ejecutivos", "bx-user-voice", "api/ejecutivos", "Ejecutivos de venta"), - ], - pagos: [ - A("Portal Pagos", "bx-credit-card", "api/portal-pagos", "Pagos en línea"), - A("Pagos", "bx-money", "api/pagos", "Caja y vouchers"), - A("WebPay", "bx-card", "api/webpay", "Transacciones Transbank"), - A("Boletas", "bx-receipt", "api/boletas", "Boletas y facturación"), - A("Arqueo", "bx-calculator", "api/arqueocaja", "Arqueo de caja"), - ], - contabilidad: [ - A("Contabilidad", "bx-detail", "api/contabilidad", "Movimientos contables"), - A("Libros", "bx-book-open", "api/libros", "Libros de compra / venta"), - A("DTE", "bx-file-blank", "api/dte", "Documentos tributarios"), - A("Documentos", "bx-folder", "api/documentos", "Repositorio documental"), - ], -}; +export function moduleUsageKind(name: string): ModuleUsageKind { + const key = (name || "").toLowerCase(); + if (key === "helpdesk" || key.includes("helpdesk")) return "helpdesk"; + if (key === "webpay" || key === "pagos" || key.includes("pago")) return "pagos"; + return "generic"; +} -const MODULE_FAMILY: Record = { - academico: "academico", - "academico-empresas": "empresas", - portal: "empresas", - empresas: "empresas", - ventas: "ventas", - comercial: "ventas", - pagos: "pagos", - contabilidad: "contabilidad", - profesores: "profesores", -}; +export function isHelpdeskModule(name: string): boolean { + return moduleUsageKind(name) === "helpdesk"; +} -export function getModuleFunctions(name: string): ApiFunction[] { - const key = name.toLowerCase(); - const family = - MODULE_FAMILY[key] ?? - Object.keys(FUNCTION_SETS).find((f) => key.includes(f)); - if (family && FUNCTION_SETS[family]) return FUNCTION_SETS[family]; - return CORE; +export function isPagosModule(name: string): boolean { + return moduleUsageKind(name) === "pagos"; } // ============================================================