[PROP-CORE-004] feat: Adapt AI roles for construction domain
- Roles: ADMIN, SUPERVISOR_OBRA, RESIDENTE, ALMACENISTA - Domain-specific tools (projects, progress, materials) - Construction industry terminology Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
0493d4b8bd
commit
058f42a4d1
@ -1,17 +1,17 @@
|
|||||||
/**
|
/**
|
||||||
* ERP Roles Configuration
|
* ERP Construcción - Roles Configuration
|
||||||
*
|
*
|
||||||
* Define roles, tools permitidos, y system prompts para cada rol en el ERP.
|
* Roles específicos para operaciones de construcción y obras.
|
||||||
* Basado en: michangarrito MCH-012/MCH-013 (role-based chatbot)
|
* Adaptado desde erp-core v1.5.0 (PROP-CORE-004)
|
||||||
*
|
*
|
||||||
* Roles disponibles:
|
* Roles:
|
||||||
* - ADMIN: Acceso completo a todas las operaciones
|
* - ADMIN: Gerente General - acceso completo
|
||||||
* - SUPERVISOR: Gestión de equipos y reportes de sucursal
|
* - SUPERVISOR_OBRA: Supervisor de obra - gestión de proyectos
|
||||||
* - OPERATOR: Operaciones de punto de venta
|
* - RESIDENTE: Residente de obra - operaciones en sitio
|
||||||
* - CUSTOMER: Acceso limitado para clientes (si se expone chatbot)
|
* - ALMACENISTA: Control de almacén y materiales
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export type ERPRole = 'ADMIN' | 'SUPERVISOR' | 'OPERATOR' | 'CUSTOMER';
|
export type ERPRole = 'ADMIN' | 'SUPERVISOR_OBRA' | 'RESIDENTE' | 'ALMACENISTA';
|
||||||
|
|
||||||
export interface ERPRoleConfig {
|
export interface ERPRoleConfig {
|
||||||
name: string;
|
name: string;
|
||||||
@ -19,234 +19,140 @@ export interface ERPRoleConfig {
|
|||||||
tools: string[];
|
tools: string[];
|
||||||
systemPromptFile: string;
|
systemPromptFile: string;
|
||||||
maxConversationHistory: number;
|
maxConversationHistory: number;
|
||||||
allowedModels?: string[]; // Si vacío, usa el default del tenant
|
allowedModels?: string[];
|
||||||
rateLimit: {
|
rateLimit: {
|
||||||
requestsPerMinute: number;
|
requestsPerMinute: number;
|
||||||
tokensPerMinute: number;
|
tokensPerMinute: number;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Configuración de roles ERP
|
|
||||||
*/
|
|
||||||
export const ERP_ROLES: Record<ERPRole, ERPRoleConfig> = {
|
export const ERP_ROLES: Record<ERPRole, ERPRoleConfig> = {
|
||||||
ADMIN: {
|
ADMIN: {
|
||||||
name: 'Administrador',
|
name: 'Gerente General',
|
||||||
description: 'Acceso completo a todas las operaciones del sistema ERP',
|
description: 'Gerente con acceso completo a todas las obras y operaciones',
|
||||||
tools: [
|
tools: [
|
||||||
// Ventas
|
// Proyectos/Obras
|
||||||
'get_sales_summary',
|
'get_projects_summary', 'get_project_status', 'get_project_budget',
|
||||||
'get_sales_report',
|
'approve_budget_change', 'get_all_projects',
|
||||||
'get_top_products',
|
|
||||||
'get_top_customers',
|
|
||||||
'get_sales_by_branch',
|
|
||||||
'create_sale',
|
|
||||||
'void_sale',
|
|
||||||
|
|
||||||
// Inventario
|
|
||||||
'get_inventory_status',
|
|
||||||
'get_low_stock_products',
|
|
||||||
'get_inventory_value',
|
|
||||||
'adjust_inventory',
|
|
||||||
'transfer_inventory',
|
|
||||||
|
|
||||||
// Compras
|
|
||||||
'get_pending_orders',
|
|
||||||
'get_supplier_info',
|
|
||||||
'create_purchase_order',
|
|
||||||
'approve_purchase',
|
|
||||||
|
|
||||||
// Finanzas
|
// Finanzas
|
||||||
'get_financial_report',
|
'get_financial_report', 'get_accounts_receivable', 'get_accounts_payable',
|
||||||
'get_accounts_receivable',
|
'get_cash_flow', 'get_kpis',
|
||||||
'get_accounts_payable',
|
// Compras
|
||||||
'get_cash_flow',
|
'get_pending_orders', 'get_supplier_info', 'create_purchase_order', 'approve_purchase',
|
||||||
|
// Inventario
|
||||||
// Usuarios y configuración
|
'get_inventory_status', 'get_inventory_value', 'transfer_inventory',
|
||||||
'manage_users',
|
// Configuración
|
||||||
'view_audit_logs',
|
'manage_users', 'view_audit_logs', 'update_settings',
|
||||||
'update_settings',
|
'get_branch_info', 'manage_branches',
|
||||||
'get_branch_info',
|
// Reportes
|
||||||
'manage_branches',
|
'generate_report', 'export_data',
|
||||||
|
// TPV
|
||||||
// Reportes avanzados
|
'configure_terminal', 'get_payment_history', 'process_refund',
|
||||||
'generate_report',
|
// Presupuestos
|
||||||
'export_data',
|
'get_estimates', 'approve_estimate',
|
||||||
'get_kpis',
|
|
||||||
],
|
],
|
||||||
systemPromptFile: 'admin-system-prompt',
|
systemPromptFile: 'admin-system-prompt',
|
||||||
maxConversationHistory: 50,
|
maxConversationHistory: 50,
|
||||||
rateLimit: {
|
rateLimit: { requestsPerMinute: 100, tokensPerMinute: 50000 },
|
||||||
requestsPerMinute: 100,
|
|
||||||
tokensPerMinute: 50000,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
SUPERVISOR: {
|
SUPERVISOR_OBRA: {
|
||||||
name: 'Supervisor',
|
name: 'Supervisor de Obra',
|
||||||
description: 'Gestión de equipos, reportes de sucursal y aprobaciones',
|
description: 'Supervisor con gestión de proyectos asignados y equipo',
|
||||||
tools: [
|
tools: [
|
||||||
// Ventas (lectura + acciones limitadas)
|
// Proyectos
|
||||||
'get_sales_summary',
|
'get_my_projects', 'get_project_status', 'update_project_progress',
|
||||||
'get_sales_report',
|
'get_project_budget', 'request_budget_change',
|
||||||
'get_top_products',
|
|
||||||
'get_sales_by_branch',
|
|
||||||
'create_sale',
|
|
||||||
|
|
||||||
// Inventario (lectura + ajustes)
|
|
||||||
'get_inventory_status',
|
|
||||||
'get_low_stock_products',
|
|
||||||
'adjust_inventory',
|
|
||||||
|
|
||||||
// Equipo
|
// Equipo
|
||||||
'get_team_performance',
|
'get_team_performance', 'get_worker_schedule', 'manage_schedules',
|
||||||
'get_employee_schedule',
|
// Compras (solicitud)
|
||||||
'manage_schedules',
|
'create_purchase_request', 'get_pending_requests',
|
||||||
|
// Inventario
|
||||||
// Aprobaciones
|
'get_inventory_status', 'request_materials', 'get_low_stock_products',
|
||||||
'approve_discounts',
|
// Sucursal/Obra
|
||||||
'approve_voids',
|
'get_branch_info', 'get_branch_report',
|
||||||
'approve_refunds',
|
// Avances
|
||||||
|
'register_progress', 'upload_evidence', 'get_progress_report',
|
||||||
// Sucursal
|
|
||||||
'get_branch_info',
|
|
||||||
'get_branch_report',
|
|
||||||
|
|
||||||
// Clientes
|
|
||||||
'get_customer_info',
|
|
||||||
'get_customer_balance',
|
|
||||||
],
|
],
|
||||||
systemPromptFile: 'supervisor-system-prompt',
|
systemPromptFile: 'supervisor-system-prompt',
|
||||||
maxConversationHistory: 30,
|
maxConversationHistory: 30,
|
||||||
rateLimit: {
|
rateLimit: { requestsPerMinute: 60, tokensPerMinute: 30000 },
|
||||||
requestsPerMinute: 60,
|
|
||||||
tokensPerMinute: 30000,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
OPERATOR: {
|
RESIDENTE: {
|
||||||
name: 'Operador',
|
name: 'Residente de Obra',
|
||||||
description: 'Operaciones de punto de venta y consultas básicas',
|
description: 'Residente con operaciones en sitio y registro de avances',
|
||||||
tools: [
|
tools: [
|
||||||
// Productos
|
// Avances
|
||||||
'search_products',
|
'register_daily_progress', 'upload_photos', 'register_incidents',
|
||||||
'get_product_price',
|
// Materiales
|
||||||
'check_product_availability',
|
'request_materials', 'confirm_material_receipt', 'check_stock',
|
||||||
|
// Personal
|
||||||
// Ventas
|
'register_attendance', 'get_daily_crew',
|
||||||
'create_sale',
|
|
||||||
'get_my_sales',
|
|
||||||
'apply_discount', // Con límite
|
|
||||||
|
|
||||||
// Clientes
|
|
||||||
'search_customers',
|
|
||||||
'get_customer_balance',
|
|
||||||
'register_payment',
|
|
||||||
|
|
||||||
// Inventario (solo lectura)
|
|
||||||
'check_stock',
|
|
||||||
|
|
||||||
// Información
|
// Información
|
||||||
'get_branch_hours',
|
'get_project_info', 'get_branch_hours', 'get_my_tasks',
|
||||||
'get_promotions',
|
// Comunicación
|
||||||
|
'report_issue', 'request_support',
|
||||||
],
|
],
|
||||||
systemPromptFile: 'operator-system-prompt',
|
systemPromptFile: 'operator-system-prompt',
|
||||||
maxConversationHistory: 20,
|
maxConversationHistory: 20,
|
||||||
rateLimit: {
|
rateLimit: { requestsPerMinute: 30, tokensPerMinute: 15000 },
|
||||||
requestsPerMinute: 30,
|
|
||||||
tokensPerMinute: 15000,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
CUSTOMER: {
|
ALMACENISTA: {
|
||||||
name: 'Cliente',
|
name: 'Almacenista',
|
||||||
description: 'Acceso limitado para clientes externos',
|
description: 'Control de almacén, recepción y despacho de materiales',
|
||||||
tools: [
|
tools: [
|
||||||
// Catálogo
|
// Inventario
|
||||||
'view_catalog',
|
'get_inventory_status', 'check_stock', 'adjust_inventory',
|
||||||
'search_products',
|
'register_material_entry', 'register_material_exit',
|
||||||
'check_availability',
|
// Recepción
|
||||||
|
'confirm_purchase_receipt', 'register_quality_inspection',
|
||||||
// Pedidos
|
// Despacho
|
||||||
'get_my_orders',
|
'prepare_dispatch', 'confirm_dispatch',
|
||||||
'track_order',
|
// Proveedores
|
||||||
|
'get_pending_deliveries', 'get_supplier_info',
|
||||||
// Cuenta
|
// Alertas
|
||||||
'get_my_balance',
|
'get_low_stock_products', 'get_expiring_materials',
|
||||||
'get_my_history',
|
|
||||||
|
|
||||||
// Soporte
|
|
||||||
'contact_support',
|
|
||||||
'get_store_info',
|
|
||||||
'get_promotions',
|
|
||||||
],
|
],
|
||||||
systemPromptFile: 'customer-system-prompt',
|
systemPromptFile: 'operator-system-prompt',
|
||||||
maxConversationHistory: 10,
|
maxConversationHistory: 20,
|
||||||
rateLimit: {
|
rateLimit: { requestsPerMinute: 30, tokensPerMinute: 15000 },
|
||||||
requestsPerMinute: 10,
|
|
||||||
tokensPerMinute: 5000,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Mapeo de rol de base de datos a ERPRole
|
|
||||||
*/
|
|
||||||
export const DB_ROLE_MAPPING: Record<string, ERPRole> = {
|
export const DB_ROLE_MAPPING: Record<string, ERPRole> = {
|
||||||
// Roles típicos de sistema
|
// Administradores
|
||||||
admin: 'ADMIN',
|
admin: 'ADMIN', administrator: 'ADMIN', gerente: 'ADMIN', owner: 'ADMIN',
|
||||||
administrator: 'ADMIN',
|
director: 'ADMIN',
|
||||||
superadmin: 'ADMIN',
|
|
||||||
owner: 'ADMIN',
|
|
||||||
|
|
||||||
// Supervisores
|
// Supervisores
|
||||||
supervisor: 'SUPERVISOR',
|
supervisor: 'SUPERVISOR_OBRA', supervisor_obra: 'SUPERVISOR_OBRA',
|
||||||
manager: 'SUPERVISOR',
|
project_manager: 'SUPERVISOR_OBRA', manager: 'SUPERVISOR_OBRA',
|
||||||
branch_manager: 'SUPERVISOR',
|
// Residentes
|
||||||
store_manager: 'SUPERVISOR',
|
residente: 'RESIDENTE', resident: 'RESIDENTE', operator: 'RESIDENTE',
|
||||||
|
ingeniero: 'RESIDENTE', field_engineer: 'RESIDENTE',
|
||||||
// Operadores
|
// Almacenistas
|
||||||
operator: 'OPERATOR',
|
almacenista: 'ALMACENISTA', warehouse: 'ALMACENISTA', bodeguero: 'ALMACENISTA',
|
||||||
cashier: 'OPERATOR',
|
storekeeper: 'ALMACENISTA',
|
||||||
sales: 'OPERATOR',
|
|
||||||
employee: 'OPERATOR',
|
|
||||||
staff: 'OPERATOR',
|
|
||||||
|
|
||||||
// Clientes
|
|
||||||
customer: 'CUSTOMER',
|
|
||||||
client: 'CUSTOMER',
|
|
||||||
guest: 'CUSTOMER',
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtener rol ERP desde rol de base de datos
|
|
||||||
*/
|
|
||||||
export function getERPRole(dbRole: string | undefined): ERPRole {
|
export function getERPRole(dbRole: string | undefined): ERPRole {
|
||||||
if (!dbRole) return 'CUSTOMER'; // Default para roles no mapeados
|
if (!dbRole) return 'RESIDENTE';
|
||||||
const normalized = dbRole.toLowerCase().trim();
|
const normalized = dbRole.toLowerCase().trim();
|
||||||
return DB_ROLE_MAPPING[normalized] || 'CUSTOMER';
|
return DB_ROLE_MAPPING[normalized] || 'RESIDENTE';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Verificar si un rol tiene acceso a un tool
|
|
||||||
*/
|
|
||||||
export function hasToolAccess(role: ERPRole, toolName: string): boolean {
|
export function hasToolAccess(role: ERPRole, toolName: string): boolean {
|
||||||
const roleConfig = ERP_ROLES[role];
|
const roleConfig = ERP_ROLES[role];
|
||||||
if (!roleConfig) return false;
|
if (!roleConfig) return false;
|
||||||
return roleConfig.tools.includes(toolName);
|
return roleConfig.tools.includes(toolName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtener todos los tools para un rol
|
|
||||||
*/
|
|
||||||
export function getToolsForRole(role: ERPRole): string[] {
|
export function getToolsForRole(role: ERPRole): string[] {
|
||||||
const roleConfig = ERP_ROLES[role];
|
const roleConfig = ERP_ROLES[role];
|
||||||
return roleConfig?.tools || [];
|
return roleConfig?.tools || [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtener configuración completa de un rol
|
|
||||||
*/
|
|
||||||
export function getRoleConfig(role: ERPRole): ERPRoleConfig | null {
|
export function getRoleConfig(role: ERPRole): ERPRoleConfig | null {
|
||||||
return ERP_ROLES[role] || null;
|
return ERP_ROLES[role] || null;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user