Nexus/DATABASE-SETUP.md

14 KiB

🗄️ Sistema de Persistencia con PostgreSQL + Prisma

Base de Datos Completa con RAG Vector Support

He implementado un sistema completo de persistencia usando PostgreSQL con soporte para vectores (pgvector) para RAG, utilizando Prisma ORM para un manejo escalable.


📊 Arquitectura de Base de Datos

Conexión PostgreSQL

Host: 192.168.1.20:5433
Database: nexus
User: postgres
Password: 72ff3d8d80c352f89d99
Extension: pgvector (para RAG)

Variables de Entorno (.env)

# Database
DATABASE_URL="postgres://postgres:72ff3d8d80c352f89d99@192.168.1.20:5433/nexus?sslmode=disable"

# Server
PORT=3000
NODE_ENV=development
CLIENT_URL=http://localhost:3001

# JWT
JWT_SECRET=your-super-secret-jwt-key-change-in-production-nexus-2026

# File Upload
MAX_FILE_SIZE=10485760
UPLOAD_DIR=./uploads

# AI Providers (optional - users configure in UI)
OPENAI_API_KEY=
ANTHROPIC_API_KEY=
GOOGLE_API_KEY=
MISTRAL_API_KEY=
COHERE_API_KEY=

🗃️ Modelos de Base de Datos

1. User

model User {
  id            String   @id @default(cuid())
  email         String   @unique
  name          String?
  password      String
  avatar        String?
  createdAt     DateTime @default(now())
  updatedAt     DateTime @updatedAt
  
  conversations Conversation[]
  aiProviders   AIProvider[]
  knowledgeBases KnowledgeBase[]
  agents        Agent[]
  settings      AppSettings?
}

Propósito: Gestión de usuarios y autenticación


2. AppSettings (Branding + Config)

model AppSettings {
  id            String   @id @default(cuid())
  userId        String   @unique
  
  // Branding
  appName       String   @default("NexusChat")
  appLogo       String?  // URL or base64
  appIcon       String?  // URL or base64 for avatar/favicon
  
  // Theme
  theme         String   @default("dark")
  primaryColor  String   @default("#667eea")
  
  // General Settings
  autoSave      Boolean  @default(true)
  soundEnabled  Boolean  @default(false)
  language      String   @default("en")
}

Propósito:

  • Personalización de marca (logo, icono, nombre)
  • Configuración de tema
  • Preferencias generales

3. AIProvider

model AIProvider {
  id            String   @id @default(cuid())
  userId        String
  
  providerId    String   // openai, anthropic, google, mistral, cohere
  name          String
  enabled       Boolean  @default(false)
  apiKey        String?  @db.Text // Encrypted
}

Propósito: Almacenar configuración de AI Providers por usuario


4. Conversation

model Conversation {
  id            String   @id @default(cuid())
  userId        String
  
  title         String
  agentId       String?
  
  modelId       String?  // gpt-4o, claude-3-opus, etc
  providerId    String?  // openai, anthropic, etc
  
  messages      Message[]
  topics        Topic[]
}

Propósito: Gestión de conversaciones de chat


5. Message

model Message {
  id              String   @id @default(cuid())
  conversationId  String
  
  role            String   // user, assistant, system
  content         String   @db.Text
  
  // Metadata
  tokensUsed      Int?
  model           String?
}

Propósito: Almacenar mensajes de las conversaciones


6. Topic

model Topic {
  id              String   @id @default(cuid())
  conversationId  String
  
  title           String
  order           Int      @default(0)
}

Propósito: Topics del panel derecho del chat


7. KnowledgeBase

model KnowledgeBase {
  id            String   @id @default(cuid())
  userId        String
  
  name          String
  description   String?  @db.Text
  
  documents     Document[]
  agents        Agent[]
}

Propósito: Contenedor de documentos para RAG


8. Document

model Document {
  id              String   @id @default(cuid())
  knowledgeBaseId String
  
  fileName        String
  fileType        String
  fileSize        Int
  filePath        String
  
  status          String   @default("processing") // processing, ready, error
  chunksCount     Int      @default(0)
  
  chunks          DocumentChunk[]
}

Propósito: Archivos subidos para RAG


9. DocumentChunk (RAG con Vectores)

