trello_fake/scripts/seed-projects-direct.js

386 lines
12 KiB
JavaScript

#!/usr/bin/env node
/**
* Script para crear proyectos de prueba en Dolibarr llamando directamente a la API
* NO requiere que Next.js esté corriendo
*
* Uso: node scripts/seed-projects-direct.js
*/
// Configuración - lee de .env.local o usa valores por defecto
const fs = require('fs');
const path = require('path');
// Leer .env.local
function loadEnv() {
const envPath = path.join(__dirname, '..', '.env.local');
const env = {};
try {
const content = fs.readFileSync(envPath, 'utf8');
content.split('\n').forEach(line => {
const [key, ...valueParts] = line.split('=');
if (key && valueParts.length > 0) {
env[key.trim()] = valueParts.join('=').trim();
}
});
} catch (e) {
console.error('Error leyendo .env.local:', e.message);
}
return env;
}
const env = loadEnv();
const DOLIBARR_API_URL = env.NEXT_PUBLIC_API_URL || 'http://localhost:8200/api/index.php';
const DOLIBARR_API_KEY = env.NEXT_PUBLIC_DOLIBARR_API_KEY || '';
if (!DOLIBARR_API_KEY) {
console.error('❌ ERROR: No se encontró NEXT_PUBLIC_DOLIBARR_API_KEY en .env.local');
process.exit(1);
}
// Nombres de clientes para asignar aleatoriamente
const clientNames = [
"TechCorp Solutions",
"Innovatech S.L.",
"Digital Factory",
"CloudBase Systems",
"DataPrime Analytics",
"WebMasters Pro",
"AppDev Studio",
"CyberTech Security",
"SmartBiz Solutions",
"NextGen Software"
];
// Datos de proyectos de ejemplo con variedad de estados y presupuestos
const projectsData = [
{
title: "Desarrollo de App Movil",
ref: "PROJ-2025-001",
description: "Aplicacion movil para gestion de inventario con funcionalidades de escaneo QR y sincronizacion en tiempo real.",
opp_amount: 45000,
opp_percent: 65,
date_start: Math.floor(new Date('2025-01-15').getTime() / 1000),
date_end: Math.floor(new Date('2025-06-30').getTime() / 1000),
},
{
title: "Rediseno Web Corporativo",
ref: "PROJ-2025-002",
description: "Renovacion completa del sitio web corporativo con nuevo diseno responsive y optimizacion SEO.",
opp_amount: 28000,
opp_percent: 90,
date_start: Math.floor(new Date('2024-11-01').getTime() / 1000),
date_end: Math.floor(new Date('2025-02-28').getTime() / 1000),
},
{
title: "Sistema de Facturacion Automatica",
ref: "PROJ-2025-003",
description: "Desarrollo de sistema automatizado para generacion y envio de facturas con integracion a contabilidad.",
opp_amount: 62000,
opp_percent: 35,
date_start: Math.floor(new Date('2025-02-01').getTime() / 1000),
date_end: Math.floor(new Date('2025-08-31').getTime() / 1000),
},
{
title: "Migracion a Cloud AWS",
ref: "PROJ-2025-004",
description: "Migracion completa de infraestructura on-premise a AWS con configuracion de alta disponibilidad.",
opp_amount: 85000,
opp_percent: 20,
date_start: Math.floor(new Date('2025-03-01').getTime() / 1000),
date_end: Math.floor(new Date('2025-12-31').getTime() / 1000),
},
{
title: "Dashboard Analitico BI",
ref: "PROJ-2025-005",
description: "Creacion de dashboard de Business Intelligence para analisis de ventas y KPIs en tiempo real.",
opp_amount: 38000,
opp_percent: 100,
date_start: Math.floor(new Date('2024-09-01').getTime() / 1000),
date_end: Math.floor(new Date('2024-12-15').getTime() / 1000),
status: 2, // Cerrado
},
{
title: "API REST Microservicios",
ref: "PROJ-2025-006",
description: "Desarrollo de arquitectura de microservicios con API REST para integracion de sistemas legacy.",
opp_amount: 72000,
opp_percent: 50,
date_start: Math.floor(new Date('2025-01-20').getTime() / 1000),
date_end: Math.floor(new Date('2025-07-31').getTime() / 1000),
},
{
title: "App de Gestion de Proyectos",
ref: "PROJ-2025-007",
description: "Plataforma web para gestion agil de proyectos con tableros Kanban, Gantt y reporting automatico.",
opp_amount: 55000,
opp_percent: 75,
date_start: Math.floor(new Date('2024-12-01').getTime() / 1000),
date_end: Math.floor(new Date('2025-05-31').getTime() / 1000),
},
{
title: "E-commerce con Marketplace",
ref: "PROJ-2025-008",
description: "Plataforma de e-commerce completa con funcionalidad de marketplace multivendedor y pasarela de pagos.",
opp_amount: 120000,
opp_percent: 15,
date_start: Math.floor(new Date('2025-04-01').getTime() / 1000),
date_end: Math.floor(new Date('2026-03-31').getTime() / 1000),
},
{
title: "Sistema CRM Personalizado",
ref: "PROJ-2025-009",
description: "CRM a medida con automatizacion de marketing, gestion de leads y pipeline de ventas.",
opp_amount: 48000,
opp_percent: 0,
date_start: Math.floor(new Date('2025-05-01').getTime() / 1000),
date_end: Math.floor(new Date('2025-11-30').getTime() / 1000),
},
{
title: "Portal de Empleados",
ref: "PROJ-2025-010",
description: "Portal interno para empleados con gestion de vacaciones, nominas, formacion y comunicacion interna.",
opp_amount: 35000,
opp_percent: 100,
date_start: Math.floor(new Date('2024-10-01').getTime() / 1000),
date_end: Math.floor(new Date('2024-12-31').getTime() / 1000),
status: 2, // Cerrado
},
{
title: "Sistema de Reservas Online",
ref: "PROJ-2025-011",
description: "Plataforma de reservas con calendario interactivo, confirmacion automatica y pasarela de pago.",
opp_amount: 42000,
opp_percent: 45,
date_start: Math.floor(new Date('2025-02-15').getTime() / 1000),
date_end: Math.floor(new Date('2025-07-15').getTime() / 1000),
},
{
title: "App de Formacion Online",
ref: "PROJ-2025-012",
description: "Plataforma LMS para formacion online con seguimiento de progreso, certificados y evaluaciones.",
opp_amount: 68000,
opp_percent: 30,
date_start: Math.floor(new Date('2025-03-10').getTime() / 1000),
date_end: Math.floor(new Date('2025-10-31').getTime() / 1000),
},
{
title: "Automatizacion de Procesos RPA",
ref: "PROJ-2025-013",
description: "Implementacion de robots de automatizacion para procesos administrativos repetitivos.",
opp_amount: 95000,
opp_percent: 10,
date_start: Math.floor(new Date('2025-06-01').getTime() / 1000),
date_end: Math.floor(new Date('2026-02-28').getTime() / 1000),
},
{
title: "Plataforma IoT Industrial",
ref: "PROJ-2025-014",
description: "Sistema de monitoreo IoT para maquinaria industrial con alertas predictivas y mantenimiento.",
opp_amount: 150000,
opp_percent: 5,
date_start: Math.floor(new Date('2025-07-01').getTime() / 1000),
date_end: Math.floor(new Date('2026-06-30').getTime() / 1000),
},
{
title: "Chatbot con IA",
ref: "PROJ-2025-015",
description: "Desarrollo de chatbot inteligente para atencion al cliente con procesamiento de lenguaje natural.",
opp_amount: 32000,
opp_percent: 80,
date_start: Math.floor(new Date('2024-11-15').getTime() / 1000),
date_end: Math.floor(new Date('2025-03-15').getTime() / 1000),
},
];
/**
* Llamar a la API de Dolibarr directamente
*/
async function dolibarrFetch(endpoint, options = {}) {
const url = `${DOLIBARR_API_URL}/${endpoint}`;
const response = await fetch(url, {
...options,
headers: {
'Content-Type': 'application/json',
'DOLAPIKEY': DOLIBARR_API_KEY,
...options.headers,
},
});
if (!response.ok) {
const text = await response.text();
throw new Error(`HTTP ${response.status}: ${text}`);
}
return response.json();
}
/**
* Crear un proyecto
*/
async function createProject(projectData) {
return dolibarrFetch('projects', {
method: 'POST',
body: JSON.stringify(projectData),
});
}
/**
* Validar proyecto (cambiar estado a abierto)
*/
async function validateProject(projectId) {
try {
await dolibarrFetch(`projects/${projectId}/validate`, {
method: 'POST',
body: JSON.stringify({ notrigger: 0 }),
});
return true;
} catch (e) {
return false;
}
}
/**
* Cerrar proyecto
*/
async function closeProject(projectId) {
try {
await dolibarrFetch(`projects/${projectId}/close`, {
method: 'POST',
body: JSON.stringify({ notrigger: 0 }),
});
return true;
} catch (e) {
return false;
}
}
/**
* Script principal
*/
async function main() {
console.log('\n🚀 SEED DE PROYECTOS DE PRUEBA PARA DOLIBARR\n');
console.log('═'.repeat(60));
console.log(`📡 API Dolibarr: ${DOLIBARR_API_URL}`);
console.log(`🔑 API Key: ${DOLIBARR_API_KEY.substring(0, 10)}...`);
console.log(`📊 Proyectos a crear: ${projectsData.length}`);
console.log('═'.repeat(60));
console.log('');
// Verificar conexión con Dolibarr
console.log('🔍 Verificando conexion con Dolibarr...');
try {
await dolibarrFetch('status');
console.log('✅ Conexion exitosa con Dolibarr\n');
} catch (error) {
console.error('❌ ERROR: No se puede conectar a Dolibarr');
console.error(` ${error.message}`);
console.error('\n Verifica que:');
console.error(' 1. Docker está corriendo');
console.error(' 2. La URL en .env.local es correcta');
console.error(' 3. La API key es válida\n');
process.exit(1);
}
let successCount = 0;
let errorCount = 0;
const errors = [];
for (let i = 0; i < projectsData.length; i++) {
const project = projectsData[i];
const num = i + 1;
const percentage = project.opp_percent;
const shouldClose = project.status === 2;
// Asignar cliente aleatorio
const clientName = clientNames[i % clientNames.length];
// Indicador visual del progreso
const progressBar = '▓'.repeat(Math.floor(percentage / 10)) + '░'.repeat(10 - Math.floor(percentage / 10));
console.log(`[${num}/${projectsData.length}] ${project.title}`);
console.log(` 📈 Progreso: [${progressBar}] ${percentage}%`);
console.log(` 💰 Presupuesto: €${project.opp_amount.toLocaleString()}`);
console.log(` 👤 Cliente: ${clientName}`);
try {
// Crear proyecto
const projectPayload = {
ref: project.ref,
title: project.title,
description: project.description,
opp_amount: project.opp_amount.toString(),
opp_percent: project.opp_percent.toString(),
date_start: project.date_start,
date_end: project.date_end,
usage_opportunity: 1,
usage_task: 1,
public: 1,
};
const projectId = await createProject(projectPayload);
console.log(` ✅ Creado con ID: ${projectId}`);
// Validar proyecto si tiene progreso > 0
if (percentage > 0) {
const validated = await validateProject(projectId);
if (validated) {
console.log(` ✓ Validado (estado: abierto)`);
// Cerrar si debe estar cerrado
if (shouldClose) {
const closed = await closeProject(projectId);
if (closed) {
console.log(` ✓ Cerrado (completado)`);
}
}
} else {
console.log(` ⚠ Creado pero no validado`);
}
} else {
console.log(` 📋 Dejado como borrador`);
}
successCount++;
// Pequeña pausa para no saturar la API
await new Promise(resolve => setTimeout(resolve, 300));
} catch (error) {
console.log(` ❌ Error: ${error.message}`);
errors.push({ project: project.title, error: error.message });
errorCount++;
}
console.log('');
}
// Resumen final
console.log('═'.repeat(60));
console.log('✨ PROCESO COMPLETADO\n');
console.log(`✅ Proyectos creados exitosamente: ${successCount}`);
console.log(`❌ Proyectos con error: ${errorCount}`);
if (errors.length > 0) {
console.log('\n📋 Errores encontrados:');
errors.forEach(({ project, error }) => {
console.log(` • ${project}: ${error}`);
});
}
console.log('═'.repeat(60));
if (successCount > 0) {
console.log('\n💡 Ahora puedes iniciar tu app con "npm run dev"');
console.log(' y ver los proyectos en http://localhost:3000\n');
}
}
// Ejecutar
main().catch(error => {
console.error('\n❌ ERROR FATAL:', error.message);
process.exit(1);
});