namespace PRecAnnot.Abstractions; public sealed record RuntimeDiagnostic { public required string Code { get; init; } public required string Message { get; init; } public string Severity { get; init; } = "Warning"; } public enum OrthoDetectionStatus { Confirmed, NotOrtho, Ambiguous, Unsupported, Failed } public enum PlantProjectDetectionStatus { NotFound, FoundWithName, FoundWithoutDisplayName, Ambiguous, Failed } public sealed record OrthoDetectionResult { public required OrthoDetectionStatus Status { get; init; } public required IReadOnlyList Evidence { get; init; } public required IReadOnlyList Diagnostics { get; init; } } public readonly record struct Point2Dto(double X, double Y); public readonly record struct Point3Dto(double X, double Y, double Z); public readonly record struct Vector2Dto(double X, double Y); public sealed record Bounds2Dto(Point2Dto Minimum, Point2Dto Maximum); public sealed record GeometrySnapshot { public Point3Dto? WorldPosition { get; init; } public Point2Dto? PaperPosition { get; init; } public Bounds2Dto? ProjectedBounds { get; init; } public double? Rotation { get; init; } public double? Elevation { get; init; } } public sealed record OrthoViewportInfo { public required string Id { get; init; } public required string DisplayName { get; init; } public double CenterX { get; init; } public double CenterY { get; init; } public double Width { get; init; } public double Height { get; init; } public double Scale { get; init; } public double TwistAngle { get; init; } public bool IsOn { get; init; } public bool IsLocked { get; init; } public string? SourceDrawingName { get; init; } public string? ViewName { get; init; } } public sealed record PlantObjectSnapshot { public required string SnapshotId { get; init; } public required string ObjectClass { get; init; } public string? Tag { get; init; } public string? LineNumber { get; init; } public string? SupportNumber { get; init; } public string? EquipmentNumber { get; init; } public required GeometrySnapshot Geometry { get; init; } public IReadOnlyDictionary Properties { get; init; } = new Dictionary(); public IReadOnlyList Diagnostics { get; init; } = Array.Empty(); public ViewMembershipStatus MembershipStatus { get; init; } = ViewMembershipStatus.NotResolved; public IReadOnlyList MembershipEvidenceCodes { get; init; } = Array.Empty(); } public enum ViewMembershipStatus { NotResolved, Resolved, PartiallyResolved, ObjectOutsideView, Unsupported, Failed } public sealed record PlantRuntimeContext { public bool HasActiveDocument { get; init; } public bool HasPlantProject { get; init; } public bool IsOrthoDrawing { get; init; } public string? DrawingName { get; init; } public string? ProjectDisplayName { get; init; } public PlantProjectDetectionStatus ProjectDetectionStatus { get; init; } = PlantProjectDetectionStatus.NotFound; public IReadOnlyList Viewports { get; init; } = Array.Empty(); public IReadOnlyList Diagnostics { get; init; } = Array.Empty(); public OrthoDetectionResult Detection { get; init; } = new() { Status = OrthoDetectionStatus.Unsupported, Evidence = Array.Empty(), Diagnostics = Array.Empty() }; } public interface IPlantRuntimeContextReader { PlantRuntimeContext ReadCurrentContext(); } public interface IOrthoViewportReader { IReadOnlyList ReadViewports(CancellationToken cancellationToken); } public enum SourceDrawingResolutionStatus { Resolved, NotReferenced, Ambiguous, MissingFromProject, Unsupported, Failed } public sealed record OrthoSourceDrawingReference { public required string StableId { get; init; } public required string DisplayName { get; init; } public string? ProjectRelativePath { get; init; } public long? ProjectDrawingRowId { get; init; } public required SourceDrawingResolutionStatus Status { get; init; } public IReadOnlyList EvidenceCodes { get; init; } = Array.Empty(); } public sealed record SourcePlantObjectSnapshot { public required string StableObjectKey { get; init; } public required string ClassName { get; init; } public string? SourceDrawingStableId { get; init; } public string? LineGroupStableKey { get; init; } public IReadOnlyDictionary Properties { get; init; } = new Dictionary(); } public sealed record SourceDrawingReadResult { public required OrthoSourceDrawingReference Source { get; init; } public IReadOnlyList Objects { get; init; } = Array.Empty(); public IReadOnlyList Diagnostics { get; init; } = Array.Empty(); } public interface IOrthoSourceDrawingResolver { IReadOnlyList Resolve(OrthoDrawingSnapshot drawing); } public sealed record OrthoDrawingSnapshot { public required string StableId { get; init; } public IReadOnlyList Views { get; init; } = Array.Empty(); } public sealed record OrthoViewSourceSnapshot { public required string ViewStableId { get; init; } public IReadOnlyList ReferencedDrawingPaths { get; init; } = Array.Empty(); } public interface ISourceDrawingDataLinksReader { SourceDrawingReadResult Read(PlantProjectContext project, OrthoSourceDrawingReference source); } public sealed record PlantProjectContext { public required string StableProjectId { get; init; } public string? ProjectDisplayName { get; init; } } public enum AnnotationOperationKind { Create, Update, Skip, Conflict, Unsupported } public sealed record AnnotationOperationPlan { public required string SourceSnapshotId { get; init; } public required AnnotationOperationKind Kind { get; init; } public string? AnnotationType { get; init; } public string? Text { get; init; } public Point2Dto? Position { get; init; } public double? Rotation { get; init; } public string? ExistingAnnotationId { get; init; } public required IReadOnlyList Reasons { get; init; } } public sealed record AnnotationPlanSummary { public int ObjectsExamined { get; init; } public int CreateCount { get; init; } public int UpdateCount { get; init; } public int SkipCount { get; init; } public int ConflictCount { get; init; } public int UnsupportedCount { get; init; } public int WarningCount { get; init; } public int ErrorCount { get; init; } } public sealed record AnnotationPlanningRequest { public required string CommandName { get; init; } public required OrthoViewportInfo Viewport { get; init; } public IReadOnlyList Objects { get; init; } = Array.Empty(); public IReadOnlyList Existing { get; init; } = Array.Empty(); } public interface IAnnotationPlanBuilder { AnnotationPlan Build(AnnotationPlanningRequest request); } public enum PRecAnnotExecutionMode { Smoke, DryRun, Apply } public interface IRuntimeWriteGuard { void EnsureWriteAllowed(string operation); } public sealed record OrthoViewportRef(string DrawingId, string ViewportId); public sealed record PlantObjectData { public required string ObjectId { get; init; } public required string ClassName { get; init; } public string? LineNumber { get; init; } public string? Tag { get; init; } public string? DisplayName { get; init; } public required AnnotationPoint Position { get; init; } public double Rotation { get; init; } } public readonly record struct AnnotationPoint(double X, double Y, double Z = 0); public sealed record ExistingAnnotation(string StableKey, string? Text, AnnotationPoint Position); public sealed record AnnotationRequest { public required OrthoViewportRef Viewport { get; init; } public required IReadOnlyList Objects { get; init; } public required IReadOnlyList Existing { get; init; } } public sealed record AnnotationIntent { public required string StableKey { get; init; } public required string Text { get; init; } public required AnnotationPoint Position { get; init; } public required double Rotation { get; init; } public required string ClassName { get; init; } public required string Layer { get; init; } } public sealed record AnnotationPlan { public int PlanSchemaVersion { get; init; } public string PlanId { get; init; } = string.Empty; public string CommandName { get; init; } = string.Empty; public IReadOnlyList Operations { get; init; } = Array.Empty(); public IReadOnlyList Diagnostics { get; init; } = Array.Empty(); public AnnotationPlanSummary Summary { get; init; } = new(); public required IReadOnlyList Create { get; init; } public required IReadOnlyList Update { get; init; } public required IReadOnlyList Delete { get; init; } public required IReadOnlyList SkipReasons { get; init; } public int ExaminedCount { get; init; } public bool IsDeterministic { get; init; } = true; } public interface IPlantProjectContext { bool IsPlantProjectOpen { get; } string? ProjectName { get; } } public interface IOrthoDrawingContext { bool IsOrthoDrawing { get; } IReadOnlyList GetViewports(); } public interface IPlantObjectReader { IReadOnlyList ReadObjects(OrthoViewportInfo viewport, CancellationToken cancellationToken); } public interface IAnnotationRepository { IReadOnlyList FindExisting(OrthoViewportRef viewport); AnnotationWriteResult Apply(AnnotationPlan plan, CancellationToken cancellationToken); } public sealed record AnnotationWriteResult(int Created, int Updated, int Deleted, int Skipped); public interface IAnnotationRuleEngine { AnnotationPlan BuildPlan(AnnotationRequest request); } public sealed record CommandUsageEvent { public required string CommandName { get; init; } public required string ResultStatus { get; init; } public int ObjectsExamined { get; init; } public int AnnotationsCreated { get; init; } public int AnnotationsUpdated { get; init; } public int AnnotationsDeleted { get; init; } public int AnnotationsSkipped { get; init; } public int WarningCount { get; init; } public int ErrorCount { get; init; } public long DurationMilliseconds { get; init; } public DateTimeOffset TimestampUtc { get; init; } = DateTimeOffset.UtcNow; } public interface ICommandUsageSink { void Record(CommandUsageEvent usageEvent); }