model DocumentChunk {
  id              String   @id @default(cuid())
  documentId      String
  
  content         String   @db.Text
  chunkIndex      Int
  
  // Vector embedding for semantic search (using pgvector)
  // TODO: Enable after pgvector extension is installed
  // embedding       Unsupported("vector(1536)")?
  
  metadata        Json?    // Additional metadata
}

Propósito:

  • Chunks de documentos procesados
  • Vector embeddings para búsqueda semántica
  • Metadata adicional

Nota: El campo embedding está comentado temporalmente. Se habilitará después de instalar la extensión pgvector en PostgreSQL.


10. Agent

model Agent {
  id              String   @id @default(cuid())
  userId          String
  
  name            String
  emoji           String   @default("🤖")
  role            String
  description     String   @db.Text
  
  status          String   @default("active") // active, inactive
  
  // Capabilities
  mcpEnabled      Boolean  @default(false)
  mcpTools        Json?    // Array of MCP tools
  
  // RAG Configuration
  ragEnabled      Boolean  @default(false)
  
  // Stats
  interactions    Int      @default(0)
  lastUsedAt      DateTime?
  
  conversations   Conversation[]
  knowledgeBases  KnowledgeBase[]
}

Propósito: Agentes IA configurables con MCP y RAG


🎨 Nueva Feature: Branding Settings

Componente SettingsBranding

Permite personalizar:

  1. Nombre de la aplicación
  2. Logo (texto) - Imagen para el header
  3. Icono (avatar) - Imagen para el chat avatar

Visual

┌──────────────────────────────────────────┐
│ ✨ Branding                              │
├──────────────────────────────────────────┤
│                                          │
│ Nombre de la Aplicación                 │
│ [NexusChat                          ]   │
│                                          │
│ ┌────────────┬──────────────────────┐  │
│ │ Logo       │ Icono                │  │
│ │            │                      │  │
│ │ ⬆️ Upload  │ ⬆️ Upload            │  │
│ │ Click para │ Click para subir    │  │
│ │ subir logo │ icono               │  │
│ │            │                      │  │
│ └────────────┴──────────────────────┘  │
│                                          │
│ [Guardar Cambios]                       │
└──────────────────────────────────────────┘

Funcionalidades

  • Upload de imagen para logo
  • Upload de imagen para icono
  • Cambiar nombre de la app
  • Preview de imágenes
  • Botón para remover imágenes
  • Guardar en localStorage (temporal)
  • TODO: Guardar en base de datos

📁 Estructura de Archivos

Backend

/
├── .env (configuración)
├── prisma/
│   ├── schema.prisma (modelos)
│   └── migrations/ (migraciones)
│
└── src/
    └── config/
        └── prisma.ts (cliente singleton)

Frontend

client/src/components/
└── SettingsBranding.tsx (nuevo componente)

🚀 Uso del Sistema

1. Iniciar Base de Datos

La base de datos ya está configurada en 192.168.1.20:5433

2. Aplicar Migraciones

cd /Users/cesarmendivil/WebstormProjects/Nexus
npx prisma migrate dev

3. Generar Cliente

npx prisma generate

4. Usar Prisma en Backend

import prisma from './config/prisma';

// Crear usuario
const user = await prisma.user.create({
  data: {
    email: 'user@example.com',
    password: 'hashed_password',
    name: 'John Doe',
  },
});

// Guardar configuración de AI Provider
await prisma.aIProvider.create({
  data: {
    userId: user.id,
    providerId: 'openai',
    name: 'OpenAI',
    enabled: true,
    apiKey: 'encrypted_key',
  },
});

// Crear conversación
const conversation = await prisma.conversation.create({
  data: {
    userId: user.id,
    title: 'Nueva conversación',
    modelId: 'gpt-4o',
    providerId: 'openai',
  },
});

// Guardar mensaje
await prisma.message.create({
  data: {
    conversationId: conversation.id,
    role: 'user',
    content: 'Hola!',
  },
});

🔄 Flujo de Datos

Configuración de AI Providers

UI (SettingsModal) 
  → localStorage (temporal)
  → Backend API (TODO)
  → Prisma
  → PostgreSQL

Branding

UI (SettingsBranding)
  → Upload imagen
  → Base64 / File
  → localStorage (temporal)
  → Backend API (TODO)
  → Prisma (AppSettings)
  → PostgreSQL

RAG Pipeline

1. Usuario sube archivo
   → KnowledgeBase

2. Backend procesa archivo
   → Divide en chunks
   → DocumentChunk

3. Genera embeddings
   → OpenAI embeddings API
   → Guarda en vector field

