using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace GB5Shared.DTO.GOP { public class GBGatewayDTO { /// /// Top-level definition of a mapping. It is versioned – the active version /// is the one the runtime uses. Think of this as the "template header". /// Example: "SAP Invoice → Canonical Invoice" /// public class MappingDefinition { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string SourceSchema { get; set; } = string.Empty; // e.g. "SAP_Invoice_v2" public string TargetSchema { get; set; } = string.Empty; // e.g. "CanonicalInvoice_v1" public MappingDirection Direction { get; set; } = MappingDirection.Inbound; public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public List Versions { get; set; } = new(); } /// /// A snapshot of a MappingDefinition at a point in time. /// Only one version per definition can be Active at once. /// New drafts are created, tested, then activated. /// public class MappingVersion { public Guid Id { get; set; } = Guid.NewGuid(); public Guid MappingDefinitionId { get; set; } public string Label { get; set; } = string.Empty; // e.g. "v1.0.0" public VersionStatus Status { get; set; } = VersionStatus.Draft; public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? ActivatedAt { get; set; } public List Nodes { get; set; } = new(); } /// /// A single field-to-field transformation rule within a MappingVersion. /// SourcePath → evaluated expression → TargetPath /// Example: "$.invoice.inv_no" → "UPPER(value)" → "$.InvoiceNumber" /// public class MappingNode { public Guid Id { get; set; } = Guid.NewGuid(); public Guid MappingVersionId { get; set; } public string SourcePath { get; set; } = string.Empty; // JSONPath in source document public string TargetPath { get; set; } = string.Empty; // JSONPath in canonical/target public string? TransformExpression { get; set; } // optional C#/JS-like expression public int ExecutionOrder { get; set; } // lower = runs first public bool IsRequired { get; set; } = true; // Optional qualifier applied to this field (validate/enrich before mapping) public Guid? QualifierVersionId { get; set; } } public sealed class MappingComponent { public Guid ComponentId { get; set; } public int TenantId { get; set; } public string Name { get; set; } public string Description { get; set; } public DateTime CreatedAt { get; set; } } public enum ExecutionStatus { Started, Qualifying, Mapping, Dispatching, Paused, // waiting for human review Completed, Failed, DeadLettered } /// How the execution was triggered. public enum ExecutionMode { RealTime, Batch, Replay } /// Data flow direction. public enum MappingDirection { Inbound, // external → canonical Outbound // canonical → external } /// Result of a single attempt. public enum AttemptResult { Success, Failure, Skipped } // ─── Mapping ───────────────────────────────────────────────────────────────── /// Draft = editable, Active = locked and in use. public enum VersionStatus { Draft, Active, Archived } // ─── Qualifier ─────────────────────────────────────────────────────────────── /// What the qualifier does to the data. public enum QualifierType { Validator, // rejects bad data Enricher // adds / transforms data } // ─── Decision Flow ──────────────────────────────────────────────────────────── /// Type of step inside a decision flow. public enum StepType { Automated, ManualReview, Approval, Notification } /// State of a workflow step waiting for a human. public enum WorkflowStepStatus { Waiting, Approved, Rejected, Escalated, Skipped } // ─── Error Handling ─────────────────────────────────────────────────────────── /// What to do when a qualifier fails. public enum OnValidationFailure { Stop, Continue, ManualReview } /// What to do when dispatching to a target system fails. public enum OnTargetFailure { Retry, ManualReview, DeadLetter } /// Backoff strategy for retries. public enum BackoffType { Fixed, Linear, Exponential } // ─── Remediation ────────────────────────────────────────────────────────────── public enum RemediationStatus { Open, InProgress, Resolved, Closed } // ─── Async / Events ─────────────────────────────────────────────────────────── public enum ExecutionEventType { Start, Resume, Retry, Pause, Cancel } public sealed class MappingComponentNode { public Guid ComponentNodeId { get; set; } public Guid ComponentId { get; set; } public string NodeType { get; set; } public string SourcePath { get; set; } public string TargetPath { get; set; } public string Expression { get; set; } public Guid? QualifierVersionId { get; set; } public int ExecutionOrder { get; set; } } public record CanonicalModelResult( Guid Id, int TenantId, string Name, string Description, string Version, bool IsActive, string CreatedBy, DateTime CreatedAt, IEnumerable Fields ); public class CanonicalModel { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string Name { get; set; } = string.Empty; // e.g. "Invoice" public string Description { get; set; } = string.Empty; public string Version { get; set; } = "1.0"; // semantic version of the CDM schema public bool IsActive { get; set; } = true; public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; // Navigation: child fields define the schema structure public List Fields { get; set; } = new(); } /// /// A single field in a CanonicalModel schema. /// Example: InvoiceNumber (string, required), TotalAmount (decimal, required) /// public class CanonicalField { public Guid Id { get; set; } = Guid.NewGuid(); public Guid CanonicalModelId { get; set; } public string Name { get; set; } = string.Empty; // PascalCase e.g. "InvoiceNumber" public string DataType { get; set; } = "string"; // string | int | decimal | bool | datetime public bool IsRequired { get; set; } = false; public string? DefaultValue { get; set; } public string? Description { get; set; } public int DisplayOrder { get; set; } } public record CanonicalFieldResult( Guid Id, string Name, string DataType, bool IsRequired, string? DefaultValue, string? Description, int DisplayOrder ); // ── Mapping ────────────────────────────────────────────────────────────────── public record MappingDefinitionResult( Guid Id, int TenantId, string Name, string Description, string SourceSchema, string TargetSchema, string Direction, string CreatedBy, DateTime CreatedAt, IEnumerable Versions ); public record MappingVersionResult( Guid Id, Guid MappingDefinitionId, string Label, string Status, string CreatedBy, DateTime CreatedAt, DateTime? ActivatedAt, IEnumerable Nodes ); public record MappingNodeResult( Guid Id, string SourcePath, string TargetPath, string? TransformExpression, int ExecutionOrder, bool IsRequired, Guid? QualifierVersionId ); public class QualifierDefinition { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public QualifierType Type { get; set; } public bool IsSystem { get; set; } = false; // system-wide vs tenant-specific public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public List Versions { get; set; } = new(); } /// /// A snapshot of the qualifier logic at a point in time. /// Script contains the validation/enrichment expression or reference. /// public class QualifierVersion { public Guid Id { get; set; } = Guid.NewGuid(); public Guid QualifierDefinitionId { get; set; } public string Label { get; set; } = string.Empty; public VersionStatus Status { get; set; } = VersionStatus.Draft; public string Script { get; set; } = string.Empty; // expression or script body public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? ActivatedAt { get; set; } } /// /// Binds a qualifier to a specific target (e.g. a MappingNode or a DecisionStep). /// This allows reusing the same qualifier across many mappings. /// public class QualifierBinding { public Guid Id { get; set; } = Guid.NewGuid(); public Guid QualifierVersionId { get; set; } public string BoundToType { get; set; } = string.Empty; // "MappingNode" | "DecisionStep" public Guid BoundToId { get; set; } public int ExecutionOrder { get; set; } } // ── Qualifier ──────────────────────────────────────────────────────────────── public record QualifierDefinitionResult( Guid Id, int TenantId, string Name, string Description, string Type, bool IsSystem, string CreatedBy, DateTime CreatedAt, IEnumerable Versions ); public record QualifierVersionResult( Guid Id, string Label, string Status, string Script, string CreatedBy, DateTime CreatedAt, DateTime? ActivatedAt ); // ── Decision Flow ───────────────────────────────────────────────────────────── public record DecisionFlowDefinitionResult( Guid Id, int TenantId, string Name, string Description, string Intent, string CreatedBy, DateTime CreatedAt, IEnumerable Versions ); public record DecisionFlowVersionResult( Guid Id, string Label, string Status, string CreatedBy, DateTime CreatedAt, DateTime? ActivatedAt, IEnumerable Steps, IEnumerable Transitions ); public record DecisionStepResult( Guid Id, string Name, string Type, int ExecutionOrder, int SlaHours, bool AllowCorrection, string? AssignedRole ); public record DecisionTransitionResult( Guid Id, Guid FromStepId, Guid ToStepId, string Condition ); public record AssignmentRuleResult( Guid Id, string Name, string MatchField, string MatchValue, string AssignTo, string Department, int Priority ); // ── Execution ───────────────────────────────────────────────────────────────── public record ExecutionSummaryResult( Guid Id, int TenantId, string Intent, string Mode, string Direction, string Status, string CreatedBy, DateTime CreatedAt, DateTime? CompletedAt, string? FailureReason ); public record ExecutionDetailResult( Guid Id, int TenantId, string Intent, string Mode, string Direction, string Status, string Payload, string CanonicalPayload, string CreatedBy, DateTime CreatedAt, DateTime? CompletedAt, string? FailureReason, IEnumerable Attempts, IEnumerable Failures ); //public record AttemptResult( // int AttemptNumber, // string Stage, // string Result, // string? ErrorMessage, // DateTime StartedAt, // DateTime? CompletedAt //); public record FailureResult( string Category, string Code, string Message, string? FieldPath, DateTime OccurredAt ); public record WorkflowStateResult( Guid Id, Guid DecisionStepId, string Status, string? AssignedTo, string? ReviewerComment, DateTime AssignedAt, DateTime? ReviewedAt ); // ── Dead Letter & Remediation ───────────────────────────────────────────────── public record DeadLetterResult( Guid Id, Guid ExecutionId, string Reason, DateTime CreatedAt ); public record RemediationCaseResult( Guid Id, Guid DeadLetterId, string Status, string AssignedTo, string? Resolution, DateTime OpenedAt, DateTime? ResolvedAt ); // ── Audit ───────────────────────────────────────────────────────────────────── public record AuditLogResult( Guid Id, string EntityType, Guid EntityId, string Action, string PerformedBy, string? OldValue, string? NewValue, DateTime OccurredAt ); // ── Tenant ─────────────────────────────────────────────────────────────────── public record TenantResult( Guid Id, string Name, string Slug, string Plan, bool IsActive, int MaxExecutions, int MaxMappings, string ContactEmail, DateTime CreatedAt ); public class AuditLog { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string EntityType { get; set; } = string.Empty; public Guid EntityId { get; set; } public string Action { get; set; } = string.Empty; public string PerformedBy { get; set; } = string.Empty; public string? OldValue { get; set; } public string? NewValue { get; set; } public string? IpAddress { get; set; } public DateTime OccurredAt { get; set; } = DateTime.UtcNow; } // ── Execution Context (runtime state) ───────────────────────────────────── /// /// The runtime state of one document/payload being processed. /// Flow: Created → Qualifying → Mapping → Dispatching → Completed | Failed | Paused /// public class ExecutionContext { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string Intent { get; set; } = string.Empty; public ExecutionMode Mode { get; set; } = ExecutionMode.RealTime; public MappingDirection Direction { get; set; } = MappingDirection.Inbound; public ExecutionStatus Status { get; set; } = ExecutionStatus.Started; public string Payload { get; set; } = string.Empty; public string CanonicalPayload { get; set; } = string.Empty; public Guid? MappingVersionId { get; set; } public Guid? DecisionFlowVersionId { get; set; } public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? CompletedAt { get; set; } public string? FailureReason { get; set; } } /// One retry/attempt of an execution. public class ExecutionAttempt { public Guid Id { get; set; } = Guid.NewGuid(); public Guid ExecutionId { get; set; } public int AttemptNumber { get; set; } = 1; public AttemptResult Result { get; set; } public string? ErrorMessage { get; set; } public string Stage { get; set; } = string.Empty; // "Qualify" | "Map" | "Dispatch" public DateTime StartedAt { get; set; } = DateTime.UtcNow; public DateTime? CompletedAt { get; set; } } /// Structured failure captured during an execution. public class ExecutionFailure { public Guid Id { get; set; } = Guid.NewGuid(); public Guid ExecutionId { get; set; } public string Category { get; set; } = string.Empty; // "Validation" | "Mapping" | "Target" public string Code { get; set; } = string.Empty; public string Message { get; set; } = string.Empty; public string? FieldPath { get; set; } public DateTime OccurredAt { get; set; } = DateTime.UtcNow; } /// State of a manual step inside an execution's workflow. public class WorkflowState { public Guid Id { get; set; } = Guid.NewGuid(); public Guid ExecutionId { get; set; } public Guid DecisionStepId { get; set; } public WorkflowStepStatus Status { get; set; } = WorkflowStepStatus.Waiting; public string? AssignedTo { get; set; } public string? ReviewerComment { get; set; } public DateTime AssignedAt { get; set; } = DateTime.UtcNow; public DateTime? ReviewedAt { get; set; } } /// Dead-lettered execution that cannot be retried automatically. public class DeadLetter { public Guid Id { get; set; } = Guid.NewGuid(); public Guid ExecutionId { get; set; } public string Reason { get; set; } = string.Empty; public string? Payload { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } /// A case opened to track resolution of a dead-lettered execution. public class RemediationCase { public Guid Id { get; set; } = Guid.NewGuid(); public Guid DeadLetterId { get; set; } public int TenantId { get; set; } public RemediationStatus Status { get; set; } = RemediationStatus.Open; public string AssignedTo { get; set; } = string.Empty; public string? Resolution { get; set; } public DateTime OpenedAt { get; set; } = DateTime.UtcNow; public DateTime? ResolvedAt { get; set; } } /// Async event to trigger or control an execution. public class ExecutionEvent { public Guid Id { get; set; } = Guid.NewGuid(); public Guid ExecutionId { get; set; } public ExecutionEventType EventType { get; set; } public string? Payload { get; set; } public DateTime PublishedAt { get; set; } = DateTime.UtcNow; } // ── Target System ───────────────────────────────────────────────────────── /// An external system that receives processed data. public class TargetSystem { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string Name { get; set; } = string.Empty; public string SystemType { get; set; } = string.Empty; // "ERP" | "CRM" | "Webhook" | "Database" public string BaseUrl { get; set; } = string.Empty; public string AuthType { get; set; } = "ApiKey"; // ApiKey | OAuth2 | BasicAuth | None public string? ApiKey { get; set; } public string? OAuthClientId { get; set; } public string? OAuthSecret { get; set; } public int RateLimit { get; set; } = 100; public int TimeoutMs { get; set; } = 30000; public bool IsActive { get; set; } = true; public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; } /// An operation (endpoint) on a TargetSystem. public class TargetOperation { public Guid Id { get; set; } = Guid.NewGuid(); public Guid TargetSystemId { get; set; } public string Name { get; set; } = string.Empty; public string HttpMethod { get; set; } = "POST"; public string Path { get; set; } = string.Empty; public string? BodyTemplate { get; set; } public string Intent { get; set; } = string.Empty; } // ── Tenant ──────────────────────────────────────────────────────────────── /// An isolated organisation using the platform. public class Tenant { public int TenantId { get; set; } = -1; public string Name { get; set; } = string.Empty; public string Slug { get; set; } = string.Empty; public string Plan { get; set; } = "Standard"; // Free | Standard | Enterprise public bool IsActive { get; set; } = true; public int MaxExecutions { get; set; } = 10000; public int MaxMappings { get; set; } = 100; public string ContactEmail { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? DeactivatedAt { get; set; } } // ── Execution Result DTOs ───────────────────────────────────────────────── public record ExecutionAttemptResult( int AttemptNumber, string Stage, string Result, string? ErrorMessage, DateTime StartedAt, DateTime? CompletedAt ); public class CanonicalModelField { public string Id { get; set; } = string.Empty; public string Name { get; set; } = string.Empty; public string DataType { get; set; } = string.Empty; public bool IsRequired { get; set; } public string? Description { get; set; } public Dictionary? Attributes { get; set; } } public class Provenance { public string? CreatedBy { get; set; } public DateTime? CreatedAt { get; set; } public string? UpdatedBy { get; set; } public DateTime? UpdatedAt { get; set; } public string? ApprovedBy { get; set; } public DateTime? ApprovedAt { get; set; } public string? ApprovalNotes { get; set; } } public class DecisionFlowDefinition { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string Name { get; set; } = string.Empty; public string Description { get; set; } = string.Empty; public string Intent { get; set; } = string.Empty; // business intent e.g. "InvoiceApproval" public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public List Versions { get; set; } = new(); } /// /// A versioned snapshot of the decision flow (steps + transitions). /// public class DecisionFlowVersion { public Guid Id { get; set; } = Guid.NewGuid(); public Guid DecisionFlowDefinitionId { get; set; } public string Label { get; set; } = string.Empty; public VersionStatus Status { get; set; } = VersionStatus.Draft; public string CreatedBy { get; set; } = string.Empty; public DateTime CreatedAt { get; set; } = DateTime.UtcNow; public DateTime? ActivatedAt { get; set; } public List Steps { get; set; } = new(); public List Transitions { get; set; } = new(); } /// /// A step within a DecisionFlowVersion. /// ManualReview/Approval steps pause the execution until a human acts. /// SlaHours defines how long before the step is escalated. /// public class DecisionStep { public Guid Id { get; set; } = Guid.NewGuid(); public Guid DecisionFlowVersionId { get; set; } public string Name { get; set; } = string.Empty; public StepType Type { get; set; } = StepType.Automated; public int ExecutionOrder { get; set; } public int SlaHours { get; set; } = 24; public bool AllowCorrection { get; set; } = false; // reviewer can edit data public string? AssignedRole { get; set; } // e.g. "finance.manager" } /// /// Defines the allowed transitions between steps. /// For Approval steps: OnApprove → NextStep, OnReject → RejectionStep. /// public class DecisionTransition { public Guid Id { get; set; } = Guid.NewGuid(); public Guid DecisionFlowVersionId { get; set; } public Guid FromStepId { get; set; } public Guid ToStepId { get; set; } public string Condition { get; set; } = "OnApprove"; // OnApprove | OnReject | OnTimeout | Always } /// /// Assignment rule that routes a manual step to the right person/team. /// Rules are evaluated in priority order; first match wins. /// public class AssignmentRule { public Guid Id { get; set; } = Guid.NewGuid(); public int TenantId { get; set; } public string Name { get; set; } = string.Empty; public string MatchField { get; set; } = string.Empty; // field on payload to match public string MatchValue { get; set; } = string.Empty; // expected value public string AssignTo { get; set; } = string.Empty; // user / group / email public string Department { get; set; } = string.Empty; public int Priority { get; set; } = 10; public bool IsActive { get; set; } = true; } } }