feat: record p-rec-annot selected-view automation evidence
This commit is contained in:
@@ -41,6 +41,7 @@ internal static class AutoAnnotateViewCommand
|
|||||||
var bubbles = classifications.Count(x => x.Representation == OrthoAnnotationRepresentation.BubbleBlock);
|
var bubbles = classifications.Count(x => x.Representation == OrthoAnnotationRepresentation.BubbleBlock);
|
||||||
document.Editor.WriteMessage($"\nPXP-AAV preview: examined={plan.Summary.ObjectsExamined}; create={plan.Summary.CreateCount}; update={plan.Summary.UpdateCount}; leaders={leaders}; bubbles={bubbles}; skip={plan.Summary.SkipCount}; conflicts={plan.Summary.ConflictCount}; PlanId={plan.PlanId}. DWG не изменён.");
|
document.Editor.WriteMessage($"\nPXP-AAV preview: examined={plan.Summary.ObjectsExamined}; create={plan.Summary.CreateCount}; update={plan.Summary.UpdateCount}; leaders={leaders}; bubbles={bubbles}; skip={plan.Summary.SkipCount}; conflicts={plan.Summary.ConflictCount}; PlanId={plan.PlanId}. DWG не изменён.");
|
||||||
RuntimeDiagnostics.Write("AutoAnnotateViewPreviewCompleted", commandName: "PXP-AAV", resultStatus: "PreviewCompleted", document: document, details: new Dictionary<string, object?> { ["PlanId"] = plan.PlanId, ["ObjectsExamined"] = plan.Summary.ObjectsExamined, ["MultiLeaderCandidates"] = leaders, ["BubbleCandidates"] = bubbles });
|
RuntimeDiagnostics.Write("AutoAnnotateViewPreviewCompleted", commandName: "PXP-AAV", resultStatus: "PreviewCompleted", document: document, details: new Dictionary<string, object?> { ["PlanId"] = plan.PlanId, ["ObjectsExamined"] = plan.Summary.ObjectsExamined, ["MultiLeaderCandidates"] = leaders, ["BubbleCandidates"] = bubbles });
|
||||||
|
ScriptDrivenFirstApplyAutomation.RecordPxpAav(plan.PlanId, objects.Select(value => value.SnapshotId).OrderBy(value => value, StringComparer.Ordinal).ToArray(), viewport.Id, plan.Summary.CreateCount, plan.Summary.SkipCount, permit is not null, plan.Summary.ObjectsExamined, objects.Count(value => value.MembershipStatus == ViewMembershipStatus.Resolved));
|
||||||
if (permit is null) return;
|
if (permit is null) return;
|
||||||
if (!string.Equals(permit.ExpectedPlanId, plan.PlanId, StringComparison.Ordinal)) throw new InvalidOperationException("APPLY_PLAN_ID_MISMATCH");
|
if (!string.Equals(permit.ExpectedPlanId, plan.PlanId, StringComparison.Ordinal)) throw new InvalidOperationException("APPLY_PLAN_ID_MISMATCH");
|
||||||
var selectedSource = objects.SingleOrDefault(x => string.Equals(x.SnapshotId, permit.TargetSnapshotId, StringComparison.Ordinal)) ?? throw new InvalidOperationException("APPLY_TARGET_NOT_FOUND");
|
var selectedSource = objects.SingleOrDefault(x => string.Equals(x.SnapshotId, permit.TargetSnapshotId, StringComparison.Ordinal)) ?? throw new InvalidOperationException("APPLY_TARGET_NOT_FOUND");
|
||||||
@@ -60,6 +61,7 @@ internal static class AutoAnnotateViewCommand
|
|||||||
var outcome = new FirstLimitedPipeAnnotationWriter().Write(document, preflight.Operation, permit.VisibilityState, permit.AnnotationTemplateDwgPath);
|
var outcome = new FirstLimitedPipeAnnotationWriter().Write(document, preflight.Operation, permit.VisibilityState, permit.AnnotationTemplateDwgPath);
|
||||||
document.Editor.WriteMessage("\nPXP-AAV Apply: " + outcome + "; AutoCAD UNDO is available.");
|
document.Editor.WriteMessage("\nPXP-AAV Apply: " + outcome + "; AutoCAD UNDO is available.");
|
||||||
RuntimeDiagnostics.Write("AutoAnnotateViewApplyCompleted", commandName: "PXP-AAV", resultStatus: outcome.ToString(), document: document, details: new Dictionary<string, object?> { ["PlanId"] = plan.PlanId });
|
RuntimeDiagnostics.Write("AutoAnnotateViewApplyCompleted", commandName: "PXP-AAV", resultStatus: outcome.ToString(), document: document, details: new Dictionary<string, object?> { ["PlanId"] = plan.PlanId });
|
||||||
|
ScriptDrivenFirstApplyAutomation.RecordApplyOutcome(outcome);
|
||||||
}
|
}
|
||||||
catch (Exception exception) { RuntimeDiagnostics.Write("AutoAnnotateViewFailed", "ERROR", commandName: "PXP-AAV", resultStatus: exception.Message, exception: exception, document: document); document.Editor.WriteMessage("\nPXP-AAV: " + exception.Message); }
|
catch (Exception exception) { RuntimeDiagnostics.Write("AutoAnnotateViewFailed", "ERROR", commandName: "PXP-AAV", resultStatus: exception.Message, exception: exception, document: document); document.Editor.WriteMessage("\nPXP-AAV: " + exception.Message); }
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -14,7 +14,7 @@ namespace PRecAnnot.Plant3D2026;
|
|||||||
// Test-only observer. The AutoCAD /b processor, never this type, drives PXP-OA.
|
// Test-only observer. The AutoCAD /b processor, never this type, drives PXP-OA.
|
||||||
internal static class ScriptDrivenFirstApplyAutomation
|
internal static class ScriptDrivenFirstApplyAutomation
|
||||||
{
|
{
|
||||||
private sealed record Config(string Phase, string OrthoDrawingPath, string EvidencePath, string FixtureMarkerPath, string ExpectedEntryAssemblySha256, bool Diagnostic);
|
private sealed record Config(string Phase, string OrthoDrawingPath, string EvidencePath, string FixtureMarkerPath, string ExpectedEntryAssemblySha256, string TargetCommand, bool Diagnostic);
|
||||||
private sealed record Run(int Sequence, string? PlanId, IReadOnlyList<string> Candidates, string? View, int Create, int Skip, bool? PermitAccepted, string? ApplyOutcome, int? DbmodBefore, int? DbmodAfter, AutomationEntityCounts? Before, AutomationEntityCounts? After, bool WillStart, bool Ended, bool Failed, bool Cancelled, int? SourceRows, int? MembershipResolved);
|
private sealed record Run(int Sequence, string? PlanId, IReadOnlyList<string> Candidates, string? View, int Create, int Skip, bool? PermitAccepted, string? ApplyOutcome, int? DbmodBefore, int? DbmodAfter, AutomationEntityCounts? Before, AutomationEntityCounts? After, bool WillStart, bool Ended, bool Failed, bool Cancelled, int? SourceRows, int? MembershipResolved);
|
||||||
private static Config? config;
|
private static Config? config;
|
||||||
private static Document? fixture;
|
private static Document? fixture;
|
||||||
@@ -93,6 +93,8 @@ internal static class ScriptDrivenFirstApplyAutomation
|
|||||||
if (!last.WillStart || last.PlanId is not null) return;
|
if (!last.WillStart || last.PlanId is not null) return;
|
||||||
runs[^1] = last with { PlanId = planId, Candidates = candidates, View = view, Create = create, Skip = skip, PermitAccepted = permitAccepted, SourceRows = sourceRows, MembershipResolved = membershipResolved };
|
runs[^1] = last with { PlanId = planId, Candidates = candidates, View = view, Create = create, Skip = skip, PermitAccepted = permitAccepted, SourceRows = sourceRows, MembershipResolved = membershipResolved };
|
||||||
}
|
}
|
||||||
|
internal static void RecordPxpAav(string? planId, IReadOnlyList<string> candidates, string? view, int create, int skip, bool? permitAccepted, int sourceRows, int membershipResolved) =>
|
||||||
|
RecordPxpOa(planId, candidates, view, create, skip, permitAccepted, sourceRows, membershipResolved);
|
||||||
|
|
||||||
internal static void RecordApplyOutcome(PipeAnnotationWriteOutcome outcome)
|
internal static void RecordApplyOutcome(PipeAnnotationWriteOutcome outcome)
|
||||||
{
|
{
|
||||||
@@ -184,7 +186,7 @@ internal static class ScriptDrivenFirstApplyAutomation
|
|||||||
private static AutomationCommandCorrelationEvidence Correlate(string kind, object sender, string rawName, bool sequenceAccepted)
|
private static AutomationCommandCorrelationEvidence Correlate(string kind, object sender, string rawName, bool sequenceAccepted)
|
||||||
{
|
{
|
||||||
var normalized = rawName.Trim();
|
var normalized = rawName.Trim();
|
||||||
var command = string.Equals(normalized, "PXP-OA", StringComparison.OrdinalIgnoreCase);
|
var command = config is not null && string.Equals(normalized, config.TargetCommand, StringComparison.OrdinalIgnoreCase);
|
||||||
var state = prepared && !terminal && config is not null && fixture is not null && database is not null;
|
var state = prepared && !terminal && config is not null && fixture is not null && database is not null;
|
||||||
var senderDocument = sender as Document;
|
var senderDocument = sender as Document;
|
||||||
var senderPath = senderDocument?.Name;
|
var senderPath = senderDocument?.Name;
|
||||||
@@ -218,7 +220,9 @@ internal static class ScriptDrivenFirstApplyAutomation
|
|||||||
{
|
{
|
||||||
var path = Environment.GetEnvironmentVariable("P_REC_ANNOT_AUTOMATION_CONFIG") ?? throw new InvalidOperationException("AUTOMATION_CONFIG_MISSING");
|
var path = Environment.GetEnvironmentVariable("P_REC_ANNOT_AUTOMATION_CONFIG") ?? throw new InvalidOperationException("AUTOMATION_CONFIG_MISSING");
|
||||||
using var json = JsonDocument.Parse(File.ReadAllText(path)); var root = json.RootElement;
|
using var json = JsonDocument.Parse(File.ReadAllText(path)); var root = json.RootElement;
|
||||||
return new(root.GetProperty("phase").GetString() ?? "Preview", root.GetProperty("orthoDrawingPath").GetString() ?? throw new InvalidOperationException("AUTOMATION_ORTHO_PATH_REQUIRED"), root.GetProperty("evidencePath").GetString() ?? throw new InvalidOperationException("AUTOMATION_EVIDENCE_PATH_REQUIRED"), root.GetProperty("fixtureMarkerPath").GetString() ?? throw new InvalidOperationException("AUTOMATION_MARKER_PATH_REQUIRED"), root.GetProperty("entryAssemblySha256").GetString() ?? throw new InvalidOperationException("AUTOMATION_ENTRY_ASSEMBLY_HASH_REQUIRED"), root.TryGetProperty("diagnostic", out var diagnostic) && diagnostic.ValueKind == JsonValueKind.True);
|
var target = root.TryGetProperty("targetCommand", out var command) ? command.GetString() : "PXP-OA";
|
||||||
|
if (string.IsNullOrWhiteSpace(target) || !target.All(value => char.IsAsciiLetterOrDigit(value) || value is '-' or '_')) throw new InvalidOperationException("AUTOMATION_TARGET_COMMAND_INVALID");
|
||||||
|
return new(root.GetProperty("phase").GetString() ?? "Preview", root.GetProperty("orthoDrawingPath").GetString() ?? throw new InvalidOperationException("AUTOMATION_ORTHO_PATH_REQUIRED"), root.GetProperty("evidencePath").GetString() ?? throw new InvalidOperationException("AUTOMATION_EVIDENCE_PATH_REQUIRED"), root.GetProperty("fixtureMarkerPath").GetString() ?? throw new InvalidOperationException("AUTOMATION_MARKER_PATH_REQUIRED"), root.GetProperty("entryAssemblySha256").GetString() ?? throw new InvalidOperationException("AUTOMATION_ENTRY_ASSEMBLY_HASH_REQUIRED"), target, root.TryGetProperty("diagnostic", out var diagnostic) && diagnostic.ValueKind == JsonValueKind.True);
|
||||||
}
|
}
|
||||||
private static void RequireGate(Config value)
|
private static void RequireGate(Config value)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user