⚡ Machotes

Generador Inteligente de Documentos · Arquitectura del Sistema

.NET 9 Blazor Server PostgreSQL 18 OpenXML JWT Auth Multi-Tenant

📐 Diagrama de Arquitectura

🖥️ Machotes-v2 Blazor Server localhost:5154 🏠 Home (landing) 🔐 Login / Register 📋 Plantillas.razor ⬆ Subir / ⚙ Procesar @rendermode InteractiveServer HTTP (request) JSON response 🔧 Machotes-API REST API localhost:5037 / 7223 🔐 AuthController 📡 PlantillasController 📦 PlantillaService 📄 DocumentService 8 endpoints REST Lectura / Escritura EF Core 📁 Sistema de Archivos Uploads/{tenantId}/{guid}.docx 50 MB max por archivo 🐘 PostgreSQL 18 (Dokploy) MachotesDB: plantillas,usuarios,tenants Filtro por tenant_id 🔐 TenantMiddleware (JWT → tenant_id) JWT claims 👤 Usuario 🔐 Login / Register 🚀 Sube .docx 📝 Pega JSON ⬇ Descarga resultado 🖱 Blazor UI 🌐 Navegador Web (SignalR) Leyenda: Blazor API REST PostgreSQL Archivos JWT / Auth 🟣 Blazor · 🟢 API REST · 🔵 PostgreSQL · 🟡 Archivos · 🔴 JWT Auth La infraestructura PostgreSQL corre en Dokploy (89.117.19.219:5433)

🔄 Flujo de Usuario

🔐 Auth JWT implementado. Al registrarse se crea automáticamente un tenant (UUID). Al iniciar sesión se obtiene un JWT con tenant_id en los claims.
🔐 Registro Crea tenant + user
🔑 Login Obtiene JWT
📋 Lista Ver plantillas
Subir Archivo .docx
⚙️ Procesar Pegar JSON
🔄 Reemplazo {clave} → valor
Descarga Documento listo

📡 Endpoints de la API

🔐 Autenticación

Método Ruta Descripción Estado
POST /api/auth/register Crear tenant + usuario → devuelve JWT
POST /api/auth/login Iniciar sesión → devuelve JWT

📄 Plantillas

Método Ruta Descripción Auth Estado
GET /api/plantillas Lista plantillas del tenant 🔐
GET /api/plantillas/{id} Obtiene una plantilla 🔐
POST /api/plantillas Sube .docx (multipart) 🔐
DELETE /api/plantillas/{id} Elimina plantilla 🔐
POST /api/plantillas/{id}/procesar Reemplaza {claves} y descarga 🔐

Body para procesar:

{
  "valores": {
    "cliente": "Juan Pérez",
    "fecha": "15/09/2026",
    "monto": "$50,000"
  }
}

🧰 Stack Tecnológico

🖥️ Frontend — Blazor Server
  • • .NET 9 con InteractiveServer mode
  • • Bootstrap 5 (responsive, dark theme)
  • • SignalR (WebSocket) para interactividad
  • • HttpClient → API REST (JWT Bearer)
  • • AuthStateService (scoped, evento OnChange)
🔧 Backend — API REST
  • • .NET 9 Web API + Controllers
  • • JWT Auth (BCrypt + HMAC-SHA256)
  • • Entity Framework Core + Npgsql
  • • DocumentFormat.OpenXml 3.2.0
  • • TenantMiddleware + CurrentTenantService
🗄️ Base de Datos
  • • PostgreSQL 18 en Dokploy
  • • 89.117.19.219:5433 / MachotesDB
  • • Tablas: plantillas, usuarios, tenants
  • • Migraciones EF Core versionadas
  • • DB compartida con filtro tenant_id
📁 Almacenamiento
  • • Disco local Uploads/{tenantId}/
  • • Nombre: {guid}_{original}.docx
  • • 50 MB max por archivo
  • • Headers/footers incluidos en reemplazo
  • • Merge de <w:t> por párrafo

🏗️ Arquitectura Multi-Tenant

Estrategia actual: DB compartida con filtro por tenant_id. Todos los clientes comparten la misma base de datos (MachotesDB). Cada registro lleva un tenant_id (UUID) y todas las consultas incluyen WHERE tenant_id = @actual. Cuando un cliente crezca, se le puede migrar a su propia DB sin cambiar la interfaz (ver plan abajo).
🖥️ Machotes 🔐 TenantMiddleware tenant_id desde JWT 🐘 MachotesDB (DB compartida) Una sola base de datos con filtro por tenant_id 👤 Cliente A — plantillas con tenant_id = a1b2... 👤 Cliente B — plantillas con tenant_id = c3d4... Características • 🟢 Una sola conexión DB • 🆔 JWT con tenant_id • 📁 Uploads/{tenantId}/ • 🔒 Filtro por código • 🧳 Migrable a DB propia cuando el cliente crezca

🧳 Plan de migración a DB propia

Cuando un tenant (ej. Cliente Beta) crezca lo suficiente, se le asigna su propia DB sin downtime y sin que el cliente lo note.

  1. Crear nueva DB (beta_db) y aplicar migraciones
  2. Copiar datos del tenant con INSERT ... WHERE tenant_id = '...'
  3. Agregar TenantDatabases: { "beta-id": "Beta" } en configuración
  4. ¡Listo! El código elige la DB según el tenant en runtime
// AppDbContext elige conexión según el tenant
var dbKey = config[$"TenantDatabases:{tenant.TenantId}"];
_connectionString = dbKey != null
    ? config.GetConnectionString(dbKey)
    : config.GetConnectionString("Default");

🗺️ Roadmap

Fase Descripción Estado
Fase 1 Blazor Server — subir, listar, procesar (en memoria) ✅ Completo
Fase 2 API REST separada + Blazor consumidor via HttpClient ✅ Completo
Fase 3 PostgreSQL + EF Core — persistencia de metadatos ✅ Completo
Fase 4 Autenticación JWT + multi-tenancy (DB compartida + tenant_id) ✅ Completo
Fase 5 Agente de IA — tool use, lenguaje natural 🚀 Futuro
Fase 6 Despliegue: API en Dokploy / Blazor en servidor Windows 🚀 Futuro

💡 Conceptos Clave

📄
Motor de reemplazo

OpenXML recorre párrafo por párrafo, une texto partido en múltiples <w:t>, reemplaza {clave} y devuelve el resultado. Incluye headers y footers. Si encuentras una llave vacía sobrante la elimina para evitar que Word pida reparar.

🔐
Aislamiento por tenant

Todos los clientes comparten la misma base de datos. El aislamiento se garantiza por código: cada consulta incluye WHERE tenant_id = @actual. Carpeta de archivos separada por tenant (Uploads/{tenantId}/).

🤖
Agentes de IA

El usuario describe en lenguaje natural qué documento necesita. El agente elige la plantilla, extrae valores y genera el JSON automáticamente. Fase futura.

📦 Repositorios

🟢 Machotes-v2 (Blazor)

github.com/romeroipmyp-dev/Machotes-v2
UI Blazor Server, páginas consumidoras.
📚 Documentación aquíDocs/Arquitectura.md

🔧 Machotes-API

github.com/romeroipmyp-dev/Machotes-API
API REST con endpoints CRUD + procesar.
📎 Docs → enlace en Readme.md