@@ -596,20 +596,63 @@ const TOOLS = [
596596 // ═══════════════════════════════════════════════════════════════════════════
597597 {
598598 name : 'update_work_order' ,
599- description : 'Update an existing work order.' ,
599+ description : 'Update an existing work order. Use to change status, assign technicians, add notes, update schedule. ' ,
600600 input_schema : {
601601 type : 'object' ,
602602 properties : {
603603 workOrderId : { type : 'number' , description : 'Work order ID' } ,
604604 title : { type : 'string' , description : 'New title' } ,
605605 description : { type : 'string' , description : 'New description' } ,
606- status : { type : 'string' , description : 'New status' } ,
606+ status : { type : 'string' , enum : [ 'pending' , 'scheduled' , 'in_progress' , 'completed' , 'cancelled' ] , description : 'New status' } ,
607607 priority : { type : 'string' , enum : [ 'low' , 'medium' , 'high' , 'urgent' ] } ,
608608 scheduledDate : { type : 'string' , description : 'Scheduled date (ISO 8601)' } ,
609+ assigneeId : { type : 'number' , description : 'User/technician ID to assign to this work order' } ,
610+ notes : { type : 'string' , description : 'Notes or comments to add to the work order' } ,
609611 } ,
610612 required : [ 'workOrderId' ] ,
611613 } ,
612614 } ,
615+ {
616+ name : 'assign_technician' ,
617+ description : 'Assign a technician to a work order. Shortcut for update_work_order with assignee.' ,
618+ input_schema : {
619+ type : 'object' ,
620+ properties : {
621+ workOrderId : { type : 'number' , description : 'Work order ID' } ,
622+ technicianId : { type : 'number' , description : 'Technician/user ID' } ,
623+ scheduledDate : { type : 'string' , description : 'Optional: Scheduled date (ISO 8601)' } ,
624+ } ,
625+ required : [ 'workOrderId' , 'technicianId' ] ,
626+ } ,
627+ } ,
628+ {
629+ name : 'convert_request_to_work_order' ,
630+ description : 'Convert a service request into a work order. Creates a work order linked to the request.' ,
631+ input_schema : {
632+ type : 'object' ,
633+ properties : {
634+ requestId : { type : 'number' , description : 'Service request ID to convert' } ,
635+ title : { type : 'string' , description : 'Work order title (defaults to request title)' } ,
636+ priority : { type : 'string' , enum : [ 'low' , 'medium' , 'high' , 'urgent' ] , description : 'Work order priority' } ,
637+ assigneeId : { type : 'number' , description : 'Optional: Technician to assign' } ,
638+ scheduledDate : { type : 'string' , description : 'Optional: Scheduled date' } ,
639+ } ,
640+ required : [ 'requestId' ] ,
641+ } ,
642+ } ,
643+ {
644+ name : 'add_work_order_note' ,
645+ description : 'Add a note or comment to an existing work order.' ,
646+ input_schema : {
647+ type : 'object' ,
648+ properties : {
649+ workOrderId : { type : 'number' , description : 'Work order ID' } ,
650+ note : { type : 'string' , description : 'Note content to add' } ,
651+ isInternal : { type : 'boolean' , description : 'Whether note is internal only (default: false)' } ,
652+ } ,
653+ required : [ 'workOrderId' , 'note' ] ,
654+ } ,
655+ } ,
613656 {
614657 name : 'delete_work_order' ,
615658 description : 'Delete a work order.' ,
@@ -1254,6 +1297,87 @@ async function executeTool(toolName: string, toolInput: Record<string, unknown>,
12541297 return JSON . stringify ( { success : true , work_order : result } ) ;
12551298 }
12561299
1300+ case 'assign_technician' : {
1301+ const { workOrderId, technicianId, scheduledDate } = toolInput ;
1302+ const updateData : Record < string , unknown > = { assigneeId : technicianId } ;
1303+ if ( scheduledDate ) updateData . scheduledDate = scheduledDate ;
1304+ if ( ! updateData . status ) updateData . status = 'scheduled' ; // Auto-set to scheduled when assigning
1305+
1306+ const result = await coperniqFetch ( `/work-orders/${ workOrderId } ` , apiKey , {
1307+ method : 'PATCH' ,
1308+ body : JSON . stringify ( updateData ) ,
1309+ } ) ;
1310+ return JSON . stringify ( { success : true , work_order : result , message : 'Technician assigned successfully' } ) ;
1311+ }
1312+
1313+ case 'convert_request_to_work_order' : {
1314+ const { requestId, title, priority, assigneeId, scheduledDate } = toolInput ;
1315+
1316+ // First, get the request details
1317+ const requestData = await coperniqFetch ( `/requests/${ requestId } ` , apiKey ) as Record < string , unknown > ;
1318+
1319+ // Create work order from request data
1320+ const workOrderData : Record < string , unknown > = {
1321+ title : title || requestData . title || `Work Order from Request #${ requestId } ` ,
1322+ description : requestData . description || '' ,
1323+ priority : priority || requestData . priority || 'medium' ,
1324+ requestId : requestId , // Link to original request
1325+ } ;
1326+
1327+ if ( assigneeId ) workOrderData . assigneeId = assigneeId ;
1328+ if ( scheduledDate ) {
1329+ workOrderData . scheduledDate = scheduledDate ;
1330+ workOrderData . status = 'scheduled' ;
1331+ }
1332+
1333+ // Create the work order
1334+ const workOrder = await coperniqFetch ( `/requests/${ requestId } /work-orders` , apiKey , {
1335+ method : 'POST' ,
1336+ body : JSON . stringify ( workOrderData ) ,
1337+ } ) ;
1338+
1339+ // Update request status to 'converted'
1340+ try {
1341+ await coperniqFetch ( `/requests/${ requestId } ` , apiKey , {
1342+ method : 'PATCH' ,
1343+ body : JSON . stringify ( { status : 'converted' } ) ,
1344+ } ) ;
1345+ } catch {
1346+ // Request status update is optional
1347+ }
1348+
1349+ return JSON . stringify ( {
1350+ success : true ,
1351+ work_order : workOrder ,
1352+ message : `Created work order from request #${ requestId } `
1353+ } ) ;
1354+ }
1355+
1356+ case 'add_work_order_note' : {
1357+ const { workOrderId, note, isInternal } = toolInput ;
1358+
1359+ // Try to add note via comments/notes endpoint, fallback to updating description
1360+ try {
1361+ const result = await coperniqFetch ( `/work-orders/${ workOrderId } /notes` , apiKey , {
1362+ method : 'POST' ,
1363+ body : JSON . stringify ( { content : note , isInternal : isInternal || false } ) ,
1364+ } ) ;
1365+ return JSON . stringify ( { success : true , note : result } ) ;
1366+ } catch {
1367+ // Fallback: Append to description
1368+ const workOrder = await coperniqFetch ( `/work-orders/${ workOrderId } ` , apiKey ) as Record < string , unknown > ;
1369+ const existingDesc = String ( workOrder . description || '' ) ;
1370+ const timestamp = new Date ( ) . toISOString ( ) ;
1371+ const newDesc = `${ existingDesc } \n\n[Note - ${ timestamp } ]: ${ note } ` ;
1372+
1373+ const result = await coperniqFetch ( `/work-orders/${ workOrderId } ` , apiKey , {
1374+ method : 'PATCH' ,
1375+ body : JSON . stringify ( { description : newDesc } ) ,
1376+ } ) ;
1377+ return JSON . stringify ( { success : true , work_order : result , message : 'Note added to description' } ) ;
1378+ }
1379+ }
1380+
12571381 case 'delete_work_order' : {
12581382 await coperniqFetch ( `/work-orders/${ toolInput . workOrderId } ` , apiKey , {
12591383 method : 'DELETE' ,
0 commit comments