[PROP-CORE-004] feat: Adapt AI roles for retail domain

- Roles: ADMIN, GERENTE_TIENDA, CAJERO, CLIENTE
- Domain-specific tools per role (POS, sales, inventory)
- Retail terminology and Spanish names

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Adrian Flores Cortes 2026-01-25 02:57:42 -06:00
parent 9de89aab5a
commit 3514e6305c

View File

@ -1,17 +1,17 @@
/** /**
* ERP Roles Configuration * ERP Retail - Roles Configuration
* *
* Define roles, tools permitidos, y system prompts para cada rol en el ERP. * Roles específicos para operaciones de retail/comercio minorista.
* 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: Dueño/Gerente General - acceso completo
* - SUPERVISOR: Gestión de equipos y reportes de sucursal * - GERENTE_TIENDA: Gerente de sucursal - gestión de tienda
* - OPERATOR: Operaciones de punto de venta * - CAJERO: Operador de punto de venta
* - CUSTOMER: Acceso limitado para clientes (si se expone chatbot) * - CLIENTE: Cliente con acceso a pedidos y catálogo
*/ */
export type ERPRole = 'ADMIN' | 'SUPERVISOR' | 'OPERATOR' | 'CUSTOMER'; export type ERPRole = 'ADMIN' | 'GERENTE_TIENDA' | 'CAJERO' | 'CLIENTE';
export interface ERPRoleConfig { export interface ERPRoleConfig {
name: string; name: string;
@ -19,234 +19,138 @@ 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: 'Administrador',
description: 'Acceso completo a todas las operaciones del sistema ERP', description: 'Dueño o gerente general con acceso completo a todas las tiendas',
tools: [ tools: [
// Ventas // Ventas
'get_sales_summary', 'get_sales_summary', 'get_sales_report', 'get_top_products',
'get_sales_report', 'get_top_customers', 'get_sales_by_branch', 'create_sale', 'void_sale',
'get_top_products',
'get_top_customers',
'get_sales_by_branch',
'create_sale',
'void_sale',
// Inventario // Inventario
'get_inventory_status', 'get_inventory_status', 'get_low_stock_products', 'get_inventory_value',
'get_low_stock_products', 'adjust_inventory', 'transfer_inventory',
'get_inventory_value',
'adjust_inventory',
'transfer_inventory',
// Compras // Compras
'get_pending_orders', 'get_pending_orders', 'get_supplier_info', 'create_purchase_order', 'approve_purchase',
'get_supplier_info',
'create_purchase_order',
'approve_purchase',
// Finanzas // Finanzas
'get_financial_report', 'get_financial_report', 'get_accounts_receivable', 'get_accounts_payable', 'get_cash_flow',
'get_accounts_receivable', // Configuración
'get_accounts_payable', 'manage_users', 'view_audit_logs', 'update_settings',
'get_cash_flow', 'get_branch_info', 'manage_branches',
// Reportes
// Usuarios y configuración 'generate_report', 'export_data', 'get_kpis',
'manage_users', // TPV
'view_audit_logs', 'configure_terminal', 'get_payment_history', 'process_refund',
'update_settings',
'get_branch_info',
'manage_branches',
// Reportes avanzados
'generate_report',
'export_data',
'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: { GERENTE_TIENDA: {
name: 'Supervisor', name: 'Gerente de Tienda',
description: 'Gestión de equipos, reportes de sucursal y aprobaciones', description: 'Gerente de sucursal con gestión de equipo y operaciones de tienda',
tools: [ tools: [
// Ventas (lectura + acciones limitadas) // Ventas
'get_sales_summary', 'get_sales_summary', 'get_sales_report', 'get_top_products',
'get_sales_report', 'get_sales_by_branch', 'create_sale',
'get_top_products', // Inventario
'get_sales_by_branch', 'get_inventory_status', 'get_low_stock_products', 'adjust_inventory',
'create_sale',
// Inventario (lectura + ajustes)
'get_inventory_status',
'get_low_stock_products',
'adjust_inventory',
// Equipo // Equipo
'get_team_performance', 'get_team_performance', 'get_employee_schedule', 'manage_schedules',
'get_employee_schedule',
'manage_schedules',
// Aprobaciones // Aprobaciones
'approve_discounts', 'approve_discounts', 'approve_voids', 'approve_refunds',
'approve_voids',
'approve_refunds',
// Sucursal // Sucursal
'get_branch_info', 'get_branch_info', 'get_branch_report',
'get_branch_report',
// Clientes // Clientes
'get_customer_info', 'get_customer_info', 'get_customer_balance',
'get_customer_balance', // Caja
'open_cash_register', 'close_cash_register', 'get_cash_summary',
], ],
systemPromptFile: 'supervisor-system-prompt', systemPromptFile: 'supervisor-system-prompt',
maxConversationHistory: 30, maxConversationHistory: 30,
rateLimit: { rateLimit: { requestsPerMinute: 60, tokensPerMinute: 30000 },
requestsPerMinute: 60,
tokensPerMinute: 30000,
},
}, },
OPERATOR: { CAJERO: {
name: 'Operador', name: 'Cajero',
description: 'Operaciones de punto de venta y consultas básicas', description: 'Operador de punto de venta y atención al cliente',
tools: [ tools: [
// Productos // Productos
'search_products', 'search_products', 'get_product_price', 'check_product_availability',
'get_product_price',
'check_product_availability',
// Ventas // Ventas
'create_sale', 'create_sale', 'get_my_sales', 'apply_discount',
'get_my_sales',
'apply_discount', // Con límite
// Clientes // Clientes
'search_customers', 'search_customers', 'get_customer_balance', 'register_payment',
'get_customer_balance',
'register_payment',
// Inventario (solo lectura) // Inventario (solo lectura)
'check_stock', 'check_stock',
// Información // Información
'get_branch_hours', 'get_branch_hours', 'get_promotions',
'get_promotions', // TPV
'process_card_payment', 'process_cash_payment', 'print_receipt',
], ],
systemPromptFile: 'operator-system-prompt', systemPromptFile: 'operator-system-prompt',
maxConversationHistory: 20, maxConversationHistory: 20,
rateLimit: { rateLimit: { requestsPerMinute: 30, tokensPerMinute: 15000 },
requestsPerMinute: 30,
tokensPerMinute: 15000,
},
}, },
CUSTOMER: { CLIENTE: {
name: 'Cliente', name: 'Cliente',
description: 'Acceso limitado para clientes externos', description: 'Cliente con acceso a catálogo y sus pedidos',
tools: [ tools: [
// Catálogo // Catálogo
'view_catalog', 'view_catalog', 'search_products', 'check_availability',
'search_products',
'check_availability',
// Pedidos // Pedidos
'get_my_orders', 'get_my_orders', 'track_order',
'track_order',
// Cuenta // Cuenta
'get_my_balance', 'get_my_balance', 'get_my_history',
'get_my_history',
// Soporte // Soporte
'contact_support', 'contact_support', 'get_store_info', 'get_promotions',
'get_store_info',
'get_promotions',
], ],
systemPromptFile: 'customer-system-prompt', systemPromptFile: 'customer-system-prompt',
maxConversationHistory: 10, maxConversationHistory: 10,
rateLimit: { rateLimit: { requestsPerMinute: 10, tokensPerMinute: 5000 },
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', superadmin: 'ADMIN', owner: 'ADMIN',
administrator: 'ADMIN', // Gerentes de tienda
superadmin: 'ADMIN', gerente: 'GERENTE_TIENDA', gerente_tienda: 'GERENTE_TIENDA',
owner: 'ADMIN', store_manager: 'GERENTE_TIENDA', manager: 'GERENTE_TIENDA', supervisor: 'GERENTE_TIENDA',
branch_manager: 'GERENTE_TIENDA',
// Supervisores // Cajeros
supervisor: 'SUPERVISOR', cajero: 'CAJERO', cashier: 'CAJERO', operator: 'CAJERO',
manager: 'SUPERVISOR', vendedor: 'CAJERO', sales: 'CAJERO', employee: 'CAJERO', staff: 'CAJERO',
branch_manager: 'SUPERVISOR',
store_manager: 'SUPERVISOR',
// Operadores
operator: 'OPERATOR',
cashier: 'OPERATOR',
sales: 'OPERATOR',
employee: 'OPERATOR',
staff: 'OPERATOR',
// Clientes // Clientes
customer: 'CUSTOMER', cliente: 'CLIENTE', customer: 'CLIENTE', client: 'CLIENTE', guest: 'CLIENTE',
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 'CLIENTE';
const normalized = dbRole.toLowerCase().trim(); const normalized = dbRole.toLowerCase().trim();
return DB_ROLE_MAPPING[normalized] || 'CUSTOMER'; return DB_ROLE_MAPPING[normalized] || 'CLIENTE';
} }
/**
* 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;
} }