feat: Mejorar estructura de monitored_apps.json con metadata completa
- Añadir campos al modelo MonitoredApp: * service_name: Nombre del servicio systemd * path: WorkingDirectory de la aplicación * entry_point: Archivo de entrada (server.js, app.js, etc.) * node_bin: Ruta completa al binario de node/python * mode: Modo de ejecución (production, development, test) * service_file_path: Ruta al archivo .service de systemd * registered_at: Timestamp de registro (ISO 8601) - Actualizar discovery.rs para extraer toda la información: * Parsear ExecStart para obtener node_bin y entry_point * Extraer NODE_ENV para determinar el modo * Guardar ruta completa al archivo .service * Usar add_app_full() con información completa - Integrar ConfigManager en AppManager: * Guardar automáticamente en monitored_apps.json al registrar apps * Eliminar del JSON al desregistrar apps * Extraer metadata desde ServiceConfig (puerto, entry_point, mode, etc.) - Mantener retrocompatibilidad con JSON antiguo mediante campos deprecated - Todos los nuevos campos usan #[serde(default)] para evitar errores de deserialización
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
|
||||
<title>Documentación API - SIAX Monitor</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/icon/favicon.svg" />
|
||||
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
|
||||
<link
|
||||
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
|
||||
@@ -112,17 +113,47 @@
|
||||
|
||||
<div class="flex-1 flex max-w-[1400px] mx-auto w-full">
|
||||
<!-- Sidebar - Table of Contents -->
|
||||
<aside class="w-64 border-r border-[#283039] bg-[#161f2a] p-6 space-y-6 overflow-y-auto">
|
||||
<aside
|
||||
class="w-64 border-r border-[#283039] bg-[#161f2a] p-6 space-y-6 overflow-y-auto"
|
||||
>
|
||||
<div>
|
||||
<h3 class="text-white font-bold text-sm mb-3">CONTENIDO</h3>
|
||||
<nav class="space-y-2">
|
||||
<a href="#intro" class="block text-[#9dabb9] text-sm hover:text-primary transition-colors">Introducción</a>
|
||||
<a href="#auth" class="block text-[#9dabb9] text-sm hover:text-primary transition-colors">Autenticación</a>
|
||||
<a href="#apps" class="block text-[#9dabb9] text-sm hover:text-primary transition-colors">Gestión de Apps</a>
|
||||
<a href="#scan" class="block text-[#9dabb9] text-sm hover:text-primary transition-colors">Escaneo</a>
|
||||
<a href="#lifecycle" class="block text-[#9dabb9] text-sm hover:text-primary transition-colors">Ciclo de Vida</a>
|
||||
<a href="#websocket" class="block text-[#9dabb9] text-sm hover:text-primary transition-colors">WebSocket</a>
|
||||
<a href="#errors" class="block text-[#9dabb9] text-sm hover:text-primary transition-colors">Códigos de Error</a>
|
||||
<a
|
||||
href="#intro"
|
||||
class="block text-[#9dabb9] text-sm hover:text-primary transition-colors"
|
||||
>Introducción</a
|
||||
>
|
||||
<a
|
||||
href="#auth"
|
||||
class="block text-[#9dabb9] text-sm hover:text-primary transition-colors"
|
||||
>Autenticación</a
|
||||
>
|
||||
<a
|
||||
href="#apps"
|
||||
class="block text-[#9dabb9] text-sm hover:text-primary transition-colors"
|
||||
>Gestión de Apps</a
|
||||
>
|
||||
<a
|
||||
href="#scan"
|
||||
class="block text-[#9dabb9] text-sm hover:text-primary transition-colors"
|
||||
>Escaneo</a
|
||||
>
|
||||
<a
|
||||
href="#lifecycle"
|
||||
class="block text-[#9dabb9] text-sm hover:text-primary transition-colors"
|
||||
>Ciclo de Vida</a
|
||||
>
|
||||
<a
|
||||
href="#websocket"
|
||||
class="block text-[#9dabb9] text-sm hover:text-primary transition-colors"
|
||||
>WebSocket</a
|
||||
>
|
||||
<a
|
||||
href="#errors"
|
||||
class="block text-[#9dabb9] text-sm hover:text-primary transition-colors"
|
||||
>Códigos de Error</a
|
||||
>
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
@@ -135,7 +166,9 @@
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[#9dabb9]">Base URL:</span>
|
||||
<span class="text-white font-mono">localhost:8080</span>
|
||||
<span class="text-white font-mono"
|
||||
>localhost:8080</span
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<span class="text-[#9dabb9]">Protocolo:</span>
|
||||
@@ -149,35 +182,70 @@
|
||||
<main class="flex-1 p-8 overflow-y-auto">
|
||||
<!-- Introduction -->
|
||||
<section id="intro" class="mb-12">
|
||||
<h1 class="text-white text-4xl font-black mb-4">Documentación API REST</h1>
|
||||
<h1 class="text-white text-4xl font-black mb-4">
|
||||
Documentación API REST
|
||||
</h1>
|
||||
<p class="text-[#9dabb9] text-lg mb-6">
|
||||
API para gestión y monitoreo de aplicaciones Node.js y Python con systemd.
|
||||
API para gestión y monitoreo de aplicaciones Node.js y
|
||||
Python con systemd.
|
||||
</p>
|
||||
|
||||
<div class="rounded-xl border border-primary/30 bg-primary/10 p-4 mb-6">
|
||||
|
||||
<div
|
||||
class="rounded-xl border border-primary/30 bg-primary/10 p-4 mb-6"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<span class="material-symbols-outlined text-primary mt-0.5">info</span>
|
||||
<span
|
||||
class="material-symbols-outlined text-primary mt-0.5"
|
||||
>info</span
|
||||
>
|
||||
<div>
|
||||
<p class="text-white font-semibold mb-1">Endpoint Base</p>
|
||||
<code class="text-primary font-mono text-sm">http://localhost:8080/api</code>
|
||||
<p class="text-white font-semibold mb-1">
|
||||
Endpoint Base
|
||||
</p>
|
||||
<code class="text-primary font-mono text-sm"
|
||||
>/api</code
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div class="rounded-xl border border-[#283039] bg-[#161f2a] p-4">
|
||||
<span class="material-symbols-outlined text-green-400 mb-2">check_circle</span>
|
||||
<p class="text-white font-semibold text-sm">REST API</p>
|
||||
<div
|
||||
class="rounded-xl border border-[#283039] bg-[#161f2a] p-4"
|
||||
>
|
||||
<span
|
||||
class="material-symbols-outlined text-green-400 mb-2"
|
||||
>check_circle</span
|
||||
>
|
||||
<p class="text-white font-semibold text-sm">
|
||||
REST API
|
||||
</p>
|
||||
<p class="text-[#9dabb9] text-xs">JSON responses</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-[#283039] bg-[#161f2a] p-4">
|
||||
<span class="material-symbols-outlined text-blue-400 mb-2">bolt</span>
|
||||
<p class="text-white font-semibold text-sm">WebSocket</p>
|
||||
<p class="text-[#9dabb9] text-xs">Logs en tiempo real</p>
|
||||
<div
|
||||
class="rounded-xl border border-[#283039] bg-[#161f2a] p-4"
|
||||
>
|
||||
<span
|
||||
class="material-symbols-outlined text-blue-400 mb-2"
|
||||
>bolt</span
|
||||
>
|
||||
<p class="text-white font-semibold text-sm">
|
||||
WebSocket
|
||||
</p>
|
||||
<p class="text-[#9dabb9] text-xs">
|
||||
Logs en tiempo real
|
||||
</p>
|
||||
</div>
|
||||
<div class="rounded-xl border border-[#283039] bg-[#161f2a] p-4">
|
||||
<span class="material-symbols-outlined text-purple-400 mb-2">schedule</span>
|
||||
<p class="text-white font-semibold text-sm">Rate Limiting</p>
|
||||
<div
|
||||
class="rounded-xl border border-[#283039] bg-[#161f2a] p-4"
|
||||
>
|
||||
<span
|
||||
class="material-symbols-outlined text-purple-400 mb-2"
|
||||
>schedule</span
|
||||
>
|
||||
<p class="text-white font-semibold text-sm">
|
||||
Rate Limiting
|
||||
</p>
|
||||
<p class="text-[#9dabb9] text-xs">1 op/segundo</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -185,19 +253,34 @@
|
||||
|
||||
<!-- Authentication -->
|
||||
<section id="auth" class="mb-12">
|
||||
<h2 class="text-white text-2xl font-bold mb-4 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">lock</span>
|
||||
<h2
|
||||
class="text-white text-2xl font-bold mb-4 flex items-center gap-2"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary"
|
||||
>lock</span
|
||||
>
|
||||
Autenticación
|
||||
</h2>
|
||||
<p class="text-[#9dabb9] mb-4">
|
||||
Actualmente la API no requiere autenticación ya que está diseñada para acceso local vía VPN.
|
||||
Actualmente la API no requiere autenticación ya que está
|
||||
diseñada para acceso local vía VPN.
|
||||
</p>
|
||||
<div class="rounded-xl border border-yellow-500/30 bg-yellow-500/10 p-4">
|
||||
<div
|
||||
class="rounded-xl border border-yellow-500/30 bg-yellow-500/10 p-4"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<span class="material-symbols-outlined text-yellow-400">warning</span>
|
||||
<span
|
||||
class="material-symbols-outlined text-yellow-400"
|
||||
>warning</span
|
||||
>
|
||||
<div>
|
||||
<p class="text-yellow-400 font-semibold">Nota de Seguridad</p>
|
||||
<p class="text-[#9dabb9] text-sm">Esta API debe ser accesible solo desde redes privadas o VPN.</p>
|
||||
<p class="text-yellow-400 font-semibold">
|
||||
Nota de Seguridad
|
||||
</p>
|
||||
<p class="text-[#9dabb9] text-sm">
|
||||
Esta API debe ser accesible solo desde redes
|
||||
privadas o VPN.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -205,52 +288,98 @@
|
||||
|
||||
<!-- Apps Management -->
|
||||
<section id="apps" class="mb-12">
|
||||
<h2 class="text-white text-2xl font-bold mb-6 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">apps</span>
|
||||
<h2
|
||||
class="text-white text-2xl font-bold mb-6 flex items-center gap-2"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary"
|
||||
>apps</span
|
||||
>
|
||||
Gestión de Aplicaciones
|
||||
</h2>
|
||||
|
||||
<!-- List Apps -->
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-green-500/20 text-green-400 text-xs font-bold font-mono">GET</span>
|
||||
<code class="text-white font-mono text-sm">/api/apps</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-green-500/20 text-green-400 text-xs font-bold font-mono"
|
||||
>GET</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/apps</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Listar todas las aplicaciones registradas</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Listar todas las aplicaciones registradas
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-6 space-y-4">
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Respuesta exitosa (200)</p>
|
||||
<pre class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto">{
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Respuesta exitosa (200)
|
||||
</p>
|
||||
<pre
|
||||
class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto"
|
||||
>
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"apps": ["app_tareas", "fidelizacion"],
|
||||
"total": 2
|
||||
},
|
||||
"error": null
|
||||
}</pre>
|
||||
}</pre
|
||||
>
|
||||
</div>
|
||||
<button onclick="tryEndpoint('GET', '/api/apps')" class="flex items-center gap-2 px-4 py-2 bg-primary hover:brightness-110 rounded-lg text-white text-sm font-medium transition-all">
|
||||
<span class="material-symbols-outlined text-sm">play_arrow</span>
|
||||
<button
|
||||
onclick="tryEndpoint('GET', '/api/apps')"
|
||||
class="flex items-center gap-2 px-4 py-2 bg-primary hover:brightness-110 rounded-lg text-white text-sm font-medium transition-all"
|
||||
>
|
||||
<span class="material-symbols-outlined text-sm"
|
||||
>play_arrow</span
|
||||
>
|
||||
Probar endpoint
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Register App -->
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono">POST</span>
|
||||
<code class="text-white font-mono text-sm">/api/apps</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono"
|
||||
>POST</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/apps</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Registrar una nueva aplicación</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Registrar una nueva aplicación
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-6 space-y-4">
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Body (JSON)</p>
|
||||
<pre class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-blue-400 overflow-x-auto">{
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Body (JSON)
|
||||
</p>
|
||||
<pre
|
||||
class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-blue-400 overflow-x-auto"
|
||||
>
|
||||
{
|
||||
"app_name": "mi-app",
|
||||
"script_path": "/opt/apps/mi-app/index.js",
|
||||
"working_directory": "/opt/apps/mi-app",
|
||||
@@ -262,11 +391,19 @@
|
||||
"restart_policy": "always",
|
||||
"app_type": "nodejs",
|
||||
"description": "Mi aplicación Node.js"
|
||||
}</pre>
|
||||
}</pre
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Respuesta exitosa (200)</p>
|
||||
<pre class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto">{
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Respuesta exitosa (200)
|
||||
</p>
|
||||
<pre
|
||||
class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto"
|
||||
>
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"app_name": "mi-app",
|
||||
@@ -275,27 +412,48 @@
|
||||
"message": "Aplicación registrada exitosamente"
|
||||
},
|
||||
"error": null
|
||||
}</pre>
|
||||
}</pre
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Delete App -->
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono">DELETE</span>
|
||||
<code class="text-white font-mono text-sm">/api/apps/:name</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono"
|
||||
>DELETE</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/apps/:name</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Eliminar una aplicación registrada</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Eliminar una aplicación registrada
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-6 space-y-4">
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Parámetros</p>
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Parámetros
|
||||
</p>
|
||||
<ul class="space-y-2">
|
||||
<li class="flex items-start gap-2">
|
||||
<code class="text-primary font-mono text-sm">name</code>
|
||||
<span class="text-[#9dabb9] text-sm">- Nombre de la aplicación</span>
|
||||
<code
|
||||
class="text-primary font-mono text-sm"
|
||||
>name</code
|
||||
>
|
||||
<span class="text-[#9dabb9] text-sm"
|
||||
>- Nombre de la aplicación</span
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -303,18 +461,36 @@
|
||||
</div>
|
||||
|
||||
<!-- Get Status -->
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-green-500/20 text-green-400 text-xs font-bold font-mono">GET</span>
|
||||
<code class="text-white font-mono text-sm">/api/apps/:name/status</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-green-500/20 text-green-400 text-xs font-bold font-mono"
|
||||
>GET</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/apps/:name/status</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Obtener estado de una aplicación</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Obtener estado de una aplicación
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-6 space-y-4">
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Respuesta exitosa (200)</p>
|
||||
<pre class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto">{
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Respuesta exitosa (200)
|
||||
</p>
|
||||
<pre
|
||||
class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto"
|
||||
>
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"name": "mi-app",
|
||||
@@ -325,7 +501,8 @@
|
||||
"systemd_status": "active",
|
||||
"last_updated": "2026-01-13T12:34:56"
|
||||
}
|
||||
}</pre>
|
||||
}</pre
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -333,23 +510,45 @@
|
||||
|
||||
<!-- Scan -->
|
||||
<section id="scan" class="mb-12">
|
||||
<h2 class="text-white text-2xl font-bold mb-6 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">search</span>
|
||||
<h2
|
||||
class="text-white text-2xl font-bold mb-6 flex items-center gap-2"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary"
|
||||
>search</span
|
||||
>
|
||||
Escaneo de Procesos
|
||||
</h2>
|
||||
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-green-500/20 text-green-400 text-xs font-bold font-mono">GET</span>
|
||||
<code class="text-white font-mono text-sm">/api/scan</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-green-500/20 text-green-400 text-xs font-bold font-mono"
|
||||
>GET</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/scan</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Escanear procesos Node.js y Python en ejecución</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Escanear procesos Node.js y Python en ejecución
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-6 space-y-4">
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Respuesta exitosa (200)</p>
|
||||
<pre class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto">{
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Respuesta exitosa (200)
|
||||
</p>
|
||||
<pre
|
||||
class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-green-400 overflow-x-auto"
|
||||
>
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"processes": [
|
||||
@@ -364,10 +563,16 @@
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
}</pre>
|
||||
}</pre
|
||||
>
|
||||
</div>
|
||||
<button onclick="tryEndpoint('GET', '/api/scan')" class="flex items-center gap-2 px-4 py-2 bg-primary hover:brightness-110 rounded-lg text-white text-sm font-medium transition-all">
|
||||
<span class="material-symbols-outlined text-sm">play_arrow</span>
|
||||
<button
|
||||
onclick="tryEndpoint('GET', '/api/scan')"
|
||||
class="flex items-center gap-2 px-4 py-2 bg-primary hover:brightness-110 rounded-lg text-white text-sm font-medium transition-all"
|
||||
>
|
||||
<span class="material-symbols-outlined text-sm"
|
||||
>play_arrow</span
|
||||
>
|
||||
Probar endpoint
|
||||
</button>
|
||||
</div>
|
||||
@@ -376,50 +581,97 @@
|
||||
|
||||
<!-- Lifecycle -->
|
||||
<section id="lifecycle" class="mb-12">
|
||||
<h2 class="text-white text-2xl font-bold mb-6 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">settings_power</span>
|
||||
<h2
|
||||
class="text-white text-2xl font-bold mb-6 flex items-center gap-2"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary"
|
||||
>settings_power</span
|
||||
>
|
||||
Ciclo de Vida
|
||||
</h2>
|
||||
|
||||
<!-- Start -->
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono">POST</span>
|
||||
<code class="text-white font-mono text-sm">/api/apps/:name/start</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono"
|
||||
>POST</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/apps/:name/start</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Iniciar una aplicación</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Iniciar una aplicación
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stop -->
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono">POST</span>
|
||||
<code class="text-white font-mono text-sm">/api/apps/:name/stop</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono"
|
||||
>POST</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/apps/:name/stop</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Detener una aplicación</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Detener una aplicación
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Restart -->
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono">POST</span>
|
||||
<code class="text-white font-mono text-sm">/api/apps/:name/restart</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-blue-500/20 text-blue-400 text-xs font-bold font-mono"
|
||||
>POST</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>/api/apps/:name/restart</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Reiniciar una aplicación</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Reiniciar una aplicación
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-yellow-500/30 bg-yellow-500/10 p-4">
|
||||
<div
|
||||
class="rounded-xl border border-yellow-500/30 bg-yellow-500/10 p-4"
|
||||
>
|
||||
<div class="flex items-start gap-3">
|
||||
<span class="material-symbols-outlined text-yellow-400">schedule</span>
|
||||
<span
|
||||
class="material-symbols-outlined text-yellow-400"
|
||||
>schedule</span
|
||||
>
|
||||
<div>
|
||||
<p class="text-yellow-400 font-semibold">Rate Limiting</p>
|
||||
<p class="text-[#9dabb9] text-sm">Las operaciones están limitadas a 1 por segundo por aplicación.</p>
|
||||
<p class="text-yellow-400 font-semibold">
|
||||
Rate Limiting
|
||||
</p>
|
||||
<p class="text-[#9dabb9] text-sm">
|
||||
Las operaciones están limitadas a 1 por
|
||||
segundo por aplicación.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -427,23 +679,45 @@
|
||||
|
||||
<!-- WebSocket -->
|
||||
<section id="websocket" class="mb-12">
|
||||
<h2 class="text-white text-2xl font-bold mb-6 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">cable</span>
|
||||
<h2
|
||||
class="text-white text-2xl font-bold mb-6 flex items-center gap-2"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary"
|
||||
>cable</span
|
||||
>
|
||||
WebSocket (Logs en tiempo real)
|
||||
</h2>
|
||||
|
||||
<div class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden">
|
||||
<div class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]">
|
||||
<div
|
||||
class="mb-8 rounded-xl border border-[#283039] bg-[#161f2a] overflow-hidden"
|
||||
>
|
||||
<div
|
||||
class="bg-[#1c2730] px-6 py-4 border-b border-[#283039]"
|
||||
>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="px-2 py-1 rounded bg-purple-500/20 text-purple-400 text-xs font-bold font-mono">WS</span>
|
||||
<code class="text-white font-mono text-sm">ws://localhost:8080/api/apps/:name/logs</code>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-purple-500/20 text-purple-400 text-xs font-bold font-mono"
|
||||
>WS</span
|
||||
>
|
||||
<code class="text-white font-mono text-sm"
|
||||
>ws://localhost:8080/api/apps/:name/logs</code
|
||||
>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">Stream de logs en tiempo real desde journalctl</p>
|
||||
<p class="text-[#9dabb9] text-sm mt-2">
|
||||
Stream de logs en tiempo real desde journalctl
|
||||
</p>
|
||||
</div>
|
||||
<div class="p-6 space-y-4">
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Ejemplo JavaScript</p>
|
||||
<pre class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-purple-400 overflow-x-auto">const ws = new WebSocket('ws://localhost:8080/api/apps/mi-app/logs');
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Ejemplo JavaScript
|
||||
</p>
|
||||
<pre
|
||||
class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-purple-400 overflow-x-auto"
|
||||
>
|
||||
const ws = new WebSocket('ws://localhost:8080/api/apps/mi-app/logs');
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log('Conectado a logs');
|
||||
@@ -460,18 +734,35 @@ ws.onerror = (error) => {
|
||||
|
||||
ws.onclose = () => {
|
||||
console.log('Desconectado');
|
||||
};</pre>
|
||||
};</pre
|
||||
>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-white font-semibold text-sm mb-2">Límites</p>
|
||||
<p
|
||||
class="text-white font-semibold text-sm mb-2"
|
||||
>
|
||||
Límites
|
||||
</p>
|
||||
<ul class="space-y-2">
|
||||
<li class="flex items-start gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-sm">check</span>
|
||||
<span class="text-[#9dabb9] text-sm">Máximo 5 conexiones concurrentes por aplicación</span>
|
||||
<span
|
||||
class="material-symbols-outlined text-primary text-sm"
|
||||
>check</span
|
||||
>
|
||||
<span class="text-[#9dabb9] text-sm"
|
||||
>Máximo 5 conexiones concurrentes
|
||||
por aplicación</span
|
||||
>
|
||||
</li>
|
||||
<li class="flex items-start gap-2">
|
||||
<span class="material-symbols-outlined text-primary text-sm">check</span>
|
||||
<span class="text-[#9dabb9] text-sm">Formato JSON desde systemd journalctl</span>
|
||||
<span
|
||||
class="material-symbols-outlined text-primary text-sm"
|
||||
>check</span
|
||||
>
|
||||
<span class="text-[#9dabb9] text-sm"
|
||||
>Formato JSON desde systemd
|
||||
journalctl</span
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -481,52 +772,98 @@ ws.onclose = () => {
|
||||
|
||||
<!-- Error Codes -->
|
||||
<section id="errors" class="mb-12">
|
||||
<h2 class="text-white text-2xl font-bold mb-6 flex items-center gap-2">
|
||||
<span class="material-symbols-outlined text-primary">error</span>
|
||||
<h2
|
||||
class="text-white text-2xl font-bold mb-6 flex items-center gap-2"
|
||||
>
|
||||
<span class="material-symbols-outlined text-primary"
|
||||
>error</span
|
||||
>
|
||||
Códigos de Error
|
||||
</h2>
|
||||
|
||||
<div class="space-y-4">
|
||||
<div class="rounded-xl border border-[#283039] bg-[#161f2a] p-4">
|
||||
<div
|
||||
class="rounded-xl border border-[#283039] bg-[#161f2a] p-4"
|
||||
>
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<span class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono">400</span>
|
||||
<p class="text-white font-semibold">Bad Request</p>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono"
|
||||
>400</span
|
||||
>
|
||||
<p class="text-white font-semibold">
|
||||
Bad Request
|
||||
</p>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm">Datos de entrada inválidos o faltantes</p>
|
||||
<p class="text-[#9dabb9] text-sm">
|
||||
Datos de entrada inválidos o faltantes
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-[#283039] bg-[#161f2a] p-4">
|
||||
<div
|
||||
class="rounded-xl border border-[#283039] bg-[#161f2a] p-4"
|
||||
>
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<span class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono">404</span>
|
||||
<p class="text-white font-semibold">Not Found</p>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono"
|
||||
>404</span
|
||||
>
|
||||
<p class="text-white font-semibold">
|
||||
Not Found
|
||||
</p>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm">Aplicación no encontrada</p>
|
||||
<p class="text-[#9dabb9] text-sm">
|
||||
Aplicación no encontrada
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-[#283039] bg-[#161f2a] p-4">
|
||||
<div
|
||||
class="rounded-xl border border-[#283039] bg-[#161f2a] p-4"
|
||||
>
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<span class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono">429</span>
|
||||
<p class="text-white font-semibold">Too Many Requests</p>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono"
|
||||
>429</span
|
||||
>
|
||||
<p class="text-white font-semibold">
|
||||
Too Many Requests
|
||||
</p>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm">Rate limit excedido (1 operación/segundo)</p>
|
||||
<p class="text-[#9dabb9] text-sm">
|
||||
Rate limit excedido (1 operación/segundo)
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="rounded-xl border border-[#283039] bg-[#161f2a] p-4">
|
||||
<div
|
||||
class="rounded-xl border border-[#283039] bg-[#161f2a] p-4"
|
||||
>
|
||||
<div class="flex items-center gap-3 mb-2">
|
||||
<span class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono">500</span>
|
||||
<p class="text-white font-semibold">Internal Server Error</p>
|
||||
<span
|
||||
class="px-2 py-1 rounded bg-red-500/20 text-red-400 text-xs font-bold font-mono"
|
||||
>500</span
|
||||
>
|
||||
<p class="text-white font-semibold">
|
||||
Internal Server Error
|
||||
</p>
|
||||
</div>
|
||||
<p class="text-[#9dabb9] text-sm">Error interno del servidor</p>
|
||||
<p class="text-[#9dabb9] text-sm">
|
||||
Error interno del servidor
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6">
|
||||
<p class="text-white font-semibold text-sm mb-2">Estructura de error</p>
|
||||
<pre class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-red-400 overflow-x-auto">{
|
||||
<p class="text-white font-semibold text-sm mb-2">
|
||||
Estructura de error
|
||||
</p>
|
||||
<pre
|
||||
class="code-block bg-[#0a0f16] p-4 rounded-lg text-sm text-red-400 overflow-x-auto"
|
||||
>
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"error": "Descripción del error"
|
||||
}</pre>
|
||||
}</pre
|
||||
>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
@@ -534,14 +871,18 @@ ws.onclose = () => {
|
||||
|
||||
<script>
|
||||
async function tryEndpoint(method, path) {
|
||||
const resultDiv = event.target.parentElement.querySelector('.result') ||
|
||||
event.target.parentElement.appendChild(document.createElement('div'));
|
||||
resultDiv.className = 'result mt-4 code-block bg-[#0a0f16] p-4 rounded-lg text-sm overflow-x-auto';
|
||||
resultDiv.textContent = 'Ejecutando...';
|
||||
const resultDiv =
|
||||
event.target.parentElement.querySelector(".result") ||
|
||||
event.target.parentElement.appendChild(
|
||||
document.createElement("div"),
|
||||
);
|
||||
resultDiv.className =
|
||||
"result mt-4 code-block bg-[#0a0f16] p-4 rounded-lg text-sm overflow-x-auto";
|
||||
resultDiv.textContent = "Ejecutando...";
|
||||
|
||||
try {
|
||||
const response = await fetch(`http://localhost:8080${path}`, {
|
||||
method: method
|
||||
const response = await fetch(path, {
|
||||
method: method,
|
||||
});
|
||||
const data = await response.json();
|
||||
resultDiv.innerHTML = `<pre class="text-green-400">${JSON.stringify(data, null, 2)}</pre>`;
|
||||
@@ -551,12 +892,17 @@ ws.onclose = () => {
|
||||
}
|
||||
|
||||
// Smooth scroll for anchor links
|
||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
||||
anchor.addEventListener('click', function (e) {
|
||||
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
|
||||
anchor.addEventListener("click", function (e) {
|
||||
e.preventDefault();
|
||||
const target = document.querySelector(this.getAttribute('href'));
|
||||
const target = document.querySelector(
|
||||
this.getAttribute("href"),
|
||||
);
|
||||
if (target) {
|
||||
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
target.scrollIntoView({
|
||||
behavior: "smooth",
|
||||
block: "start",
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user