Skip to content

Latest commit

 

History

History
349 lines (259 loc) · 10.8 KB

File metadata and controls

349 lines (259 loc) · 10.8 KB

NexusCad - Arquitectura de Servicios Windows

📋 Visión general

NexusCad utiliza Servicios Windows para el backend API en entornos de producción, garantizando disponibilidad continua sin intervención del usuario.


🎯 Decisión arquitectónica

¿Por qué Servicio Windows?

Contexto:

  • El Administrator (WPF) necesita una API siempre disponible
  • Los usuarios no técnicos no deberían iniciar procesos manualmente
  • La API debe arrancar automáticamente con el sistema

Alternativas evaluadas:

Opción Ventajas Desventajas Decisión
Servicio Windows ✅ Inicio automático
✅ Siempre disponible
✅ Gestión centralizada
⚠️ Complica desarrollo
⚠️ Requiere reiniciar para cambios
ELEGIDA para producción
Auto-inicio desde Admin ✅ Simple
✅ Fácil desarrollo
❌ Proceso hijo
❌ No sobrevive a cierre del Admin
❌ Descartada
Ejecutable manual ✅ Muy simple ❌ El usuario debe iniciarlo
❌ Puede olvidarse
❌ Descartada
Tray Icon ✅ Visual
✅ Control fácil
❌ El usuario debe iniciarlo
❌ Complejidad extra
⏳ Considerada post-MVP

🏗️ Arquitectura

┌─────────────────────────────────────────────────────────┐
│                    ENTORNO DE PRODUCCIÓN                │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Windows Startup                                        │
│       │                                                 │
│       ▼                                                 │
│  ┌──────────────────────────┐                          │
│  │ NexusCadApi Service      │  (Servicio Windows)      │
│  │ (Auto-start)             │                          │
│  │                          │                          │
│  │ http://localhost:5140    │                          │
│  └────────────┬─────────────┘                          │
│               │ REST API                                │
│               │                                         │
│      ┌────────┴────────┐                                │
│      ▼                 ▼                                │
│  ┌──────────┐    ┌──────────┐                          │
│  │  Admin   │    │ Runtime  │                          │
│  │  (WPF)   │    │  (Web)   │                          │
│  └──────────┘    └──────────┘                          │
│                                                         │
└─────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────┐
│                    ENTORNO DE DESARROLLO                │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  Visual Studio F5                                       │
│       │                                                 │
│       ├────────────────┬─────────────────┐              │
│       ▼                ▼                 ▼              │
│  ┌──────────┐    ┌──────────┐     ┌──────────┐        │
│  │   API    │    │  Admin   │     │  Tests   │        │
│  │ (Debug)  │    │  (WPF)   │     │ (xUnit)  │        │
│  └──────────┘    └──────────┘     └──────────┘        │
│                                                         │
│  (NO usar servicio Windows durante desarrollo)         │
│                                                         │
└─────────────────────────────────────────────────────────┘

🔄 Ciclo de vida

Producción

graph TD
    A[Sistema arranca] --> B[Servicio NexusCadApi inicia]
    B --> C[API escucha en puerto 5140]
    C --> D[Usuario abre Admin]
    D --> E[Admin conecta a API]
    E --> F[Usuario trabaja normalmente]
    F --> G[Usuario cierra Admin]
    G --> C
    C --> H[Sistema se apaga]
    H --> I[Servicio se detiene limpiamente]
Loading

Desarrollo

graph TD
    A[Developer abre Visual Studio] --> B[F5 - Multiple Startup]
    B --> C[API inicia modo Debug]
    B --> D[Admin inicia modo Debug]
    C --> E[Breakpoints activos]
    D --> E
    E --> F[Cierra Visual Studio]
    F --> G[Procesos terminan]
Loading

📦 Implementación

Configuración del proyecto API

El proyecto NexusCad.Api debe estar configurado como ejecutable autónomo para funcionar como servicio:

<!-- NexusCad.Api.csproj -->
<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <OutputType>Exe</OutputType>
    <IsPackable>false</IsPackable>
  </PropertyGroup>
</Project>

Program.cs

// src/NexusCad.Api/Program.cs
var builder = WebApplication.CreateBuilder(args);

// Configurar para ejecutarse como servicio Windows
builder.Host.UseWindowsService();

// ... resto de configuración ...

var app = builder.Build();
app.Run();

