Skip to content

VisioScripting public-API pre-lock cleanup (Phases B + C) #182

Description

@saveenr

Actionable follow-up to the hybrid-public-API decision in #156. This issue covers the pre-lock cleanup that must land before #131 starts the gitbook write-up.

Scope

Two phases. Phase A (dead-method removal) is deferred to CY27 per the project's "improve before audience-reducing changes" guiding principle, tracked separately.

Phase B — Boundary-leak facade methods

The audit under #156 found two cmdlet patterns that bypass the Client facade. Add facade methods, migrate consumers, internalize the previously-leaked types/methods.

Loaders leak (VisioScripting.Loaders.*.LoadFromXml(...)):

  • Add Client.Model.LoadDirectedGraphFromXml(XDocument) returning DirectedGraphDocument
  • Add Client.Model.LoadOrgChartFromXml(XDocument) returning OrgChartDocument
  • Migrate ImportVisioModel.cs to call the new facade methods
  • Migrate the 2 tests in VTest.Models/ that call DirectedGraphDocumentLoader.LoadFromXml(...) / OrgChartDocumentLoader.LoadFromXml(...) directly
  • Mark DirectedGraphDocumentLoader and OrgChartDocumentLoader internal
  • Drop the unused LoadFromXml(client, string filename) overload on DirectedGraphDocumentLoader (no external caller)

Dimensions leak (VisioScripting.Models.*Dimensions.Get_*Dimensions(...)):

  • Add Client.Page.GetPageDimensions(TargetPages) returning List<Models.PageDimensions>
  • Add Client.Selection.GetShapeDimensions(TargetShapes) returning List<Models.ShapeDimensions> (placement-of-convenience; a dedicated ShapeCommands is a larger architectural question, deferred)
  • Migrate MeasureVisioPage.cs and MeasureVisioShape.cs
  • Mark the static factory methods internal. Keep the PageDimensions / ShapeDimensions types public (they are return values)

Phase C — Enforcement layer

Apply the layered enforcement strategy from #156 Q2.

  • Mark VisioScripting.Helpers/* types internal (5 files: ArrangeHelper, InteropHelper, ReflectionHelper, SelectionHelper, TextHelper, WildcardHelper). Add [InternalsVisibleTo(...)] for VisioPowerShell and the four test projects (VTest, VTest.Models, VTest.Scripting, VTest.PowerShell). Relocate the one external test of WildcardHelper to VTest's internal-test scope or use the InternalsVisibleTo path
  • Mark CommandTarget and CommandTargetFlags internal
  • Mark Client.GetCommandTarget(flags) either internal or, if that breaks the *Commands plumbing, public with [EditorBrowsable(Never)] and an XML doc comment
  • Sweep VisioScripting.Models/* for any types not appearing in any public signature, mark them internal
  • Add [EditorBrowsable(Never)] + XML doc comments to any types that have to stay public for signature reasons but are not part of the contract
  • Write ADR at docs/decisions/visioscripting-public-api.md capturing the hybrid contract — what is in, what is out, the enforcement layers, and the rationale (point at the #156 decision comment)
  • Add a paragraph to CLAUDE.md per-commit conventions section noting that public surface changes on VisioScripting.Client / *Commands classes are breaking changes

Out of scope

  • Phase A — dead-method removal. ~36 unused public methods + dead LayerCommands class + 4 unused OutputCommands methods + ContainerrCommands.cs filename typo. Tracked in the CY27 follow-up issue (filed alongside this one).
  • PublicAPI.Shipped.txt analyzer. Deferred per #156 Q2; can be added later if drift becomes a real problem.
  • Architectural question "should there be a ShapeCommands class?" Deferred.

Acceptance

  • All Phase B and Phase C task-list items above checked off
  • Build clean across the solution
  • All 230 tests still pass
  • ADR landed
  • CLAUDE.md updated

Blocks

  • #131 (document VisioScripting.Client on gitbook). After this lands, #131 writes against the locked surface.

References

  • Decision and rationale: #156 closing comment
  • Usage audit findings (informs the *Commands placements for new facade methods): #156 discussion thread

Effort

M. ~9 hours total: Phase B ~6h, Phase C ~3h. Separable into two PRs if convenient.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions