diff --git a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberEditCommands.cs b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberEditCommands.cs index 879ca13..288f40a 100644 --- a/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberEditCommands.cs +++ b/Plant3D2026/P_Rec_Annot/src/PRecAnnot.Plant3D2026/LineNumberEditCommands.cs @@ -50,6 +50,16 @@ internal static class LineNumberEditCommands if (document is null) return; try { + // These legacy editing paths are mutating commands. Until each + // command has a permit that binds its selected owned block and + // requested edit, DryRun must remain read-only rather than letting + // an editor prompt accidentally commit a transaction. + if (!IsApply()) + { + document.Editor.WriteMessage($"\n{command} preview boundary: Apply permit is required; DWG не изменён."); + RuntimeDiagnostics.Write("LineNumberEditPreviewCompleted", commandName: command, resultStatus: "ApplyPermitRequired", document: document); + return; + } var options = new PromptEntityOptions($"\n{prompt}"); options.SetRejectMessage("\nТребуется вхождение блока PXP-LN."); options.AddAllowedClass(typeof(BlockReference), true); @@ -67,4 +77,6 @@ internal static class LineNumberEditCommands document.Editor.WriteMessage($"\n{command}: {exception.Message}"); } } + + private static bool IsApply() => string.Equals(Environment.GetEnvironmentVariable("P_REC_ANNOT_RUNTIME_MODE"), "Apply", StringComparison.OrdinalIgnoreCase); } diff --git a/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/LineNumberEditCommandRegistrationTests.cs b/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/LineNumberEditCommandRegistrationTests.cs index 3ec83f2..bc09e63 100644 --- a/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/LineNumberEditCommandRegistrationTests.cs +++ b/Plant3D2026/P_Rec_Annot/tests/PRecAnnot.Core.Tests/LineNumberEditCommandRegistrationTests.cs @@ -53,6 +53,10 @@ public sealed class LineNumberEditCommandRegistrationTests Assert.Contains("if (!IsApply())", refresh); Assert.Contains("LINE_NUMBER_REFRESH_APPLY_REQUIRES_EXACTLY_ONE_OPERATION", refresh); Assert.Contains("LineNumberApplyPermitReader.Validate", refresh); + + var edits = File.ReadAllText(Path.Combine(ProjectRoot, "LineNumberEditCommands.cs")); + Assert.Contains("if (!IsApply())", edits); + Assert.Contains("Apply permit is required", edits); Assert.Contains("PlantLineNumberCandidateReader", refresh); Assert.Contains("LineNumberCommandPreviewService", refresh); Assert.Contains("ApplyEdits", refresh);