@burdenoff/microfe-atheletebridge 2026.1031.1 → 2026.1031.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/atheletebridge/components/ai/AiModelPicker.d.ts.map +1 -1
- package/dist/atheletebridge/components/ai/AiModelPicker.js +17 -3
- package/dist/atheletebridge/components/ai/AiModelPicker.js.map +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
- package/dist/atheletebridge/types/index.d.ts +6 -0
- package/dist/atheletebridge/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiModelPicker.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/components/ai/AiModelPicker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAqBH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+
|
|
1
|
+
{"version":3,"file":"AiModelPicker.d.ts","sourceRoot":"","sources":["../../../../src/atheletebridge/components/ai/AiModelPicker.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAqBH,wBAAgB,aAAa,CAAC,EAAE,SAAS,EAAE,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BAyNlE"}
|
|
@@ -15,9 +15,10 @@ function C({ className: C }) {
|
|
|
15
15
|
return !e || A.some((t) => S(t) === S(e)) ? A : [{
|
|
16
16
|
provider: e.provider,
|
|
17
17
|
model: e.model,
|
|
18
|
-
label: "
|
|
18
|
+
label: "Retired model saved by this workspace",
|
|
19
19
|
isDefault: !1,
|
|
20
|
-
capabilities: []
|
|
20
|
+
capabilities: [],
|
|
21
|
+
configured: !1
|
|
21
22
|
}, ...A];
|
|
22
23
|
}, [A, T.data]), P = O ?? M, F = N.find((e) => S(e) === P) ?? null, I = !!O && O !== M, L = T.data?.autoPilotEnabled ?? !1, R = T.data?.autoPilotLastRunAt ?? null;
|
|
23
24
|
return /* @__PURE__ */ _(b, {
|
|
@@ -67,7 +68,8 @@ function C({ className: C }) {
|
|
|
67
68
|
e.provider,
|
|
68
69
|
"/",
|
|
69
70
|
e.model,
|
|
70
|
-
e.isDefault ? " (default)" : ""
|
|
71
|
+
e.isDefault ? " (default)" : "",
|
|
72
|
+
e.configured ? "" : " (not available on this deployment)"
|
|
71
73
|
]
|
|
72
74
|
}, S(e)))]
|
|
73
75
|
})
|
|
@@ -116,6 +118,18 @@ function C({ className: C }) {
|
|
|
116
118
|
children: [/* @__PURE__ */ _(f, { className: "h-3.5 w-3.5" }), " Saved"]
|
|
117
119
|
})]
|
|
118
120
|
}),
|
|
121
|
+
F && !F.configured && /* @__PURE__ */ v("p", {
|
|
122
|
+
role: "status",
|
|
123
|
+
className: "mt-3 rounded-lg border border-status-warning-border bg-status-warning-bg-subtle px-3 py-2 text-sm text-status-warning-text",
|
|
124
|
+
children: [
|
|
125
|
+
F.provider,
|
|
126
|
+
"/",
|
|
127
|
+
F.model,
|
|
128
|
+
" cannot be called on this deployment (no API key is configured for ",
|
|
129
|
+
F.provider,
|
|
130
|
+
"). Decisions will run on the next available provider, and the agent activity feed shows which model answered each one."
|
|
131
|
+
]
|
|
132
|
+
}),
|
|
119
133
|
F && F.capabilities.length > 0 && /* @__PURE__ */ _("div", {
|
|
120
134
|
className: "mt-2 flex flex-wrap gap-1.5",
|
|
121
135
|
children: F.capabilities.map((e) => /* @__PURE__ */ _("span", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AiModelPicker.js","names":[],"sources":["../../../../src/atheletebridge/components/ai/AiModelPicker.tsx"],"sourcesContent":["/**\n * AI model picker + autopilot control\n * @module atheletebridge/components/ai\n *\n * The workspace's saved (provider, model) pair — read from\n * `athWorkspaceAiConfig`, chosen from `athAiModelCatalog`, saved with\n * `athSetWorkspaceAiModel` — plus the per-workspace autopilot opt-in\n * (`athSetWorkspaceAutoPilot`).\n *\n * The autopilot copy is deliberately unglamorous. The loop only ever records a\n * PROPOSED adjustment that a coach still has to accept, and it is additionally\n * gated by the `ATHELETEBRIDGE_AGENT_LOOP_ENABLED` deployment kill switch,\n * which is OFF in production. A toggle that implies \"the AI now coaches for\n * you\" would be a lie in both directions, so it says exactly what it does.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Bot, Check, Cpu, Loader2, Save } from 'lucide-react';\nimport { Badge, GlassCard, Switch } from '@burdenoff/fe-libs/ui';\nimport { FormField, fieldInputClass } from '../form';\nimport {\n useAiModelCatalog,\n useSetWorkspaceAiModel,\n useSetWorkspaceAutoPilot,\n useWorkspaceAiConfig,\n} from '../../hooks/useAthleteBridgeApi';\nimport type { AthAiModelInfo } from '../../types';\nimport { formatDate } from '../../utils/formatters';\nimport { timeAgo } from '../../utils/timeAgo';\nimport { AiErrorNotice } from './AiErrorNotice';\n\n/** Stable option key. Model ids are provider-specific, so both parts matter. */\nconst optionKey = (entry: Pick<AthAiModelInfo, 'provider' | 'model'>): string =>\n `${entry.provider}::${entry.model}`;\n\nexport function AiModelPicker({ className }: { className?: string }) {\n const catalog = useAiModelCatalog();\n const config = useWorkspaceAiConfig();\n const setModel = useSetWorkspaceAiModel();\n const setAutoPilot = useSetWorkspaceAutoPilot();\n\n const [draftKey, setDraftKey] = useState<string | null>(null);\n\n const catalogEntries = useMemo(() => catalog.data ?? [], [catalog.data]);\n const defaultEntry = useMemo(\n () => catalogEntries.find((entry) => entry.isDefault) ?? null,\n [catalogEntries]\n );\n\n // The saved pair, or the catalog default when the workspace has never chosen\n // one (a null config means \"using the platform default chain\", not an error).\n const savedKey = config.data\n ? optionKey(config.data)\n : defaultEntry\n ? optionKey(defaultEntry)\n : '';\n\n // A saved pair that is no longer in the catalog still has to be selectable,\n // or the select silently displays a DIFFERENT model than the one in force.\n const entries = useMemo(() => {\n const saved = config.data;\n if (!saved || catalogEntries.some((entry) => optionKey(entry) === optionKey(saved))) {\n return catalogEntries;\n }\n return [\n {\n provider: saved.provider,\n model: saved.model,\n label: 'Saved by this workspace',\n isDefault: false,\n capabilities: [],\n },\n ...catalogEntries,\n ];\n }, [catalogEntries, config.data]);\n const selectedKey = draftKey ?? savedKey;\n const selectedEntry = entries.find((entry) => optionKey(entry) === selectedKey) ?? null;\n const isDirty = Boolean(draftKey) && draftKey !== savedKey;\n\n const autoPilotEnabled = config.data?.autoPilotEnabled ?? false;\n const lastRunAt = config.data?.autoPilotLastRunAt ?? null;\n\n const handleSave = () => {\n if (!selectedEntry) {\n return;\n }\n setModel.mutate(\n { provider: selectedEntry.provider, model: selectedEntry.model },\n { onSuccess: () => setDraftKey(null) }\n );\n };\n\n return (\n <GlassCard treatment=\"insight\" className={className}>\n <div className=\"p-6\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <Cpu className=\"h-5 w-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Model</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n The provider and model every AthleteBridge decision runs on. A named provider is a\n first preference, not a lock — the service still falls back through the rest of the\n chain if it cannot answer.\n </p>\n </div>\n </div>\n\n <div className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-[minmax(0,1fr)_auto] sm:items-end\">\n <FormField label=\"Provider and model\" htmlFor=\"ai-model\">\n <select\n id=\"ai-model\"\n className={fieldInputClass}\n value={selectedKey}\n disabled={catalog.isLoading || entries.length === 0}\n onChange={(event) => setDraftKey(event.target.value)}\n >\n {entries.length === 0 && <option value=\"\">No models available</option>}\n {entries.map((entry) => (\n <option key={optionKey(entry)} value={optionKey(entry)}>\n {entry.label} — {entry.provider}/{entry.model}\n {entry.isDefault ? ' (default)' : ''}\n </option>\n ))}\n </select>\n </FormField>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={!isDirty || !selectedEntry || setModel.isPending}\n className=\"inline-flex h-[2.625rem] items-center justify-center gap-1.5 rounded-lg bg-action-primary-bg px-4 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {setModel.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n Save model\n </button>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-2 text-sm text-text-secondary\">\n {config.isLoading ? (\n <span className=\"inline-flex items-center gap-1.5\">\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" /> Loading workspace configuration…\n </span>\n ) : config.data ? (\n <>\n <span>In use:</span>\n <Badge variant=\"secondary\">\n {config.data.provider}/{config.data.model}\n </Badge>\n {selectedEntry?.isDefault && savedKey === optionKey(selectedEntry) && (\n <Badge variant=\"outline\">Platform default</Badge>\n )}\n <span className=\"text-xs text-text-muted\">\n Saved {timeAgo(config.data.updatedAt)}\n </span>\n </>\n ) : (\n <span>\n This workspace has not chosen a model, so decisions run on the platform default chain\n {defaultEntry ? ` (${defaultEntry.provider}/${defaultEntry.model})` : ''}.\n </span>\n )}\n {setModel.isSuccess && !isDirty && (\n <span className=\"inline-flex items-center gap-1 text-xs text-status-success-text\">\n <Check className=\"h-3.5 w-3.5\" /> Saved\n </span>\n )}\n </div>\n\n {selectedEntry && selectedEntry.capabilities.length > 0 && (\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {selectedEntry.capabilities.map((capability) => (\n <span\n key={capability}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {capability}\n </span>\n ))}\n </div>\n )}\n\n {catalog.isError && <AiErrorNotice className=\"mt-4\" error={catalog.error} />}\n {setModel.isError && <AiErrorNotice className=\"mt-4\" error={setModel.error} />}\n\n {/* Autopilot */}\n <div className=\"mt-6 border-t border-border-seam pt-5\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <label\n htmlFor=\"ai-autopilot\"\n className=\"flex items-center gap-2 text-sm font-medium text-text-primary\"\n >\n <Bot className=\"h-4 w-4\" aria-hidden=\"true\" />\n Autopilot\n </label>\n <p className=\"mt-1 text-sm text-text-secondary\">\n When on, a scheduled tick may assess athletes on this workspace's programs and\n record a <strong className=\"font-medium text-text-primary\">PROPOSED</strong>{' '}\n adjustment. It never changes prescribed training load — a coach still has to accept\n or override every proposal.\n </p>\n <p className=\"mt-1 text-xs text-text-muted\">\n The loop is also gated per deployment by{' '}\n <code className=\"rounded bg-bg-sunken px-1 py-0.5 font-mono\">\n ATHELETEBRIDGE_AGENT_LOOP_ENABLED\n </code>\n , which is off in production. Turning this on alone does not start anything.\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2 pt-1\">\n {setAutoPilot.isPending && (\n <Loader2 className=\"h-4 w-4 animate-spin text-text-secondary\" />\n )}\n <Switch\n id=\"ai-autopilot\"\n checked={autoPilotEnabled}\n disabled={config.isLoading || setAutoPilot.isPending}\n onCheckedChange={(checked) => setAutoPilot.mutate(checked)}\n aria-label=\"Enable autopilot for this workspace\"\n />\n </div>\n </div>\n <p className=\"mt-3 text-xs text-text-muted\">\n {lastRunAt\n ? `A scheduled tick last considered this workspace on ${formatDate(lastRunAt)} (${timeAgo(lastRunAt)}).`\n : 'No scheduled tick has considered this workspace yet.'}\n </p>\n {setAutoPilot.isError && <AiErrorNotice className=\"mt-4\" error={setAutoPilot.error} />}\n </div>\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AiModelPicker.js","names":[],"sources":["../../../../src/atheletebridge/components/ai/AiModelPicker.tsx"],"sourcesContent":["/**\n * AI model picker + autopilot control\n * @module atheletebridge/components/ai\n *\n * The workspace's saved (provider, model) pair — read from\n * `athWorkspaceAiConfig`, chosen from `athAiModelCatalog`, saved with\n * `athSetWorkspaceAiModel` — plus the per-workspace autopilot opt-in\n * (`athSetWorkspaceAutoPilot`).\n *\n * The autopilot copy is deliberately unglamorous. The loop only ever records a\n * PROPOSED adjustment that a coach still has to accept, and it is additionally\n * gated by the `ATHELETEBRIDGE_AGENT_LOOP_ENABLED` deployment kill switch,\n * which is OFF in production. A toggle that implies \"the AI now coaches for\n * you\" would be a lie in both directions, so it says exactly what it does.\n */\n\nimport { useMemo, useState } from 'react';\nimport { Bot, Check, Cpu, Loader2, Save } from 'lucide-react';\nimport { Badge, GlassCard, Switch } from '@burdenoff/fe-libs/ui';\nimport { FormField, fieldInputClass } from '../form';\nimport {\n useAiModelCatalog,\n useSetWorkspaceAiModel,\n useSetWorkspaceAutoPilot,\n useWorkspaceAiConfig,\n} from '../../hooks/useAthleteBridgeApi';\nimport type { AthAiModelInfo } from '../../types';\nimport { formatDate } from '../../utils/formatters';\nimport { timeAgo } from '../../utils/timeAgo';\nimport { AiErrorNotice } from './AiErrorNotice';\n\n/** Stable option key. Model ids are provider-specific, so both parts matter. */\nconst optionKey = (entry: Pick<AthAiModelInfo, 'provider' | 'model'>): string =>\n `${entry.provider}::${entry.model}`;\n\nexport function AiModelPicker({ className }: { className?: string }) {\n const catalog = useAiModelCatalog();\n const config = useWorkspaceAiConfig();\n const setModel = useSetWorkspaceAiModel();\n const setAutoPilot = useSetWorkspaceAutoPilot();\n\n const [draftKey, setDraftKey] = useState<string | null>(null);\n\n const catalogEntries = useMemo(() => catalog.data ?? [], [catalog.data]);\n const defaultEntry = useMemo(\n () => catalogEntries.find((entry) => entry.isDefault) ?? null,\n [catalogEntries]\n );\n\n // The saved pair, or the catalog default when the workspace has never chosen\n // one (a null config means \"using the platform default chain\", not an error).\n const savedKey = config.data\n ? optionKey(config.data)\n : defaultEntry\n ? optionKey(defaultEntry)\n : '';\n\n // A saved pair that is no longer in the catalog still has to be selectable,\n // or the select silently displays a DIFFERENT model than the one in force.\n const entries = useMemo(() => {\n const saved = config.data;\n if (!saved || catalogEntries.some((entry) => optionKey(entry) === optionKey(saved))) {\n return catalogEntries;\n }\n return [\n {\n provider: saved.provider,\n model: saved.model,\n label: 'Retired model saved by this workspace',\n isDefault: false,\n capabilities: [],\n // The service no longer calls a pair that has left the catalog; it\n // uses the provider's default model instead.\n configured: false,\n },\n ...catalogEntries,\n ];\n }, [catalogEntries, config.data]);\n const selectedKey = draftKey ?? savedKey;\n const selectedEntry = entries.find((entry) => optionKey(entry) === selectedKey) ?? null;\n const isDirty = Boolean(draftKey) && draftKey !== savedKey;\n\n const autoPilotEnabled = config.data?.autoPilotEnabled ?? false;\n const lastRunAt = config.data?.autoPilotLastRunAt ?? null;\n\n const handleSave = () => {\n if (!selectedEntry) {\n return;\n }\n setModel.mutate(\n { provider: selectedEntry.provider, model: selectedEntry.model },\n { onSuccess: () => setDraftKey(null) }\n );\n };\n\n return (\n <GlassCard treatment=\"insight\" className={className}>\n <div className=\"p-6\">\n <div className=\"flex items-start gap-3\">\n <div className=\"flex h-10 w-10 shrink-0 items-center justify-center rounded-xl bg-[var(--color-accent-soft)] text-text-primary\">\n <Cpu className=\"h-5 w-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Model</h2>\n <p className=\"mt-1 text-sm text-text-secondary\">\n The provider and model every AthleteBridge decision runs on. A named provider is a\n first preference, not a lock — the service still falls back through the rest of the\n chain if it cannot answer.\n </p>\n </div>\n </div>\n\n <div className=\"mt-5 grid grid-cols-1 gap-4 sm:grid-cols-[minmax(0,1fr)_auto] sm:items-end\">\n <FormField label=\"Provider and model\" htmlFor=\"ai-model\">\n <select\n id=\"ai-model\"\n className={fieldInputClass}\n value={selectedKey}\n disabled={catalog.isLoading || entries.length === 0}\n onChange={(event) => setDraftKey(event.target.value)}\n >\n {entries.length === 0 && <option value=\"\">No models available</option>}\n {entries.map((entry) => (\n <option key={optionKey(entry)} value={optionKey(entry)}>\n {entry.label} — {entry.provider}/{entry.model}\n {entry.isDefault ? ' (default)' : ''}\n {entry.configured ? '' : ' (not available on this deployment)'}\n </option>\n ))}\n </select>\n </FormField>\n <button\n type=\"button\"\n onClick={handleSave}\n disabled={!isDirty || !selectedEntry || setModel.isPending}\n className=\"inline-flex h-[2.625rem] items-center justify-center gap-1.5 rounded-lg bg-action-primary-bg px-4 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:cursor-not-allowed disabled:opacity-60\"\n >\n {setModel.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n Save model\n </button>\n </div>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-2 text-sm text-text-secondary\">\n {config.isLoading ? (\n <span className=\"inline-flex items-center gap-1.5\">\n <Loader2 className=\"h-3.5 w-3.5 animate-spin\" /> Loading workspace configuration…\n </span>\n ) : config.data ? (\n <>\n <span>In use:</span>\n <Badge variant=\"secondary\">\n {config.data.provider}/{config.data.model}\n </Badge>\n {selectedEntry?.isDefault && savedKey === optionKey(selectedEntry) && (\n <Badge variant=\"outline\">Platform default</Badge>\n )}\n <span className=\"text-xs text-text-muted\">\n Saved {timeAgo(config.data.updatedAt)}\n </span>\n </>\n ) : (\n <span>\n This workspace has not chosen a model, so decisions run on the platform default chain\n {defaultEntry ? ` (${defaultEntry.provider}/${defaultEntry.model})` : ''}.\n </span>\n )}\n {setModel.isSuccess && !isDirty && (\n <span className=\"inline-flex items-center gap-1 text-xs text-status-success-text\">\n <Check className=\"h-3.5 w-3.5\" /> Saved\n </span>\n )}\n </div>\n\n {selectedEntry && !selectedEntry.configured && (\n <p\n role=\"status\"\n className=\"mt-3 rounded-lg border border-status-warning-border bg-status-warning-bg-subtle px-3 py-2 text-sm text-status-warning-text\"\n >\n {selectedEntry.provider}/{selectedEntry.model} cannot be called on this deployment (no\n API key is configured for {selectedEntry.provider}). Decisions will run on the next\n available provider, and the agent activity feed shows which model answered each one.\n </p>\n )}\n\n {selectedEntry && selectedEntry.capabilities.length > 0 && (\n <div className=\"mt-2 flex flex-wrap gap-1.5\">\n {selectedEntry.capabilities.map((capability) => (\n <span\n key={capability}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {capability}\n </span>\n ))}\n </div>\n )}\n\n {catalog.isError && <AiErrorNotice className=\"mt-4\" error={catalog.error} />}\n {setModel.isError && <AiErrorNotice className=\"mt-4\" error={setModel.error} />}\n\n {/* Autopilot */}\n <div className=\"mt-6 border-t border-border-seam pt-5\">\n <div className=\"flex items-start justify-between gap-4\">\n <div className=\"min-w-0\">\n <label\n htmlFor=\"ai-autopilot\"\n className=\"flex items-center gap-2 text-sm font-medium text-text-primary\"\n >\n <Bot className=\"h-4 w-4\" aria-hidden=\"true\" />\n Autopilot\n </label>\n <p className=\"mt-1 text-sm text-text-secondary\">\n When on, a scheduled tick may assess athletes on this workspace's programs and\n record a <strong className=\"font-medium text-text-primary\">PROPOSED</strong>{' '}\n adjustment. It never changes prescribed training load — a coach still has to accept\n or override every proposal.\n </p>\n <p className=\"mt-1 text-xs text-text-muted\">\n The loop is also gated per deployment by{' '}\n <code className=\"rounded bg-bg-sunken px-1 py-0.5 font-mono\">\n ATHELETEBRIDGE_AGENT_LOOP_ENABLED\n </code>\n , which is off in production. Turning this on alone does not start anything.\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-2 pt-1\">\n {setAutoPilot.isPending && (\n <Loader2 className=\"h-4 w-4 animate-spin text-text-secondary\" />\n )}\n <Switch\n id=\"ai-autopilot\"\n checked={autoPilotEnabled}\n disabled={config.isLoading || setAutoPilot.isPending}\n onCheckedChange={(checked) => setAutoPilot.mutate(checked)}\n aria-label=\"Enable autopilot for this workspace\"\n />\n </div>\n </div>\n <p className=\"mt-3 text-xs text-text-muted\">\n {lastRunAt\n ? `A scheduled tick last considered this workspace on ${formatDate(lastRunAt)} (${timeAgo(lastRunAt)}).`\n : 'No scheduled tick has considered this workspace yet.'}\n </p>\n {setAutoPilot.isError && <AiErrorNotice className=\"mt-4\" error={setAutoPilot.error} />}\n </div>\n </div>\n </GlassCard>\n );\n}\n"],"mappings":"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"}
|
|
@@ -829,7 +829,7 @@ var ge = (e = {}) => {
|
|
|
829
829
|
let { apiGatewayUrl: t } = e();
|
|
830
830
|
return i({
|
|
831
831
|
queryKey: ["atheletebridge", "ai-model-catalog"],
|
|
832
|
-
queryFn: async () => (await u("query AthAiModelCatalog {\n athAiModelCatalog { provider model label isDefault capabilities }\n }", {}, t)).athAiModelCatalog,
|
|
832
|
+
queryFn: async () => (await u("query AthAiModelCatalog {\n athAiModelCatalog { provider model label isDefault capabilities configured }\n }", {}, t)).athAiModelCatalog,
|
|
833
833
|
staleTime: 30 * 6e4
|
|
834
834
|
});
|
|
835
835
|
}, ve = () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAthleteBridgeApi.js","names":[],"sources":["../../../src/atheletebridge/hooks/useAthleteBridgeApi.ts"],"sourcesContent":["/**\n * AthleteBridge API hooks\n * @module atheletebridge/hooks\n *\n * Thin react-query wrappers over the real `wspace-atheletebridge-svc` federated\n * GraphQL contract, reached through the workspace gateway with the workspace\n * dual-token. Every query/mutation here maps 1:1 to an `ath*` root field in the\n * service's `.hive-schema.graphql`. NO MOCKS — all data is live.\n */\n\nimport { useCallback, useMemo } from 'react';\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch, clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql';\n\nimport { useAthleteBridge } from '../context';\nimport type {\n AthAgentRun,\n AthAgentRunConnection,\n AthAgentRunOverride,\n AthAiAssessment,\n AthAiModelInfo,\n AthAvailability,\n AthAvailabilityConnection,\n AthCompleteSessionInput,\n AthCreateFixtureInput,\n AthCreateProgramInput,\n AthCreateTeamInput,\n AthAddMemberInput,\n AthAddDrillInput,\n AthBookSessionInput,\n AthDrill,\n AthFixture,\n AthFixtureConnection,\n AthFixtureStatus,\n AthGenerateProgramInput,\n AthGenerateProgramResult,\n AthLogWorkoutInput,\n AthMember,\n AthMemberConnection,\n AthMemberStatus,\n AthPerformanceMetric,\n AthPerformanceMetricConnection,\n AthPlanAdjustment,\n AthProgram,\n AthProgramConnection,\n AthProgramLevel,\n AthProgramStatus,\n AthRecordMetricInput,\n AthRecordResultInput,\n AthSession,\n AthSessionConnection,\n AthSessionStatus,\n AthSetAvailabilityInput,\n AthSport,\n AthStanding,\n AthStandingConnection,\n AthTeam,\n AthTeamConnection,\n AthTeamStatus,\n AthUpdateProgramInput,\n AthUpdateTeamInput,\n AthWorkoutLog,\n AthWorkoutLogConnection,\n AthWorkspaceAiConfig,\n PaginationInput,\n} from '../types';\n\n// ============================================================================\n// Typed errors\n// ============================================================================\n\n/** `extensions.code` for an upstream AI provider that is down or unconfigured. */\nexport const AI_PROVIDER_UNAVAILABLE = 'AI_PROVIDER_UNAVAILABLE';\n\n/**\n * A GraphQL error surfaced with its `extensions` intact.\n *\n * The svc throws stable, typed errors (`NOT_FOUND`, `CONFLICT`,\n * `FAILED_PRECONDITION`, `AI_PROVIDER_UNAVAILABLE`, `BAD_USER_INPUT`) and, for\n * AI failures, an `extensions.agentRunId` pointing at the FAILED ledger row\n * that holds every attempt's raw upstream message. Flattening all of that into\n * `new Error(message)` is what made an unconfigured provider indistinguishable\n * from a crashed service, so the code and the run id are carried through to the\n * UI instead.\n */\nexport class AthApiError extends Error {\n /** `extensions.code`, or null when the server did not send one. */\n readonly code: string | null;\n /** `extensions.agentRunId` — the ledger row to inspect, when present. */\n readonly agentRunId: string | null;\n\n constructor(message: string, extensions?: Record<string, unknown>) {\n super(message);\n this.name = 'AthApiError';\n const code = extensions?.code;\n const agentRunId = extensions?.agentRunId;\n this.code = typeof code === 'string' && code ? code : null;\n this.agentRunId = typeof agentRunId === 'string' && agentRunId ? agentRunId : null;\n }\n}\n\n/** Whether an unknown thrown value is an AI-provider outage we can explain. */\nexport const isAiProviderUnavailable = (error: unknown): error is AthApiError =>\n error instanceof AthApiError && error.code === AI_PROVIDER_UNAVAILABLE;\n\n// ============================================================================\n// Low-level query wrapper\n// ============================================================================\n\nconst athQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n const first = response.errors[0];\n throw new AthApiError(first?.message ?? 'GraphQL request failed', first?.extensions);\n }\n\n if (!response.data) {\n throw new AthApiError('GraphQL response did not include data');\n }\n\n // This MFE bypasses Apollo, so fe-libs' short-lived graphqlFetch read cache\n // would otherwise serve pre-write data to the very next refetch issued by a\n // mutation's onSuccess invalidation. Clear it after any successful mutation so\n // every downstream read is fresh (fleet-wide stale-read-after-write fix).\n if (query.trimStart().startsWith('mutation')) {\n clearGraphqlFetchResponseCache();\n }\n\n return response.data;\n};\n\n// Global-gateway read wrapper — the workspace-scoped MFE reaches the tenant user\n// directory (for real user pickers) through the global gateway.\nconst athGlobalQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'global',\n query,\n variables,\n suppressGlobalErrorEvent: true,\n });\n\n if (response.errors?.length) {\n const first = response.errors[0];\n throw new AthApiError(first?.message ?? 'GraphQL request failed', first?.extensions);\n }\n\n if (!response.data) {\n throw new AthApiError('GraphQL response did not include data');\n }\n\n return response.data;\n};\n\n// ============================================================================\n// GraphQL fragments (inline strings — exact fields from the svc schema)\n// ============================================================================\n\nconst TEAM_FIELDS = `\n id workspaceId name sport status description ageGroup season homeVenue\n headCoachId tags createdAt updatedAt\n`;\n\nconst MEMBER_FIELDS = `\n id workspaceId teamId userId displayName role status position jerseyNumber\n height weight dominantSide notes joinedAt createdAt updatedAt\n`;\n\nconst CRICKET_INNINGS_FIELDS = `\n runs wickets overs balls extras\n`;\n\nconst CRICKET_SCORECARD_FIELDS = `\n homeInnings { ${CRICKET_INNINGS_FIELDS} }\n awayInnings { ${CRICKET_INNINGS_FIELDS} }\n winner decidedBy margin superOver dls\n`;\n\nconst FIXTURE_FIELDS = `\n id workspaceId type status competition round venue homeTeamId awayTeamId\n homeScore awayScore extraTimeHomeScore extraTimeAwayScore penaltyHomeScore penaltyAwayScore\n cricketScorecard { ${CRICKET_SCORECARD_FIELDS} }\n scheduledAt kickoffAt notes createdAt updatedAt\n homeTeam { id name sport }\n awayTeam { id name sport }\n`;\n\nconst STANDING_FIELDS = `\n id workspaceId competition teamId played won drawn lost goalsFor goalsAgainst\n points rank createdAt updatedAt\n team { id name sport }\n`;\n\nconst DRILL_FIELDS = `\n id workspaceId programId name description weekNumber orderIndex sets reps\n durationSec restSec createdAt updatedAt\n video { id }\n`;\n\nconst PROGRAM_FIELDS = `\n id workspaceId coachId name sport level status summary weeks isTemplate tags\n createdAt updatedAt\n`;\n\nconst SESSION_FIELDS = `\n id workspaceId coachId athleteId programId title type status location\n meetingUrl scheduledAt durationMin completedAt feedback rating\n createdAt updatedAt\n`;\n\nconst WORKOUT_LOG_FIELDS = `\n id workspaceId athleteId programId title status performedAt durationMin rpe\n totalLoad metrics notes createdAt updatedAt\n`;\n\nconst METRIC_FIELDS = `\n id workspaceId athleteId type label value unit source recordedAt\n createdAt updatedAt\n`;\n\n// ============================================================================\n// Teams\n// ============================================================================\n\nexport interface TeamFilters {\n sport?: AthSport;\n status?: AthTeamStatus;\n pagination?: PaginationInput;\n}\n\nexport const useTeams = (filters: TeamFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'teams', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListTeams: AthTeamConnection }>(\n `query AthListTeams($sport: AthSport, $status: AthTeamStatus, $pagination: PaginationInput) {\n athListTeams(sport: $sport, status: $status, pagination: $pagination) {\n items { ${TEAM_FIELDS} members { items { id } } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n sport: filters.sport,\n status: filters.status,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListTeams;\n },\n });\n};\n\nexport const useTeam = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'team', id],\n queryFn: async () => {\n const result = await athQuery<{ athTeam: AthTeam | null }>(\n `query AthTeam($id: ID!) {\n athTeam(id: $id) {\n ${TEAM_FIELDS}\n members { items { ${MEMBER_FIELDS} } }\n fixtures { items { ${FIXTURE_FIELDS} } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athTeam;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useTeamMembers = (teamId: string | undefined, status?: AthMemberStatus) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'members', teamId, status],\n queryFn: async () => {\n const result = await athQuery<{ athListMembers: AthMemberConnection }>(\n `query AthListMembers($teamId: ID!, $status: AthMemberStatus) {\n athListMembers(teamId: $teamId, status: $status) { items { ${MEMBER_FIELDS} } }\n }`,\n { teamId, status },\n apiGatewayUrl\n );\n return result.athListMembers.items;\n },\n enabled: Boolean(teamId),\n });\n};\n\nexport const useCreateTeam = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthCreateTeamInput) => {\n const result = await athQuery<{ athCreateTeam: AthTeam }>(\n `mutation AthCreateTeam($input: AthCreateTeamInput!) {\n athCreateTeam(input: $input) { ${TEAM_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athCreateTeam;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'teams'] });\n },\n });\n};\n\nexport const useUpdateTeam = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: AthUpdateTeamInput }) => {\n const result = await athQuery<{ athUpdateTeam: AthTeam }>(\n `mutation AthUpdateTeam($id: ID!, $input: AthUpdateTeamInput!) {\n athUpdateTeam(id: $id, input: $input) { ${TEAM_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athUpdateTeam;\n },\n onSuccess: (team) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'teams'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'team', team.id] });\n },\n });\n};\n\nexport const useArchiveTeam = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athArchiveTeam: boolean }>(\n `mutation AthArchiveTeam($id: ID!) { athArchiveTeam(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athArchiveTeam;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'teams'] });\n },\n });\n};\n\nexport const useAddMember = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthAddMemberInput) => {\n const result = await athQuery<{ athAddMember: AthMember }>(\n `mutation AthAddMember($input: AthAddMemberInput!) {\n athAddMember(input: $input) { ${MEMBER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athAddMember;\n },\n onSuccess: (member) => {\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'members', member.teamId],\n });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'team', member.teamId] });\n },\n });\n};\n\nexport const useRemoveMember = (teamId?: string) => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athRemoveMember: boolean }>(\n `mutation AthRemoveMember($id: ID!) { athRemoveMember(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athRemoveMember;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'members', teamId] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'team', teamId] });\n },\n });\n};\n\n// ============================================================================\n// Fixtures & standings\n// ============================================================================\n\nexport interface FixtureFilters {\n status?: AthFixtureStatus;\n teamId?: string;\n pagination?: PaginationInput;\n}\n\nexport const useFixtures = (filters: FixtureFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'fixtures', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListFixtures: AthFixtureConnection }>(\n `query AthListFixtures($status: AthFixtureStatus, $teamId: ID, $pagination: PaginationInput) {\n athListFixtures(status: $status, teamId: $teamId, pagination: $pagination) {\n items { ${FIXTURE_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n teamId: filters.teamId,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListFixtures;\n },\n });\n};\n\nexport const useFixture = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'fixture', id],\n queryFn: async () => {\n const result = await athQuery<{ athFixture: AthFixture | null }>(\n `query AthFixture($id: ID!) {\n athFixture(id: $id) { ${FIXTURE_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athFixture;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useStandings = (competition: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'standings', competition],\n queryFn: async () => {\n const result = await athQuery<{ athStandings: AthStandingConnection }>(\n `query AthStandings($competition: String!) {\n athStandings(competition: $competition) { items { ${STANDING_FIELDS} } }\n }`,\n { competition },\n apiGatewayUrl\n );\n return result.athStandings.items;\n },\n enabled: Boolean(competition),\n });\n};\n\nexport const useScheduleFixture = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthCreateFixtureInput) => {\n const result = await athQuery<{ athScheduleFixture: AthFixture }>(\n `mutation AthScheduleFixture($input: AthCreateFixtureInput!) {\n athScheduleFixture(input: $input) { ${FIXTURE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athScheduleFixture;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'fixtures'] });\n },\n });\n};\n\nexport const useRecordFixtureResult = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: AthRecordResultInput }) => {\n const result = await athQuery<{ athRecordFixtureResult: AthFixture }>(\n `mutation AthRecordFixtureResult($id: ID!, $input: AthRecordResultInput!) {\n athRecordFixtureResult(id: $id, input: $input) { ${FIXTURE_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athRecordFixtureResult;\n },\n onSuccess: (fixture) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'fixtures'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'fixture', fixture.id] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'standings'] });\n },\n });\n};\n\n// ============================================================================\n// Programs & drills\n// ============================================================================\n\nexport interface ProgramFilters {\n sport?: AthSport;\n level?: AthProgramLevel;\n status?: AthProgramStatus;\n pagination?: PaginationInput;\n}\n\nexport const usePrograms = (filters: ProgramFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'programs', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListPrograms: AthProgramConnection }>(\n `query AthListPrograms($sport: AthSport, $level: AthProgramLevel, $status: AthProgramStatus, $pagination: PaginationInput) {\n athListPrograms(sport: $sport, level: $level, status: $status, pagination: $pagination) {\n items { ${PROGRAM_FIELDS} drills { items { id } } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n sport: filters.sport,\n level: filters.level,\n status: filters.status,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListPrograms;\n },\n });\n};\n\nexport const useProgram = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'program', id],\n queryFn: async () => {\n const result = await athQuery<{ athProgram: AthProgram | null }>(\n `query AthProgram($id: ID!) {\n athProgram(id: $id) {\n ${PROGRAM_FIELDS}\n drills { items { ${DRILL_FIELDS} } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athProgram;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthCreateProgramInput) => {\n const result = await athQuery<{ athCreateProgram: AthProgram }>(\n `mutation AthCreateProgram($input: AthCreateProgramInput!) {\n athCreateProgram(input: $input) { ${PROGRAM_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athCreateProgram;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n },\n });\n};\n\nexport const useUpdateProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: AthUpdateProgramInput }) => {\n const result = await athQuery<{ athUpdateProgram: AthProgram }>(\n `mutation AthUpdateProgram($id: ID!, $input: AthUpdateProgramInput!) {\n athUpdateProgram(id: $id, input: $input) { ${PROGRAM_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athUpdateProgram;\n },\n onSuccess: (program) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'program', program.id] });\n },\n });\n};\n\nexport const useTransitionProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: AthProgramStatus }) => {\n const result = await athQuery<{ athTransitionProgram: AthProgram }>(\n `mutation AthTransitionProgram($id: ID!, $status: AthProgramStatus!) {\n athTransitionProgram(id: $id, status: $status) { ${PROGRAM_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.athTransitionProgram;\n },\n onSuccess: (program) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'program', program.id] });\n },\n });\n};\n\nexport const useArchiveProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athArchiveProgram: boolean }>(\n `mutation AthArchiveProgram($id: ID!) { athArchiveProgram(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athArchiveProgram;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n },\n });\n};\n\nexport const useAddDrill = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthAddDrillInput) => {\n const result = await athQuery<{ athAddDrill: AthDrill }>(\n `mutation AthAddDrill($input: AthAddDrillInput!) {\n athAddDrill(input: $input) { ${DRILL_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athAddDrill;\n },\n onSuccess: (drill) => {\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'program', drill.programId],\n });\n },\n });\n};\n\nexport const useRemoveDrill = (programId?: string) => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athRemoveDrill: boolean }>(\n `mutation AthRemoveDrill($id: ID!) { athRemoveDrill(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athRemoveDrill;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'program', programId] });\n },\n });\n};\n\n// ============================================================================\n// Coaching sessions\n// ============================================================================\n\nexport interface SessionFilters {\n athleteId?: string;\n coachId?: string;\n status?: AthSessionStatus;\n pagination?: PaginationInput;\n}\n\nexport const useSessions = (filters: SessionFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'sessions', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListSessions: AthSessionConnection }>(\n `query AthListSessions($athleteId: ID, $coachId: ID, $status: AthSessionStatus, $pagination: PaginationInput) {\n athListSessions(athleteId: $athleteId, coachId: $coachId, status: $status, pagination: $pagination) {\n items { ${SESSION_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n athleteId: filters.athleteId,\n coachId: filters.coachId,\n status: filters.status,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListSessions;\n },\n });\n};\n\nexport const useSession = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'session', id],\n queryFn: async () => {\n const result = await athQuery<{ athSession: AthSession | null }>(\n `query AthSession($id: ID!) {\n athSession(id: $id) { ${SESSION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athSession;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useBookSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthBookSessionInput) => {\n const result = await athQuery<{ athBookSession: AthSession }>(\n `mutation AthBookSession($input: AthBookSessionInput!) {\n athBookSession(input: $input) { ${SESSION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athBookSession;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n },\n });\n};\n\nexport const useConfirmSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athConfirmSession: AthSession }>(\n `mutation AthConfirmSession($id: ID!) {\n athConfirmSession(id: $id) { ${SESSION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athConfirmSession;\n },\n onSuccess: (session) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'session', session.id] });\n },\n });\n};\n\nexport const useCompleteSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input?: AthCompleteSessionInput }) => {\n const result = await athQuery<{ athCompleteSession: AthSession }>(\n `mutation AthCompleteSession($id: ID!, $input: AthCompleteSessionInput) {\n athCompleteSession(id: $id, input: $input) { ${SESSION_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athCompleteSession;\n },\n onSuccess: (session) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'session', session.id] });\n },\n });\n};\n\nexport const useCancelSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athCancelSession: AthSession }>(\n `mutation AthCancelSession($id: ID!) {\n athCancelSession(id: $id) { ${SESSION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athCancelSession;\n },\n onSuccess: (session) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'session', session.id] });\n },\n });\n};\n\n// ============================================================================\n// Workout logs & performance metrics\n// ============================================================================\n\nexport interface WorkoutLogFilters {\n athleteId?: string;\n programId?: string;\n pagination?: PaginationInput;\n}\n\nexport const useWorkoutLogs = (filters: WorkoutLogFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'workout-logs', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListWorkoutLogs: AthWorkoutLogConnection }>(\n `query AthListWorkoutLogs($athleteId: ID, $programId: ID, $pagination: PaginationInput) {\n athListWorkoutLogs(athleteId: $athleteId, programId: $programId, pagination: $pagination) {\n items { ${WORKOUT_LOG_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n athleteId: filters.athleteId,\n programId: filters.programId,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListWorkoutLogs;\n },\n });\n};\n\n/**\n * An athlete's performance metrics, newest `recordedAt` first (the svc orders\n * `recordedAt: desc`). `pagination` is optional — omit it to take the server\n * default page; pass a limit when the caller needs a deeper history window than\n * the default (the svc clamps `limit` to its own ceiling, so a caller can ask\n * for more rows but never for unbounded ones).\n */\nexport const usePerformanceMetrics = (\n athleteId: string | undefined,\n pagination?: PaginationInput\n) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'metrics', athleteId, pagination ?? null],\n queryFn: async () => {\n const result = await athQuery<{ athPerformanceMetrics: AthPerformanceMetricConnection }>(\n `query AthPerformanceMetrics($athleteId: ID!, $pagination: PaginationInput) {\n athPerformanceMetrics(athleteId: $athleteId, pagination: $pagination) {\n items { ${METRIC_FIELDS} }\n }\n }`,\n { athleteId, pagination },\n apiGatewayUrl\n );\n return result.athPerformanceMetrics.items;\n },\n enabled: Boolean(athleteId),\n });\n};\n\nexport const useLogWorkout = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthLogWorkoutInput) => {\n const result = await athQuery<{ athLogWorkout: AthWorkoutLog }>(\n `mutation AthLogWorkout($input: AthLogWorkoutInput!) {\n athLogWorkout(input: $input) { ${WORKOUT_LOG_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athLogWorkout;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'workout-logs'] });\n },\n });\n};\n\nexport const useRecordMetric = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthRecordMetricInput) => {\n const result = await athQuery<{ athRecordMetric: AthPerformanceMetric }>(\n `mutation AthRecordMetric($input: AthRecordMetricInput!) {\n athRecordMetric(input: $input) { ${METRIC_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athRecordMetric;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'metrics'] });\n },\n });\n};\n\n// ============================================================================\n// Availability / RSVP (BOFF-4134)\n// ============================================================================\n\nconst AVAILABILITY_FIELDS = `\n id workspaceId memberId fixtureId sessionId response respondedAt note\n createdAt updatedAt\n member { id displayName role }\n`;\n\nexport interface AvailabilityFilters {\n fixtureId?: string;\n sessionId?: string;\n}\n\n/** Lists availability responses for a fixture OR a session. */\nexport const useAvailability = (filters: AvailabilityFilters) => {\n const { apiGatewayUrl } = useAthleteBridge();\n const { fixtureId, sessionId } = filters;\n return useQuery({\n queryKey: ['atheletebridge', 'availability', fixtureId ?? null, sessionId ?? null],\n queryFn: async () => {\n const result = await athQuery<{ athListAvailability: AthAvailabilityConnection }>(\n `query AthListAvailability($fixtureId: ID, $sessionId: ID) {\n athListAvailability(fixtureId: $fixtureId, sessionId: $sessionId) {\n items { ${AVAILABILITY_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { fixtureId, sessionId },\n apiGatewayUrl\n );\n return result.athListAvailability.items;\n },\n enabled: Boolean(fixtureId || sessionId),\n });\n};\n\nexport const useSetAvailability = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthSetAvailabilityInput) => {\n const result = await athQuery<{ athSetAvailability: AthAvailability }>(\n `mutation AthSetAvailability($input: AthSetAvailabilityInput!) {\n athSetAvailability(input: $input) { ${AVAILABILITY_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athSetAvailability;\n },\n onSuccess: (row) => {\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'availability', row.fixtureId ?? null, row.sessionId ?? null],\n });\n },\n });\n};\n\n/**\n * Nudges roster members who have not yet responded. Publishes a domain event\n * for a future notification consumer to deliver — it does not itself send\n * push/email (no delivery channel is wired up yet). Returns the number of\n * members nudged.\n */\nexport const useRemindAvailability = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: { fixtureId?: string; sessionId?: string }) => {\n const result = await athQuery<{ athRemindAvailability: number }>(\n `mutation AthRemindAvailability($fixtureId: ID, $sessionId: ID) {\n athRemindAvailability(fixtureId: $fixtureId, sessionId: $sessionId)\n }`,\n input,\n apiGatewayUrl\n );\n return result.athRemindAvailability;\n },\n });\n};\n\n// ============================================================================\n// Workspace files — drill demo videos live in wspace-files-svc, reached through\n// the same workspace gateway. Blobs never touch the atheletebridge subgraph.\n// ============================================================================\n\nconst fileExtensionOf = (fileName: string): string => {\n const dot = fileName.lastIndexOf('.');\n return dot >= 0 ? fileName.slice(dot + 1).toLowerCase() : 'bin';\n};\n\n/**\n * Upload a file to wspace-files-svc via the standard three-step flow\n * (initiateUpload → presigned PUT → completeUpload) and resolve the new file id,\n * ready to pass as `AthAddDrillInput.videoFileId`.\n */\nexport const useUploadFile = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useCallback(\n async (file: File): Promise<string> => {\n const initiated = await athQuery<{\n initiateUpload: { uploadUrl: string | null; session: { id: string } };\n }>(\n `mutation AthInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) { uploadUrl session { id } }\n }`,\n {\n input: {\n fileName: file.name,\n extension: fileExtensionOf(file.name),\n fileSize: file.size,\n mimeType: file.type || 'application/octet-stream',\n visibility: 'WORKSPACE',\n },\n },\n apiGatewayUrl\n );\n\n const uploadUrl = initiated.initiateUpload.uploadUrl;\n const sessionId = initiated.initiateUpload.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('Upload could not be initialised.');\n }\n\n const put = await fetch(uploadUrl, {\n method: 'PUT',\n body: file,\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n });\n if (!put.ok) {\n throw new Error(`Storage rejected the upload (HTTP ${put.status}).`);\n }\n\n const completed = await athQuery<{ completeUpload: { fileId: string } }>(\n `mutation AthCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) { fileId }\n }`,\n { input: { sessionId } },\n apiGatewayUrl\n );\n return completed.completeUpload.fileId;\n },\n [apiGatewayUrl]\n );\n};\n\nexport interface WorkspaceFileRef {\n id: string;\n name: string;\n downloadUrl: string | null;\n}\n\n/**\n * Resolve a wspace-files File (a drill's demo video) by id, on demand. Kept as a\n * separate lazy read so a missing/expired blob can never break the program page.\n */\nexport const useFile = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'file', id],\n queryFn: async () => {\n const result = await athQuery<{ getFile: WorkspaceFileRef | null }>(\n `query AthGetFile($id: ID!) {\n getFile(id: $id) { id name downloadUrl }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.getFile;\n },\n enabled: Boolean(id),\n staleTime: 60_000,\n });\n};\n\n// ============================================================================\n// User directory (global gateway) — resolve real users for team member add so a\n// coach never has to paste a raw UUID.\n// ============================================================================\n\nexport interface DirectoryUser {\n id: string;\n name: string | null;\n firstName: string | null;\n lastName: string | null;\n email: string;\n username: string;\n}\n\n/** Best display name for a directory user (name → first+last → username → email). */\nexport const directoryUserName = (user: DirectoryUser): string => {\n if (user.name?.trim()) return user.name.trim();\n const full = [user.firstName, user.lastName].filter(Boolean).join(' ').trim();\n if (full) return full;\n if (user.username?.trim()) return user.username.trim();\n return user.email;\n};\n\n/**\n * Search the tenant user directory by name/email. Enabled once the term is at\n * least two characters; failures are surfaced to the caller (which offers a\n * manual-id fallback) rather than as a global error toast.\n */\nexport const useUserSearch = (search: string) => {\n const term = search.trim();\n return useQuery({\n queryKey: ['atheletebridge', 'user-search', term],\n queryFn: async () => {\n const result = await athGlobalQuery<{\n users: { users: DirectoryUser[]; hasMore: boolean };\n }>(\n `query AthUserSearch($filter: UserFilterInput, $pagination: PaginationInput) {\n users(filter: $filter, pagination: $pagination) {\n users { id name firstName lastName email username }\n hasMore\n }\n }`,\n { filter: { search: term }, pagination: { limit: 8, offset: 0 } }\n );\n return result.users.users;\n },\n enabled: term.length >= 2,\n staleTime: 30_000,\n retry: false,\n });\n};\n\n// ============================================================================\n// User id resolution (global gateway) — resolve a set of user ids to real\n// names/emails for identity chips (coach/athlete), mirroring the UserSearchSelect\n// directory pattern. Batched into one aliased request, cached, and RBAC-safe:\n// on any error it degrades to an empty map so callers fall back to id-seeded\n// monograms rather than surfacing an error toast.\n// ============================================================================\n\nexport interface ResolvedUser {\n id: string;\n name: string;\n email: string | null;\n}\n\n/**\n * Resolve the given user ids to `{ id, name, email }` via the global `user(id)`\n * query (one aliased round-trip). Unknown / forbidden ids are simply absent from\n * the returned map.\n */\nexport const useUsersByIds = (ids: ReadonlyArray<string | null | undefined>) => {\n const unique = useMemo(\n () =>\n Array.from(\n new Set(ids.filter((value): value is string => Boolean(value && value.trim())))\n ).sort(),\n [ids]\n );\n\n return useQuery({\n queryKey: ['atheletebridge', 'users-by-id', unique],\n queryFn: async (): Promise<Record<string, ResolvedUser>> => {\n if (unique.length === 0) {\n return {};\n }\n const varDefs = unique.map((_, i) => `$id${i}: ID!`).join(', ');\n const selections = unique\n .map((_, i) => `u${i}: user(id: $id${i}) { id name firstName lastName email username }`)\n .join('\\n');\n const variables: Record<string, string> = {};\n unique.forEach((id, i) => {\n variables[`id${i}`] = id;\n });\n\n // Read tolerantly: don't throw on partial/RBAC errors — keep whatever\n // aliases resolved so a single forbidden id can't blank the whole feed.\n const response = await graphqlFetch<Record<string, DirectoryUser | null>>({\n gateway: 'global',\n query: `query AthUsersByIds(${varDefs}) {\\n${selections}\\n}`,\n variables,\n suppressGlobalErrorEvent: true,\n });\n\n const data = response.data ?? {};\n const map: Record<string, ResolvedUser> = {};\n for (const value of Object.values(data)) {\n if (value && value.id) {\n map[value.id] = {\n id: value.id,\n name: directoryUserName(value),\n email: value.email ?? null,\n };\n }\n }\n return map;\n },\n enabled: unique.length > 0,\n staleTime: 5 * 60_000,\n retry: false,\n });\n};\n\nexport interface UserDirectory {\n byId: Record<string, ResolvedUser>;\n isLoading: boolean;\n isError: boolean;\n /** Resolved display name for an id, or undefined while unknown. */\n nameOf: (id: string | null | undefined) => string | undefined;\n /** Resolved email for an id, or undefined while unknown. */\n emailOf: (id: string | null | undefined) => string | null | undefined;\n}\n\n/**\n * Convenience wrapper over {@link useUsersByIds} returning name/email lookup\n * helpers, so identity components can resolve ids without touching the query.\n */\nexport const useUserDirectory = (ids: ReadonlyArray<string | null | undefined>): UserDirectory => {\n const query = useUsersByIds(ids);\n const byId = query.data ?? {};\n return {\n byId,\n isLoading: query.isLoading,\n isError: query.isError,\n nameOf: (id) => (id ? byId[id]?.name : undefined),\n emailOf: (id) => (id ? byId[id]?.email : undefined),\n };\n};\n\n// ============================================================================\n// Recent activity — a unified, time-ordered feed derived PURELY from records\n// already loaded on the page (teams/fixtures/sessions/programs). No extra\n// network, no fabricated events: every item maps to a real timestamp on a real\n// row.\n// ============================================================================\n\nexport type ActivityType =\n 'team-created' | 'member-added' | 'fixture-updated' | 'program-published' | 'session-completed';\n\nexport interface ActivityItem {\n id: string;\n type: ActivityType;\n title: string;\n subtitle?: string;\n /** ISO timestamp the event occurred at. */\n at: string;\n entityId: string;\n entityKind: 'team' | 'fixture' | 'session' | 'program';\n}\n\nexport interface RecentActivityInput {\n teams?: AthTeam[];\n fixtures?: AthFixture[];\n sessions?: AthSession[];\n programs?: AthProgram[];\n /** Max items to return (newest first). Default 8. */\n limit?: number;\n}\n\n/** Derive a typed, time-ordered activity feed from already-loaded records. */\nexport const useRecentActivity = ({\n teams = [],\n fixtures = [],\n sessions = [],\n programs = [],\n limit = 8,\n}: RecentActivityInput): ActivityItem[] =>\n useMemo(() => {\n const items: ActivityItem[] = [];\n\n for (const team of teams) {\n items.push({\n id: `team-${team.id}`,\n type: 'team-created',\n title: `Team ${team.name} created`,\n at: team.createdAt,\n entityId: team.id,\n entityKind: 'team',\n });\n for (const member of team.members?.items ?? []) {\n items.push({\n id: `member-${member.id}`,\n type: 'member-added',\n title: `${member.displayName} added to ${team.name}`,\n at: member.joinedAt ?? member.createdAt,\n entityId: team.id,\n entityKind: 'team',\n });\n }\n }\n\n for (const program of programs) {\n if (program.status === 'PUBLISHED') {\n items.push({\n id: `program-${program.id}`,\n type: 'program-published',\n title: `${program.name} published`,\n at: program.updatedAt,\n entityId: program.id,\n entityKind: 'program',\n });\n }\n }\n\n for (const fixture of fixtures) {\n const home = fixture.homeTeam?.name ?? 'Home';\n const away = fixture.awayTeam?.name ?? (fixture.awayTeamId ? 'Away' : 'TBD');\n const hasScore = fixture.homeScore !== null && fixture.awayScore !== null;\n items.push({\n id: `fixture-${fixture.id}`,\n type: 'fixture-updated',\n title: hasScore\n ? `${home} ${fixture.homeScore}–${fixture.awayScore} ${away}`\n : `Fixture ${home} vs ${away} updated`,\n subtitle: fixture.competition ?? undefined,\n at: fixture.updatedAt,\n entityId: fixture.id,\n entityKind: 'fixture',\n });\n }\n\n for (const session of sessions) {\n if (session.status === 'COMPLETED') {\n items.push({\n id: `session-${session.id}`,\n type: 'session-completed',\n title: `Session \"${session.title}\" completed`,\n subtitle: session.rating !== null ? `Rated ${session.rating}/5` : undefined,\n at: session.completedAt ?? session.updatedAt,\n entityId: session.id,\n entityKind: 'session',\n });\n }\n }\n\n return items\n .filter((item) => Boolean(item.at) && !Number.isNaN(new Date(item.at).getTime()))\n .sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime())\n .slice(0, limit);\n }, [teams, fixtures, sessions, programs, limit]);\n\n// ============================================================================\n// Athlete profile — compose a team member with that athlete's real training\n// data (performance metrics + workout logs + coaching sessions), keyed off the\n// member's userId (the athleteId used across the training tables).\n// ============================================================================\n\nexport interface AthleteProfile {\n /** The resolved team member, or null while loading / not found. */\n member: AthMember | null;\n /** The user id used across sessions / metrics / workouts. */\n athleteId: string | undefined;\n metrics: AthPerformanceMetric[];\n workouts: AthWorkoutLog[];\n sessions: AthSession[];\n isLoading: boolean;\n isError: boolean;\n}\n\n/** Compose a member + their metrics, workout logs and sessions into a profile. */\nexport const useAthleteProfile = (\n teamId: string | undefined,\n memberId: string | undefined\n): AthleteProfile => {\n const membersQuery = useTeamMembers(teamId);\n const member = useMemo(\n () => (membersQuery.data ?? []).find((m) => m.id === memberId) ?? null,\n [membersQuery.data, memberId]\n );\n const athleteId = member?.userId;\n\n const metricsQuery = usePerformanceMetrics(athleteId);\n const workoutsQuery = useWorkoutLogs({ athleteId, pagination: { limit: 100 } });\n const sessionsQuery = useSessions({ athleteId, pagination: { limit: 100 } });\n\n return {\n member,\n athleteId,\n metrics: metricsQuery.data ?? [],\n workouts: workoutsQuery.data?.items ?? [],\n sessions: sessionsQuery.data?.items ?? [],\n isLoading:\n membersQuery.isLoading ||\n (Boolean(athleteId) &&\n (metricsQuery.isLoading || workoutsQuery.isLoading || sessionsQuery.isLoading)),\n isError:\n membersQuery.isError ||\n metricsQuery.isError ||\n workoutsQuery.isError ||\n sessionsQuery.isError,\n };\n};\n\n// ============================================================================\n// Coach analytics — honest aggregates over real sessions / workouts / fixtures\n// / standings. No fabricated wellness or injury data.\n// ============================================================================\n\nexport interface SessionStatusCount {\n status: AthSessionStatus;\n count: number;\n}\n\nexport interface RatingByCoach {\n coachId: string;\n avgRating: number;\n count: number;\n}\n\nexport interface AnalyticsTrendPoint {\n label: string;\n value: number;\n}\n\n/**\n * One athlete's acute:chronic workload, computed from that athlete's own real\n * `AthWorkoutLog.totalLoad` rows in the sampled page.\n *\n * `acute` is the summed load of the last 7 days and `chronic` the mean weekly\n * load over the last 28 days (28-day sum ÷ 4), matching the workspace-wide\n * `trainingLoad` maths. `loadedCount` is how many of those 28-day workouts\n * actually carried a `totalLoad`: when it is 0 the athlete trained but nobody\n * recorded a load, and `acute` / `chronic` are 0 because nothing was measured —\n * NOT because the athlete did nothing. Callers must render that case as\n * \"no load recorded\" rather than as a real zero.\n */\nexport interface AthleteTrainingLoad {\n athleteId: string;\n acute: number;\n chronic: number;\n /** acute ÷ chronic, or null when there is no chronic load to divide by. */\n ratio: number | null;\n /** Workouts by this athlete inside the 28-day window. */\n workoutCount: number;\n /** How many of those workouts carried a real `totalLoad`. */\n loadedCount: number;\n}\n\nexport interface CoachAnalytics {\n totalSessions: number;\n ratedCount: number;\n /** Mean of session.rating over rated sessions, or null when none rated. */\n avgRating: number | null;\n completedCount: number;\n completedPct: number;\n sessionsByStatus: SessionStatusCount[];\n ratingByCoach: RatingByCoach[];\n coachIds: string[];\n /** Acute (last 7d) vs chronic (avg weekly over 28d) workout load + ratio. */\n trainingLoad: { acute: number; chronic: number; ratio: number | null };\n /** Per-athlete acute/chronic load over the same windows, heaviest acute first. */\n loadByAthlete: AthleteTrainingLoad[];\n /** Distinct athlete ids seen in the sampled workout logs (for name lookup). */\n athleteIds: string[];\n /**\n * True when the sampled workout page stopped short of 28 days ago — the svc\n * clamps `limit`, so a busy workspace returns only the newest N workouts and\n * every load figure below (workspace-wide AND per athlete) under-counts.\n */\n loadSampleTruncated: boolean;\n /** Weekly total workout load, oldest → newest (from real totalLoad). */\n loadTrend: AnalyticsTrendPoint[];\n /** Weekly session count, oldest → newest. */\n sessionTrend: AnalyticsTrendPoint[];\n /** Standings snapshot for the resolved competition. */\n standings: AthStanding[];\n competition: string | null;\n isLoading: boolean;\n isError: boolean;\n}\n\nexport interface CoachAnalyticsOptions {\n /** Competition for the standings snapshot; else the most-used one in fixtures. */\n competition?: string;\n /** Rows to sample from each list query. Default 200. */\n sampleLimit?: number;\n}\n\n/** Bucket rows into `weeks` weekly totals ending at \"now\" (oldest → newest). */\nfunction weeklyTrend<T>(\n rows: readonly T[],\n getDate: (row: T) => string,\n getValue: (row: T) => number,\n weeks = 8\n): AnalyticsTrendPoint[] {\n const MS_WEEK = 7 * 86_400_000;\n const now = Date.now();\n const buckets = Array.from({ length: weeks }, () => 0);\n for (const row of rows) {\n const time = new Date(getDate(row)).getTime();\n if (Number.isNaN(time)) {\n continue;\n }\n const age = now - time;\n if (age < 0) {\n continue;\n }\n const weeksAgo = Math.floor(age / MS_WEEK);\n if (weeksAgo >= 0 && weeksAgo < weeks) {\n buckets[weeks - 1 - weeksAgo] += getValue(row);\n }\n }\n return buckets.map((value, i) => {\n const ago = weeks - 1 - i;\n return { label: ago === 0 ? 'Now' : `${ago}w`, value };\n });\n}\n\n/** Aggregate real coaching data for the analytics dashboard. */\nexport const useCoachAnalytics = (options: CoachAnalyticsOptions = {}): CoachAnalytics => {\n const { competition: competitionOpt, sampleLimit = 200 } = options;\n\n const sessionsQuery = useSessions({ pagination: { limit: sampleLimit } });\n const workoutsQuery = useWorkoutLogs({ pagination: { limit: sampleLimit } });\n const fixturesQuery = useFixtures({ pagination: { limit: sampleLimit } });\n\n const sessions = useMemo(() => sessionsQuery.data?.items ?? [], [sessionsQuery.data]);\n const workouts = useMemo(() => workoutsQuery.data?.items ?? [], [workoutsQuery.data]);\n const fixtures = useMemo(() => fixturesQuery.data?.items ?? [], [fixturesQuery.data]);\n\n // Resolve the competition for the standings snapshot.\n const competition = useMemo(() => {\n if (competitionOpt) {\n return competitionOpt;\n }\n const counts = new Map<string, number>();\n for (const fixture of fixtures) {\n if (fixture.competition) {\n counts.set(fixture.competition, (counts.get(fixture.competition) ?? 0) + 1);\n }\n }\n let top: string | null = null;\n let best = 0;\n for (const [comp, n] of counts) {\n if (n > best) {\n best = n;\n top = comp;\n }\n }\n return top;\n }, [competitionOpt, fixtures]);\n\n const standingsQuery = useStandings(competition ?? undefined);\n\n return useMemo<CoachAnalytics>(() => {\n const totalSessions = sessions.length;\n const rated = sessions.filter((s) => s.rating !== null);\n const ratedCount = rated.length;\n const avgRating =\n ratedCount > 0 ? rated.reduce((acc, s) => acc + (s.rating ?? 0), 0) / ratedCount : null;\n const completedCount = sessions.filter((s) => s.status === 'COMPLETED').length;\n const completedPct = totalSessions > 0 ? (completedCount / totalSessions) * 100 : 0;\n\n const statusOrder: AthSessionStatus[] = [\n 'REQUESTED',\n 'CONFIRMED',\n 'COMPLETED',\n 'CANCELLED',\n 'NO_SHOW',\n ];\n const statusCounts = new Map<AthSessionStatus, number>();\n for (const s of sessions) {\n statusCounts.set(s.status, (statusCounts.get(s.status) ?? 0) + 1);\n }\n const sessionsByStatus = statusOrder\n .map((status) => ({ status, count: statusCounts.get(status) ?? 0 }))\n .filter((entry) => entry.count > 0);\n\n const byCoach = new Map<string, { sum: number; count: number }>();\n for (const s of rated) {\n const entry = byCoach.get(s.coachId) ?? { sum: 0, count: 0 };\n entry.sum += s.rating ?? 0;\n entry.count += 1;\n byCoach.set(s.coachId, entry);\n }\n const ratingByCoach = Array.from(byCoach.entries())\n .map(([coachId, { sum, count }]) => ({ coachId, avgRating: sum / count, count }))\n .sort((a, b) => b.avgRating - a.avgRating);\n\n const coachIds = Array.from(new Set(sessions.map((s) => s.coachId)));\n\n // Training load (ACWR) from real workout totalLoad — workspace-wide and,\n // in the same pass, per athlete (every row already carries `athleteId`).\n const now = Date.now();\n const DAY = 86_400_000;\n const acuteFrom = now - 7 * DAY;\n const chronicFrom = now - 28 * DAY;\n let acute = 0;\n let chronic28 = 0;\n let oldestSampledAt = Number.POSITIVE_INFINITY;\n const perAthlete = new Map<\n string,\n { acute: number; chronic28: number; workoutCount: number; loadedCount: number }\n >();\n for (const w of workouts) {\n const performedAt = new Date(w.performedAt).getTime();\n if (Number.isNaN(performedAt)) {\n continue;\n }\n if (performedAt < oldestSampledAt) {\n oldestSampledAt = performedAt;\n }\n const load = w.totalLoad ?? 0;\n if (performedAt >= acuteFrom) {\n acute += load;\n }\n if (performedAt >= chronicFrom) {\n chronic28 += load;\n }\n if (performedAt < chronicFrom || !w.athleteId) {\n continue;\n }\n const entry = perAthlete.get(w.athleteId) ?? {\n acute: 0,\n chronic28: 0,\n workoutCount: 0,\n loadedCount: 0,\n };\n entry.chronic28 += load;\n entry.workoutCount += 1;\n if (w.totalLoad != null) {\n entry.loadedCount += 1;\n }\n if (performedAt >= acuteFrom) {\n entry.acute += load;\n }\n perAthlete.set(w.athleteId, entry);\n }\n const chronic = chronic28 / 4;\n const ratio = chronic > 0 ? acute / chronic : null;\n\n const loadByAthlete: AthleteTrainingLoad[] = Array.from(perAthlete.entries())\n .map(([athleteId, entry]) => {\n const athleteChronic = entry.chronic28 / 4;\n return {\n athleteId,\n acute: entry.acute,\n chronic: athleteChronic,\n ratio: athleteChronic > 0 ? entry.acute / athleteChronic : null,\n workoutCount: entry.workoutCount,\n loadedCount: entry.loadedCount,\n };\n })\n .sort((a, b) => b.acute - a.acute || b.chronic - a.chronic);\n\n // The svc clamps `limit`, so `hasMore` plus a sample that never reaches\n // back 28 days means every load number above is a floor, not a total.\n const loadSampleTruncated =\n (workoutsQuery.data?.pageInfo.hasMore ?? false) && oldestSampledAt > chronicFrom;\n\n const loadTrend = weeklyTrend(\n workouts,\n (w) => w.performedAt,\n (w) => w.totalLoad ?? 0\n );\n const sessionTrend = weeklyTrend(\n sessions,\n (s) => s.scheduledAt,\n () => 1\n );\n\n return {\n totalSessions,\n ratedCount,\n avgRating,\n completedCount,\n completedPct,\n sessionsByStatus,\n ratingByCoach,\n coachIds,\n trainingLoad: { acute, chronic, ratio },\n loadByAthlete,\n athleteIds: loadByAthlete.map((entry) => entry.athleteId),\n loadSampleTruncated,\n loadTrend,\n sessionTrend,\n standings: standingsQuery.data ?? [],\n competition,\n isLoading:\n sessionsQuery.isLoading ||\n workoutsQuery.isLoading ||\n fixturesQuery.isLoading ||\n (Boolean(competition) && standingsQuery.isLoading),\n isError:\n sessionsQuery.isError ||\n workoutsQuery.isError ||\n fixturesQuery.isError ||\n standingsQuery.isError,\n };\n }, [\n sessions,\n workouts,\n workoutsQuery.data,\n competition,\n standingsQuery.data,\n standingsQuery.isLoading,\n standingsQuery.isError,\n sessionsQuery.isLoading,\n sessionsQuery.isError,\n workoutsQuery.isLoading,\n workoutsQuery.isError,\n fixturesQuery.isLoading,\n fixturesQuery.isError,\n ]);\n};\n\n// ============================================================================\n// AI operations (BOFF-3574) — model selection, the append-only decision ledger\n// and the coach's review actions. Every field below is live in the composed\n// production supergraph; nothing here is mocked.\n// ============================================================================\n\nconst AGENT_RUN_FIELDS = `\n id workspaceId actorId actorType provider model trigger status error\n promptSummary inputRefs decision tokensIn tokensOut latencyMs costUsd\n createdAt\n`;\n\nconst AI_CONFIG_FIELDS = `\n workspaceId provider model autoPilotEnabled autoPilotLastRunAt updatedAt\n`;\n\n/** The selectable (provider, model) pairs, with the platform default marked. */\nexport const useAiModelCatalog = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'ai-model-catalog'],\n queryFn: async () => {\n const result = await athQuery<{ athAiModelCatalog: AthAiModelInfo[] }>(\n `query AthAiModelCatalog {\n athAiModelCatalog { provider model label isDefault capabilities }\n }`,\n {},\n apiGatewayUrl\n );\n return result.athAiModelCatalog;\n },\n // A static catalog — refetching it on every focus is pure noise.\n staleTime: 30 * 60_000,\n });\n};\n\n/**\n * The workspace's saved AI config, or null when it has never overridden the\n * platform default chain (the query is nullable by design — a null here means\n * \"using the platform default\", not \"failed\").\n */\nexport const useWorkspaceAiConfig = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'ai-config'],\n queryFn: async () => {\n const result = await athQuery<{ athWorkspaceAiConfig: AthWorkspaceAiConfig | null }>(\n `query AthWorkspaceAiConfig {\n athWorkspaceAiConfig { ${AI_CONFIG_FIELDS} }\n }`,\n {},\n apiGatewayUrl\n );\n return result.athWorkspaceAiConfig;\n },\n });\n};\n\nexport const useSetWorkspaceAiModel = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ provider, model }: { provider: string; model: string }) => {\n const result = await athQuery<{ athSetWorkspaceAiModel: AthWorkspaceAiConfig }>(\n `mutation AthSetWorkspaceAiModel($provider: String!, $model: String!) {\n athSetWorkspaceAiModel(provider: $provider, model: $model) { ${AI_CONFIG_FIELDS} }\n }`,\n { provider, model },\n apiGatewayUrl\n );\n return result.athSetWorkspaceAiModel;\n },\n onSuccess: (config) => {\n queryClient.setQueryData(['atheletebridge', 'ai-config'], config);\n },\n });\n};\n\n/**\n * Opt this workspace into (or out of) the autonomous coaching loop. The loop is\n * ALSO gated per deployment by `ATHELETEBRIDGE_AGENT_LOOP_ENABLED`, so enabling\n * it here does not on its own start anything — and even when it does run it\n * only ever records a PROPOSED adjustment for a coach to resolve.\n */\nexport const useSetWorkspaceAutoPilot = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (enabled: boolean) => {\n const result = await athQuery<{ athSetWorkspaceAutoPilot: AthWorkspaceAiConfig }>(\n `mutation AthSetWorkspaceAutoPilot($enabled: Boolean!) {\n athSetWorkspaceAutoPilot(enabled: $enabled) { ${AI_CONFIG_FIELDS} }\n }`,\n { enabled },\n apiGatewayUrl\n );\n return result.athSetWorkspaceAutoPilot;\n },\n onSuccess: (config) => {\n queryClient.setQueryData(['atheletebridge', 'ai-config'], config);\n },\n });\n};\n\nexport interface AgentRunFilters {\n /** Rows per page. */\n limit?: number;\n /** Rows to skip. Offset-based: the composed PaginationInput has no cursor. */\n offset?: number;\n /** Only runs whose `inputRefs.athleteId` is this athlete's user id. */\n athleteId?: string;\n /** Only runs whose `inputRefs.teamId` is this team. */\n teamId?: string;\n /** Only runs whose `inputRefs.programId` is this program. */\n programId?: string;\n}\n\n/** The server-side `AthAgentRunFilter`, or null when nothing narrows the list. */\nfunction toAgentRunFilter(filters: AgentRunFilters): Record<string, string> | null {\n const filter: Record<string, string> = {};\n if (filters.athleteId) filter.athleteId = filters.athleteId;\n if (filters.teamId) filter.teamId = filters.teamId;\n if (filters.programId) filter.programId = filters.programId;\n return Object.keys(filter).length > 0 ? filter : null;\n}\n\n/**\n * The workspace's AI decision ledger, most recent first — optionally narrowed\n * to one athlete, team or program (the decision cards on those views).\n */\nexport const useAgentRuns = (filters: AgentRunFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n const { limit = 10, offset = 0 } = filters;\n const filter = toAgentRunFilter(filters);\n return useQuery({\n queryKey: ['atheletebridge', 'agent-runs', limit, offset, filter],\n queryFn: async () => {\n const result = await athQuery<{ athAgentRuns: AthAgentRunConnection }>(\n `query AthAgentRuns($pagination: PaginationInput, $filter: AthAgentRunFilter) {\n athAgentRuns(pagination: $pagination, filter: $filter) {\n items { ${AGENT_RUN_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { pagination: { limit, offset }, filter },\n apiGatewayUrl\n );\n return result.athAgentRuns;\n },\n });\n};\n\n/**\n * A single ledger row by id. Used to resolve the `extensions.agentRunId` an\n * `AI_PROVIDER_UNAVAILABLE` error carries, so the user sees the recorded\n * failure instead of a generic toast.\n */\nexport const useAgentRun = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'agent-run', id],\n queryFn: async () => {\n const result = await athQuery<{ athAgentRun: AthAgentRun | null }>(\n `query AthAgentRun($id: ID!) {\n athAgentRun(id: $id) { ${AGENT_RUN_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athAgentRun;\n },\n enabled: Boolean(id),\n retry: false,\n });\n};\n\n/**\n * A program with its AI provenance (`context.lastAiAdjustment`). Kept separate\n * from {@link useProgram} so the `context` selection — which only the AI\n * Operations page needs — stays off every other program read.\n */\nexport const useProgramAiState = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'program-ai-state', id],\n queryFn: async () => {\n const result = await athQuery<{\n athProgram: (Pick<AthProgram, 'id' | 'name' | 'status'> & { context: unknown }) | null;\n }>(\n `query AthProgramAiState($id: ID!) {\n athProgram(id: $id) { id name status context }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athProgram;\n },\n enabled: Boolean(id),\n retry: false,\n });\n};\n\n/**\n * Generate a DRAFT program from a live model call. Throws {@link AthApiError}\n * with code `AI_PROVIDER_UNAVAILABLE` (and the FAILED ledger row's id) when no\n * provider in the chain could answer.\n */\nexport const useGenerateProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthGenerateProgramInput) => {\n const result = await athQuery<{ athGenerateProgram: AthGenerateProgramResult }>(\n `mutation AthGenerateProgram($input: AthGenerateProgramInput!) {\n athGenerateProgram(input: $input) {\n agentRunId\n drillCount\n sessionCount\n program { ${PROGRAM_FIELDS} }\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athGenerateProgram;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'agent-runs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n },\n });\n};\n\n/**\n * Ask the AI to read an athlete's recent load/metric trend and PROPOSE an\n * adjustment onto a program. It changes no prescribed training load by itself —\n * a coach resolves it with {@link useOverrideAgentRun}.\n */\nexport const useAdjustPlanFromPerformance = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({\n athleteId,\n programId,\n requestedProvider,\n }: {\n athleteId: string;\n programId: string;\n requestedProvider?: string;\n }) => {\n const result = await athQuery<{ athAdjustPlanFromPerformance: AthPlanAdjustment }>(\n `mutation AthAdjustPlanFromPerformance($athleteId: ID!, $programId: ID!, $requestedProvider: String) {\n athAdjustPlanFromPerformance(athleteId: $athleteId, programId: $programId, requestedProvider: $requestedProvider) {\n agentRunId athleteId programId assessment rationale confidence\n recommendedWeeklyLoadChangePct flags appliedToProgram createdAt\n }\n }`,\n { athleteId, programId, requestedProvider },\n apiGatewayUrl\n );\n return result.athAdjustPlanFromPerformance;\n },\n onSuccess: (adjustment) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'agent-runs'] });\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'program-ai-state', adjustment.programId],\n });\n },\n });\n};\n\n/**\n * A coach's review of a prior AI decision. Recorded as a NEW, append-only\n * ledger row — never an edit of the original — which resolves the program's\n * `lastAiAdjustment` to ACCEPTED (same assessment) or OVERRIDDEN (a different\n * one).\n */\nexport const useOverrideAgentRun = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({\n runId,\n programId,\n assessment,\n note,\n }: {\n runId: string;\n programId: string;\n assessment: AthAiAssessment;\n note: string;\n }) => {\n const result = await athQuery<{ athOverrideAgentRun: AthAgentRunOverride }>(\n `mutation AthOverrideAgentRun($runId: ID!, $programId: ID!, $assessment: AthAiAssessment!, $note: String!) {\n athOverrideAgentRun(runId: $runId, programId: $programId, assessment: $assessment, note: $note) {\n id workspaceId programId supersedesRunId assessment note\n appliedToProgram createdAt\n }\n }`,\n { runId, programId, assessment, note },\n apiGatewayUrl\n );\n return result.athOverrideAgentRun;\n },\n onSuccess: (override) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'agent-runs'] });\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'program-ai-state', override.programId],\n });\n },\n });\n};\n\n// ============================================================================\n// Health probe\n// ============================================================================\n\nexport const useHealth = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'health'],\n queryFn: async () => {\n const result = await athQuery<{ athHealth: string }>(\n `query AthHealth { athHealth }`,\n {},\n apiGatewayUrl\n );\n return result.athHealth;\n },\n });\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"useAthleteBridgeApi.js","names":[],"sources":["../../../src/atheletebridge/hooks/useAthleteBridgeApi.ts"],"sourcesContent":["/**\n * AthleteBridge API hooks\n * @module atheletebridge/hooks\n *\n * Thin react-query wrappers over the real `wspace-atheletebridge-svc` federated\n * GraphQL contract, reached through the workspace gateway with the workspace\n * dual-token. Every query/mutation here maps 1:1 to an `ath*` root field in the\n * service's `.hive-schema.graphql`. NO MOCKS — all data is live.\n */\n\nimport { useCallback, useMemo } from 'react';\n\nimport { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';\n\nimport { graphqlFetch, clearGraphqlFetchResponseCache } from '@burdenoff/fe-libs/shared/graphql';\n\nimport { useAthleteBridge } from '../context';\nimport type {\n AthAgentRun,\n AthAgentRunConnection,\n AthAgentRunOverride,\n AthAiAssessment,\n AthAiModelInfo,\n AthAvailability,\n AthAvailabilityConnection,\n AthCompleteSessionInput,\n AthCreateFixtureInput,\n AthCreateProgramInput,\n AthCreateTeamInput,\n AthAddMemberInput,\n AthAddDrillInput,\n AthBookSessionInput,\n AthDrill,\n AthFixture,\n AthFixtureConnection,\n AthFixtureStatus,\n AthGenerateProgramInput,\n AthGenerateProgramResult,\n AthLogWorkoutInput,\n AthMember,\n AthMemberConnection,\n AthMemberStatus,\n AthPerformanceMetric,\n AthPerformanceMetricConnection,\n AthPlanAdjustment,\n AthProgram,\n AthProgramConnection,\n AthProgramLevel,\n AthProgramStatus,\n AthRecordMetricInput,\n AthRecordResultInput,\n AthSession,\n AthSessionConnection,\n AthSessionStatus,\n AthSetAvailabilityInput,\n AthSport,\n AthStanding,\n AthStandingConnection,\n AthTeam,\n AthTeamConnection,\n AthTeamStatus,\n AthUpdateProgramInput,\n AthUpdateTeamInput,\n AthWorkoutLog,\n AthWorkoutLogConnection,\n AthWorkspaceAiConfig,\n PaginationInput,\n} from '../types';\n\n// ============================================================================\n// Typed errors\n// ============================================================================\n\n/** `extensions.code` for an upstream AI provider that is down or unconfigured. */\nexport const AI_PROVIDER_UNAVAILABLE = 'AI_PROVIDER_UNAVAILABLE';\n\n/**\n * A GraphQL error surfaced with its `extensions` intact.\n *\n * The svc throws stable, typed errors (`NOT_FOUND`, `CONFLICT`,\n * `FAILED_PRECONDITION`, `AI_PROVIDER_UNAVAILABLE`, `BAD_USER_INPUT`) and, for\n * AI failures, an `extensions.agentRunId` pointing at the FAILED ledger row\n * that holds every attempt's raw upstream message. Flattening all of that into\n * `new Error(message)` is what made an unconfigured provider indistinguishable\n * from a crashed service, so the code and the run id are carried through to the\n * UI instead.\n */\nexport class AthApiError extends Error {\n /** `extensions.code`, or null when the server did not send one. */\n readonly code: string | null;\n /** `extensions.agentRunId` — the ledger row to inspect, when present. */\n readonly agentRunId: string | null;\n\n constructor(message: string, extensions?: Record<string, unknown>) {\n super(message);\n this.name = 'AthApiError';\n const code = extensions?.code;\n const agentRunId = extensions?.agentRunId;\n this.code = typeof code === 'string' && code ? code : null;\n this.agentRunId = typeof agentRunId === 'string' && agentRunId ? agentRunId : null;\n }\n}\n\n/** Whether an unknown thrown value is an AI-provider outage we can explain. */\nexport const isAiProviderUnavailable = (error: unknown): error is AthApiError =>\n error instanceof AthApiError && error.code === AI_PROVIDER_UNAVAILABLE;\n\n// ============================================================================\n// Low-level query wrapper\n// ============================================================================\n\nconst athQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>,\n baseUrl?: string\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'workspace',\n baseUrl,\n query,\n variables,\n workspaceToken: true,\n });\n\n if (response.errors?.length) {\n const first = response.errors[0];\n throw new AthApiError(first?.message ?? 'GraphQL request failed', first?.extensions);\n }\n\n if (!response.data) {\n throw new AthApiError('GraphQL response did not include data');\n }\n\n // This MFE bypasses Apollo, so fe-libs' short-lived graphqlFetch read cache\n // would otherwise serve pre-write data to the very next refetch issued by a\n // mutation's onSuccess invalidation. Clear it after any successful mutation so\n // every downstream read is fresh (fleet-wide stale-read-after-write fix).\n if (query.trimStart().startsWith('mutation')) {\n clearGraphqlFetchResponseCache();\n }\n\n return response.data;\n};\n\n// Global-gateway read wrapper — the workspace-scoped MFE reaches the tenant user\n// directory (for real user pickers) through the global gateway.\nconst athGlobalQuery = async <TData>(\n query: string,\n variables: Record<string, unknown>\n): Promise<TData> => {\n const response = await graphqlFetch<TData>({\n gateway: 'global',\n query,\n variables,\n suppressGlobalErrorEvent: true,\n });\n\n if (response.errors?.length) {\n const first = response.errors[0];\n throw new AthApiError(first?.message ?? 'GraphQL request failed', first?.extensions);\n }\n\n if (!response.data) {\n throw new AthApiError('GraphQL response did not include data');\n }\n\n return response.data;\n};\n\n// ============================================================================\n// GraphQL fragments (inline strings — exact fields from the svc schema)\n// ============================================================================\n\nconst TEAM_FIELDS = `\n id workspaceId name sport status description ageGroup season homeVenue\n headCoachId tags createdAt updatedAt\n`;\n\nconst MEMBER_FIELDS = `\n id workspaceId teamId userId displayName role status position jerseyNumber\n height weight dominantSide notes joinedAt createdAt updatedAt\n`;\n\nconst CRICKET_INNINGS_FIELDS = `\n runs wickets overs balls extras\n`;\n\nconst CRICKET_SCORECARD_FIELDS = `\n homeInnings { ${CRICKET_INNINGS_FIELDS} }\n awayInnings { ${CRICKET_INNINGS_FIELDS} }\n winner decidedBy margin superOver dls\n`;\n\nconst FIXTURE_FIELDS = `\n id workspaceId type status competition round venue homeTeamId awayTeamId\n homeScore awayScore extraTimeHomeScore extraTimeAwayScore penaltyHomeScore penaltyAwayScore\n cricketScorecard { ${CRICKET_SCORECARD_FIELDS} }\n scheduledAt kickoffAt notes createdAt updatedAt\n homeTeam { id name sport }\n awayTeam { id name sport }\n`;\n\nconst STANDING_FIELDS = `\n id workspaceId competition teamId played won drawn lost goalsFor goalsAgainst\n points rank createdAt updatedAt\n team { id name sport }\n`;\n\nconst DRILL_FIELDS = `\n id workspaceId programId name description weekNumber orderIndex sets reps\n durationSec restSec createdAt updatedAt\n video { id }\n`;\n\nconst PROGRAM_FIELDS = `\n id workspaceId coachId name sport level status summary weeks isTemplate tags\n createdAt updatedAt\n`;\n\nconst SESSION_FIELDS = `\n id workspaceId coachId athleteId programId title type status location\n meetingUrl scheduledAt durationMin completedAt feedback rating\n createdAt updatedAt\n`;\n\nconst WORKOUT_LOG_FIELDS = `\n id workspaceId athleteId programId title status performedAt durationMin rpe\n totalLoad metrics notes createdAt updatedAt\n`;\n\nconst METRIC_FIELDS = `\n id workspaceId athleteId type label value unit source recordedAt\n createdAt updatedAt\n`;\n\n// ============================================================================\n// Teams\n// ============================================================================\n\nexport interface TeamFilters {\n sport?: AthSport;\n status?: AthTeamStatus;\n pagination?: PaginationInput;\n}\n\nexport const useTeams = (filters: TeamFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'teams', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListTeams: AthTeamConnection }>(\n `query AthListTeams($sport: AthSport, $status: AthTeamStatus, $pagination: PaginationInput) {\n athListTeams(sport: $sport, status: $status, pagination: $pagination) {\n items { ${TEAM_FIELDS} members { items { id } } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n sport: filters.sport,\n status: filters.status,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListTeams;\n },\n });\n};\n\nexport const useTeam = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'team', id],\n queryFn: async () => {\n const result = await athQuery<{ athTeam: AthTeam | null }>(\n `query AthTeam($id: ID!) {\n athTeam(id: $id) {\n ${TEAM_FIELDS}\n members { items { ${MEMBER_FIELDS} } }\n fixtures { items { ${FIXTURE_FIELDS} } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athTeam;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useTeamMembers = (teamId: string | undefined, status?: AthMemberStatus) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'members', teamId, status],\n queryFn: async () => {\n const result = await athQuery<{ athListMembers: AthMemberConnection }>(\n `query AthListMembers($teamId: ID!, $status: AthMemberStatus) {\n athListMembers(teamId: $teamId, status: $status) { items { ${MEMBER_FIELDS} } }\n }`,\n { teamId, status },\n apiGatewayUrl\n );\n return result.athListMembers.items;\n },\n enabled: Boolean(teamId),\n });\n};\n\nexport const useCreateTeam = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthCreateTeamInput) => {\n const result = await athQuery<{ athCreateTeam: AthTeam }>(\n `mutation AthCreateTeam($input: AthCreateTeamInput!) {\n athCreateTeam(input: $input) { ${TEAM_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athCreateTeam;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'teams'] });\n },\n });\n};\n\nexport const useUpdateTeam = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: AthUpdateTeamInput }) => {\n const result = await athQuery<{ athUpdateTeam: AthTeam }>(\n `mutation AthUpdateTeam($id: ID!, $input: AthUpdateTeamInput!) {\n athUpdateTeam(id: $id, input: $input) { ${TEAM_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athUpdateTeam;\n },\n onSuccess: (team) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'teams'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'team', team.id] });\n },\n });\n};\n\nexport const useArchiveTeam = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athArchiveTeam: boolean }>(\n `mutation AthArchiveTeam($id: ID!) { athArchiveTeam(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athArchiveTeam;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'teams'] });\n },\n });\n};\n\nexport const useAddMember = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthAddMemberInput) => {\n const result = await athQuery<{ athAddMember: AthMember }>(\n `mutation AthAddMember($input: AthAddMemberInput!) {\n athAddMember(input: $input) { ${MEMBER_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athAddMember;\n },\n onSuccess: (member) => {\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'members', member.teamId],\n });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'team', member.teamId] });\n },\n });\n};\n\nexport const useRemoveMember = (teamId?: string) => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athRemoveMember: boolean }>(\n `mutation AthRemoveMember($id: ID!) { athRemoveMember(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athRemoveMember;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'members', teamId] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'team', teamId] });\n },\n });\n};\n\n// ============================================================================\n// Fixtures & standings\n// ============================================================================\n\nexport interface FixtureFilters {\n status?: AthFixtureStatus;\n teamId?: string;\n pagination?: PaginationInput;\n}\n\nexport const useFixtures = (filters: FixtureFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'fixtures', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListFixtures: AthFixtureConnection }>(\n `query AthListFixtures($status: AthFixtureStatus, $teamId: ID, $pagination: PaginationInput) {\n athListFixtures(status: $status, teamId: $teamId, pagination: $pagination) {\n items { ${FIXTURE_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n status: filters.status,\n teamId: filters.teamId,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListFixtures;\n },\n });\n};\n\nexport const useFixture = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'fixture', id],\n queryFn: async () => {\n const result = await athQuery<{ athFixture: AthFixture | null }>(\n `query AthFixture($id: ID!) {\n athFixture(id: $id) { ${FIXTURE_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athFixture;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useStandings = (competition: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'standings', competition],\n queryFn: async () => {\n const result = await athQuery<{ athStandings: AthStandingConnection }>(\n `query AthStandings($competition: String!) {\n athStandings(competition: $competition) { items { ${STANDING_FIELDS} } }\n }`,\n { competition },\n apiGatewayUrl\n );\n return result.athStandings.items;\n },\n enabled: Boolean(competition),\n });\n};\n\nexport const useScheduleFixture = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthCreateFixtureInput) => {\n const result = await athQuery<{ athScheduleFixture: AthFixture }>(\n `mutation AthScheduleFixture($input: AthCreateFixtureInput!) {\n athScheduleFixture(input: $input) { ${FIXTURE_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athScheduleFixture;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'fixtures'] });\n },\n });\n};\n\nexport const useRecordFixtureResult = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: AthRecordResultInput }) => {\n const result = await athQuery<{ athRecordFixtureResult: AthFixture }>(\n `mutation AthRecordFixtureResult($id: ID!, $input: AthRecordResultInput!) {\n athRecordFixtureResult(id: $id, input: $input) { ${FIXTURE_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athRecordFixtureResult;\n },\n onSuccess: (fixture) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'fixtures'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'fixture', fixture.id] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'standings'] });\n },\n });\n};\n\n// ============================================================================\n// Programs & drills\n// ============================================================================\n\nexport interface ProgramFilters {\n sport?: AthSport;\n level?: AthProgramLevel;\n status?: AthProgramStatus;\n pagination?: PaginationInput;\n}\n\nexport const usePrograms = (filters: ProgramFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'programs', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListPrograms: AthProgramConnection }>(\n `query AthListPrograms($sport: AthSport, $level: AthProgramLevel, $status: AthProgramStatus, $pagination: PaginationInput) {\n athListPrograms(sport: $sport, level: $level, status: $status, pagination: $pagination) {\n items { ${PROGRAM_FIELDS} drills { items { id } } }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n sport: filters.sport,\n level: filters.level,\n status: filters.status,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListPrograms;\n },\n });\n};\n\nexport const useProgram = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'program', id],\n queryFn: async () => {\n const result = await athQuery<{ athProgram: AthProgram | null }>(\n `query AthProgram($id: ID!) {\n athProgram(id: $id) {\n ${PROGRAM_FIELDS}\n drills { items { ${DRILL_FIELDS} } }\n }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athProgram;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useCreateProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthCreateProgramInput) => {\n const result = await athQuery<{ athCreateProgram: AthProgram }>(\n `mutation AthCreateProgram($input: AthCreateProgramInput!) {\n athCreateProgram(input: $input) { ${PROGRAM_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athCreateProgram;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n },\n });\n};\n\nexport const useUpdateProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input: AthUpdateProgramInput }) => {\n const result = await athQuery<{ athUpdateProgram: AthProgram }>(\n `mutation AthUpdateProgram($id: ID!, $input: AthUpdateProgramInput!) {\n athUpdateProgram(id: $id, input: $input) { ${PROGRAM_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athUpdateProgram;\n },\n onSuccess: (program) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'program', program.id] });\n },\n });\n};\n\nexport const useTransitionProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, status }: { id: string; status: AthProgramStatus }) => {\n const result = await athQuery<{ athTransitionProgram: AthProgram }>(\n `mutation AthTransitionProgram($id: ID!, $status: AthProgramStatus!) {\n athTransitionProgram(id: $id, status: $status) { ${PROGRAM_FIELDS} }\n }`,\n { id, status },\n apiGatewayUrl\n );\n return result.athTransitionProgram;\n },\n onSuccess: (program) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'program', program.id] });\n },\n });\n};\n\nexport const useArchiveProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athArchiveProgram: boolean }>(\n `mutation AthArchiveProgram($id: ID!) { athArchiveProgram(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athArchiveProgram;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n },\n });\n};\n\nexport const useAddDrill = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthAddDrillInput) => {\n const result = await athQuery<{ athAddDrill: AthDrill }>(\n `mutation AthAddDrill($input: AthAddDrillInput!) {\n athAddDrill(input: $input) { ${DRILL_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athAddDrill;\n },\n onSuccess: (drill) => {\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'program', drill.programId],\n });\n },\n });\n};\n\nexport const useRemoveDrill = (programId?: string) => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athRemoveDrill: boolean }>(\n `mutation AthRemoveDrill($id: ID!) { athRemoveDrill(id: $id) }`,\n { id },\n apiGatewayUrl\n );\n return result.athRemoveDrill;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'program', programId] });\n },\n });\n};\n\n// ============================================================================\n// Coaching sessions\n// ============================================================================\n\nexport interface SessionFilters {\n athleteId?: string;\n coachId?: string;\n status?: AthSessionStatus;\n pagination?: PaginationInput;\n}\n\nexport const useSessions = (filters: SessionFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'sessions', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListSessions: AthSessionConnection }>(\n `query AthListSessions($athleteId: ID, $coachId: ID, $status: AthSessionStatus, $pagination: PaginationInput) {\n athListSessions(athleteId: $athleteId, coachId: $coachId, status: $status, pagination: $pagination) {\n items { ${SESSION_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n athleteId: filters.athleteId,\n coachId: filters.coachId,\n status: filters.status,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListSessions;\n },\n });\n};\n\nexport const useSession = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'session', id],\n queryFn: async () => {\n const result = await athQuery<{ athSession: AthSession | null }>(\n `query AthSession($id: ID!) {\n athSession(id: $id) { ${SESSION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athSession;\n },\n enabled: Boolean(id),\n });\n};\n\nexport const useBookSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthBookSessionInput) => {\n const result = await athQuery<{ athBookSession: AthSession }>(\n `mutation AthBookSession($input: AthBookSessionInput!) {\n athBookSession(input: $input) { ${SESSION_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athBookSession;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n },\n });\n};\n\nexport const useConfirmSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athConfirmSession: AthSession }>(\n `mutation AthConfirmSession($id: ID!) {\n athConfirmSession(id: $id) { ${SESSION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athConfirmSession;\n },\n onSuccess: (session) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'session', session.id] });\n },\n });\n};\n\nexport const useCompleteSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ id, input }: { id: string; input?: AthCompleteSessionInput }) => {\n const result = await athQuery<{ athCompleteSession: AthSession }>(\n `mutation AthCompleteSession($id: ID!, $input: AthCompleteSessionInput) {\n athCompleteSession(id: $id, input: $input) { ${SESSION_FIELDS} }\n }`,\n { id, input },\n apiGatewayUrl\n );\n return result.athCompleteSession;\n },\n onSuccess: (session) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'session', session.id] });\n },\n });\n};\n\nexport const useCancelSession = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (id: string) => {\n const result = await athQuery<{ athCancelSession: AthSession }>(\n `mutation AthCancelSession($id: ID!) {\n athCancelSession(id: $id) { ${SESSION_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athCancelSession;\n },\n onSuccess: (session) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'session', session.id] });\n },\n });\n};\n\n// ============================================================================\n// Workout logs & performance metrics\n// ============================================================================\n\nexport interface WorkoutLogFilters {\n athleteId?: string;\n programId?: string;\n pagination?: PaginationInput;\n}\n\nexport const useWorkoutLogs = (filters: WorkoutLogFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'workout-logs', filters],\n queryFn: async () => {\n const result = await athQuery<{ athListWorkoutLogs: AthWorkoutLogConnection }>(\n `query AthListWorkoutLogs($athleteId: ID, $programId: ID, $pagination: PaginationInput) {\n athListWorkoutLogs(athleteId: $athleteId, programId: $programId, pagination: $pagination) {\n items { ${WORKOUT_LOG_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n {\n athleteId: filters.athleteId,\n programId: filters.programId,\n pagination: filters.pagination,\n },\n apiGatewayUrl\n );\n return result.athListWorkoutLogs;\n },\n });\n};\n\n/**\n * An athlete's performance metrics, newest `recordedAt` first (the svc orders\n * `recordedAt: desc`). `pagination` is optional — omit it to take the server\n * default page; pass a limit when the caller needs a deeper history window than\n * the default (the svc clamps `limit` to its own ceiling, so a caller can ask\n * for more rows but never for unbounded ones).\n */\nexport const usePerformanceMetrics = (\n athleteId: string | undefined,\n pagination?: PaginationInput\n) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'metrics', athleteId, pagination ?? null],\n queryFn: async () => {\n const result = await athQuery<{ athPerformanceMetrics: AthPerformanceMetricConnection }>(\n `query AthPerformanceMetrics($athleteId: ID!, $pagination: PaginationInput) {\n athPerformanceMetrics(athleteId: $athleteId, pagination: $pagination) {\n items { ${METRIC_FIELDS} }\n }\n }`,\n { athleteId, pagination },\n apiGatewayUrl\n );\n return result.athPerformanceMetrics.items;\n },\n enabled: Boolean(athleteId),\n });\n};\n\nexport const useLogWorkout = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthLogWorkoutInput) => {\n const result = await athQuery<{ athLogWorkout: AthWorkoutLog }>(\n `mutation AthLogWorkout($input: AthLogWorkoutInput!) {\n athLogWorkout(input: $input) { ${WORKOUT_LOG_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athLogWorkout;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'workout-logs'] });\n },\n });\n};\n\nexport const useRecordMetric = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthRecordMetricInput) => {\n const result = await athQuery<{ athRecordMetric: AthPerformanceMetric }>(\n `mutation AthRecordMetric($input: AthRecordMetricInput!) {\n athRecordMetric(input: $input) { ${METRIC_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athRecordMetric;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'metrics'] });\n },\n });\n};\n\n// ============================================================================\n// Availability / RSVP (BOFF-4134)\n// ============================================================================\n\nconst AVAILABILITY_FIELDS = `\n id workspaceId memberId fixtureId sessionId response respondedAt note\n createdAt updatedAt\n member { id displayName role }\n`;\n\nexport interface AvailabilityFilters {\n fixtureId?: string;\n sessionId?: string;\n}\n\n/** Lists availability responses for a fixture OR a session. */\nexport const useAvailability = (filters: AvailabilityFilters) => {\n const { apiGatewayUrl } = useAthleteBridge();\n const { fixtureId, sessionId } = filters;\n return useQuery({\n queryKey: ['atheletebridge', 'availability', fixtureId ?? null, sessionId ?? null],\n queryFn: async () => {\n const result = await athQuery<{ athListAvailability: AthAvailabilityConnection }>(\n `query AthListAvailability($fixtureId: ID, $sessionId: ID) {\n athListAvailability(fixtureId: $fixtureId, sessionId: $sessionId) {\n items { ${AVAILABILITY_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { fixtureId, sessionId },\n apiGatewayUrl\n );\n return result.athListAvailability.items;\n },\n enabled: Boolean(fixtureId || sessionId),\n });\n};\n\nexport const useSetAvailability = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthSetAvailabilityInput) => {\n const result = await athQuery<{ athSetAvailability: AthAvailability }>(\n `mutation AthSetAvailability($input: AthSetAvailabilityInput!) {\n athSetAvailability(input: $input) { ${AVAILABILITY_FIELDS} }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athSetAvailability;\n },\n onSuccess: (row) => {\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'availability', row.fixtureId ?? null, row.sessionId ?? null],\n });\n },\n });\n};\n\n/**\n * Nudges roster members who have not yet responded. Publishes a domain event\n * for a future notification consumer to deliver — it does not itself send\n * push/email (no delivery channel is wired up yet). Returns the number of\n * members nudged.\n */\nexport const useRemindAvailability = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: { fixtureId?: string; sessionId?: string }) => {\n const result = await athQuery<{ athRemindAvailability: number }>(\n `mutation AthRemindAvailability($fixtureId: ID, $sessionId: ID) {\n athRemindAvailability(fixtureId: $fixtureId, sessionId: $sessionId)\n }`,\n input,\n apiGatewayUrl\n );\n return result.athRemindAvailability;\n },\n });\n};\n\n// ============================================================================\n// Workspace files — drill demo videos live in wspace-files-svc, reached through\n// the same workspace gateway. Blobs never touch the atheletebridge subgraph.\n// ============================================================================\n\nconst fileExtensionOf = (fileName: string): string => {\n const dot = fileName.lastIndexOf('.');\n return dot >= 0 ? fileName.slice(dot + 1).toLowerCase() : 'bin';\n};\n\n/**\n * Upload a file to wspace-files-svc via the standard three-step flow\n * (initiateUpload → presigned PUT → completeUpload) and resolve the new file id,\n * ready to pass as `AthAddDrillInput.videoFileId`.\n */\nexport const useUploadFile = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useCallback(\n async (file: File): Promise<string> => {\n const initiated = await athQuery<{\n initiateUpload: { uploadUrl: string | null; session: { id: string } };\n }>(\n `mutation AthInitiateUpload($input: InitiateUploadInput!) {\n initiateUpload(input: $input) { uploadUrl session { id } }\n }`,\n {\n input: {\n fileName: file.name,\n extension: fileExtensionOf(file.name),\n fileSize: file.size,\n mimeType: file.type || 'application/octet-stream',\n visibility: 'WORKSPACE',\n },\n },\n apiGatewayUrl\n );\n\n const uploadUrl = initiated.initiateUpload.uploadUrl;\n const sessionId = initiated.initiateUpload.session.id;\n if (!uploadUrl || !sessionId) {\n throw new Error('Upload could not be initialised.');\n }\n\n const put = await fetch(uploadUrl, {\n method: 'PUT',\n body: file,\n headers: { 'Content-Type': file.type || 'application/octet-stream' },\n });\n if (!put.ok) {\n throw new Error(`Storage rejected the upload (HTTP ${put.status}).`);\n }\n\n const completed = await athQuery<{ completeUpload: { fileId: string } }>(\n `mutation AthCompleteUpload($input: CompleteUploadInput!) {\n completeUpload(input: $input) { fileId }\n }`,\n { input: { sessionId } },\n apiGatewayUrl\n );\n return completed.completeUpload.fileId;\n },\n [apiGatewayUrl]\n );\n};\n\nexport interface WorkspaceFileRef {\n id: string;\n name: string;\n downloadUrl: string | null;\n}\n\n/**\n * Resolve a wspace-files File (a drill's demo video) by id, on demand. Kept as a\n * separate lazy read so a missing/expired blob can never break the program page.\n */\nexport const useFile = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'file', id],\n queryFn: async () => {\n const result = await athQuery<{ getFile: WorkspaceFileRef | null }>(\n `query AthGetFile($id: ID!) {\n getFile(id: $id) { id name downloadUrl }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.getFile;\n },\n enabled: Boolean(id),\n staleTime: 60_000,\n });\n};\n\n// ============================================================================\n// User directory (global gateway) — resolve real users for team member add so a\n// coach never has to paste a raw UUID.\n// ============================================================================\n\nexport interface DirectoryUser {\n id: string;\n name: string | null;\n firstName: string | null;\n lastName: string | null;\n email: string;\n username: string;\n}\n\n/** Best display name for a directory user (name → first+last → username → email). */\nexport const directoryUserName = (user: DirectoryUser): string => {\n if (user.name?.trim()) return user.name.trim();\n const full = [user.firstName, user.lastName].filter(Boolean).join(' ').trim();\n if (full) return full;\n if (user.username?.trim()) return user.username.trim();\n return user.email;\n};\n\n/**\n * Search the tenant user directory by name/email. Enabled once the term is at\n * least two characters; failures are surfaced to the caller (which offers a\n * manual-id fallback) rather than as a global error toast.\n */\nexport const useUserSearch = (search: string) => {\n const term = search.trim();\n return useQuery({\n queryKey: ['atheletebridge', 'user-search', term],\n queryFn: async () => {\n const result = await athGlobalQuery<{\n users: { users: DirectoryUser[]; hasMore: boolean };\n }>(\n `query AthUserSearch($filter: UserFilterInput, $pagination: PaginationInput) {\n users(filter: $filter, pagination: $pagination) {\n users { id name firstName lastName email username }\n hasMore\n }\n }`,\n { filter: { search: term }, pagination: { limit: 8, offset: 0 } }\n );\n return result.users.users;\n },\n enabled: term.length >= 2,\n staleTime: 30_000,\n retry: false,\n });\n};\n\n// ============================================================================\n// User id resolution (global gateway) — resolve a set of user ids to real\n// names/emails for identity chips (coach/athlete), mirroring the UserSearchSelect\n// directory pattern. Batched into one aliased request, cached, and RBAC-safe:\n// on any error it degrades to an empty map so callers fall back to id-seeded\n// monograms rather than surfacing an error toast.\n// ============================================================================\n\nexport interface ResolvedUser {\n id: string;\n name: string;\n email: string | null;\n}\n\n/**\n * Resolve the given user ids to `{ id, name, email }` via the global `user(id)`\n * query (one aliased round-trip). Unknown / forbidden ids are simply absent from\n * the returned map.\n */\nexport const useUsersByIds = (ids: ReadonlyArray<string | null | undefined>) => {\n const unique = useMemo(\n () =>\n Array.from(\n new Set(ids.filter((value): value is string => Boolean(value && value.trim())))\n ).sort(),\n [ids]\n );\n\n return useQuery({\n queryKey: ['atheletebridge', 'users-by-id', unique],\n queryFn: async (): Promise<Record<string, ResolvedUser>> => {\n if (unique.length === 0) {\n return {};\n }\n const varDefs = unique.map((_, i) => `$id${i}: ID!`).join(', ');\n const selections = unique\n .map((_, i) => `u${i}: user(id: $id${i}) { id name firstName lastName email username }`)\n .join('\\n');\n const variables: Record<string, string> = {};\n unique.forEach((id, i) => {\n variables[`id${i}`] = id;\n });\n\n // Read tolerantly: don't throw on partial/RBAC errors — keep whatever\n // aliases resolved so a single forbidden id can't blank the whole feed.\n const response = await graphqlFetch<Record<string, DirectoryUser | null>>({\n gateway: 'global',\n query: `query AthUsersByIds(${varDefs}) {\\n${selections}\\n}`,\n variables,\n suppressGlobalErrorEvent: true,\n });\n\n const data = response.data ?? {};\n const map: Record<string, ResolvedUser> = {};\n for (const value of Object.values(data)) {\n if (value && value.id) {\n map[value.id] = {\n id: value.id,\n name: directoryUserName(value),\n email: value.email ?? null,\n };\n }\n }\n return map;\n },\n enabled: unique.length > 0,\n staleTime: 5 * 60_000,\n retry: false,\n });\n};\n\nexport interface UserDirectory {\n byId: Record<string, ResolvedUser>;\n isLoading: boolean;\n isError: boolean;\n /** Resolved display name for an id, or undefined while unknown. */\n nameOf: (id: string | null | undefined) => string | undefined;\n /** Resolved email for an id, or undefined while unknown. */\n emailOf: (id: string | null | undefined) => string | null | undefined;\n}\n\n/**\n * Convenience wrapper over {@link useUsersByIds} returning name/email lookup\n * helpers, so identity components can resolve ids without touching the query.\n */\nexport const useUserDirectory = (ids: ReadonlyArray<string | null | undefined>): UserDirectory => {\n const query = useUsersByIds(ids);\n const byId = query.data ?? {};\n return {\n byId,\n isLoading: query.isLoading,\n isError: query.isError,\n nameOf: (id) => (id ? byId[id]?.name : undefined),\n emailOf: (id) => (id ? byId[id]?.email : undefined),\n };\n};\n\n// ============================================================================\n// Recent activity — a unified, time-ordered feed derived PURELY from records\n// already loaded on the page (teams/fixtures/sessions/programs). No extra\n// network, no fabricated events: every item maps to a real timestamp on a real\n// row.\n// ============================================================================\n\nexport type ActivityType =\n 'team-created' | 'member-added' | 'fixture-updated' | 'program-published' | 'session-completed';\n\nexport interface ActivityItem {\n id: string;\n type: ActivityType;\n title: string;\n subtitle?: string;\n /** ISO timestamp the event occurred at. */\n at: string;\n entityId: string;\n entityKind: 'team' | 'fixture' | 'session' | 'program';\n}\n\nexport interface RecentActivityInput {\n teams?: AthTeam[];\n fixtures?: AthFixture[];\n sessions?: AthSession[];\n programs?: AthProgram[];\n /** Max items to return (newest first). Default 8. */\n limit?: number;\n}\n\n/** Derive a typed, time-ordered activity feed from already-loaded records. */\nexport const useRecentActivity = ({\n teams = [],\n fixtures = [],\n sessions = [],\n programs = [],\n limit = 8,\n}: RecentActivityInput): ActivityItem[] =>\n useMemo(() => {\n const items: ActivityItem[] = [];\n\n for (const team of teams) {\n items.push({\n id: `team-${team.id}`,\n type: 'team-created',\n title: `Team ${team.name} created`,\n at: team.createdAt,\n entityId: team.id,\n entityKind: 'team',\n });\n for (const member of team.members?.items ?? []) {\n items.push({\n id: `member-${member.id}`,\n type: 'member-added',\n title: `${member.displayName} added to ${team.name}`,\n at: member.joinedAt ?? member.createdAt,\n entityId: team.id,\n entityKind: 'team',\n });\n }\n }\n\n for (const program of programs) {\n if (program.status === 'PUBLISHED') {\n items.push({\n id: `program-${program.id}`,\n type: 'program-published',\n title: `${program.name} published`,\n at: program.updatedAt,\n entityId: program.id,\n entityKind: 'program',\n });\n }\n }\n\n for (const fixture of fixtures) {\n const home = fixture.homeTeam?.name ?? 'Home';\n const away = fixture.awayTeam?.name ?? (fixture.awayTeamId ? 'Away' : 'TBD');\n const hasScore = fixture.homeScore !== null && fixture.awayScore !== null;\n items.push({\n id: `fixture-${fixture.id}`,\n type: 'fixture-updated',\n title: hasScore\n ? `${home} ${fixture.homeScore}–${fixture.awayScore} ${away}`\n : `Fixture ${home} vs ${away} updated`,\n subtitle: fixture.competition ?? undefined,\n at: fixture.updatedAt,\n entityId: fixture.id,\n entityKind: 'fixture',\n });\n }\n\n for (const session of sessions) {\n if (session.status === 'COMPLETED') {\n items.push({\n id: `session-${session.id}`,\n type: 'session-completed',\n title: `Session \"${session.title}\" completed`,\n subtitle: session.rating !== null ? `Rated ${session.rating}/5` : undefined,\n at: session.completedAt ?? session.updatedAt,\n entityId: session.id,\n entityKind: 'session',\n });\n }\n }\n\n return items\n .filter((item) => Boolean(item.at) && !Number.isNaN(new Date(item.at).getTime()))\n .sort((a, b) => new Date(b.at).getTime() - new Date(a.at).getTime())\n .slice(0, limit);\n }, [teams, fixtures, sessions, programs, limit]);\n\n// ============================================================================\n// Athlete profile — compose a team member with that athlete's real training\n// data (performance metrics + workout logs + coaching sessions), keyed off the\n// member's userId (the athleteId used across the training tables).\n// ============================================================================\n\nexport interface AthleteProfile {\n /** The resolved team member, or null while loading / not found. */\n member: AthMember | null;\n /** The user id used across sessions / metrics / workouts. */\n athleteId: string | undefined;\n metrics: AthPerformanceMetric[];\n workouts: AthWorkoutLog[];\n sessions: AthSession[];\n isLoading: boolean;\n isError: boolean;\n}\n\n/** Compose a member + their metrics, workout logs and sessions into a profile. */\nexport const useAthleteProfile = (\n teamId: string | undefined,\n memberId: string | undefined\n): AthleteProfile => {\n const membersQuery = useTeamMembers(teamId);\n const member = useMemo(\n () => (membersQuery.data ?? []).find((m) => m.id === memberId) ?? null,\n [membersQuery.data, memberId]\n );\n const athleteId = member?.userId;\n\n const metricsQuery = usePerformanceMetrics(athleteId);\n const workoutsQuery = useWorkoutLogs({ athleteId, pagination: { limit: 100 } });\n const sessionsQuery = useSessions({ athleteId, pagination: { limit: 100 } });\n\n return {\n member,\n athleteId,\n metrics: metricsQuery.data ?? [],\n workouts: workoutsQuery.data?.items ?? [],\n sessions: sessionsQuery.data?.items ?? [],\n isLoading:\n membersQuery.isLoading ||\n (Boolean(athleteId) &&\n (metricsQuery.isLoading || workoutsQuery.isLoading || sessionsQuery.isLoading)),\n isError:\n membersQuery.isError ||\n metricsQuery.isError ||\n workoutsQuery.isError ||\n sessionsQuery.isError,\n };\n};\n\n// ============================================================================\n// Coach analytics — honest aggregates over real sessions / workouts / fixtures\n// / standings. No fabricated wellness or injury data.\n// ============================================================================\n\nexport interface SessionStatusCount {\n status: AthSessionStatus;\n count: number;\n}\n\nexport interface RatingByCoach {\n coachId: string;\n avgRating: number;\n count: number;\n}\n\nexport interface AnalyticsTrendPoint {\n label: string;\n value: number;\n}\n\n/**\n * One athlete's acute:chronic workload, computed from that athlete's own real\n * `AthWorkoutLog.totalLoad` rows in the sampled page.\n *\n * `acute` is the summed load of the last 7 days and `chronic` the mean weekly\n * load over the last 28 days (28-day sum ÷ 4), matching the workspace-wide\n * `trainingLoad` maths. `loadedCount` is how many of those 28-day workouts\n * actually carried a `totalLoad`: when it is 0 the athlete trained but nobody\n * recorded a load, and `acute` / `chronic` are 0 because nothing was measured —\n * NOT because the athlete did nothing. Callers must render that case as\n * \"no load recorded\" rather than as a real zero.\n */\nexport interface AthleteTrainingLoad {\n athleteId: string;\n acute: number;\n chronic: number;\n /** acute ÷ chronic, or null when there is no chronic load to divide by. */\n ratio: number | null;\n /** Workouts by this athlete inside the 28-day window. */\n workoutCount: number;\n /** How many of those workouts carried a real `totalLoad`. */\n loadedCount: number;\n}\n\nexport interface CoachAnalytics {\n totalSessions: number;\n ratedCount: number;\n /** Mean of session.rating over rated sessions, or null when none rated. */\n avgRating: number | null;\n completedCount: number;\n completedPct: number;\n sessionsByStatus: SessionStatusCount[];\n ratingByCoach: RatingByCoach[];\n coachIds: string[];\n /** Acute (last 7d) vs chronic (avg weekly over 28d) workout load + ratio. */\n trainingLoad: { acute: number; chronic: number; ratio: number | null };\n /** Per-athlete acute/chronic load over the same windows, heaviest acute first. */\n loadByAthlete: AthleteTrainingLoad[];\n /** Distinct athlete ids seen in the sampled workout logs (for name lookup). */\n athleteIds: string[];\n /**\n * True when the sampled workout page stopped short of 28 days ago — the svc\n * clamps `limit`, so a busy workspace returns only the newest N workouts and\n * every load figure below (workspace-wide AND per athlete) under-counts.\n */\n loadSampleTruncated: boolean;\n /** Weekly total workout load, oldest → newest (from real totalLoad). */\n loadTrend: AnalyticsTrendPoint[];\n /** Weekly session count, oldest → newest. */\n sessionTrend: AnalyticsTrendPoint[];\n /** Standings snapshot for the resolved competition. */\n standings: AthStanding[];\n competition: string | null;\n isLoading: boolean;\n isError: boolean;\n}\n\nexport interface CoachAnalyticsOptions {\n /** Competition for the standings snapshot; else the most-used one in fixtures. */\n competition?: string;\n /** Rows to sample from each list query. Default 200. */\n sampleLimit?: number;\n}\n\n/** Bucket rows into `weeks` weekly totals ending at \"now\" (oldest → newest). */\nfunction weeklyTrend<T>(\n rows: readonly T[],\n getDate: (row: T) => string,\n getValue: (row: T) => number,\n weeks = 8\n): AnalyticsTrendPoint[] {\n const MS_WEEK = 7 * 86_400_000;\n const now = Date.now();\n const buckets = Array.from({ length: weeks }, () => 0);\n for (const row of rows) {\n const time = new Date(getDate(row)).getTime();\n if (Number.isNaN(time)) {\n continue;\n }\n const age = now - time;\n if (age < 0) {\n continue;\n }\n const weeksAgo = Math.floor(age / MS_WEEK);\n if (weeksAgo >= 0 && weeksAgo < weeks) {\n buckets[weeks - 1 - weeksAgo] += getValue(row);\n }\n }\n return buckets.map((value, i) => {\n const ago = weeks - 1 - i;\n return { label: ago === 0 ? 'Now' : `${ago}w`, value };\n });\n}\n\n/** Aggregate real coaching data for the analytics dashboard. */\nexport const useCoachAnalytics = (options: CoachAnalyticsOptions = {}): CoachAnalytics => {\n const { competition: competitionOpt, sampleLimit = 200 } = options;\n\n const sessionsQuery = useSessions({ pagination: { limit: sampleLimit } });\n const workoutsQuery = useWorkoutLogs({ pagination: { limit: sampleLimit } });\n const fixturesQuery = useFixtures({ pagination: { limit: sampleLimit } });\n\n const sessions = useMemo(() => sessionsQuery.data?.items ?? [], [sessionsQuery.data]);\n const workouts = useMemo(() => workoutsQuery.data?.items ?? [], [workoutsQuery.data]);\n const fixtures = useMemo(() => fixturesQuery.data?.items ?? [], [fixturesQuery.data]);\n\n // Resolve the competition for the standings snapshot.\n const competition = useMemo(() => {\n if (competitionOpt) {\n return competitionOpt;\n }\n const counts = new Map<string, number>();\n for (const fixture of fixtures) {\n if (fixture.competition) {\n counts.set(fixture.competition, (counts.get(fixture.competition) ?? 0) + 1);\n }\n }\n let top: string | null = null;\n let best = 0;\n for (const [comp, n] of counts) {\n if (n > best) {\n best = n;\n top = comp;\n }\n }\n return top;\n }, [competitionOpt, fixtures]);\n\n const standingsQuery = useStandings(competition ?? undefined);\n\n return useMemo<CoachAnalytics>(() => {\n const totalSessions = sessions.length;\n const rated = sessions.filter((s) => s.rating !== null);\n const ratedCount = rated.length;\n const avgRating =\n ratedCount > 0 ? rated.reduce((acc, s) => acc + (s.rating ?? 0), 0) / ratedCount : null;\n const completedCount = sessions.filter((s) => s.status === 'COMPLETED').length;\n const completedPct = totalSessions > 0 ? (completedCount / totalSessions) * 100 : 0;\n\n const statusOrder: AthSessionStatus[] = [\n 'REQUESTED',\n 'CONFIRMED',\n 'COMPLETED',\n 'CANCELLED',\n 'NO_SHOW',\n ];\n const statusCounts = new Map<AthSessionStatus, number>();\n for (const s of sessions) {\n statusCounts.set(s.status, (statusCounts.get(s.status) ?? 0) + 1);\n }\n const sessionsByStatus = statusOrder\n .map((status) => ({ status, count: statusCounts.get(status) ?? 0 }))\n .filter((entry) => entry.count > 0);\n\n const byCoach = new Map<string, { sum: number; count: number }>();\n for (const s of rated) {\n const entry = byCoach.get(s.coachId) ?? { sum: 0, count: 0 };\n entry.sum += s.rating ?? 0;\n entry.count += 1;\n byCoach.set(s.coachId, entry);\n }\n const ratingByCoach = Array.from(byCoach.entries())\n .map(([coachId, { sum, count }]) => ({ coachId, avgRating: sum / count, count }))\n .sort((a, b) => b.avgRating - a.avgRating);\n\n const coachIds = Array.from(new Set(sessions.map((s) => s.coachId)));\n\n // Training load (ACWR) from real workout totalLoad — workspace-wide and,\n // in the same pass, per athlete (every row already carries `athleteId`).\n const now = Date.now();\n const DAY = 86_400_000;\n const acuteFrom = now - 7 * DAY;\n const chronicFrom = now - 28 * DAY;\n let acute = 0;\n let chronic28 = 0;\n let oldestSampledAt = Number.POSITIVE_INFINITY;\n const perAthlete = new Map<\n string,\n { acute: number; chronic28: number; workoutCount: number; loadedCount: number }\n >();\n for (const w of workouts) {\n const performedAt = new Date(w.performedAt).getTime();\n if (Number.isNaN(performedAt)) {\n continue;\n }\n if (performedAt < oldestSampledAt) {\n oldestSampledAt = performedAt;\n }\n const load = w.totalLoad ?? 0;\n if (performedAt >= acuteFrom) {\n acute += load;\n }\n if (performedAt >= chronicFrom) {\n chronic28 += load;\n }\n if (performedAt < chronicFrom || !w.athleteId) {\n continue;\n }\n const entry = perAthlete.get(w.athleteId) ?? {\n acute: 0,\n chronic28: 0,\n workoutCount: 0,\n loadedCount: 0,\n };\n entry.chronic28 += load;\n entry.workoutCount += 1;\n if (w.totalLoad != null) {\n entry.loadedCount += 1;\n }\n if (performedAt >= acuteFrom) {\n entry.acute += load;\n }\n perAthlete.set(w.athleteId, entry);\n }\n const chronic = chronic28 / 4;\n const ratio = chronic > 0 ? acute / chronic : null;\n\n const loadByAthlete: AthleteTrainingLoad[] = Array.from(perAthlete.entries())\n .map(([athleteId, entry]) => {\n const athleteChronic = entry.chronic28 / 4;\n return {\n athleteId,\n acute: entry.acute,\n chronic: athleteChronic,\n ratio: athleteChronic > 0 ? entry.acute / athleteChronic : null,\n workoutCount: entry.workoutCount,\n loadedCount: entry.loadedCount,\n };\n })\n .sort((a, b) => b.acute - a.acute || b.chronic - a.chronic);\n\n // The svc clamps `limit`, so `hasMore` plus a sample that never reaches\n // back 28 days means every load number above is a floor, not a total.\n const loadSampleTruncated =\n (workoutsQuery.data?.pageInfo.hasMore ?? false) && oldestSampledAt > chronicFrom;\n\n const loadTrend = weeklyTrend(\n workouts,\n (w) => w.performedAt,\n (w) => w.totalLoad ?? 0\n );\n const sessionTrend = weeklyTrend(\n sessions,\n (s) => s.scheduledAt,\n () => 1\n );\n\n return {\n totalSessions,\n ratedCount,\n avgRating,\n completedCount,\n completedPct,\n sessionsByStatus,\n ratingByCoach,\n coachIds,\n trainingLoad: { acute, chronic, ratio },\n loadByAthlete,\n athleteIds: loadByAthlete.map((entry) => entry.athleteId),\n loadSampleTruncated,\n loadTrend,\n sessionTrend,\n standings: standingsQuery.data ?? [],\n competition,\n isLoading:\n sessionsQuery.isLoading ||\n workoutsQuery.isLoading ||\n fixturesQuery.isLoading ||\n (Boolean(competition) && standingsQuery.isLoading),\n isError:\n sessionsQuery.isError ||\n workoutsQuery.isError ||\n fixturesQuery.isError ||\n standingsQuery.isError,\n };\n }, [\n sessions,\n workouts,\n workoutsQuery.data,\n competition,\n standingsQuery.data,\n standingsQuery.isLoading,\n standingsQuery.isError,\n sessionsQuery.isLoading,\n sessionsQuery.isError,\n workoutsQuery.isLoading,\n workoutsQuery.isError,\n fixturesQuery.isLoading,\n fixturesQuery.isError,\n ]);\n};\n\n// ============================================================================\n// AI operations (BOFF-3574) — model selection, the append-only decision ledger\n// and the coach's review actions. Every field below is live in the composed\n// production supergraph; nothing here is mocked.\n// ============================================================================\n\nconst AGENT_RUN_FIELDS = `\n id workspaceId actorId actorType provider model trigger status error\n promptSummary inputRefs decision tokensIn tokensOut latencyMs costUsd\n createdAt\n`;\n\nconst AI_CONFIG_FIELDS = `\n workspaceId provider model autoPilotEnabled autoPilotLastRunAt updatedAt\n`;\n\n/** The selectable (provider, model) pairs, with the platform default marked. */\nexport const useAiModelCatalog = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'ai-model-catalog'],\n queryFn: async () => {\n const result = await athQuery<{ athAiModelCatalog: AthAiModelInfo[] }>(\n `query AthAiModelCatalog {\n athAiModelCatalog { provider model label isDefault capabilities configured }\n }`,\n {},\n apiGatewayUrl\n );\n return result.athAiModelCatalog;\n },\n // A static catalog — refetching it on every focus is pure noise.\n staleTime: 30 * 60_000,\n });\n};\n\n/**\n * The workspace's saved AI config, or null when it has never overridden the\n * platform default chain (the query is nullable by design — a null here means\n * \"using the platform default\", not \"failed\").\n */\nexport const useWorkspaceAiConfig = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'ai-config'],\n queryFn: async () => {\n const result = await athQuery<{ athWorkspaceAiConfig: AthWorkspaceAiConfig | null }>(\n `query AthWorkspaceAiConfig {\n athWorkspaceAiConfig { ${AI_CONFIG_FIELDS} }\n }`,\n {},\n apiGatewayUrl\n );\n return result.athWorkspaceAiConfig;\n },\n });\n};\n\nexport const useSetWorkspaceAiModel = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({ provider, model }: { provider: string; model: string }) => {\n const result = await athQuery<{ athSetWorkspaceAiModel: AthWorkspaceAiConfig }>(\n `mutation AthSetWorkspaceAiModel($provider: String!, $model: String!) {\n athSetWorkspaceAiModel(provider: $provider, model: $model) { ${AI_CONFIG_FIELDS} }\n }`,\n { provider, model },\n apiGatewayUrl\n );\n return result.athSetWorkspaceAiModel;\n },\n onSuccess: (config) => {\n queryClient.setQueryData(['atheletebridge', 'ai-config'], config);\n },\n });\n};\n\n/**\n * Opt this workspace into (or out of) the autonomous coaching loop. The loop is\n * ALSO gated per deployment by `ATHELETEBRIDGE_AGENT_LOOP_ENABLED`, so enabling\n * it here does not on its own start anything — and even when it does run it\n * only ever records a PROPOSED adjustment for a coach to resolve.\n */\nexport const useSetWorkspaceAutoPilot = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (enabled: boolean) => {\n const result = await athQuery<{ athSetWorkspaceAutoPilot: AthWorkspaceAiConfig }>(\n `mutation AthSetWorkspaceAutoPilot($enabled: Boolean!) {\n athSetWorkspaceAutoPilot(enabled: $enabled) { ${AI_CONFIG_FIELDS} }\n }`,\n { enabled },\n apiGatewayUrl\n );\n return result.athSetWorkspaceAutoPilot;\n },\n onSuccess: (config) => {\n queryClient.setQueryData(['atheletebridge', 'ai-config'], config);\n },\n });\n};\n\nexport interface AgentRunFilters {\n /** Rows per page. */\n limit?: number;\n /** Rows to skip. Offset-based: the composed PaginationInput has no cursor. */\n offset?: number;\n /** Only runs whose `inputRefs.athleteId` is this athlete's user id. */\n athleteId?: string;\n /** Only runs whose `inputRefs.teamId` is this team. */\n teamId?: string;\n /** Only runs whose `inputRefs.programId` is this program. */\n programId?: string;\n}\n\n/** The server-side `AthAgentRunFilter`, or null when nothing narrows the list. */\nfunction toAgentRunFilter(filters: AgentRunFilters): Record<string, string> | null {\n const filter: Record<string, string> = {};\n if (filters.athleteId) filter.athleteId = filters.athleteId;\n if (filters.teamId) filter.teamId = filters.teamId;\n if (filters.programId) filter.programId = filters.programId;\n return Object.keys(filter).length > 0 ? filter : null;\n}\n\n/**\n * The workspace's AI decision ledger, most recent first — optionally narrowed\n * to one athlete, team or program (the decision cards on those views).\n */\nexport const useAgentRuns = (filters: AgentRunFilters = {}) => {\n const { apiGatewayUrl } = useAthleteBridge();\n const { limit = 10, offset = 0 } = filters;\n const filter = toAgentRunFilter(filters);\n return useQuery({\n queryKey: ['atheletebridge', 'agent-runs', limit, offset, filter],\n queryFn: async () => {\n const result = await athQuery<{ athAgentRuns: AthAgentRunConnection }>(\n `query AthAgentRuns($pagination: PaginationInput, $filter: AthAgentRunFilter) {\n athAgentRuns(pagination: $pagination, filter: $filter) {\n items { ${AGENT_RUN_FIELDS} }\n pageInfo { cursor hasMore }\n }\n }`,\n { pagination: { limit, offset }, filter },\n apiGatewayUrl\n );\n return result.athAgentRuns;\n },\n });\n};\n\n/**\n * A single ledger row by id. Used to resolve the `extensions.agentRunId` an\n * `AI_PROVIDER_UNAVAILABLE` error carries, so the user sees the recorded\n * failure instead of a generic toast.\n */\nexport const useAgentRun = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'agent-run', id],\n queryFn: async () => {\n const result = await athQuery<{ athAgentRun: AthAgentRun | null }>(\n `query AthAgentRun($id: ID!) {\n athAgentRun(id: $id) { ${AGENT_RUN_FIELDS} }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athAgentRun;\n },\n enabled: Boolean(id),\n retry: false,\n });\n};\n\n/**\n * A program with its AI provenance (`context.lastAiAdjustment`). Kept separate\n * from {@link useProgram} so the `context` selection — which only the AI\n * Operations page needs — stays off every other program read.\n */\nexport const useProgramAiState = (id: string | undefined) => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'program-ai-state', id],\n queryFn: async () => {\n const result = await athQuery<{\n athProgram: (Pick<AthProgram, 'id' | 'name' | 'status'> & { context: unknown }) | null;\n }>(\n `query AthProgramAiState($id: ID!) {\n athProgram(id: $id) { id name status context }\n }`,\n { id },\n apiGatewayUrl\n );\n return result.athProgram;\n },\n enabled: Boolean(id),\n retry: false,\n });\n};\n\n/**\n * Generate a DRAFT program from a live model call. Throws {@link AthApiError}\n * with code `AI_PROVIDER_UNAVAILABLE` (and the FAILED ledger row's id) when no\n * provider in the chain could answer.\n */\nexport const useGenerateProgram = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async (input: AthGenerateProgramInput) => {\n const result = await athQuery<{ athGenerateProgram: AthGenerateProgramResult }>(\n `mutation AthGenerateProgram($input: AthGenerateProgramInput!) {\n athGenerateProgram(input: $input) {\n agentRunId\n drillCount\n sessionCount\n program { ${PROGRAM_FIELDS} }\n }\n }`,\n { input },\n apiGatewayUrl\n );\n return result.athGenerateProgram;\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'agent-runs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'programs'] });\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'sessions'] });\n },\n });\n};\n\n/**\n * Ask the AI to read an athlete's recent load/metric trend and PROPOSE an\n * adjustment onto a program. It changes no prescribed training load by itself —\n * a coach resolves it with {@link useOverrideAgentRun}.\n */\nexport const useAdjustPlanFromPerformance = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({\n athleteId,\n programId,\n requestedProvider,\n }: {\n athleteId: string;\n programId: string;\n requestedProvider?: string;\n }) => {\n const result = await athQuery<{ athAdjustPlanFromPerformance: AthPlanAdjustment }>(\n `mutation AthAdjustPlanFromPerformance($athleteId: ID!, $programId: ID!, $requestedProvider: String) {\n athAdjustPlanFromPerformance(athleteId: $athleteId, programId: $programId, requestedProvider: $requestedProvider) {\n agentRunId athleteId programId assessment rationale confidence\n recommendedWeeklyLoadChangePct flags appliedToProgram createdAt\n }\n }`,\n { athleteId, programId, requestedProvider },\n apiGatewayUrl\n );\n return result.athAdjustPlanFromPerformance;\n },\n onSuccess: (adjustment) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'agent-runs'] });\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'program-ai-state', adjustment.programId],\n });\n },\n });\n};\n\n/**\n * A coach's review of a prior AI decision. Recorded as a NEW, append-only\n * ledger row — never an edit of the original — which resolves the program's\n * `lastAiAdjustment` to ACCEPTED (same assessment) or OVERRIDDEN (a different\n * one).\n */\nexport const useOverrideAgentRun = () => {\n const queryClient = useQueryClient();\n const { apiGatewayUrl } = useAthleteBridge();\n return useMutation({\n mutationFn: async ({\n runId,\n programId,\n assessment,\n note,\n }: {\n runId: string;\n programId: string;\n assessment: AthAiAssessment;\n note: string;\n }) => {\n const result = await athQuery<{ athOverrideAgentRun: AthAgentRunOverride }>(\n `mutation AthOverrideAgentRun($runId: ID!, $programId: ID!, $assessment: AthAiAssessment!, $note: String!) {\n athOverrideAgentRun(runId: $runId, programId: $programId, assessment: $assessment, note: $note) {\n id workspaceId programId supersedesRunId assessment note\n appliedToProgram createdAt\n }\n }`,\n { runId, programId, assessment, note },\n apiGatewayUrl\n );\n return result.athOverrideAgentRun;\n },\n onSuccess: (override) => {\n void queryClient.invalidateQueries({ queryKey: ['atheletebridge', 'agent-runs'] });\n void queryClient.invalidateQueries({\n queryKey: ['atheletebridge', 'program-ai-state', override.programId],\n });\n },\n });\n};\n\n// ============================================================================\n// Health probe\n// ============================================================================\n\nexport const useHealth = () => {\n const { apiGatewayUrl } = useAthleteBridge();\n return useQuery({\n queryKey: ['atheletebridge', 'health'],\n queryFn: async () => {\n const result = await athQuery<{ athHealth: string }>(\n `query AthHealth { athHealth }`,\n {},\n apiGatewayUrl\n );\n return result.athHealth;\n },\n });\n};\n"],"mappings":"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"}
|
|
@@ -383,6 +383,12 @@ export interface AthAiModelInfo {
|
|
|
383
383
|
label: string;
|
|
384
384
|
isDefault: boolean;
|
|
385
385
|
capabilities: string[];
|
|
386
|
+
/**
|
|
387
|
+
* Whether this deployment can call the provider right now (adapter
|
|
388
|
+
* registered and API key set). An unconfigured pair can still be saved; its
|
|
389
|
+
* decisions then run on the next configured provider in the chain.
|
|
390
|
+
*/
|
|
391
|
+
configured: boolean;
|
|
386
392
|
}
|
|
387
393
|
/**
|
|
388
394
|
* The workspace's saved default AI provider/model. `autoPilotEnabled` is the
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/types/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/types/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@burdenoff/microfe-atheletebridge",
|
|
3
|
-
"version": "2026.1031.
|
|
3
|
+
"version": "2026.1031.2",
|
|
4
4
|
"description": "Burdenoff AthleteBridge Microfrontend - Sports, coaching & training platform for teams, fixtures, programs, sessions and athlete performance",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|