El método UseWindowsService() es clave: hace que la aplicación funcione tanto como:

  • Aplicación de consola normal (en desarrollo)
  • Servicio Windows (en producción)

🛠️ Scripts de gestión

Ubicación: dev-scripts/

Instalación inicial

# Como Administrador
.\dev-scripts\install-api-service.ps1

Pasos internos:

  1. dotnet publish -c ReleaseC:\NexusCad\Api
  2. sc.exe create NexusCadApi binPath=...
  3. sc.exe start NexusCadApi

Durante desarrollo

# Detener servicio para poder compilar
.\dev-scripts\stop-api-service.ps1

# Trabajar normalmente
dotnet build
dotnet run --project src/NexusCad.Api

# Actualizar servicio con cambios
.\dev-scripts\update-api-service.ps1

Desinstalación

# Como Administrador
.\dev-scripts\uninstall-api-service.ps1

Ver dev-scripts/README.md para detalles completos.


⚠️ Consideraciones de desarrollo

Problema: Archivos bloqueados

Cuando el servicio está corriendo, mantiene los archivos DLL bloqueados:

PS> dotnet build
error MSB3021: Unable to copy file "obj\Debug\net8.0\NexusCad.Api.dll" 
to "bin\Debug\net8.0\NexusCad.Api.dll". 
The process cannot access the file because it is being used by another process.

Solución:

.\dev-scripts\stop-api-service.ps1
dotnet build

Recomendación: NO instalar servicio durante desarrollo

Flujo óptimo:

  1. Fase de desarrollo:

    • NO instalar el servicio
    • Usar Visual Studio F5 o dotnet run
    • Compilar y probar libremente
  2. Antes de entregar a usuario:

    • Compilar versión Release
    • Instalar como servicio
    • Probar end-to-end
  3. Después de cambios (con servicio instalado):

    • Detener servicio
    • Hacer cambios
    • Actualizar servicio

🔍 Monitorización

Ver estado del servicio

# PowerShell
Get-Service NexusCadApi

# CMD
sc.exe query NexusCadApi

Ver logs

# Event Viewer
Get-EventLog -LogName Application -Source NexusCadApi -Newest 20

# Si Serilog está configurado para archivos
Get-Content C:\NexusCad\Logs\api-*.log -Tail 50

Healthcheck

# Comprobar que la API responde
Invoke-RestMethod http://localhost:5140/api/health

🚀 Despliegue en producción

Checklist de instalación

  • Windows Server 2019+ o Windows 10/11
  • .NET 8 Runtime instalado
  • PostgreSQL 16 corriendo y accesible
  • Puerto 5140 disponible
  • Cuenta de servicio configurada (opcional, por defecto usa LocalSystem)

Pasos

  1. Clonar repositorio en servidor:

    git clone https://github.com/JaviFRx/NexusCad.git C:\NexusCad\Source
    cd C:\NexusCad\Source
  2. Instalar servicio:

    # Como Administrador
    .\dev-scripts\install-api-service.ps1
  3. Verificar:

    Get-Service NexusCadApi
    Invoke-RestMethod http://localhost:5140/api/health
    Start-Process http://localhost:5140/swagger
  4. Configurar inicio automático (ya está por defecto):

    sc.exe config NexusCadApi start= auto

Actualizaciones

# En servidor de producción
cd C:\NexusCad\Source
git pull origin main

# Como Administrador
.\dev-scripts\update-api-service.ps1

🔒 Seguridad

Cuenta de servicio

Por defecto, el servicio corre como LocalSystem. Para producción, considera usar una cuenta dedicada:

# Crear cuenta de servicio
$password = ConvertTo-SecureString "Passw0rd123!" -AsPlainText -Force
New-LocalUser -Name "NexusCadSvc" -Password $password -PasswordNeverExpires

# Configurar servicio para usar esa cuenta
sc.exe config NexusCadApi obj= ".\NexusCadSvc" password= "Passw0rd123!"

# Dar permisos a la carpeta
icacls C:\NexusCad\Api /grant "NexusCadSvc:(OI)(CI)F" /T

Firewall

Si necesitas acceso remoto:

New-NetFirewallRule -DisplayName "NexusCad API" `
    -Direction Inbound `
    -LocalPort 5140 `
    -Protocol TCP `
    -Action Allow

📚 Referencias


Última actualización: Fase 1 - Documentación de arquitectura de servicios