diff --git a/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts b/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts index 81ac8469..6c023c66 100644 --- a/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts +++ b/src/common/Api/LeCoffreApi/sdk/CollaboratorService.ts @@ -4,9 +4,6 @@ import User from 'src/sdk/User'; import AbstractService from './AbstractService'; -import OfficeService from './OfficeService'; -import RoleService from './RoleService'; -import OfficeRoleService from './OfficeRoleService'; import { DEFAULT_STORAGE_URLS } from '@Front/Config/AppConstants'; export default class CollaboratorService extends AbstractService { @@ -15,7 +12,7 @@ export default class CollaboratorService extends AbstractService { super(); } - public static createCollaborator(collaboratorData: any, validatorId: string): Promise { + public static async createCollaborator(collaboratorData: any, validatorId: string): Promise<{ processId: string, processData: any }> { const ownerId: string = User.getInstance().getPairingId()!; const processData: any = { @@ -28,134 +25,85 @@ export default class CollaboratorService extends AbstractService { }; const privateFields: string[] = Object.keys(processData); - privateFields.splice(privateFields.indexOf('uid'), 1); - privateFields.splice(privateFields.indexOf('utype'), 1); - privateFields.splice(privateFields.indexOf('isDeleted'), 1); + const allFields: string[] = [...privateFields, 'roles']; const roles: any = { demiurge: { - members: [ownerId], + members: [ownerId, validatorId], validation_rules: [], storages: [] }, owner: { - members: [ownerId], + members: [ownerId, validatorId], validation_rules: [ { - quorum: 1, - fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'], - min_sig_member: 1, - }, - ], - storages: [...DEFAULT_STORAGE_URLS] - }, - validator: { - members: [validatorId], - validation_rules: [ - { - quorum: 1, - fields: [...privateFields, 'roles', 'uid', 'utype', 'isDeleted'], - min_sig_member: 1, + quorum: 0.01, + fields: allFields, + min_sig_member: 0.01, }, ], storages: [...DEFAULT_STORAGE_URLS] }, apophis: { - members: [ownerId], + members: [ownerId, validatorId], validation_rules: [], storages: [] } }; - return new Promise((resolve: (processCreated: any) => void, reject: (error: string) => void) => { - this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => { - this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => { - this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => { - this.getCollaboratorByUid(processCreated.processData.uid).then(resolve).catch(reject); - }).catch(reject); - }).catch(reject); - }).catch(reject); - }); + try { + const processCreated = await this.messageBus.createProcess(processData, privateFields, roles); + await this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id); + await this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id); + const finalProcessData = await this.messageBus.getProcessData(processCreated.processId); + return { processId: processCreated.processId, processData: finalProcessData }; + } catch (error) { + throw error; + } } - public static getCollaborators(callback: (processes: any[]) => void, waitForAll: boolean = false): void { - // Check if we have valid cache - const items: any[] = this.getItems('_collaborators_'); - if (items.length > 0 && !waitForAll) { - setTimeout(() => callback([...items]), 0); + public static getCollaborators(callback: (processes: Record) => void): void { + const items: Record = this.getItems('_collaborators_'); + if (Object.keys(items).length > 0) { + setTimeout(() => callback(items), 0); } - this.messageBus.getProcessesDecoded((publicValues: any) => - publicValues['uid'] && - publicValues['utype'] && - publicValues['utype'] === 'collaborator' && - publicValues['isDeleted'] && - publicValues['isDeleted'] === 'false' && - !items.map((item: any) => item.processData.uid).includes(publicValues['uid']) - ).then(async (processes: any[]) => { - if (processes.length === 0) { - if (waitForAll) { - callback([...items]); + this.messageBus.getProcessesDecoded((processId: string, data: any) => + data['utype'] && + data['utype'] === 'collaborator' && + data['isDeleted'] && + data['isDeleted'] === 'false' && + !Object.keys(items).includes(processId) + ).then(async (processesData: Record) => { + if (Object.keys(processesData).length === 0) { + // If no new processes and no cached items, return empty array + if (Object.keys(items).length === 0) { + callback([]); } return; } - const updatedItems: any[] = [...items]; - - for (let processIndex = 0; processIndex < processes.length; processIndex++) { - let process = processes[processIndex]; - - if (!waitForAll) { - process = await this.completeCollaborator(process, (processInProgress: any) => { - const currentItems: any[] = [...updatedItems]; - - const existingIndex: number = currentItems.findIndex(item => item.processData?.uid === processInProgress.processData?.uid); - if (existingIndex >= 0) { - currentItems[existingIndex] = processInProgress; - } else { - currentItems.push(processInProgress); - } - - callback(currentItems); - }); - } else { - process = await this.completeCollaborator(process); - } - - // Update cache - this.setItem('_collaborators_', process); - - const existingIndex: number = updatedItems.findIndex(item => item.processData?.uid === process.processData?.uid); - if (existingIndex >= 0) { - updatedItems[existingIndex] = process; - } else { - updatedItems.push(process); - } - - if (!waitForAll) { - callback([...updatedItems]); - } - } - - if (waitForAll) { - callback([...updatedItems]); - } + // Single callback with all completed items + callback(items); + }).catch(error => { + console.error('Failed to fetch collaborators:', error); + // Return cached data if available, otherwise empty array + callback(items); }); } - public static getCollaboratorsBy(whereClause: { [path: string]: any }): Promise { - return new Promise((resolve: (collaborators: any[]) => void) => { - this.getCollaborators((processes: any[]) => { - if (processes.length === 0) { - resolve([]); + public static getCollaboratorsBy(whereClause: { [path: string]: any }): Promise> { + return new Promise>((resolve: (collaborators: Record) => void) => { + this.getCollaborators((processes: Record) => { + if (Object.keys(processes).length === 0) { + resolve({}); } else { - resolve(processes.filter((process: any) => { - const collaborator: any = process.processData; - + const filteredEntries = Object.entries(processes).filter(([processId, process]) => { for (const path in whereClause) { const paths: string[] = path.split('.'); - let value: any = collaborator; + let value: any = process; + value['processId'] = processId; for (let i = 0; i < paths.length; i++) { const currentPath = paths[i]; if (!currentPath || value === undefined || value === null) { @@ -170,19 +118,28 @@ export default class CollaboratorService extends AbstractService { } return true; - })); + }); + + // Convert filtered entries back to a Record + const filteredProcesses: Record = {}; + filteredEntries.forEach(([processId, process]) => { + filteredProcesses[processId] = process; + }); + + resolve(filteredProcesses); } - }, true); + }); }); } public static getCollaboratorBy(whereClause: { [path: string]: any }): Promise { return new Promise((resolve: (collaborator: any | null) => void) => { - this.getCollaborators((processes: any[]) => { - if (processes.length === 0) { + this.getCollaborators((processes: Record) => { + const processArray = Object.values(processes); + if (processArray.length === 0) { resolve(null); } else { - resolve(processes.find((process: any) => { + resolve(processArray.find((process: any) => { const collaborator: any = process.processData; for (const path in whereClause) { @@ -205,120 +162,30 @@ export default class CollaboratorService extends AbstractService { return true; })); } - }, true); + }); }); } - public static getCollaboratorByUid(uid: string, forceRefresh: boolean = false): Promise { - // Check if we have valid cache - const item: any = this.getItem('_collaborators_', uid); - if (item && !forceRefresh) { - return Promise.resolve(item); + public static async updateCollaborator(processId: string, newData: any): Promise { + try { + const processUpdated = await this.messageBus.updateProcess( + processId, + { updated_at: new Date().toISOString(), ...newData }, + [], + null + ); + + const newStateId: string = processUpdated.diffs[0]?.state_id; + await this.messageBus.notifyUpdate(processId, newStateId); + await this.messageBus.validateState(processId, newStateId); + + const processData = await this.messageBus.getProcessData(processId); + + // Update cache + this.setItem('_collaborators_', processId, processData); + } catch (error) { + console.error('Failed to update collaborator:', error); + throw error; // Re-throw to allow caller to handle } - - return new Promise((resolve: (process: any) => void, reject: (error: string) => void) => { - this.messageBus.getProcessesDecoded((publicValues: any) => - publicValues['uid'] && - publicValues['uid'] === uid && - publicValues['utype'] && - publicValues['utype'] === 'collaborator' && - publicValues['isDeleted'] && - publicValues['isDeleted'] === 'false' - ).then(async (processes: any[]) => { - if (processes.length === 0) { - resolve(null); - } else { - let process: any = processes[0]; - process = await this.completeCollaborator(process); - - // Update cache - this.setItem('_collaborators_', process); - - resolve(process); - } - }).catch(reject); - }); - } - - public static updateCollaborator(process: any, newData: any): Promise { - return new Promise((resolve: () => void, reject: (error: string) => void) => { - this.messageBus.updateProcess(process.processId, { updated_at: new Date().toISOString(), ...newData }, [], null).then((processUpdated: any) => { - const newStateId: string = processUpdated.diffs[0]?.state_id; - this.messageBus.notifyUpdate(process.processId, newStateId).then(() => { - this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => { - const collaboratorUid: string = process.processData.uid; - this.removeItem('_collaborators_', collaboratorUid); - - this.getCollaboratorByUid(collaboratorUid, true).then(resolve).catch(reject); - }).catch(reject); - }).catch(reject); - }).catch(reject); - }); - } - - private static async completeCollaborator(process: any, progressCallback?: (processInProgress: any) => void): Promise { - const progressiveProcess: any = JSON.parse(JSON.stringify(process)); - - if (process.processData.office) { - const office: any = (await OfficeService.getOfficeByUid(process.processData.office.uid)).processData; - if (office) { - process.processData.office = { - uid: office.uid, - idNot: office.idNot, - crpcen: office.crpcen, - name: office.name, - office_status: office.office_status - }; - - if (progressCallback) { - progressiveProcess.processData.office = process.processData.office; - progressCallback(JSON.parse(JSON.stringify(progressiveProcess))); - } - } else { - console.error('Office not found'); - } - } - - if (process.processData.role) { - const role: any = (await RoleService.getRoleByUid(process.processData.role.uid)).processData; - if (!role) { - console.error('Role not found'); - } else { - process.processData.role = { - uid: role.uid, - name: role.name - }; - } - - if (progressCallback) { - progressiveProcess.processData.role = process.processData.role; - progressCallback(JSON.parse(JSON.stringify(progressiveProcess))); - } - } - - if (process.processData.office_role) { - const officeRole: any = (await OfficeRoleService.getOfficeRoleByUid(process.processData.office_role.uid)).processData; - if (!officeRole) { - console.error('Office role not found'); - } else { - process.processData.office_role = { - uid: officeRole.uid, - name: officeRole.name, - rules: officeRole.rules?.map((rule: any) => { - return { - uid: rule.uid, - name: rule.name - }; - }) - }; - } - - if (progressCallback) { - progressiveProcess.processData.office_role = process.processData.office_role; - progressCallback(JSON.parse(JSON.stringify(progressiveProcess))); - } - } - - return process; } }