Hybrid portal — May 2026: The cloud portal at /dashboard is the canonical entry point for every developer. Read-only views (feature envs, PRs, pipelines, audit, agents) and cloud-side writes (provision, deploy, refresh, teardown, cherry-pick, RBAC) run server-side under the platform-admin SPN — zero local install required. The Fabric Dev tray app described below is only needed when you need to edit code locally (TMDL, dbt models) or run things against local DuckDB. See the canonical developer journey below.
Developer Dashboard
The Developer Dashboard is split in two halves: the cloud portal at /dashboard (Entra-gated, always on) and the local Fabric Dev tray app that owns the loopback FastAPI UI and handles fabric-dev:// deep links from the cloud side.
What it does
The dashboard gives you all feature environments at a glance (status, branch, profile, age), typed forms with validation for every scripts/fabric subcommand (provision, teardown, deploy, refresh, cherry-pick, and more), a cherry-pick queue for promoting commits across environment branches, a Jobs tray that streams live stdout/stderr from any running script, and access that is gated via the FP GER Develop Entra group — the same group required to run the CLI directly.
Canonical developer journey (Day 0 → Day 4)
This is the v1 acceptance flow from the hybrid portal spec §9.
| Day | Step | Cloud URL | Runs where |
|---|---|---|---|
| 0 | IT adds you to FP GER Develop. Open the portal. Live grid of every feature env. Zero install. | /dashboard | Cloud |
| 1 | Click New feature env. Choose profile + developers + seed strategy, submit. ~90 s to provision Fabric workspaces under the platform-admin SPN. Progress visible in Runs. | /feature-envs/new | Cloud |
| 2 | On the env detail page, click Open locally. Browser dispatches fabric-dev://open-feature?slug=... to the tray; tray creates a git worktree and opens VS Code. Edit TMDL / dbt models. | /feature-envs/detail?slug=… | Cloud → tray → editor |
| 2 (later) | Push the feature branch. Click Deploy (scope: Both) on the detail page. fabric-cicd runs cloud-side; log streams in-page. | /feature-envs/detail?slug=… | Cloud |
| 3 | In the worktree: dbt build --target local against DuckDB for bronze→gold modelling. Tray heartbeat appears at /operations/agents. | — | Local (tray) |
| 4 | Approve + merge the PR. Teardown on the detail page cleans up workspaces. Tray's fabric-dev://teardown-local?slug=... removes the local worktree (after OS confirm). | /feature-envs/detail?slug=… | Cloud → tray |
Onboarding (3 steps)
1. Sign in to the cloud portal
Visit /dashboard and sign in with your Geris Entra account. You can already use every read-only view and every cloud-side action (provision, refresh, deploy, teardown, cherry-pick) from any browser — phone included.
2. Install the Fabric Dev tray app (only when you need to edit locally)
See Local Tray App for the MSIX install steps. After install:
- The tray icon (blue "F") starts at every login.
fabric-dev:URLs from the portal are dispatched automatically.- Click Sign in (az login) in the tray menu once to register your Entra session.
The tray bundles the existing loopback dashboard (formerly scripts/fabric-ui.cmd) and the fabric-dev:// URL handler in one MSIX. The legacy pip install -r requirements.txt + double-click fabric-ui.cmd flow is retired.
3. Optional — clone the repo for dbt/TMDL editing
git clone https://geris-devops@dev.azure.com/geris-devops/insights-requests/_git/fabric_monorepo
cd fabric_monorepo
On first fabric-dev:// click that needs a worktree, the tray app prompts you for this path and persists the choice at %APPDATA%/fabric-dev/config.json (Windows) / ~/Library/Application Support/fabric-dev/ (macOS) / ~/.config/fabric-dev/ (Linux).
How to add a new command
The loopback UI served by the tray app at
http://127.0.0.1:8765is separate from the cloud portal. Commands in the local UI are declared inscripts/fabric_ui/jobs/registry.pyand are NOT the same as cloud portal API routes. The legacyfabric-ui.cmdlauncher is fully retired — the tray app owns the loopback UI lifecycle now. See Local Tray App.
All local dashboard commands are declared in scripts/fabric_ui/jobs/registry.py. Add a new Command entry to the REGISTRY list:
from scripts.fabric_ui.jobs.registry import Command, Arg, REGISTRY
REGISTRY.append(
Command(
name="my-command",
label="My new command",
script=["bash", "scripts/my_script.sh"],
args=[
Arg("feature", "feature-picker", required=True, positional=True,
help="Target feature environment."),
Arg("mode", "enum", required=True, cli_flag="--mode",
choices=("fast", "full")),
],
lock_key=lambda args: f"feature:{args.get('feature', '_unknown')}",
exclusive=True,
destructive=False,
contributor_required=True,
help="Short description shown in the form header.",
)
)
The dashboard picks up the new entry on next launch — no template changes needed. Argument types available:
| Type | Rendered as |
|---|---|
string | Free-text input |
feature-picker | Dropdown populated from live environment list |
enum | Select with fixed choices |
upn-chips | Multi-value UPN input (email addresses) |
file | File picker |
flag | Checkbox |
Set destructive=True to require the user to type the feature name as confirmation before the form submits.
Security
- Loopback only. uvicorn binds to
127.0.0.1— the dashboard is never reachable from the network. - CSRF protection. Every state-changing request requires a session-scoped CSRF token set by the launcher.
- Host / Origin allowlist. The server rejects requests whose
HostorOriginheader is notlocalhost:8765or127.0.0.1:8765, blocking DNS-rebinding attacks. azgate. On every form submission the server callsaz account showto verify an active session and then checks the caller's Entra group membership (FP GER Develop) via Microsoft Graph. Cached for 15 minutes;force_auth_recheck=Truecommands bypass the cache.- No git writes. The dashboard never commits, pushes, or modifies any file in the repository. All mutations happen through the same scripts the CLI calls.
Related Pages
- Cloud Portal — Page Reference — Per-page breakdown of every live cloud portal route
- Developer Workflow — End-to-end feature lifecycle
- Local Development Setup — Prerequisites and DuckDB walkthrough
- Feature Provisioning Profiles — Profile decision tree
- Local Tray App — Install +
fabric-dev://URL scheme