PreDisconnect Trigger
- PreDisconnect Trigger programs are executed while a Relationship Instance is being disconnected, before the platform code for disconnect executes.
- They are used to validate or manipulate the relationship based on business requirements.
- They are executed synchronously, i.e. in the same transaction as the relationship disconnect.
- They are executed before standard validations are executed by the platform code.
Coding guidelines
-
PreDisconnect Trigger program is a class that must implement the interface
IPreDisconnectTriggerProgramAsyncpublic interface IPreDisconnectTriggerProgramAsync{Task<ProgramResult> RunAsync(Guid relationId);}NOTE: Use
IPreDisconnectTriggerProgramAsyncwith theRunAsyncmethod. -
Protrak runtime passes the
relationIdof the relationship being disconnected to the trigger. -
If you need relation details or the related instances, fetch them explicitly before making decisions.
-
Program should return a ProgramResult object:
- If
IsSuccessis true, then the trigger execution is considered as successful. - If
IsSuccessis false, then the trigger is considered as failed, subsequent code is not executed, and the DB transaction is rolled back. - If
IsSuccessis false, ideally thestring[] Errorsshould be populated with proper error messages which will be returned in API response, which can be displayed to end user.
- If
-
Because the trigger runs before the disconnect, the relation and the linked instances are still available to the trigger.
Typical use cases for PreDisconnect Trigger
- Validate whether the relationship can be disconnected where some complex business logic is involved.
- Prevent disconnect when related business data still depends on the relationship.
- Clean up or adjust instance state before the relation is removed.
- Remove access or dependent data that must be handled before the relationship goes away.
- If any validations or cleanup steps need to use a third-party service or integration.
Anti-patterns or when not to use PreDisconnect Trigger
- Prefer configuration over customization. Avoid using a program when configurable validations or cleanup are possible.
- Do not use PreDisconnect trigger to make changes that are not reversible, like sending an email. If the disconnect process fails, the transaction will be rolled back, but the side effect would already have happened.
- Do not assume the relation has already been removed. PreDisconnect runs before disconnect, so queries should be written with that timing in mind.
Sample Code
using Prorigo.Protrak.API.Contracts;
using Prorigo.Protrak.API.Services;
using Prorigo.Protrak.Programs;
using System;
using System.Threading.Tasks;
public class ProjectToTaskPreDisconnectTriggerProgram : IPreDisconnectTriggerProgramAsync
{
public IInstanceService InstanceService { get; set; }
public IRelationService RelationService { get; set; }
private readonly string RELATION_PROJECT_TO_TASK = "ProjectToTask";
private readonly string ATTRIBUTE_TASK_STATUS = "Status";
public async Task<ProgramResult> RunAsync(Guid relationId)
{
var relation = await RelationService.GetRelationAsync(relationId);
if (relation == null)
{
return new ProgramResult
{
IsSuccess = false,
Errors = new[] { "Relationship could not be found." }
};
}
var taskInstance = await InstanceService.GetInstanceAsync(relation.DestinationInstanceId, new[] { ATTRIBUTE_TASK_STATUS });
var status = taskInstance?.GetTextAttributeValue(ATTRIBUTE_TASK_STATUS);
if (string.Equals(status, "Closed", StringComparison.OrdinalIgnoreCase))
{
return new ProgramResult
{
IsSuccess = false,
Errors = new[] { "Closed tasks cannot be disconnected from the project." }
};
}
return new ProgramResult { IsSuccess = true };
}
}
Note:
The Run method (from IPreDisconnectTriggerProgram) is available for legacy synchronous implementations.