service

Revit Panel (React in WebView2)

The React UI inside the add-in's dockable pane. Owns what a person sees and every decision they make; owns no Revit knowledge at all.

ServiceImplemented in the add-in

What it owns

The review surface. Which classifications a person accepts, which duplicate parameters they merge and onto what, and what they are told before they decide.

It compiles into assets/ inside the add-in and is served from a virtual host, so it ships as part of the same binary (ADR-5).

What it must never assume

Danger

🔴 Two of the five parameter commands can refuse, and one of them freezes Revit for half a minute with no Stop. Both facts are in the wire-name declarations the panel keeps, because a UI built against a happier assumption is a UI that misreports the add-in to whoever is using it.

  • revit.paramsSurvey was measured at 27,909 ms on a 734-type building, all of it holding Revit’s main loop. ⚠️ Pass an explicit timeoutMs. The client default is 30,000 ms, so by the only measurement anyone has taken it does survive — with 2.1 seconds of margin, on the smallest model this will ever meet. Do not rely on that. And do not show a Stop button — the command takes no cancellation source and nothing inside it checks a token, so the button would do nothing, which is worse than not offering one.
  • revit.paramsDryRun returns canApply: false and a whyNotApply sentence. Show it. A dry run beside no apply button leaves a person to work out whether the button is missing or the feature is broken.
  • A timeout is not a failure. A long command that outlives its timeout still finishes, and its answer is recoverable through buildplan.getLastClassification or buildplan.getLastWriteBack (ADR-17). The panel used to drop those answers on the floor.
  • buildplan.takeGuardNotices DRAINS. Call it once and render what comes back; a second call returns nothing and that is not the same as “nothing happened”.

The contract, kept honest from both sides

The wire names are declared in TypeScript and in C#, and each side’s suite asserts the same values — plus two exhaustive checks that neither side can carry a name the other does not. That pair exists because a name added in C# and forgotten in TypeScript is a command the panel can never call, and the reverse is one the add-in answers “unknown” to. Both fail only at runtime, in front of a user.

What it does not do

  • It never calls the BuildPlan API itself (ADR-9). Everything goes through the add-in, which owns the credential and the cache.
  • It holds the review in progress, including the mapping decisions, which travel in the command payload rather than being stored in the model (ADR-31). ⚠️ That stops being sufficient the moment a review has to survive a Revit restart, and the ADR says what lands then.