← All frames
Installations · Frame (g) · route /apps/:appId/installations

Installation states

The states the installations surface must render: loading, no installations yet, a load failure, read-only for a caller who can't manage scopes, the orphaned-target edge case (target portal removed/suspended → status, not crash), the remove confirmation, and the cross-tenant add denial.

(g1) Loading

Installations

Loading…

(g2) No installations yet

Installations

0 scopes

Not installed anywhere yet

This app isn't scoped to any organization, portal or user. Add an installation to make it available to a target you administer.

(g3) Couldn't load
(g4) Read-only — caller can't manage scopes (fail-closed)
TargetScope levelStatus
Northwind Inc.
organization Active
(g5) Orphaned target — portal removed/suspended → status, never a crash
TargetScope levelStatus
Legacy portal prt_legacy · target no longer resolvable
portal Target removed
The install row renders from its own record even when the target can't be resolved — it shows an orphaned status and stays removable. It never throws or blanks the table.
(g6) Confirm remove installation
(g7) Add to a target outside your authority — 403, in place

Contract (anticipated). (g1) in-flight GET …/installations. (g2) empty is a real state — an app installed nowhere. (g3) non-2xx with retry. (g4) read-only is fail-closed: no Add/Remove rendered. (g5) is the edge the epic calls out: an installation whose target portal was removed/suspended renders data-installation-status="orphaned" from its own record and stays removable — it must not crash or blank the list. (g6) remove is DELETE …/installations/{id} behind a confirm. (g7) add authorizes the target via Permit; a target outside the caller's authority is 403 FORBIDDEN_TARGET, in place.

Review · app-management approve or reject each flow ↓
app-listpendingApproveReject
app-detailpendingApproveReject
installationspendingApproveReject