Skip to content

Commit 10022fe

Browse files
docs(agentex-ui): tighten comments to the non-obvious
Trim redundant/verbose comments across the account-picker BFF layer (drop lines that restate the code or repeat a docstring); no behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 6b8fb8f commit 10022fe

7 files changed

Lines changed: 34 additions & 62 deletions

File tree

agentex-ui/app/api/_lib/bff.ts

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
1-
/**
2-
* Server-only platform API upstream, shared by the platform-backed BFF routes
3-
* (/api/feedback, /api/user-info). SGP_API_URL preferred; falls back to the dashboard
4-
* app origin's /api.
5-
*/
1+
/** Server-only platform API base for the BFF routes. Prefers SGP_API_URL, else the app URL. */
62
export const SGP_BASE_URL =
73
process.env.SGP_API_URL ??
84
(process.env.NEXT_PUBLIC_SGP_APP_URL
95
? `${process.env.NEXT_PUBLIC_SGP_APP_URL}/api`
106
: undefined);
117

128
/**
13-
* Apply BFF credentials to an outgoing upstream request's `headers`, in place, so no
14-
* credential reaches client JS. Shared by every /api/* proxy (agentex, platform):
15-
* - `x-selected-account-id` from the client (sourced from the account_id query param);
16-
* forwarded as-is — the upstream authorizes the principal's access to the account.
17-
* - any client-supplied `authorization` is dropped so a client can't inject its own
18-
* bearer token; the request cookies are forwarded for the upstream's cookie auth.
9+
* Attach credentials to an upstream request's `headers` in place, so none reach client JS:
10+
* forward `x-selected-account-id` (the upstream authorizes the account), drop any
11+
* client-sent `authorization`, and forward cookies for the upstream's own auth.
1912
*/
2013
export async function applyBffCredentials(
2114
req: Request,
@@ -25,7 +18,6 @@ export async function applyBffCredentials(
2518
if (accountId) headers.set('x-selected-account-id', accountId);
2619
else headers.delete('x-selected-account-id');
2720

28-
// Credentials are server-managed: never trust a client-sent Authorization header.
2921
headers.delete('authorization');
3022

3123
const cookie = req.headers.get('cookie');

agentex-ui/app/api/agentex/[...path]/route.ts

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
11
import { applyBffCredentials } from '@/app/api/_lib/bff';
22

33
/**
4-
* BFF proxy for the Agentex API. The browser ALWAYS calls this same-origin route, so
5-
* the backend origin + credentials never touch client JS. Credentials (access token
6-
* or forwarded cookies, plus x-selected-account-id) are applied server-side by
7-
* applyBffCredentials — see app/api/_lib/bff.ts.
4+
* Same-origin BFF proxy for the Agentex API, so the upstream URL and credentials never
5+
* reach client JS. applyBffCredentials attaches credentials server-side.
86
*/
97
export const dynamic = 'force-dynamic';
108

11-
// Server-only upstream — the client only ever calls /api/agentex, so the backend URL
12-
// stays out of the browser bundle.
139
const UPSTREAM = (
1410
process.env.AGENTEX_API_URL ?? 'http://localhost:5003'
1511
).replace(/\/$/, '');
1612

17-
// Hop-by-hop request headers to drop before forwarding. Credential headers (`cookie`,
18-
// `authorization`) are intentionally NOT listed here: applyBffCredentials owns them — it
19-
// deletes any client-supplied values and sets the server-managed ones — so the same
20-
// stripping applies to every /api/* proxy, not just this route.
13+
// Hop-by-hop headers to drop. Credential headers (cookie/authorization) are handled by
14+
// applyBffCredentials, not here.
2115
const STRIP_REQ = ['host', 'connection', 'content-length'];
2216
const STRIP_RES = [
2317
'content-encoding',

agentex-ui/app/api/feedback/route.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,7 @@ export async function POST(request: Request) {
7878
);
7979
}
8080

81-
// Same server-side credentials the agentex proxy forwards (access token or cookies,
82-
// plus x-selected-account-id) — the client never sends them.
81+
// Credentials attached server-side (see applyBffCredentials).
8382
const sgpHeaders = new Headers({ 'Content-Type': 'application/json' });
8483
await applyBffCredentials(request, sgpHeaders);
8584
const now = new Date().toISOString();

agentex-ui/app/api/user-info/route.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,9 @@ import { NextResponse } from 'next/server';
33
import { applyBffCredentials, SGP_BASE_URL } from '@/app/api/_lib/bff';
44

55
/**
6-
* BFF proxy for the one SGP endpoint agentex-ui needs client-side: the caller's
7-
* accounts (access_profiles), used to bootstrap / switch the selected account. Scoped
8-
* to just this path — deliberately NOT a catch-all SGP proxy — so the browser can't
9-
* reach arbitrary SGP endpoints with the server-attached credentials.
6+
* Scoped BFF proxy for the caller's accounts (access_profiles), used to bootstrap/switch
7+
* the selected account. Only this path is exposed — not a catch-all — so the browser can't
8+
* reach arbitrary platform endpoints with the server-attached credentials.
109
*/
1110
export const dynamic = 'force-dynamic';
1211

agentex-ui/components/account-picker/account-picker.tsx

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@ export function AccountPicker({
3737
const profiles = useMemo(() => data?.access_profiles ?? [], [data]);
3838
const selectedId = selectedAccountId ?? undefined;
3939

40-
// Reset (not just invalidate) account-scoped data on a switch. invalidate keeps the
41-
// previous data cached during the refetch, so the new account would briefly render the
42-
// old account's agents (HomeView) before recalibrating; reset clears it so we show a
43-
// loading state instead. user-info is preserved — the account list doesn't change.
40+
// Reset (not invalidate) account-scoped data on switch: invalidate keeps the old data
41+
// cached during refetch, briefly showing the previous account's agents. user-info is
42+
// preserved — the account list doesn't change on switch.
4443
const resetAccountScoped = useCallback(
4544
() =>
4645
queryClient.resetQueries({
@@ -73,8 +72,8 @@ export function AccountPicker({
7372

7473
if (!accountsEnabled) return null;
7574

76-
// A size-9 icon tile — the collapsed-rail footprint. Shared by the loading placeholder
77-
// (muted) and the single-account display (solid, with the name as a tooltip).
75+
// Size-9 collapsed-rail tile — shared by the loading placeholder (muted) and the
76+
// single-account display (solid).
7877
const iconTile = (opts?: { muted?: boolean; title?: string | undefined }) => (
7978
<div
8079
title={opts?.title}
@@ -89,8 +88,7 @@ export function AccountPicker({
8988
</div>
9089
);
9190

92-
// While accounts load, show a disabled, empty picker (icon only) instead of a skeleton
93-
// block — keeps the row stable and reads as a loading account selector.
91+
// Loading: a disabled, empty picker (icon only) rather than a skeleton — keeps the row stable.
9492
if (isLoading) {
9593
return collapsed ? (
9694
iconTile({ muted: true })
@@ -123,8 +121,7 @@ export function AccountPicker({
123121
);
124122

125123
if (collapsed) {
126-
// Single account → static icon; multiple → an icon-only trigger whose dropdown pops
127-
// out beside the collapsed rail (Radix keeps it in view).
124+
// Single → static icon; multiple → icon-only trigger (dropdown pops out beside the rail).
128125
if (single) return iconTile({ title: current?.account.name });
129126
return (
130127
<Select value={selectedId ?? ''} onValueChange={onAccountChange}>
@@ -142,8 +139,7 @@ export function AccountPicker({
142139
);
143140
}
144141

145-
// A single account needs no switcher — show it as static context, matching the New Chat
146-
// button's size + spacing (size-5 icon, p-2, medium weight).
142+
// Single account: no switcher, just static context (matches the New Chat button).
147143
if (single) {
148144
return (
149145
<div

agentex-ui/components/providers/agentex-provider.tsx

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,19 @@ import {
2020
interface AgentexContextValue {
2121
agentexClient: AgentexSDK;
2222
sgpAppURL: string;
23-
// Whether the platform API is configured, so the account picker can fetch/switch accounts
23+
// Platform API configured the account picker can fetch/switch accounts.
2424
accountsEnabled: boolean;
25-
// Selected account id (from the `account_id` query param) + a setter that mirrors it
26-
// to the URL and updates the header the SDK sends.
25+
// Selected account (from the `account_id` param) + a setter that mirrors it to the URL.
2726
selectedAccountId: string | null;
2827
setSelectedAccountId: (id: string, replace?: boolean) => void;
2928
}
3029

3130
const AgentexContext = createContext<AgentexContextValue | null>(null);
3231

3332
/**
34-
* Main provider. The SDK ALWAYS targets the same-origin BFF proxy (`/api/agentex`), which
35-
* forwards credentials server-side. The selected account travels as the
36-
* `x-selected-account-id` header, sourced from the `account_id` query param — no cookie
37-
* involved.
33+
* The SDK always targets the same-origin BFF (`/api/agentex`), which attaches credentials
34+
* server-side. The selected account rides as `x-selected-account-id`, from the `account_id`
35+
* query param.
3836
*/
3937
export function AgentexProvider({
4038
children,
@@ -47,9 +45,8 @@ export function AgentexProvider({
4745
}) {
4846
const { sgpAccountID, updateParams } = useSafeSearchParams();
4947

50-
// Synchronous source for the SDK's per-request header. Seeded from the URL and kept in
51-
// sync with it; setSelectedAccountId also sets it synchronously so a switch's refetch doesn't
52-
// race the (async) URL navigation.
48+
// Synchronous source for the SDK header: setSelectedAccountId sets it before the (async)
49+
// URL navigation, so a switch's refetch doesn't race it.
5350
const selectedAccountIdRef = useRef<string | null>(sgpAccountID);
5451
useEffect(() => {
5552
selectedAccountIdRef.current = sgpAccountID;
@@ -61,8 +58,8 @@ export function AgentexProvider({
6158
updateParams(
6259
{
6360
[SearchParamKey.SGP_ACCOUNT_ID]: id,
64-
// An explicit switch (not the initial bootstrap, which passes replace) drops the
65-
// open task — it's account-scoped and won't resolve under the new account.
61+
// An explicit switch (not bootstrap, which passes replace) drops the open task:
62+
// it's account-scoped and won't resolve under the new account.
6663
...(replace ? {} : { [SearchParamKey.TASK_ID]: null }),
6764
},
6865
replace
@@ -72,9 +69,8 @@ export function AgentexProvider({
7269
);
7370

7471
const agentexClient = useMemo(() => {
75-
// The SDK builds request URLs with `new URL()`, so the base must be ABSOLUTE. On the
76-
// server `window` is absent, but no request fires during the initial server render
77-
// (react-query fetches on the client); the client render recomputes an absolute URL.
72+
// The SDK builds URLs with `new URL()`, so the base must be absolute. `window` is absent
73+
// on the server, but no request fires during SSR; the client render recomputes it.
7874
const baseURL =
7975
typeof window !== 'undefined'
8076
? `${window.location.origin}/api/agentex`

agentex-ui/hooks/use-user-info.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,7 @@ type UserInfo = { access_profiles: AccessProfile[] };
1616

1717
export const userInfoKey = ['user-info'] as const;
1818

19-
/**
20-
* Fetches the caller's accounts (access_profiles) via the scoped `/api/user-info` BFF
21-
* proxy, to bootstrap / switch the selected account. `enabled` gates the fetch (off when
22-
* the platform API isn't configured).
23-
*/
19+
/** Caller's accounts (access_profiles) via /api/user-info; `enabled` off when unconfigured. */
2420
export function useUserInfo(enabled: boolean) {
2521
return useQuery({
2622
queryKey: userInfoKey,
@@ -30,8 +26,8 @@ export function useUserInfo(enabled: boolean) {
3026
if (!res.ok) throw new Error(`user-info: ${res.status}`);
3127
return res.json();
3228
},
33-
// The account list is stable for the session — fetch once, don't refetch on remount
34-
// (e.g. the account_id navigation) or focus.
29+
// The account list is stable for the session — don't refetch on the account_id
30+
// navigation or window focus.
3531
staleTime: Infinity,
3632
refetchOnWindowFocus: false,
3733
});

0 commit comments

Comments
 (0)