Files

239 lines
9.3 KiB
TypeScript
Raw Permalink Normal View History

2026-02-04 00:11:19 +05:00
import { PrismaClient, Prisma } from '@prisma/client';
import * as bcrypt from 'bcrypt';
import * as fs from 'fs';
import * as path from 'path';
const prisma = new PrismaClient();
async function main() {
console.log('Starting database seed...');
// Clear existing data (order: children first)
await prisma.chatMessage.deleteMany();
await prisma.chatSession.deleteMany();
await prisma.estimateShare.deleteMany();
await prisma.estimateTotal.deleteMany();
await prisma.estimateItem.deleteMany();
await prisma.estimate.deleteMany();
await prisma.user.deleteMany();
await prisma.priceItem.deleteMany();
await prisma.priceTable.deleteMany();
await prisma.priceBook.deleteMany();
await prisma.coefficient.deleteMany();
await prisma.inflationIndex.deleteMany();
await prisma.surveyDirection.deleteMany();
await prisma.setting.deleteMany();
console.log('Cleared existing data');
// Admin user (логин: its@info.ru, пароль: Nemo348ax@)
const adminPasswordHash = await bcrypt.hash('Nemo348ax@', 10);
await prisma.user.create({
data: {
email: 'its@info.ru',
passwordHash: adminPasswordHash,
name: 'Админ',
},
});
console.log('Created admin user (its@info.ru / Nemo348ax@)');
// Demo user for development (email: demo@example.com, password: demo)
const demoPasswordHash = await bcrypt.hash('demo', 10);
await prisma.user.create({
data: {
email: 'demo@example.com',
passwordHash: demoPasswordHash,
name: 'Демо',
},
});
console.log('Created demo user (demo@example.com / demo)');
// Seed Survey Directions
const directions = await Promise.all([
prisma.surveyDirection.create({
data: {
code: 'geodesy',
name: 'Инженерно-геодезические изыскания',
shortName: 'Геодезия',
},
}),
prisma.surveyDirection.create({
data: {
code: 'geology',
name: 'Инженерно-геологические изыскания',
shortName: 'Геология',
},
}),
prisma.surveyDirection.create({
data: {
code: 'ecology',
name: 'Инженерно-экологические изыскания',
shortName: 'Экология',
},
}),
prisma.surveyDirection.create({
data: {
code: 'hydrology',
name: 'Инженерно-гидрометеорологические изыскания',
shortName: 'Гидрометеорология',
},
}),
]);
console.log(`Created ${directions.length} survey directions`);
// Seed Inflation Indices
const inflationIndices = await Promise.all([
prisma.inflationIndex.create({
data: {
baseDate: new Date('1991-01-01'),
effectiveFrom: new Date('2015-08-13'),
indexValue: new Prisma.Decimal(76.24),
documentRef: 'Письмо Минстроя и ЖКХ России № 25760-ЮР/08 от 13.08.2015г.',
isActive: true,
},
}),
prisma.inflationIndex.create({
data: {
baseDate: new Date('2001-01-01'),
effectiveFrom: new Date('2015-08-13'),
indexValue: new Prisma.Decimal(6.70),
documentRef: 'Письмо Минстроя и ЖКХ России № 25760-ЮР/08 от 13.08.2015г.',
isActive: true,
},
}),
]);
console.log(`Created ${inflationIndices.length} inflation indices`);
// Seed Coefficients
const coefficients = [
// Regional coefficients
{ type: 'regional', code: 'reg-1.08', name: 'Районный коэффициент 1.08', value: 1.08, description: 'К заработной плате 1.15' },
{ type: 'regional', code: 'reg-1.10', name: 'Районный коэффициент 1.10', value: 1.10, description: 'К заработной плате 1.20' },
{ type: 'regional', code: 'reg-1.15', name: 'Районный коэффициент 1.15', value: 1.15, description: 'К заработной плате 1.30' },
// Company coefficients
{ type: 'company', code: 'gazprom-544', name: 'Коэффициент ОАО «Газпром»', value: 1.00, description: '№544 от 26.12.2013 г.' },
{ type: 'company', code: 'geovector', name: 'Коэффициент ООО «ГеоВектор»', value: 0.2092, description: 'Коэффициент компании' },
// Special coefficients
{ type: 'special', code: 'computer-tech', name: 'Компьютерные технологии', value: 1.20, description: 'При выполнении камеральных работ с применением компьютерных технологий' },
{ type: 'special', code: 'night-work', name: 'Ночные работы', value: 1.35, description: 'При работе в ночное время (22:00-06:00)' },
{ type: 'special', code: 'special-regime', name: 'Специальный режим', value: 1.25, description: 'Территории со специальным режимом' },
];
for (const coef of coefficients) {
await prisma.coefficient.create({
data: {
type: coef.type,
code: coef.code,
name: coef.name,
value: new Prisma.Decimal(coef.value),
description: coef.description,
},
});
}
console.log(`Created ${coefficients.length} coefficients`);
// Seed Settings
const settings = [
{ key: 'default_executor', value: 'ООО "ГеоВектор"', type: 'string', category: 'company', label: 'Исполнитель по умолчанию' },
{ key: 'default_vat_rate', value: '20', type: 'number', category: 'company', label: 'Ставка НДС по умолчанию (%)' },
{ key: 'company_coefficient', value: '0.2092', type: 'number', category: 'company', label: 'Коэффициент компании' },
{ key: 'ai_provider', value: 'iieasy', type: 'string', category: 'ai', label: 'AI провайдер' },
{ key: 'iieasy_model', value: 'google/gemma-3n-e4b', type: 'string', category: 'ai', label: 'Модель iieasy' },
{ key: 'lmstudio_url', value: 'http://localhost:1234/v1', type: 'string', category: 'ai', label: 'URL LM Studio' },
];
for (const setting of settings) {
await prisma.setting.create({ data: setting });
}
console.log(`Created ${settings.length} settings`);
// Load and seed price books from JSON files
const dataDir = path.join(__dirname, '../../data/price-books');
// Load Geodesy price book
const geodesyPath = path.join(dataDir, 'geodesy-2004.json');
if (fs.existsSync(geodesyPath)) {
const geodesyData = JSON.parse(fs.readFileSync(geodesyPath, 'utf-8'));
await seedPriceBook(geodesyData);
console.log('Loaded geodesy-2004 price book');
}
// Load Geology price book
const geologyPath = path.join(dataDir, 'geology-ecology-1999.json');
if (fs.existsSync(geologyPath)) {
const geologyData = JSON.parse(fs.readFileSync(geologyPath, 'utf-8'));
await seedPriceBook(geologyData);
console.log('Loaded geology-ecology-1999 price book');
}
console.log('Database seeding completed!');
}
async function seedPriceBook(data: any) {
const priceBook = await prisma.priceBook.create({
data: {
code: data.priceBook.code,
name: data.priceBook.name,
baseDate: new Date(data.priceBook.baseDate),
approvedBy: data.priceBook.approvedBy,
effectiveDate: data.priceBook.effectiveDate ? new Date(data.priceBook.effectiveDate) : null,
},
});
for (const table of data.tables) {
const priceTable = await prisma.priceTable.create({
data: {
priceBookId: priceBook.id,
tableNumber: table.tableNumber,
name: table.name,
unit: table.unit,
notes: table.notes || null,
},
});
for (const item of table.items) {
await prisma.priceItem.create({
data: {
priceBookId: priceBook.id,
priceTableId: priceTable.id,
paragraph: item.paragraph,
workType: item.workType || item.networkType || item.type || `Таблица ${table.tableNumber}`,
description: item.description || null,
priceField1: item.category1Field ?? item.cat1 ?? item.undevelopedField ?? null,
priceOffice1: item.category1Office ?? item.undevelopedOffice ?? null,
priceField2: item.category2Field ?? item.cat2 ?? item.builtUpField ?? null,
priceOffice2: item.category2Office ?? item.builtUpOffice ?? null,
priceField3: item.category3Field ?? item.cat3 ?? item.industrialField ?? null,
priceOffice3: item.category3Office ?? item.industrialOffice ?? null,
priceSimple: item.price ?? item.fieldPrice ?? null,
attributes: {
scale: item.scale,
category: item.category,
reliefHeight: item.reliefHeight,
depth: item.depth,
diameter: item.diameter,
accuracy: item.accuracy,
passability: item.passability,
...item,
},
},
});
}
}
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});