using System.Collections.Generic; using System.Data.Common; using System.Threading.Tasks; using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.WorkFlow; namespace GB5Shared.WorkFlow.WorkFlowRunTime { /// /// Low-level persistence contract for the workflow engine. /// All methods accept a so the engine can /// co-ordinate everything inside one database transaction. /// public interface IWorkFlowRunTime { // ── Config resolution ───────────────────────────────────────────────── /// /// Returns all MWORKFLOWCONFIG rows that might apply for the given context, /// ordered most-specific-first. The engine evaluates EVALCONDITION on /// each row and picks the first match. /// Task> GetWorkflowConfigsAsync( int entityId, int clientId, int ouId, int bizTransactionClassId, int bizTransactionId, LoginDTO loginDTO, DbTransaction dbTransaction); /// /// Looks up MBIZTRANSACTIONTYPE.BIZTRANSACTIONTYPEID by BizTransactionClassId. /// Returns -1 when no matching row exists (FK-safe fallback). /// Task GetBizTransactionTypeIdAsync( int bizTransactionClassId, LoginDTO loginDTO, DbTransaction dbTransaction); // ── Definition load ─────────────────────────────────────────────────── /// Loads a workflow by its PK (already resolved via MWORKFLOWCONFIG). Task GetWorkflowByIdAsync( int workflowId, LoginDTO loginDTO, DbTransaction dbTransaction); /// /// Loads the latest active workflow definition by EntityId + TenantId /// (kept for backward compat with old path). /// Task GetActiveDefinitionAsync( int entityId, LoginDTO loginDTO, DbTransaction dbTransaction); /// /// Legacy helper used by the old CheckWorkFlowApplicability path. /// Returns only the header row (no steps/transitions). /// Task GetActiveWorkflowAsync( int entityId, LoginDTO loginDTO, DbTransaction dbTransaction); Task> GetConditionAsync( int? conditionGroupId, LoginDTO loginDTO, DbTransaction dbTransaction); Task> GetRuleGroupsAsync( IEnumerable ruleGroupIds, LoginDTO loginDTO, DbTransaction dbTransaction); // ── Instance CRUD ───────────────────────────────────────────────────── /// /// Deletes any pending TWORKFLOWTASK and TWORKFLOWINSTANCE rows for the /// given tenant + entity + object before a fresh instance is inserted. /// Only rows with WORKFLOWSTATUS = 0 (Pending) are removed. /// Task DeleteDuplicateInstanceAsync( int entityId, int objectId, LoginDTO loginDTO, DbTransaction dbTransaction); /// /// Cancels every REAL pending (WORKFLOWSTATUS=0) instance for the given tenant + /// entity + object — unlike , this also /// cancels instances that already have history (i.e. a genuine in-flight approval), /// used when the underlying record is deleted or resubmitted after an edit. Also /// cancels the pending TWORKFLOWTASK rows and, for WIP-backed instances, the linked /// TWORKFLOWWIP row. Returns the instances that were cancelled so the caller can /// write TWORKFLOWHISTORY entries against each. /// Task> CancelPendingInstancesAsync( int entityId, int objectId, LoginDTO loginDTO, DbTransaction dbTransaction); Task InsertInstanceAsync( WorkflowInstance instance, LoginDTO loginDTO, DbTransaction dbTransaction); Task UpdateInstanceAsync( WorkflowInstance instance, LoginDTO loginDTO, DbTransaction dbTransaction); Task GetInstanceAsync( long instanceId, LoginDTO loginDTO, DbTransaction dbTransaction); Task GetInstanceAsync( long clientId, string entityName, long entityId, LoginDTO loginDTO, DbTransaction dbTransaction); // ── Task CRUD ───────────────────────────────────────────────────────── Task InsertTaskAsync( WorkflowTask task, LoginDTO loginDTO, DbTransaction dbTransaction); Task UpdateTaskAsync( WorkflowTask task, LoginDTO loginDTO, DbTransaction dbTransaction); Task GetTaskAsync( int taskId, LoginDTO loginDTO, DbTransaction dbTransaction); /// /// Returns all pending tasks for a given instance + approval level. /// Used to decide whether the level is complete. /// Task> GetPendingTasksForLevelAsync( int instanceId, int approvalLevel, LoginDTO loginDTO, DbTransaction dbTransaction); /// Kept for backward compat (step-based parallel check). Task> GetPendingTasksForStepAsync( int instanceId, long stepId, LoginDTO loginDTO, DbTransaction dbTransaction); Task> GetInboxTasksAsync( long userId, IEnumerable? roles, IEnumerable? pools, LoginDTO loginDTO, DbTransaction dbTransaction); // ── History ─────────────────────────────────────────────────────────── Task InsertHistoryAsync( WorkflowHistory history, LoginDTO loginDTO, DbTransaction dbTransaction); // ── Delegation ──────────────────────────────────────────────────────── Task> GetUserDelegationsAsync( long principalUserId, LoginDTO loginDTO, DbTransaction dbTransaction); // ── WIP (Form-Based Approval) ───────────────────────────────────────── /// /// Inserts a new TWORKFLOWWIP row (STATUS=Pending, WorkflowInstanceId=-1). /// Returns the new WipId. /// Task InsertWipAsync( int entityId, int tenantId, string dataJson, string? loginJson, string? apiEndpoint, int createdById, LoginDTO loginDTO, DbTransaction dbTransaction); /// Binds the workflow instance to the WIP row after the instance is created. Task UpdateWipInstanceIdAsync( int wipId, int workflowInstanceId, int modifiedById, LoginDTO loginDTO, DbTransaction dbTransaction); /// Returns the WIP record linked to a workflow instance, or null if this is not a WIP instance. Task GetWipByInstanceIdAsync( int instanceId, LoginDTO loginDTO, DbTransaction dbTransaction); /// Updates the WIP STATUS and LASTACTION; sets OBJECTID when the real entity has been saved. Task UpdateWipStatusAsync( int wipId, byte status, byte lastAction, int objectId, int modifiedById, LoginDTO loginDTO, DbTransaction dbTransaction); // ── Auto-approve ────────────────────────────────────────────────────── /// /// Returns all pending tasks whose DUEON has passed and whose step /// has ISAUTOAPPROVE = 0 (0=Yes). Used by the background auto-approve job. /// Task> GetOverdueAutoApproveTasksAsync( LoginDTO loginDTO, DbTransaction dbTransaction); } }