feat: Initial commit - Mexus App
Sistema de Gestión de Obras de Construcción completo con: - Dashboard con KPIs y gráficos - Módulo de obras con fases y tareas - Control financiero (gastos, presupuestos) - Gestión de recursos (personal, subcontratistas) - Inventario de materiales con alertas de stock - Reportes con exportación CSV - Autenticación con roles (NextAuth.js v5) - API REST completa - Documentación de API y base de datos - Configuración Docker para despliegue Stack: Next.js 14+, TypeScript, Tailwind CSS, Prisma, PostgreSQL Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
315
prisma/seed.ts
Normal file
315
prisma/seed.ts
Normal file
@@ -0,0 +1,315 @@
|
||||
import { PrismaClient, Role, EstadoObra, CategoriaGasto } from "@prisma/client";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
async function main() {
|
||||
console.log("Seeding database...");
|
||||
|
||||
// Create empresa
|
||||
const empresa = await prisma.empresa.create({
|
||||
data: {
|
||||
nombre: "Constructora Demo S.A. de C.V.",
|
||||
rfc: "CDM123456ABC",
|
||||
direccion: "Av. Principal #123, Ciudad de Mexico",
|
||||
telefono: "55 1234 5678",
|
||||
email: "contacto@constructorademo.com",
|
||||
},
|
||||
});
|
||||
|
||||
console.log("Created empresa:", empresa.nombre);
|
||||
|
||||
// Create admin user
|
||||
const hashedPassword = await bcrypt.hash("admin123", 12);
|
||||
const adminUser = await prisma.user.create({
|
||||
data: {
|
||||
email: "admin@demo.com",
|
||||
password: hashedPassword,
|
||||
nombre: "Admin",
|
||||
apellido: "Demo",
|
||||
role: Role.ADMIN,
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log("Created admin user:", adminUser.email);
|
||||
|
||||
// Create supervisor user
|
||||
const supervisorUser = await prisma.user.create({
|
||||
data: {
|
||||
email: "supervisor@demo.com",
|
||||
password: hashedPassword,
|
||||
nombre: "Juan",
|
||||
apellido: "Supervisor",
|
||||
role: Role.SUPERVISOR,
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
});
|
||||
|
||||
// Create cliente
|
||||
const cliente = await prisma.cliente.create({
|
||||
data: {
|
||||
nombre: "Cliente Residencial SA",
|
||||
rfc: "CRS987654XYZ",
|
||||
direccion: "Calle Ejemplo #456",
|
||||
telefono: "55 9876 5432",
|
||||
email: "cliente@ejemplo.com",
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log("Created cliente:", cliente.nombre);
|
||||
|
||||
// Create obra
|
||||
const obra = await prisma.obra.create({
|
||||
data: {
|
||||
nombre: "Torre Residencial Norte",
|
||||
descripcion: "Proyecto de torre residencial de 20 pisos con amenidades",
|
||||
direccion: "Av. Reforma #500, CDMX",
|
||||
estado: EstadoObra.EN_PROGRESO,
|
||||
fechaInicio: new Date("2024-01-15"),
|
||||
fechaFinPrevista: new Date("2025-06-30"),
|
||||
porcentajeAvance: 35,
|
||||
presupuestoTotal: 15000000,
|
||||
gastoTotal: 5250000,
|
||||
empresaId: empresa.id,
|
||||
clienteId: cliente.id,
|
||||
supervisorId: supervisorUser.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log("Created obra:", obra.nombre);
|
||||
|
||||
// Create fases
|
||||
const fases = await Promise.all([
|
||||
prisma.faseObra.create({
|
||||
data: {
|
||||
nombre: "Cimentacion",
|
||||
descripcion: "Excavacion y cimentacion profunda",
|
||||
orden: 1,
|
||||
porcentajeAvance: 100,
|
||||
obraId: obra.id,
|
||||
},
|
||||
}),
|
||||
prisma.faseObra.create({
|
||||
data: {
|
||||
nombre: "Estructura",
|
||||
descripcion: "Construccion de estructura de concreto",
|
||||
orden: 2,
|
||||
porcentajeAvance: 60,
|
||||
obraId: obra.id,
|
||||
},
|
||||
}),
|
||||
prisma.faseObra.create({
|
||||
data: {
|
||||
nombre: "Instalaciones",
|
||||
descripcion: "Instalaciones electricas, hidraulicas y sanitarias",
|
||||
orden: 3,
|
||||
porcentajeAvance: 10,
|
||||
obraId: obra.id,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log("Created", fases.length, "fases");
|
||||
|
||||
// Create presupuesto
|
||||
const presupuesto = await prisma.presupuesto.create({
|
||||
data: {
|
||||
nombre: "Presupuesto Principal 2024",
|
||||
descripcion: "Presupuesto inicial aprobado",
|
||||
total: 15000000,
|
||||
aprobado: true,
|
||||
obraId: obra.id,
|
||||
},
|
||||
});
|
||||
|
||||
// Create partidas
|
||||
await Promise.all([
|
||||
prisma.partidaPresupuesto.create({
|
||||
data: {
|
||||
codigo: "CIM-001",
|
||||
descripcion: "Excavacion y cimentacion",
|
||||
unidad: "METRO_CUBICO",
|
||||
cantidad: 500,
|
||||
precioUnitario: 2500,
|
||||
total: 1250000,
|
||||
categoria: CategoriaGasto.MANO_DE_OBRA,
|
||||
presupuestoId: presupuesto.id,
|
||||
},
|
||||
}),
|
||||
prisma.partidaPresupuesto.create({
|
||||
data: {
|
||||
codigo: "EST-001",
|
||||
descripcion: "Concreto estructural",
|
||||
unidad: "METRO_CUBICO",
|
||||
cantidad: 2000,
|
||||
precioUnitario: 3500,
|
||||
total: 7000000,
|
||||
categoria: CategoriaGasto.MATERIALES,
|
||||
presupuestoId: presupuesto.id,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
// Create gastos
|
||||
const gastos = await Promise.all([
|
||||
prisma.gasto.create({
|
||||
data: {
|
||||
concepto: "Compra de cemento",
|
||||
descripcion: "500 toneladas de cemento Portland",
|
||||
monto: 1500000,
|
||||
fecha: new Date("2024-02-01"),
|
||||
categoria: CategoriaGasto.MATERIALES,
|
||||
estado: "APROBADO",
|
||||
obraId: obra.id,
|
||||
creadoPorId: adminUser.id,
|
||||
aprobadoPorId: adminUser.id,
|
||||
fechaAprobacion: new Date("2024-02-02"),
|
||||
},
|
||||
}),
|
||||
prisma.gasto.create({
|
||||
data: {
|
||||
concepto: "Renta de maquinaria",
|
||||
descripcion: "Excavadora y retroexcavadora",
|
||||
monto: 750000,
|
||||
fecha: new Date("2024-02-15"),
|
||||
categoria: CategoriaGasto.EQUIPOS,
|
||||
estado: "APROBADO",
|
||||
obraId: obra.id,
|
||||
creadoPorId: supervisorUser.id,
|
||||
aprobadoPorId: adminUser.id,
|
||||
fechaAprobacion: new Date("2024-02-16"),
|
||||
},
|
||||
}),
|
||||
prisma.gasto.create({
|
||||
data: {
|
||||
concepto: "Nomina trabajadores",
|
||||
descripcion: "Pago quincenal",
|
||||
monto: 500000,
|
||||
fecha: new Date("2024-03-01"),
|
||||
categoria: CategoriaGasto.MANO_DE_OBRA,
|
||||
estado: "PAGADO",
|
||||
obraId: obra.id,
|
||||
creadoPorId: adminUser.id,
|
||||
aprobadoPorId: adminUser.id,
|
||||
fechaAprobacion: new Date("2024-03-01"),
|
||||
},
|
||||
}),
|
||||
prisma.gasto.create({
|
||||
data: {
|
||||
concepto: "Compra de acero",
|
||||
descripcion: "Varilla corrugada",
|
||||
monto: 2000000,
|
||||
fecha: new Date("2024-03-15"),
|
||||
categoria: CategoriaGasto.MATERIALES,
|
||||
estado: "PENDIENTE",
|
||||
obraId: obra.id,
|
||||
creadoPorId: supervisorUser.id,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log("Created", gastos.length, "gastos");
|
||||
|
||||
// Create materiales
|
||||
const materiales = await Promise.all([
|
||||
prisma.material.create({
|
||||
data: {
|
||||
codigo: "CEM-001",
|
||||
nombre: "Cemento Portland",
|
||||
descripcion: "Cemento gris tipo I",
|
||||
unidad: "BOLSA",
|
||||
precioUnitario: 180,
|
||||
stockMinimo: 100,
|
||||
stockActual: 250,
|
||||
ubicacion: "Bodega A",
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
}),
|
||||
prisma.material.create({
|
||||
data: {
|
||||
codigo: "VAR-001",
|
||||
nombre: "Varilla corrugada 3/8",
|
||||
descripcion: "Varilla de acero corrugado",
|
||||
unidad: "PIEZA",
|
||||
precioUnitario: 120,
|
||||
stockMinimo: 500,
|
||||
stockActual: 1200,
|
||||
ubicacion: "Bodega B",
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
}),
|
||||
prisma.material.create({
|
||||
data: {
|
||||
codigo: "GRA-001",
|
||||
nombre: "Grava 3/4",
|
||||
descripcion: "Grava triturada",
|
||||
unidad: "METRO_CUBICO",
|
||||
precioUnitario: 450,
|
||||
stockMinimo: 50,
|
||||
stockActual: 30,
|
||||
ubicacion: "Patio",
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log("Created", materiales.length, "materiales");
|
||||
|
||||
// Create empleados
|
||||
const empleados = await Promise.all([
|
||||
prisma.empleado.create({
|
||||
data: {
|
||||
nombre: "Pedro",
|
||||
apellido: "Martinez",
|
||||
documento: "PEMA850101ABC",
|
||||
telefono: "55 1111 2222",
|
||||
puesto: "Maestro de Obra",
|
||||
salarioBase: 25000,
|
||||
fechaIngreso: new Date("2023-01-15"),
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
}),
|
||||
prisma.empleado.create({
|
||||
data: {
|
||||
nombre: "Maria",
|
||||
apellido: "Garcia",
|
||||
documento: "MAGA900520XYZ",
|
||||
telefono: "55 3333 4444",
|
||||
puesto: "Ingeniero Residente",
|
||||
salarioBase: 35000,
|
||||
fechaIngreso: new Date("2023-03-01"),
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
}),
|
||||
]);
|
||||
|
||||
console.log("Created", empleados.length, "empleados");
|
||||
|
||||
// Create subcontratistas
|
||||
await prisma.subcontratista.create({
|
||||
data: {
|
||||
nombre: "Instalaciones Electromecanicas SA",
|
||||
rfc: "IEL123456ABC",
|
||||
especialidad: "Instalaciones Electricas",
|
||||
telefono: "55 5555 6666",
|
||||
email: "contacto@ielsa.com",
|
||||
empresaId: empresa.id,
|
||||
},
|
||||
});
|
||||
|
||||
console.log("Seed completed successfully!");
|
||||
console.log("\nCredenciales de acceso:");
|
||||
console.log("Email: admin@demo.com");
|
||||
console.log("Password: admin123");
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error(e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(async () => {
|
||||
await prisma.$disconnect();
|
||||
});
|
||||
Reference in New Issue
Block a user