| | | 1 | | using System.Text.Json.Serialization; |
| | | 2 | | |
| | | 3 | | namespace Services.ApiServices.PartsnavigatorApi; |
| | | 4 | | |
| | | 5 | | /// <summary>Ответ <c>GET /partsnavigator/{brand}/{number}</c> (контракт — /openapi.json парсера).</summary> |
| | | 6 | | public sealed class PartsnavigatorLookup |
| | | 7 | | { |
| | | 8 | | [JsonPropertyName("query")] public string Query { get; set; } = string.Empty; |
| | | 9 | | [JsonPropertyName("exists")] public bool Exists { get; set; } |
| | | 10 | | [JsonPropertyName("requested")] public PartsnavigatorPart? Requested { get; set; } |
| | | 11 | | [JsonPropertyName("analogs")] public List<PartsnavigatorAnalog>? Analogs { get; set; } |
| | | 12 | | [JsonPropertyName("analogs_blocked")] public bool AnalogsBlocked { get; set; } |
| | | 13 | | [JsonPropertyName("warnings")] public List<string> Warnings { get; set; } = []; |
| | | 14 | | } |
| | | 15 | | |
| | | 16 | | public sealed class PartsnavigatorPart |
| | | 17 | | { |
| | 32 | 18 | | [JsonPropertyName("brand")] public string Brand { get; set; } = string.Empty; |
| | 32 | 19 | | [JsonPropertyName("number")] public string Number { get; set; } = string.Empty; |
| | 19 | 20 | | [JsonPropertyName("url")] public string Url { get; set; } = string.Empty; |
| | 33 | 21 | | [JsonPropertyName("name")] public string Name { get; set; } = string.Empty; |
| | 19 | 22 | | [JsonPropertyName("images")] public List<string> Images { get; set; } = []; |
| | 4 | 23 | | [JsonPropertyName("characteristics_source")] public string? CharacteristicsSource { get; set; } |
| | 20 | 24 | | [JsonPropertyName("characteristics")] public Dictionary<string, string> Characteristics { get; set; } = []; |
| | 0 | 25 | | [JsonPropertyName("rating")] public string? Rating { get; set; } |
| | 4 | 26 | | [JsonPropertyName("brand_info")] public PartsnavigatorBrandInfo? BrandInfo { get; set; } |
| | | 27 | | } |
| | | 28 | | |
| | | 29 | | public sealed class PartsnavigatorBrandInfo |
| | | 30 | | { |
| | | 31 | | [JsonPropertyName("name")] public string Name { get; set; } = string.Empty; |
| | | 32 | | [JsonPropertyName("found")] public bool Found { get; set; } |
| | | 33 | | [JsonPropertyName("logo_url")] public string? LogoUrl { get; set; } |
| | | 34 | | [JsonPropertyName("description")] public string Description { get; set; } = string.Empty; |
| | | 35 | | [JsonPropertyName("website")] public string? Website { get; set; } |
| | | 36 | | [JsonPropertyName("country")] public string? Country { get; set; } |
| | | 37 | | } |
| | | 38 | | |
| | | 39 | | public sealed class PartsnavigatorAnalog |
| | | 40 | | { |
| | | 41 | | [JsonPropertyName("brand")] public string Brand { get; set; } = string.Empty; |
| | | 42 | | [JsonPropertyName("number")] public string Number { get; set; } = string.Empty; |
| | | 43 | | [JsonPropertyName("description")] public string Description { get; set; } = string.Empty; |
| | | 44 | | [JsonPropertyName("is_requested")] public bool IsRequested { get; set; } |
| | | 45 | | [JsonPropertyName("is_analog")] public bool IsAnalog { get; set; } |
| | | 46 | | [JsonPropertyName("url")] public string Url { get; set; } = string.Empty; |
| | | 47 | | [JsonPropertyName("image_url")] public string? ImageUrl { get; set; } |
| | | 48 | | [JsonPropertyName("availability")] public string? Availability { get; set; } |
| | | 49 | | [JsonPropertyName("delivery")] public string? Delivery { get; set; } |
| | | 50 | | [JsonPropertyName("price")] public string? Price { get; set; } |
| | | 51 | | } |
| | | 52 | | |
| | | 53 | | /// <summary>Формат ошибки парсера: <c>{"status":"error","code":"…","message":"…","retry":true}</c>.</summary> |
| | | 54 | | internal sealed class PartsnavigatorErrorBody |
| | | 55 | | { |
| | | 56 | | [JsonPropertyName("code")] public string? Code { get; set; } |
| | | 57 | | [JsonPropertyName("message")] public string? Message { get; set; } |
| | | 58 | | [JsonPropertyName("retry")] public bool Retry { get; set; } |
| | | 59 | | } |
| | | 60 | | |
| | | 61 | | public enum PartsnavigatorStatus |
| | | 62 | | { |
| | | 63 | | Found, |
| | | 64 | | NotFound, |
| | | 65 | | Error |
| | | 66 | | } |
| | | 67 | | |
| | | 68 | | /// <summary>Итог запроса к парсеру без исключений наружу: найдено, нет такого артикула или сбой (с признаком повтора).< |
| | | 69 | | public sealed record PartsnavigatorResult( |
| | | 70 | | PartsnavigatorStatus Status, |
| | | 71 | | PartsnavigatorLookup? Lookup = null, |
| | | 72 | | string? ErrorCode = null, |
| | | 73 | | string? Message = null, |
| | | 74 | | bool Retry = false, |
| | | 75 | | string? MatchedBrand = null) |
| | | 76 | | { |
| | | 77 | | public static PartsnavigatorResult Found(PartsnavigatorLookup lookup) => new(PartsnavigatorStatus.Found, lookup); |
| | | 78 | | public static PartsnavigatorResult NotFound(string? message = null) => new(PartsnavigatorStatus.NotFound, null, "NOT |
| | | 79 | | public static PartsnavigatorResult Failure(string code, string message, bool retry) => new(PartsnavigatorStatus.Erro |
| | | 80 | | } |