using System.Text.Json; using System.Text.Json.Serialization; namespace MetaApi.Models; /// /// Request from Gateway to MetaApi. /// Identical contract to GoogleApi.Models.ProviderRequest for Gateway compatibility. /// public sealed class ProviderRequest { /// /// Operation to execute (e.g., "Ping", "CreateCampaign", "GetCampaignInsights") /// public string Operation { get; set; } = string.Empty; /// /// Tenant/account ID - maps to Meta ad account ID (act_XXXXXXX). /// Populated by Gateway from tbAdAccount.accExternalAccountId where accNetwork='meta'. /// public string? TenantId { get; set; } /// /// Login customer ID - maps to Meta Business Manager ID. /// In Meta's agency model, the BM owns and manages client ad accounts. /// Populated by Gateway from tbAdAccount.accLoginAccountId. /// public string? LoginCustomerId { get; set; } /// /// Correlation ID for request tracing /// public string? RequestId { get; set; } /// /// Operation-specific payload /// public JsonElement? Payload { get; set; } /// /// Deserialize payload to strongly-typed object /// public T GetPayload() where T : new() { if (Payload == null || Payload.Value.ValueKind == JsonValueKind.Null || Payload.Value.ValueKind == JsonValueKind.Undefined) return new T(); try { return JsonSerializer.Deserialize(Payload.Value.GetRawText(), JsonOptions.Default) ?? new T(); } catch { return new T(); } } } /// /// Response from MetaApi to Gateway. /// Identical contract to GoogleApi.Models.ProviderResponse. /// public sealed class ProviderResponse { public bool Ok { get; set; } public string? RequestId { get; set; } public object? Data { get; set; } public ProviderError? Error { get; set; } public static ProviderResponse Success(string? requestId, object? data = null) => new() { Ok = true, RequestId = requestId, Data = data }; public static ProviderResponse Fail(string? requestId, string code, string message, object? detail = null) => new() { Ok = false, RequestId = requestId, Error = new ProviderError { Code = code, Message = message, Detail = detail } }; } public sealed class ProviderError { public string Code { get; set; } = "ERROR"; public string Message { get; set; } = "Unknown error"; public object? Detail { get; set; } } internal static class JsonOptions { public static readonly JsonSerializerOptions Default = new(JsonSerializerDefaults.Web) { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull }; }