195 lines
6.1 KiB
JavaScript
195 lines
6.1 KiB
JavaScript
/**
|
|
* Prompt Loader
|
|
*
|
|
* Utilities to load AI prompts from the ai_prompts PostgreSQL table.
|
|
* Supports loading prompts by base type (e.g., 'name_validation' loads
|
|
* name_validation_system, name_validation_general, and optionally
|
|
* name_validation_company_specific).
|
|
*/
|
|
|
|
/**
|
|
* Load a single prompt by exact type
|
|
* @param {Object} pool - PostgreSQL pool
|
|
* @param {string} promptType - Exact prompt type (e.g., 'name_validation_system')
|
|
* @param {string} [company] - Company identifier (for company_specific types)
|
|
* @returns {Promise<string|null>} Prompt text or null if not found
|
|
*/
|
|
async function loadPromptByType(pool, promptType, company = null) {
|
|
try {
|
|
let result;
|
|
|
|
if (company) {
|
|
result = await pool.query(
|
|
'SELECT prompt_text FROM ai_prompts WHERE prompt_type = $1 AND company = $2',
|
|
[promptType, company]
|
|
);
|
|
} else {
|
|
result = await pool.query(
|
|
'SELECT prompt_text FROM ai_prompts WHERE prompt_type = $1 AND company IS NULL',
|
|
[promptType]
|
|
);
|
|
}
|
|
|
|
return result.rows[0]?.prompt_text || null;
|
|
} catch (error) {
|
|
console.error(`[PromptLoader] Error loading ${promptType} prompt:`, error.message);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load all prompts for a task type (system, general, and optionally company-specific)
|
|
*
|
|
* @param {Object} pool - PostgreSQL pool
|
|
* @param {string} baseType - Base type name (e.g., 'name_validation', 'description_validation')
|
|
* @param {string|null} [company] - Optional company ID for company-specific prompts
|
|
* @returns {Promise<{system: string|null, general: string|null, companySpecific: string|null}>}
|
|
*/
|
|
async function loadPromptsByType(pool, baseType, company = null) {
|
|
const systemType = `${baseType}_system`;
|
|
const generalType = `${baseType}_general`;
|
|
const companyType = `${baseType}_company_specific`;
|
|
|
|
// Load system and general prompts in parallel
|
|
const [system, general] = await Promise.all([
|
|
loadPromptByType(pool, systemType),
|
|
loadPromptByType(pool, generalType)
|
|
]);
|
|
|
|
// Load company-specific prompt if company is provided
|
|
let companySpecific = null;
|
|
if (company) {
|
|
companySpecific = await loadPromptByType(pool, companyType, company);
|
|
}
|
|
|
|
return {
|
|
system,
|
|
general,
|
|
companySpecific
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Load name validation prompts
|
|
* @param {Object} pool - PostgreSQL pool
|
|
* @param {string|null} [company] - Optional company ID
|
|
* @returns {Promise<{system: string|null, general: string|null, companySpecific: string|null}>}
|
|
*/
|
|
async function loadNameValidationPrompts(pool, company = null) {
|
|
return loadPromptsByType(pool, 'name_validation', company);
|
|
}
|
|
|
|
/**
|
|
* Load description validation prompts
|
|
* @param {Object} pool - PostgreSQL pool
|
|
* @param {string|null} [company] - Optional company ID
|
|
* @returns {Promise<{system: string|null, general: string|null, companySpecific: string|null}>}
|
|
*/
|
|
async function loadDescriptionValidationPrompts(pool, company = null) {
|
|
return loadPromptsByType(pool, 'description_validation', company);
|
|
}
|
|
|
|
/**
|
|
* Load sanity check prompts (no company-specific variant)
|
|
* @param {Object} pool - PostgreSQL pool
|
|
* @returns {Promise<{system: string|null, general: string|null, companySpecific: null}>}
|
|
*/
|
|
async function loadSanityCheckPrompts(pool) {
|
|
return loadPromptsByType(pool, 'sanity_check', null);
|
|
}
|
|
|
|
/**
|
|
* Load bulk validation prompts (GPT-5 validation)
|
|
* @param {Object} pool - PostgreSQL pool
|
|
* @param {string|null} [company] - Optional company ID
|
|
* @returns {Promise<{system: string|null, general: string|null, companySpecific: string|null}>}
|
|
*/
|
|
async function loadBulkValidationPrompts(pool, company = null) {
|
|
return loadPromptsByType(pool, 'bulk_validation', company);
|
|
}
|
|
|
|
/**
|
|
* Load bulk validation prompts for multiple companies at once
|
|
* @param {Object} pool - PostgreSQL pool
|
|
* @param {string[]} companyIds - Array of company IDs
|
|
* @returns {Promise<{system: string|null, general: string|null, companyPrompts: Map<string, string>}>}
|
|
*/
|
|
async function loadBulkValidationPromptsForCompanies(pool, companyIds = []) {
|
|
// Load system and general prompts
|
|
const [system, general] = await Promise.all([
|
|
loadPromptByType(pool, 'bulk_validation_system'),
|
|
loadPromptByType(pool, 'bulk_validation_general')
|
|
]);
|
|
|
|
// Load company-specific prompts for all provided companies
|
|
const companyPrompts = new Map();
|
|
|
|
if (companyIds.length > 0) {
|
|
try {
|
|
const result = await pool.query(
|
|
`SELECT company, prompt_text FROM ai_prompts
|
|
WHERE prompt_type = 'bulk_validation_company_specific'
|
|
AND company = ANY($1)`,
|
|
[companyIds]
|
|
);
|
|
|
|
for (const row of result.rows) {
|
|
companyPrompts.set(row.company, row.prompt_text);
|
|
}
|
|
} catch (error) {
|
|
console.error('[PromptLoader] Error loading company-specific prompts:', error.message);
|
|
}
|
|
}
|
|
|
|
return {
|
|
system,
|
|
general,
|
|
companyPrompts
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Validate that required prompts exist, throw error if missing
|
|
* @param {Object} prompts - Prompts object from loadPromptsByType
|
|
* @param {string} baseType - Base type for error messages
|
|
* @param {Object} options - Validation options
|
|
* @param {boolean} [options.requireSystem=true] - Require system prompt
|
|
* @param {boolean} [options.requireGeneral=true] - Require general prompt
|
|
* @throws {Error} If required prompts are missing
|
|
*/
|
|
function validateRequiredPrompts(prompts, baseType, options = {}) {
|
|
const { requireSystem = true, requireGeneral = true } = options;
|
|
const missing = [];
|
|
|
|
if (requireSystem && !prompts.system) {
|
|
missing.push(`${baseType}_system`);
|
|
}
|
|
|
|
if (requireGeneral && !prompts.general) {
|
|
missing.push(`${baseType}_general`);
|
|
}
|
|
|
|
if (missing.length > 0) {
|
|
throw new Error(
|
|
`Missing required AI prompts: ${missing.join(', ')}. ` +
|
|
`Please add these prompts in Settings > AI Validation Prompts.`
|
|
);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
// Core loader
|
|
loadPromptByType,
|
|
loadPromptsByType,
|
|
|
|
// Task-specific loaders
|
|
loadNameValidationPrompts,
|
|
loadDescriptionValidationPrompts,
|
|
loadSanityCheckPrompts,
|
|
loadBulkValidationPrompts,
|
|
loadBulkValidationPromptsForCompanies,
|
|
|
|
// Validation
|
|
validateRequiredPrompts
|
|
};
|