4. Búsqueda semántica
   → Query → embedding
   → pgvector similarity search
   → Retorna chunks relevantes

📊 Diagrama de Relaciones

User
  ├── Conversation
  │     ├── Message
  │     └── Topic
  │
  ├── AIProvider
  │
  ├── KnowledgeBase
  │     └── Document
  │           └── DocumentChunk (with vector)
  │
  ├── Agent
  │     └── KnowledgeBase (many-to-many)
  │
  └── AppSettings

🔒 Seguridad

API Keys

  • Almacenadas en campo @db.Text
  • ⚠️ TODO: Implementar encriptación
  • No expuestas en el cliente

Passwords

  • ⚠️ TODO: Implementar hashing (bcrypt)
  • Campo password en User model

JWT

  • Secret configurado en .env
  • ⚠️ TODO: Implementar autenticación

📋 Próximos Pasos

Backend APIs a Implementar

1. Auth

POST /api/auth/register
POST /api/auth/login
POST /api/auth/logout
GET  /api/auth/me

2. AI Providers

GET    /api/providers
POST   /api/providers
PUT    /api/providers/:id
DELETE /api/providers/:id

3. Conversations

GET    /api/conversations
POST   /api/conversations
GET    /api/conversations/:id
DELETE /api/conversations/:id
POST   /api/conversations/:id/messages

4. Knowledge Base

GET    /api/knowledge
POST   /api/knowledge
POST   /api/knowledge/:id/documents
GET    /api/knowledge/:id/documents
DELETE /api/documents/:id

5. Agents

GET    /api/agents
POST   /api/agents
PUT    /api/agents/:id
DELETE /api/agents/:id

6. Settings

GET    /api/settings
PUT    /api/settings
POST   /api/settings/branding/upload

🎯 Integración con Frontend

useChat Hook (Actualizar)

// En lugar de localStorage
const messages = await fetch('/api/conversations/${id}/messages');

// Guardar mensaje
await fetch('/api/conversations/${id}/messages', {
  method: 'POST',
  body: JSON.stringify({ content, role: 'user' }),
});

SettingsAIProviders (Actualizar)

// En lugar de localStorage
const providers = await fetch('/api/providers');

// Guardar provider
await fetch('/api/providers', {
  method: 'POST',
  body: JSON.stringify(providerData),
});

SettingsBranding (Actualizar)

// Upload logo
const formData = new FormData();
formData.append('logo', file);

await fetch('/api/settings/branding/upload', {
  method: 'POST',
  body: formData,
});

🗄️ Comandos Útiles de Prisma

Ver Base de Datos

npx prisma studio

Abre interfaz web en http://localhost:5555

Crear Migración

npx prisma migrate dev --name migration_name

Reset Database

npx prisma migrate reset

Pull Schema from DB

npx prisma db pull

Push Schema to DB (sin migración)

npx prisma db push

Estado Actual

╔════════════════════════════════════════════╗
║  ✅ BASE DE DATOS CONFIGURADA             ║
║                                            ║
║  PostgreSQL: 192.168.1.20:5433            ║
║  Database: nexus                          ║
║  ORM: Prisma                              ║
║  Extension: pgvector (preparado)          ║
║                                            ║
║  Modelos: 10                              ║
║  - User                                   ║
║  - AppSettings (Branding)                 ║
║  - AIProvider                             ║
║  - Conversation                           ║
║  - Message                                ║
║  - Topic                                  ║
║  - KnowledgeBase                          ║
║  - Document                               ║
║  - DocumentChunk (RAG)                    ║
║  - Agent                                  ║
║                                            ║
║  Features Frontend:                       ║
║  ✅ Branding Settings UI                  ║
║  ✅ Upload logo/icono                     ║
║  ✅ Cambiar nombre app                    ║
║                                            ║
║  TODO:                                     ║
║  ⏳ Backend APIs                          ║
║  ⏳ Autenticación                         ║
║  ⏳ Encriptación API Keys                 ║
║  ⏳ Integración RAG pipeline              ║
║                                            ║
║  Estado: ESTRUCTURA COMPLETA ✅           ║
╚════════════════════════════════════════════╝

Implementado: 14 de Febrero, 2026
Base de Datos: PostgreSQL con pgvector
ORM: Prisma
Modelos: 10 completos
Features: Branding Settings UI
Estado: ESTRUCTURA LISTA - APIs PENDIENTES