using System; using System.Collections.Generic; using Newtonsoft.Json; namespace GB5Shared.DTO.GOP { // ============================================================ // GOP PLATFORM DTOs // Maps to MGop* (master) and TGop* (transaction) SQL tables // ClientId resolved from LoginDTO.ClientId at runtime // ============================================================ // ── Request / Response ─────────────────────────────────────── public class GopSubmitRequestDTO { public string SourceCode { get; set; } = string.Empty; // e.g. "TASK_SAVE_API" public string PayloadJson { get; set; } = string.Empty; // JSON body (task payload etc.) // Environment is NOT accepted from the client — resolved server-side from IConfiguration["GOP:Environment"] public string? IdempotencyKey { get; set; } public int Priority { get; set; } = 5; } public class GopSubmitResponseDTO { public int QueueId { get; set; } public int ExecutionId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public string SnapshotVersion { get; set; } = string.Empty; public string Status { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; } public class GopOpenRemediationRequestDTO { public int ExecutionId { get; set; } public int QueueId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public string SnapshotVersion { get; set; } = string.Empty; public int FailedNodeId { get; set; } public string FailedNodeCode { get; set; } = string.Empty; public string OriginalPayloadJson { get; set; } = string.Empty; public string TargetResponseJson { get; set; } = string.Empty; public string IssueListJson { get; set; } = string.Empty; public string? AssignedTo { get; set; } } public class GopResolveRemediationRequestDTO { public int RemediationId { get; set; } public string ResolutionNotes { get; set; } = string.Empty; } // ── Master: Target Operation ───────────────────────────────── // Maps to MGOPTARGETOPERATION — the API registry used by ApiCall flow-step nodes. public class GopTargetOperationDTO { public int TargetOperationId { get; set; } public int TenantId { get; set; } public string OperationCode { get; set; } = string.Empty; public string OperationName { get; set; } = string.Empty; public string BaseUrl { get; set; } = string.Empty; public string RelativePath { get; set; } = string.Empty; /// GET | POST | PUT | PATCH | DELETE public string HttpMethod { get; set; } = "POST"; public string? RequestSchemaJson { get; set; } public string? ResponseSchemaJson { get; set; } public string? SpecHash { get; set; } // Entity Viewer registry reuse — NULL for GOP Flow ApiCall rows. // EntityCode matches MQUALIFIERENTITY.ENTITYCODE's convention. Populated for // entity-CRUD rows, whose OperationCode follows '{EntityCode}.Get'/'.Save'/'.Delete'. public string? EntityCode { get; set; } public string? IdFieldName { get; set; } // Both populated by GetGopTargetOperation's join from EntityCode to MENTITY — // not persisted columns on MGOPTARGETOPERATION. NULL when EntityCode is unset // (every GOP Flow ApiCall row). public int? EntityId { get; set; } public string? EntityName { get; set; } public int Version { get; set; } public int Status { get; set; } public int SortOrder { get; set; } // Audit fields — set by DAL before insert/update public int CreatedById { get; set; } public int ModifiedById { get; set; } } // Dropdown population — id/code/name only, no schema/URL payload. public class GopTargetOperationSelectListDTO { public int TargetOperationId { get; set; } public string OperationCode { get; set; } = string.Empty; public string OperationName { get; set; } = string.Empty; } // ── Master: Source Binding ─────────────────────────────────── public class GopSourceBindingDTO { public int ClientId { get; set; } public int SourceBindingId { get; set; } public string SourceType { get; set; } = string.Empty; // FILE | API | EVENT public string SourceCode { get; set; } = string.Empty; public string SourceName { get; set; } = string.Empty; public string? Description { get; set; } public int FlowId { get; set; } public string SnapshotVersion { get; set; } = string.Empty; public string Environment { get; set; } = "PROD"; public bool IsActive { get; set; } = true; /// Populated by joining MGOPFLOW on FlowId — not a persisted column. public string? GopFlowName { get; set; } } // ── Master: Flow ───────────────────────────────────────────── public class GopFlowDTO { public int ClientId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public string FlowName { get; set; } = string.Empty; public string? Description { get; set; } public string Status { get; set; } = string.Empty; public int Version { get; set; } public string? DriftStatus { get; set; } } // ── Master: Flow Snapshot ───────────────────────────────────── public class GopFlowSnapshotDTO { public int ClientId { get; set; } public int SnapshotId { get; set; } public int FlowId { get; set; } public string SnapshotVersion { get; set; } = string.Empty; public string Environment { get; set; } = string.Empty; public string SpecAggregateHash { get; set; } = string.Empty; public string SnapshotJson { get; set; } = string.Empty; public bool IsActive { get; set; } = true; public DateTime PublishedAt { get; set; } public string PublishedBy { get; set; } = string.Empty; } // ── Master: Flow Step (design-time graph node) ───────────────── // Maps to MGOPFLOWSTEP — authored via the Flow Designer, resolved into an // immutable GopFlowSnapshotStepDTO at publish time. public class GopFlowStepDTO { public int ClientId { get; set; } public int FlowStepId { get; set; } public int FlowId { get; set; } public string NodeCode { get; set; } = string.Empty; public string NodeName { get; set; } = string.Empty; /// Qualifier | Mapper | ApiCall | Approval public string NodeType { get; set; } = string.Empty; public string? LogicalServiceName { get; set; } public int TargetOperationId { get; set; } = -1; public int TimeoutSeconds { get; set; } = 60; public int MaxRetries { get; set; } = 3; public bool SupportsRemediation { get; set; } = false; public int SortOrder { get; set; } /// Approval steps only — who a paused execution shows up assigned to. /// Required (role or user) for an Approval step before the flow can publish. public string? AssignedRole { get; set; } public int? AssignedToUserId { get; set; } /// Populated by joining MGOPFLOW on FlowId — not a persisted column. public string? GopFlowName { get; set; } /// Populated by joining MGOPTARGETOPERATION on TargetOperationId — not a persisted /// column. Null for non-ApiCall steps (TargetOperationId is -1 for those). public string? OperationName { get; set; } } // ── Master: Flow Step Edge (design-time DAG edge) ─────────────── // Maps to MGOPFLOWSTEPEDGE — connects two GopFlowStepDTO nodes within a flow. public class GopFlowStepEdgeDTO { public int ClientId { get; set; } public int FlowStepEdgeId { get; set; } public int FlowId { get; set; } public int FromStepId { get; set; } public int ToStepId { get; set; } /// MGOPFLOWSTEP.NODECODE of FromStepId — read-only, populated via join. public string? FromStepName { get; set; } /// MGOPFLOWSTEP.NODENAME of ToStepId — read-only, populated via join. public string? ToStepName { get; set; } public string? EdgeLabel { get; set; } /// Always | OnSuccess | OnFailure — which outcome of FromStepId traverses this edge. public string EdgeCondition { get; set; } = "Always"; } // ── Combined design-time graph (steps + edges) for a flow ─────── public class GopFlowGraphDTO { public GopFlowDTO Flow { get; set; } = new(); public List Steps { get; set; } = new(); public List Edges { get; set; } = new(); } // ── Master: Flow Snapshot Step Edge (immutable, resolved at publish time) ── // Maps to MGOPFLOWSNAPSHOTSTEPEDGE — the edge set GopExecutionPipeline traverses // at runtime. Snapshotted alongside MGOPFLOWSNAPSHOTSTEP so a flow's routing // can't drift after publish even if the design-time graph changes later. public class GopFlowSnapshotStepEdgeDTO { public int ClientId { get; set; } public int SnapshotStepEdgeId { get; set; } public int SnapshotId { get; set; } public string SnapshotVersion { get; set; } = string.Empty; public int FromNodeId { get; set; } public int ToNodeId { get; set; } public string? EdgeLabel { get; set; } public string EdgeCondition { get; set; } = "Always"; } // ── Master: Flow Snapshot Step ──────────────────────────────── public class GopFlowSnapshotStepDTO { public int ClientId { get; set; } public int SnapshotStepId { get; set; } public int SnapshotId { get; set; } public string SnapshotVersion { get; set; } = string.Empty; public int StepOrder { get; set; } public int NodeId { get; set; } public string NodeCode { get; set; } = string.Empty; public string NodeType { get; set; } = string.Empty; // Qualifier | Mapper | ApiCall public string LogicalServiceName { get; set; } = string.Empty; public string ResolvedEndpoint { get; set; } = string.Empty; // base URL or INTERNAL public string HttpMethod { get; set; } = string.Empty; public string RelativePath { get; set; } = string.Empty; public string? RequestSchemaJson { get; set; } public string? ResponseSchemaJson { get; set; } public string? MappingJson { get; set; } public string SpecHash { get; set; } = string.Empty; public int TimeoutSeconds { get; set; } = 60; public int MaxRetries { get; set; } = 3; public bool SupportsRemediation { get; set; } = false; /// Approval steps only — copied from GopFlowStepDTO at publish time. public string? AssignedRole { get; set; } public int? AssignedToUserId { get; set; } } // ── Master: Canonical Model ──────────────────────────────────── // Maps to MCANONICALMODEL — a reusable, typed schema for one business // entity/document (e.g. "PO", "LEAVE", "RESUME") shared across every Mapper // that produces or consumes that document, instead of each Mapper inventing // its own open-ended shape. EntityCode intentionally matches the EntityCode // convention already used by MQUALIFIERENTITY. public class GopCanonicalModelDTO { public int TenantId { get; set; } public int CanonicalModelId { get; set; } public string EntityCode { get; set; } = string.Empty; public string ModelName { get; set; } = string.Empty; public string? Description { get; set; } public int Version { get; set; } = 1; public bool IsActive { get; set; } = true; public int SortOrder { get; set; } public int Status { get; set; } = 1; /// Library tier, same convention as PortletType/Dashboard/ReportView's own /// SourceType: 1=Framework, 2=DevAdmin are protected "Standard" library rows a tenant /// session cannot edit/deactivate (see CanonicalModelBLL.GuardSourceType). Column already /// exists live (MCANONICALMODEL.SOURCETYPE, default 5=User) — this DTO just newly exposes /// it; default here matches the live column default exactly. public byte SourceType { get; set; } = 5; } // ── Master: Canonical Field ───────────────────────────────────── // Maps to MCANONICALFIELD — one field of a canonical model's schema. public class GopCanonicalFieldDTO { public int TenantId { get; set; } public int CanonicalFieldId { get; set; } public int CanonicalModelId { get; set; } /// JSONPath into the canonical document, e.g. "$.PONumber". public string FieldPath { get; set; } = string.Empty; public string FieldName { get; set; } = string.Empty; /// String | Number | Date | Bool | Array | Object public string DataType { get; set; } = "String"; public bool IsRequired { get; set; } = false; public string? DefaultValue { get; set; } public string? Description { get; set; } public int SortOrder { get; set; } } // ── Master: Document Type ──────────────────────────────────────── // Maps to MGOPDOCUMENTTYPE — a named, reusable "shape of an incoming source // file/document" (e.g. "SBI Bank Statement (Excel)", "Generic CSV"), each // optionally pointing at the GopCanonicalModelDTO its rows normally map to. // A library of these (SourceType Framework rows) ships pre-built for popular // formats; tenants can add their own or clone-and-customize a library one. public class GopDocumentTypeDTO { public int TenantId { get; set; } public int DocumentTypeId { get; set; } public string EntityCode { get; set; } = string.Empty; public string DocumentTypeName { get; set; } = string.Empty; /// Matches IceMapDTO.IceMapIceSourceType's own enum: Excel|Json|Xml|Csv. public string SourceFormat { get; set; } = "Excel"; /// Optional starter link — "this format normally maps to this canonical shape." public int? DefaultCanonicalModelId { get; set; } /// Expected classification label an AI document-identifier capability returns /// for this document type (e.g. "RESUME") — used by GopDocumentIntakeBLL to resolve which /// DocumentType/EntityCode (and therefore which GopSourceBinding/flow) an uploaded file /// belongs to. Case-insensitive match, admin-editable so it can be corrected without a /// redeploy once the real classifier's output vocabulary is confirmed. Null for rows not /// used by the AI intake pipeline (e.g. the pre-existing Excel/CSV library rows). public string? AiClassificationLabel { get; set; } public string? Description { get; set; } public int SortOrder { get; set; } public int Status { get; set; } = 1; /// Same Framework(1)/DevAdmin(2)=Standard tiering as GopCanonicalModelDTO's own /// SourceType; default 5=User to match the live convention on MCANONICALMODEL/MCANONICALFIELD. public byte SourceType { get; set; } = 5; } // ── Master: Qualifier Rules ─────────────────────────────────── public class GopQualifierDefinitionDTO { public int ClientId { get; set; } public int QualifierId { get; set; } public string QualifierCode { get; set; } = string.Empty; public string QualifierName { get; set; } = string.Empty; public bool IsActive { get; set; } = true; } public class GopQualifierRuleDTO { public int ClientId { get; set; } public int RuleId { get; set; } public int QualifierId { get; set; } public int RuleOrder { get; set; } public string RuleName { get; set; } = string.Empty; public string FieldPath { get; set; } = string.Empty; // JSONPath e.g. $.TaskNumber public string Operator { get; set; } = string.Empty; // NotNull | Regex | In | Range public string? ExpectedValue { get; set; } public string ErrorCode { get; set; } = string.Empty; public string ErrorMessage { get; set; } = string.Empty; public string Severity { get; set; } = "Error"; // Error | Warning } // ── Master: Mapper Field Rules ──────────────────────────────── public class GopMapperDefinitionDTO { public int ClientId { get; set; } public int MapperId { get; set; } public string MapperCode { get; set; } = string.Empty; public string MapperName { get; set; } = string.Empty; public string SourceFormat { get; set; } = string.Empty; public string TargetFormat { get; set; } = string.Empty; public bool IsActive { get; set; } = true; } public class GopMapperFieldRuleDTO { public int ClientId { get; set; } public int RuleId { get; set; } public int MapperId { get; set; } public int RuleOrder { get; set; } public string SourcePath { get; set; } = string.Empty; public string TargetPath { get; set; } = string.Empty; public string? TransformExpression { get; set; } public string? DefaultValue { get; set; } public bool IsRequired { get; set; } = false; } // ── Transaction: Execution Queue ────────────────────────────── public class GopExecutionQueueDTO { public int ClientId { get; set; } public int QueueId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public string SnapshotVersion { get; set; } = string.Empty; public string? SourceCode { get; set; } public string PayloadJson { get; set; } = string.Empty; public string? IdempotencyKey { get; set; } public int Priority { get; set; } = 5; public string Status { get; set; } = "Pending"; public int RetryCount { get; set; } = 0; public int MaxRetry { get; set; } = 5; public string? LeaseOwner { get; set; } public DateTime? LeaseAt { get; set; } public DateTime? LeaseUntil { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? CompletedAt { get; set; } public string? ErrorMessage { get; set; } } // ── Transaction: Execution Header ───────────────────────────── public class GopExecutionHeaderDTO { public int ClientId { get; set; } public int ExecutionId { get; set; } public int QueueId { get; set; } public int? ParentExecutionId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public string SnapshotVersion { get; set; } = string.Empty; public string Status { get; set; } = "Created"; public string SourcePayloadJson { get; set; } = string.Empty; public int? CurrentNodeId { get; set; } public string? CurrentNodeCode { get; set; } /// Output payload of the last successfully completed node — set when an /// Approval-gate node pauses the pipeline, so a resumed execution continues from /// here instead of restarting from SourcePayloadJson. public string? LastOutputPayloadJson { get; set; } /// Set from the paused Approval step when Status='PendingApproval' — who owns the task. public string? AssignedRole { get; set; } public int? AssignedToUserId { get; set; } public DateTime StartedAt { get; set; } = DateTime.UtcNow; public DateTime? CompletedAt { get; set; } public long? TotalDurationMs { get; set; } public string? ErrorMessage { get; set; } public bool IsReplay { get; set; } = false; } // ── Transaction: Execution Node Log ─────────────────────────── public class GopExecutionNodeLogDTO { public int ClientId { get; set; } public int NodeLogId { get; set; } public int ExecutionId { get; set; } public int NodeId { get; set; } public string NodeCode { get; set; } = string.Empty; public int StepOrder { get; set; } public int AttemptNo { get; set; } = 1; public string Status { get; set; } = string.Empty; // Running | Success | Failed public string? RequestPayloadJson { get; set; } public string? ResponsePayloadJson { get; set; } public int? HttpStatusCode { get; set; } public string? HttpMethod { get; set; } public string? EndpointUrl { get; set; } public long? DurationMs { get; set; } public string? ErrorCode { get; set; } public string? ErrorMessage { get; set; } public DateTime StartedAt { get; set; } = DateTime.UtcNow; public DateTime? CompletedAt { get; set; } } // ── Transaction: Execution State Log ────────────────────────── public class GopExecutionStateLogDTO { public int ClientId { get; set; } public int ExecutionId { get; set; } public string? PreviousStatus { get; set; } public string NewStatus { get; set; } = string.Empty; public string? ReasonCode { get; set; } public string? ChangedBy { get; set; } public DateTime ChangedAt { get; set; } = DateTime.UtcNow; } // ── Transaction: Execution Metrics ──────────────────────────── public class GopExecutionMetricsDTO { public int ClientId { get; set; } public int ExecutionId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public long TotalDurationMs { get; set; } public int NodeCount { get; set; } public int TotalRetries { get; set; } = 0; public bool IsSuccess { get; set; } public DateTime RecordedAt { get; set; } = DateTime.UtcNow; } // ── Transaction: Execution Node Metrics ─────────────────────── public class GopExecutionNodeMetricsDTO { public int ClientId { get; set; } public int ExecutionId { get; set; } public int NodeId { get; set; } public string NodeCode { get; set; } = string.Empty; public long DurationMs { get; set; } public int RetryAttempts { get; set; } = 0; public int? HttpStatusCode { get; set; } public bool IsSuccess { get; set; } public DateTime RecordedAt { get; set; } = DateTime.UtcNow; } // ── Transaction: Dead Letter ─────────────────────────────────── public class GopDeadLetterDTO { public int ClientId { get; set; } public int DlqId { get; set; } public int ExecutionId { get; set; } public int QueueId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public string SnapshotVersion { get; set; } = string.Empty; public int FailedNodeId { get; set; } public string FailedNodeCode { get; set; } = string.Empty; public string PayloadJson { get; set; } = string.Empty; public string ErrorMessage { get; set; } = string.Empty; public string? ErrorStack { get; set; } public int RetryCount { get; set; } public string FailureCategory { get; set; } = "Transient"; // Transient | Fatal | BusinessLogic public DateTime MovedToDlqAt { get; set; } = DateTime.UtcNow; public bool IsResolved { get; set; } = false; public DateTime? ResolvedAt { get; set; } public string? ResolvedBy { get; set; } } // ── Transaction: Remediation ────────────────────────────────── public class GopRemediationDTO { public int ClientId { get; set; } public int RemediationId { get; set; } public int ExecutionId { get; set; } public int QueueId { get; set; } public int FlowId { get; set; } public string FlowCode { get; set; } = string.Empty; public string SnapshotVersion { get; set; } = string.Empty; public int FailedNodeId { get; set; } public string FailedNodeCode { get; set; } = string.Empty; public string OriginalPayloadJson { get; set; } = string.Empty; public string TargetResponseJson { get; set; } = string.Empty; public string IssueListJson { get; set; } = string.Empty; public string Status { get; set; } = "Open"; // Open | InProgress | Resolved | Closed public int ResubmissionCount { get; set; } = 0; public string? AssignedTo { get; set; } public string? ResolutionNotes { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? ResolvedAt { get; set; } public string? ResolvedBy { get; set; } } // ── Transaction: Execution Lock ─────────────────────────────── public class GopExecutionLockDTO { public int ClientId { get; set; } public int ExecutionId { get; set; } public string LockedBy { get; set; } = string.Empty; public DateTime LockedAt { get; set; } = DateTime.UtcNow; public DateTime ExpiresAt { get; set; } } // ── Transaction: Source File ────────────────────────────────── public class GopSourceFileDTO { public int ClientId { get; set; } public int FileId { get; set; } public string SourceCode { get; set; } = string.Empty; public string OriginalFileName { get; set; } = string.Empty; public string? StoredFilePath { get; set; } public long? FileSizeBytes { get; set; } public string? MimeType { get; set; } public string UploadedBy { get; set; } = string.Empty; public DateTime UploadedAt { get; set; } = DateTime.UtcNow; public string Status { get; set; } = "Uploaded"; public int? QueueId { get; set; } } // ── Internal: Mapping Step Item (parsed from MappingJson) ───── public class GopMappingStepItem { [JsonProperty("order")] public int Order { get; set; } [JsonProperty("sourcePath")] public string SourcePath { get; set; } = string.Empty; [JsonProperty("targetPath")] public string TargetPath { get; set; } = string.Empty; [JsonProperty("transform")] public string? Transform { get; set; } } // ── Dashboard ───────────────────────────────────────────────── public class GopQueueDashboardDTO { public string Status { get; set; } = string.Empty; public int QueueCount { get; set; } } // ── File Upload ─────────────────────────────────────────────── /// Overall result returned by the file-upload endpoint. public class GopFileUploadResponseDTO { public int FileId { get; set; } public string FileName { get; set; } = string.Empty; public string SourceType { get; set; } = string.Empty; public int TotalRecords { get; set; } public int SubmittedCount { get; set; } public int FailedCount { get; set; } public string Status { get; set; } = string.Empty; // Queued | PartialFailed | Failed public List Results { get; set; } = new(); } /// Per-row submission result inside a file upload response. public class GopFileUploadItemResultDTO { public int RowIndex { get; set; } public int? QueueId { get; set; } public int? ExecutionId { get; set; } public string Status { get; set; } = string.Empty; // Queued | Failed public string? Error { get; set; } } }