namespace GB5Shared.DTO.PubSub
{
///
/// Rich event wrapper published to Dapr pubsub.
/// Carries TOUTBOX metadata (EventTypeId, TenantId, ObjectId) alongside
/// the entity payload so EventSub subscribers can identify the event and
/// resolve the correct MACTION rows without an extra DB lookup.
/// Published by OutBox.PublishPendingEventsAsync on topic "EVENTTYPEID:{id}".
///
public class OutboxEventMessage
{
/// FK to MEVENTTYPE — identifies what happened.
public int EventTypeId { get; set; }
/// FK to entity type (ENTITYID on MEVENTTYPE).
public int ObjectTypeId { get; set; }
/// PK of the saved entity (e.g. TaskId).
public int ObjectId { get; set; }
/// Tenant that owns the event (TOUTBOX.TENANTID).
public int TenantId { get; set; }
/// UserId who triggered the original business event (TOUTBOX.USERID).
public int UserId { get; set; }
/// Serialised entity DTO (TOUTBOX.PAYLOAD).
public string Payload { get; set; } = "{}";
/// Correlation key from TOUTBOX — links all downstream rows to the originating outbox event.
public string CorrelationKey { get; set; } = string.Empty;
///
/// The MSERVER connection name (LoginDTO.ConnectionDatabaseName) used by the publisher.
/// Carried in the message so the framework subscriber can connect to the exact same
/// tenant database without re-deriving it from MSERVERCONFIG — which can have multiple
/// active records for the same ClientId and return the wrong database.
/// When set, EventSubBLL uses this directly and skips the MSERVERCONFIG lookup entirely.
///
public string ConnectionName { get; set; } = string.Empty;
///
/// JSON-serialized array of .
/// Set by BLL on UPDATE operations only; null for INSERT (full snapshot is in TEVENTLOG.DATA).
/// EventLogSubBLL deserializes this and writes individual rows to TEVENTLOGCHANGE.
/// Example: [{"FieldName":"Amount","OldValue":"1000","NewValue":"5000"}]
///
public string? Changes { get; set; }
/// GUID of the originating header row (TOUTBOX.HEADERROWGUID). Nullable.
public Guid? HeaderRowGuid { get; set; }
///
/// Full LoginDTO serialised as JSON — carries the complete session context of the user
/// who triggered the event (WorkOUId, RoleId, BranchId, timezone, formats, etc.).
/// Populated by BaseEntityAppService.ExecuteSaveAsync on the direct Dapr publish path.
/// Defaults to "{}" on the outbox background-retry path where login state is
/// unavailable; subscribers must handle both forms gracefully.
/// WipApprovalId and RequestUrl are server-side-only and are excluded by [JsonIgnore].
///
public string LoginJson { get; set; } = "{}";
///
/// Pipeline context serialised as JSON — carries EntityId, ObjectId, EventTypeId,
/// caller-supplied Facts (e.g. ParentTaskId, WIP bypass flag), and the DB_ENRICH bag
/// values written by qualifier rules (e.g. ReportingToEmployeeId, DepartmentId).
/// Also includes WorkflowInfo (mode, id, config) resolved during the save pipeline.
/// Populated by BaseEntityAppService.ExecuteSaveAsync on the direct Dapr publish path.
/// Defaults to a minimal JSON object on the outbox background-retry path.
///
public string ContextJson { get; set; } = "{}";
///
/// W3C traceparent of the publisher's span (direct-publish or outbox-relay
/// producer activity). Carried in the message body itself — rather than relying on
/// Dapr/broker-level metadata propagation, which varies by pubsub component and
/// CloudEvent wrapping mode — so EventActionSubscribeController can always
/// reconstruct the correct parent via
/// DaprEventTracing.StartSubscribeActivity and Zipkin/Jaeger stitch the
/// publish → subscribe spans together across the service boundary.
///
public string? TraceParent { get; set; }
/// W3C tracestate accompanying , if any.
public string? TraceState { get; set; }
}
}