feat: add ordrestyring simulation runner
This commit is contained in:
173
scripts/run-ordrestyring-simulations.js
Normal file
173
scripts/run-ordrestyring-simulations.js
Normal file
@@ -0,0 +1,173 @@
|
||||
const path = require('path');
|
||||
const mysql = require('mysql2/promise');
|
||||
const databaseService = require('../backend/src/services/databaseService');
|
||||
const OrderSuggestionService = require('../backend/src/services/orderSuggestionService');
|
||||
|
||||
require('dotenv').config({
|
||||
path: path.join(__dirname, '..', 'backend/.env')
|
||||
});
|
||||
|
||||
const MAX_CASES = 9;
|
||||
|
||||
function ensureEnvVar(key) {
|
||||
if (!process.env[key]) {
|
||||
throw new Error(`Environment variable ${key} is required to run simulations`);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadRichCases(connection, limit = MAX_CASES * 2) {
|
||||
const [rows] = await connection.execute(
|
||||
`
|
||||
SELECT
|
||||
c.case_number,
|
||||
c.customer_number,
|
||||
c.description,
|
||||
c.remarks,
|
||||
c.status,
|
||||
COALESCE(c.updated_at, c.creation_date, c.created_at) AS latest_activity
|
||||
FROM ordrestyring_local.cases c
|
||||
WHERE c.case_number IS NOT NULL
|
||||
AND c.case_number <> ''
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM ordrestyring_local.hours h
|
||||
WHERE h.new_case_number = c.case_number
|
||||
AND h.new_case_number <> ''
|
||||
)
|
||||
AND EXISTS (
|
||||
SELECT 1
|
||||
FROM ordrestyring_local.case_materials m
|
||||
WHERE m.case_number = c.case_number
|
||||
AND m.case_number <> ''
|
||||
)
|
||||
ORDER BY GREATEST(
|
||||
CHAR_LENGTH(COALESCE(c.description, '')),
|
||||
CHAR_LENGTH(COALESCE(c.remarks, ''))
|
||||
) DESC,
|
||||
c.updated_at DESC
|
||||
LIMIT ?
|
||||
`,
|
||||
[limit]
|
||||
);
|
||||
|
||||
return rows;
|
||||
}
|
||||
|
||||
async function createSimulationProject(databaseService, caseRow) {
|
||||
const projectName = `Simulering: Ordrestyring sag ${caseRow.case_number}`;
|
||||
const description = `${caseRow.description || ''} ${caseRow.remarks || ''}`.trim() || 'Simuleret beskrivelse';
|
||||
const customerName = caseRow.customer_name || caseRow.customer_number || 'Ordrestyring kunde';
|
||||
const [result] = await databaseService.pool.execute(
|
||||
`
|
||||
INSERT INTO customer_projects (
|
||||
project_name,
|
||||
customer_name,
|
||||
customer_number,
|
||||
project_description
|
||||
) VALUES (?, ?, ?, ?)
|
||||
`,
|
||||
[
|
||||
projectName,
|
||||
customerName,
|
||||
caseRow.customer_number || null,
|
||||
description
|
||||
]
|
||||
);
|
||||
|
||||
const projectId = result.insertId;
|
||||
await databaseService.pool.execute(
|
||||
`
|
||||
INSERT INTO roof_geometry (
|
||||
project_id,
|
||||
roof_type,
|
||||
total_area,
|
||||
roof_pitch
|
||||
) VALUES (?, ?, ?, ?)
|
||||
`,
|
||||
[projectId, 'skraat_tag', 120, 30]
|
||||
);
|
||||
|
||||
return projectId;
|
||||
}
|
||||
|
||||
async function cleanupSimulationProject(databaseService, projectId) {
|
||||
await databaseService.pool.execute('DELETE FROM roof_geometry WHERE project_id = ?', [projectId]);
|
||||
await databaseService.pool.execute('DELETE FROM customer_projects WHERE id = ?', [projectId]);
|
||||
}
|
||||
|
||||
function summarizeSuggestion(suggestion) {
|
||||
const materialsCount = suggestion.materialsDraft.length;
|
||||
const laborHours = suggestion.laborDraft
|
||||
.reduce((sum, task) => sum + (Number(task.totalHours) || 0), 0);
|
||||
|
||||
return {
|
||||
recommendation: suggestion.recommendation?.recommendedPackage?.packageId || suggestion.recommendation?.recommendedPackage?.name || 'Ingen pakke',
|
||||
description: suggestion.recommendation?.descriptionDraft || suggestion.recommendation?.suggestedDescription || 'Ingen beskrivelse',
|
||||
materialsCount,
|
||||
laborHours: Number(laborHours.toFixed(2)),
|
||||
warnings: suggestion.recommendation?.warnings || [],
|
||||
clarifications: suggestion.recommendation?.clarifications || []
|
||||
};
|
||||
}
|
||||
|
||||
async function runSimulation() {
|
||||
ensureEnvVar('DB_PASSWORD');
|
||||
const ordrestyringConn = await mysql.createConnection({
|
||||
host: process.env.DB_HOST || '127.0.0.1',
|
||||
port: parseInt(process.env.DB_PORT, 10) || 3306,
|
||||
user: process.env.DB_USER || 'tilbudgivern_service',
|
||||
password: process.env.DB_PASSWORD,
|
||||
database: 'ordrestyring_local'
|
||||
});
|
||||
|
||||
await databaseService.initialize();
|
||||
const suggestionService = new OrderSuggestionService(databaseService);
|
||||
|
||||
const richCases = await loadRichCases(ordrestyringConn);
|
||||
const uniqueCases = [];
|
||||
const seenCases = new Set();
|
||||
for (const item of richCases) {
|
||||
if (!item.case_number || seenCases.has(item.case_number)) {
|
||||
continue;
|
||||
}
|
||||
seenCases.add(item.case_number);
|
||||
uniqueCases.push(item);
|
||||
}
|
||||
const selectedCases = uniqueCases.slice(0, MAX_CASES);
|
||||
console.log(`Fetched ${richCases.length} rows, simulating ${selectedCases.length} unique cases`);
|
||||
const results = [];
|
||||
|
||||
for (const caseRow of selectedCases) {
|
||||
console.log(`\n=== Simulerer case ${caseRow.case_number} (${caseRow.status || 'ukendt status'}) ===`);
|
||||
const projectId = await createSimulationProject(databaseService, caseRow);
|
||||
try {
|
||||
const suggestion = await suggestionService.getOrderSuggestions(projectId, { limit: 5 });
|
||||
const summary = summarizeSuggestion(suggestion);
|
||||
console.log(JSON.stringify({
|
||||
caseNumber: caseRow.case_number,
|
||||
summary,
|
||||
matches: suggestion.matches.map(match => ({
|
||||
source: match.sourceType,
|
||||
description: match.description || match.projectDescription || '',
|
||||
totalHours: match.totalHours,
|
||||
relevance: match.relevanceScore
|
||||
}))
|
||||
}, null, 2));
|
||||
results.push({ caseNumber: caseRow.case_number, summary });
|
||||
} catch (error) {
|
||||
console.error(`Fejl ved simulering af ${caseRow.case_number}:`, error.message);
|
||||
} finally {
|
||||
await cleanupSimulationProject(databaseService, projectId);
|
||||
}
|
||||
}
|
||||
|
||||
console.log('\n--- Simulationsoverblik ---');
|
||||
console.log(JSON.stringify(results, null, 2));
|
||||
await ordrestyringConn.end();
|
||||
await databaseService.pool.end();
|
||||
}
|
||||
|
||||
runSimulation().catch(error => {
|
||||
console.error('Simuleringsscript fejlede:', error.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user