Files
Stirling-PDF/app
ConnorYoh 31d52d4c32 Connect flow for self-hosted account linking, and the triggers that drive it (#7415)
Replaces the bare account-link login box with a guided Connect flow, and
wires up the triggers that actually put it in front of someone.
## Top bar 
<img width="1580" height="422" alt="image"
src="https://github.com/user-attachments/assets/719e12fc-121a-4caa-bc72-124c5167b011"
/>

## The modal

Three steps on the portal's own `FlowModal` + `StepModalHeader`, the
shells procurement and prepay already wear:

1. **What you unlock** — six benefits as a plain list.
<img width="817" height="503" alt="image"
src="https://github.com/user-attachments/assets/4644ddd2-6181-44e1-9be9-7a961972195d"
/>

2. **Sign in** — the existing `SupabaseLoginForm`, reseated.
<img width="880" height="930" alt="image"
src="https://github.com/user-attachments/assets/fc66cbbb-9f98-40a4-9daa-4f2447713f39"
/>

3. **Connected** — confirms, then deep links into Users, Pipelines and
Policies.
<img width="876" height="752" alt="image"
src="https://github.com/user-attachments/assets/28358e4d-a44f-4118-a8ae-8275984ebd00"
/>


Re-auth stays a single step with no pitch and no success screen.

## The triggers

**`LinkGate` stops being dead code.** It was built as the drop-anywhere
"link to unlock" wrapper and was imported by nothing. It is now a
blocking empty state that replaces the feature it guards, wired into
Pipelines, Policies, Users, Sources and Integrations.

**Scoped to creating and editing, never viewing.** Existing pipelines,
policies, sources and connections keep listing and running, so upgrading
an unlinked instance cannot take away something that already works. The
clicks that would open a builder or a create modal ask for the
connection first, which is the moment an admin has already declared
intent.

## Capability signal

`accountLinkAvailable` on `/api/v1/config/app-config`. Gating needs two
facts: whether the instance is linked (`LinkContext`) and whether it
*could* be (this flag). The account-link endpoints 404 when the feature
flag is off, which the client cannot distinguish from "not linked yet" —
so gating on link state alone would lock all five views on every default
install with no way out. `useConnectGate` holds that decision in one
place and shares the app-config query key, so it costs no extra request.

Read from the environment rather than `AccountLinkProperties` because
`:core` cannot depend on `:proprietary`.
2026-09-01 10:39:57 +00:00
..