Add three new NestJS modules following DDD/CQRS architecture: - Industrial: KCN (industrial park) management with PostGIS geo queries, Typesense search, and market statistics - Transfer: Furniture/premises transfer listings with AI-powered price estimation and depreciation modeling - Reports: Async AI report generation via BullMQ with Claude narrative service, PDF generation, and macro data integration Includes Prisma schema models, migrations, seed scripts, and app.module wiring with BullMQ Redis config. Co-Authored-By: Paperclip <noreply@paperclip.ing>
117 lines
8.0 KiB
TypeScript
117 lines
8.0 KiB
TypeScript
import { PrismaClient } from '@prisma/client';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function main() {
|
|
console.log('Seeding macroeconomic data...');
|
|
|
|
// ─── Macroeconomic Data ────────────────────────────────
|
|
const macroData = [
|
|
// Ho Chi Minh City
|
|
{ province: 'Hồ Chí Minh', indicator: 'gdp', value: 1680000, unit: 'tỷ VND', period: '2025', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'gdp', value: 1550000, unit: 'tỷ VND', period: '2024', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'gdp', value: 1420000, unit: 'tỷ VND', period: '2023', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'fdi', value: 8200, unit: 'triệu USD', period: '2025', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'fdi', value: 7500, unit: 'triệu USD', period: '2024', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'population', value: 10200000, unit: 'người', period: '2025', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'urbanization', value: 87.5, unit: '%', period: '2025', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'labor_force', value: 5100000, unit: 'người', period: '2025', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'avg_wage', value: 420, unit: 'USD/tháng', period: '2025', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'cpi', value: 4.2, unit: '%', period: '2025', source: 'GSO' },
|
|
{ province: 'Hồ Chí Minh', indicator: 'mortgage_rate', value: 8.5, unit: '%', period: '2025', source: 'SBV' },
|
|
|
|
// Binh Duong
|
|
{ province: 'Bình Dương', indicator: 'gdp', value: 480000, unit: 'tỷ VND', period: '2025', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'gdp', value: 440000, unit: 'tỷ VND', period: '2024', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'gdp', value: 405000, unit: 'tỷ VND', period: '2023', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'fdi', value: 3800, unit: 'triệu USD', period: '2025', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'fdi', value: 3500, unit: 'triệu USD', period: '2024', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'population', value: 2800000, unit: 'người', period: '2025', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'urbanization', value: 82.0, unit: '%', period: '2025', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'labor_force', value: 1600000, unit: 'người', period: '2025', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'avg_wage', value: 350, unit: 'USD/tháng', period: '2025', source: 'GSO' },
|
|
{ province: 'Bình Dương', indicator: 'industrial_output', value: 380000, unit: 'tỷ VND', period: '2025', source: 'GSO' },
|
|
|
|
// Dong Nai
|
|
{ province: 'Đồng Nai', indicator: 'gdp', value: 420000, unit: 'tỷ VND', period: '2025', source: 'GSO' },
|
|
{ province: 'Đồng Nai', indicator: 'gdp', value: 385000, unit: 'tỷ VND', period: '2024', source: 'GSO' },
|
|
{ province: 'Đồng Nai', indicator: 'fdi', value: 4200, unit: 'triệu USD', period: '2025', source: 'GSO' },
|
|
{ province: 'Đồng Nai', indicator: 'population', value: 3250000, unit: 'người', period: '2025', source: 'GSO' },
|
|
{ province: 'Đồng Nai', indicator: 'labor_force', value: 1800000, unit: 'người', period: '2025', source: 'GSO' },
|
|
{ province: 'Đồng Nai', indicator: 'avg_wage', value: 340, unit: 'USD/tháng', period: '2025', source: 'GSO' },
|
|
{ province: 'Đồng Nai', indicator: 'industrial_output', value: 350000, unit: 'tỷ VND', period: '2025', source: 'GSO' },
|
|
|
|
// Ha Noi
|
|
{ province: 'Hà Nội', indicator: 'gdp', value: 1250000, unit: 'tỷ VND', period: '2025', source: 'GSO' },
|
|
{ province: 'Hà Nội', indicator: 'fdi', value: 6500, unit: 'triệu USD', period: '2025', source: 'GSO' },
|
|
{ province: 'Hà Nội', indicator: 'population', value: 8600000, unit: 'người', period: '2025', source: 'GSO' },
|
|
{ province: 'Hà Nội', indicator: 'urbanization', value: 72.0, unit: '%', period: '2025', source: 'GSO' },
|
|
{ province: 'Hà Nội', indicator: 'mortgage_rate', value: 8.5, unit: '%', period: '2025', source: 'SBV' },
|
|
];
|
|
|
|
for (const d of macroData) {
|
|
await prisma.macroeconomicData.upsert({
|
|
where: { province_indicator_period: { province: d.province, indicator: d.indicator, period: d.period } },
|
|
create: d,
|
|
update: { value: d.value, unit: d.unit, source: d.source },
|
|
});
|
|
}
|
|
console.log(` Seeded ${macroData.length} macroeconomic data points.`);
|
|
|
|
// ─── Infrastructure Projects ───────────────────────────
|
|
console.log('Seeding infrastructure projects...');
|
|
|
|
const infraProjects = [
|
|
{ name: 'Metro Bến Thành - Suối Tiên (Line 1)', province: 'Hồ Chí Minh', category: 'metro', status: 'under_construction', investmentVND: BigInt(43_700_000_000_000), description: '19.7km, 14 ga, dự kiến vận hành 2024-2025' },
|
|
{ name: 'Metro Bến Thành - Tham Lương (Line 2)', province: 'Hồ Chí Minh', category: 'metro', status: 'planning', investmentVND: BigInt(47_800_000_000_000), description: '11.3km, 10 ga' },
|
|
{ name: 'Cao tốc TP.HCM - Long Thành - Dầu Giây (mở rộng)', province: 'Hồ Chí Minh', category: 'highway', status: 'under_construction', investmentVND: BigInt(9_000_000_000_000), description: 'Mở rộng lên 8-10 làn' },
|
|
{ name: 'Sân bay Long Thành - Giai đoạn 1', province: 'Đồng Nai', category: 'airport', status: 'under_construction', investmentVND: BigInt(109_000_000_000_000), description: 'Công suất 25 triệu HK/năm' },
|
|
{ name: 'Cảng Cái Mép - Thị Vải (mở rộng)', province: 'Bà Rịa - Vũng Tàu', category: 'port', status: 'completed', investmentVND: BigInt(12_000_000_000_000), description: 'Cảng container nước sâu lớn nhất VN' },
|
|
{ name: 'Vành đai 3 TP.HCM', province: 'Hồ Chí Minh', category: 'highway', status: 'under_construction', investmentVND: BigInt(75_400_000_000_000), description: '76km qua 4 tỉnh thành' },
|
|
{ name: 'Cao tốc Bến Lức - Long Thành', province: 'Đồng Nai', category: 'highway', status: 'under_construction', investmentVND: BigInt(31_300_000_000_000), description: '57.8km, kết nối BD-DN' },
|
|
{ name: 'Metro Nhổn - Ga Hà Nội (Line 3)', province: 'Hà Nội', category: 'metro', status: 'under_construction', investmentVND: BigInt(34_800_000_000_000), description: '12.5km' },
|
|
{ name: 'Đường sắt tốc độ cao Bắc Nam (GĐ1)', province: 'Hà Nội', category: 'railway', status: 'planning', investmentVND: BigInt(670_000_000_000_000), description: 'HN-Vinh & NhaTrang-TPHCM' },
|
|
{ name: 'Cao tốc Mỹ Phước - Tân Vạn (mở rộng)', province: 'Bình Dương', category: 'highway', status: 'under_construction', investmentVND: BigInt(4_500_000_000_000), description: 'Kết nối KCN Bình Dương' },
|
|
];
|
|
|
|
for (const p of infraProjects) {
|
|
const existing = await prisma.infrastructureProject.findFirst({
|
|
where: { name: p.name, province: p.province },
|
|
});
|
|
if (!existing) {
|
|
await prisma.infrastructureProject.create({ data: p });
|
|
}
|
|
}
|
|
console.log(` Seeded ${infraProjects.length} infrastructure projects.`);
|
|
|
|
// ─── Update Plan maxReports ────────────────────────────
|
|
console.log('Updating plan quotas for reports...');
|
|
|
|
await prisma.plan.updateMany({
|
|
where: { tier: 'FREE' },
|
|
data: { maxReports: 0 },
|
|
});
|
|
await prisma.plan.updateMany({
|
|
where: { tier: 'AGENT_PRO' },
|
|
data: { maxReports: 2 },
|
|
});
|
|
await prisma.plan.updateMany({
|
|
where: { tier: 'INVESTOR' },
|
|
data: { maxReports: 5 },
|
|
});
|
|
await prisma.plan.updateMany({
|
|
where: { tier: 'ENTERPRISE' },
|
|
data: { maxReports: 999 },
|
|
});
|
|
console.log(' Plan quotas updated.');
|
|
|
|
console.log('Done!');
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
})
|
|
.finally(() => prisma.$disconnect());
|