From b6ca2f7b21fa32f361146c6b5f8012fbcfd34e70 Mon Sep 17 00:00:00 2001 From: Shahovalov MIkhail Date: Wed, 27 May 2026 18:38:33 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20drawing=5Fadd=5Fdiametral=5Fdimension?= =?UTF-8?q?=20=E2=80=94=20=D1=83=D0=BF=D1=80=D0=BE=D1=87=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20?= =?UTF-8?q?Codex=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=B0=D1=86=D0=B8?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #2: инвариант диаметра value>0 (value<=0||!IsFinite, не Abs<1e-6). #3: сообщение create_standard_views обобщено (номера видов для инструментов размеров). #4a: ToRadians проверяет конечность результата (переполнение). #5d: тест viewNumber:999 (вид не найден). #6: комментарий DimensionType переформулирован (COM-дефолт). Тесты: DrawingDiametralTests 4→5. Итого 141 unit + 77 integration = 218. Co-Authored-By: Claude Opus 4.7 (1M context) --- ...26-05-27-drawing-diametral-dimension-design.md | 14 +++++++++++++- .../Drawings/DimensionOrientation.cs | 5 ++++- src/Kompas.Mcp.Core/Drawings/DrawingService.cs | 7 ++++--- src/Kompas.Mcp.Host/Tools/DrawingTools.cs | 2 +- .../Integration/DrawingDiametralTests.cs | 15 +++++++++++++++ 5 files changed, 37 insertions(+), 6 deletions(-) diff --git a/docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md b/docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md index 221691c..9fefbbe 100644 --- a/docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md +++ b/docs/superpowers/specs/2026-05-27-drawing-diametral-dimension-design.md @@ -1,7 +1,19 @@ # Дизайн: диаметральный размер на виде чертежа (drawing_add_diametral_dimension) через API7 **Дата:** 2026-05-27 -**Статус:** реализовано и проверено (4 интеграционных + unit, всего 217); ревью Codex спека учтено +**Статус:** реализовано и проверено (5 интеграционных + unit, всего 218); ревью Codex спека и реализации учтено + +## Правки по ревью реализации Codex + +- **#2** инвариант диаметра: пост-проверка `value <= 0 || !double.IsFinite(value)` (а не `Abs<1e-6`). +- **#3** сообщение `drawing_create_standard_views` обобщено: «номера видов для инструментов размеров». +- **#4a** `DimensionAngles.ToRadians` — проверка конечности результата (защита от переполнения). +- **#5d** тест `viewNumber: 999` (виды есть, номер не найден) — покрывает ветку FindView. +- **#6** комментарий `DimensionType` переформулирован (просто COM-дефолт, без претензии на «стиль»). +- **#4b** минимальный радиус — отклонён (`>0` честный контракт). **#5a/#5b/#5c** (реальная окружность, + read-back угла, пост-Add откат) — отклонены (инструмент geometry-agnostic; ToRadians покрыт unit; + пост-Add сбой для radius>0 не форсировать). Транзитный сбой пакета (нестабильность КОМПАС после + большого прогона) не воспроизводится — повторный прогон 5/5 зелёный. ## Правки по ревью Codex diff --git a/src/Kompas.Mcp.Core/Drawings/DimensionOrientation.cs b/src/Kompas.Mcp.Core/Drawings/DimensionOrientation.cs index 0c463d4..a7290ac 100644 --- a/src/Kompas.Mcp.Core/Drawings/DimensionOrientation.cs +++ b/src/Kompas.Mcp.Core/Drawings/DimensionOrientation.cs @@ -21,7 +21,10 @@ public static class DimensionAngles { if (!double.IsFinite(degrees)) throw new ArgumentException("Угол должен быть конечным числом.", nameof(degrees)); - return degrees * Math.PI / 180.0; + var result = degrees * (Math.PI / 180.0); + if (!double.IsFinite(result)) // защита от переполнения на экстремальных degrees + throw new ArgumentOutOfRangeException(nameof(degrees), "Угол слишком велик (переполнение при переводе в радианы)."); + return result; } } diff --git a/src/Kompas.Mcp.Core/Drawings/DrawingService.cs b/src/Kompas.Mcp.Core/Drawings/DrawingService.cs index 458c2d5..8cb8b6c 100644 --- a/src/Kompas.Mcp.Core/Drawings/DrawingService.cs +++ b/src/Kompas.Mcp.Core/Drawings/DrawingService.cs @@ -158,7 +158,8 @@ public sealed class DrawingService try { dim.Xc = xc; dim.Yc = yc; dim.Radius = radius; dim.Angle = angleRad; - // DimensionType (стиль линии) не задаём — принимаем COM-дефолт (стандартный стиль). + // DimensionType (стиль размерной линии) не задаём — оставляем COM-дефолт (полярность bool + // не подтверждена; дефолт даёт валидный размер с верным значением — проверено спайком). ((IDimensionText)dim).AutoNominalValue = true; if (!dim.Update()) @@ -167,8 +168,8 @@ public sealed class DrawingService throw new InvalidOperationException("Диаметральный размер построен невалидным."); var value = ((IDimensionText)dim).NominalValue; // диаметр = 2·radius - if (Math.Abs(value) < 1e-6) - throw new InvalidOperationException("Диаметральный размер измерил нулевое значение."); + if (value <= 0 || !double.IsFinite(value)) // инвариант диаметра: строго положительный + throw new InvalidOperationException($"Диаметральный размер измерил некорректное значение ({value})."); return new DrawingDimensionResult { Value = value, ViewNumber = view.Number }; } catch diff --git a/src/Kompas.Mcp.Host/Tools/DrawingTools.cs b/src/Kompas.Mcp.Host/Tools/DrawingTools.cs index 7ea265b..93cbec5 100644 --- a/src/Kompas.Mcp.Host/Tools/DrawingTools.cs +++ b/src/Kompas.Mcp.Host/Tools/DrawingTools.cs @@ -26,7 +26,7 @@ public sealed class DrawingTools(KompasSession session, DrawingService drawing) var r = await drawing.CreateStandardViewsAsync(partFilePath, scale, x, y); var numbers = string.Join(", ", r.ViewNumbers); return $"Создано {r.Created} стандартных вида на чертеже (всего видов: {r.Total}, масштаб {scale}). " + - $"Номера созданных видов: {numbers} (для drawing_add_linear_dimension)."; + $"Номера созданных видов: {numbers} (для инструментов простановки размеров — параметр viewNumber)."; } [McpServerTool(Name = "drawing_fill_title_block")] diff --git a/tests/Kompas.Mcp.Tests/Integration/DrawingDiametralTests.cs b/tests/Kompas.Mcp.Tests/Integration/DrawingDiametralTests.cs index 0dcfac5..6b21991 100644 --- a/tests/Kompas.Mcp.Tests/Integration/DrawingDiametralTests.cs +++ b/tests/Kompas.Mcp.Tests/Integration/DrawingDiametralTests.cs @@ -98,4 +98,19 @@ public sealed class DrawingDiametralTests : IntegrationTestBase } finally { await _docs.CloseAsync(save: false); } } + + [Fact] + public async Task Unknown_view_number_throws() + { + var partFile = await BuildAndSaveBoxAsync(); + await _docs.CreateAsync(KompasDocumentType.Drawing); + try + { + await _drawing.CreateStandardViewsAsync(partFile, 1.0, 100, 150); + // Виды есть, но номер 999 не существует → ветка FindView "вид не найден". + await Assert.ThrowsAsync(() => + _drawing.AddDiametralDimensionAsync(viewNumber: 999, xc: 0, yc: 0, radius: 10, angleDeg: 0)); + } + finally { await _docs.CloseAsync(save: false); } + } }