mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-09 13:01:00 +00:00
fix(insights): gate /api/insights/generate POST on assistant feature flag
Every visit to /insights or any sub-route used to fire POST /api/insights/generate from InsightsLayoutShell. The mutation returned null on 422 (no provider configured) so the UI degraded gracefully, but the server kept absorbing the call on every cold mount and the dev-server logs filled with '422 Unprocessable Entity'. Read the operator's assistant flag matrix from /api/feature-flags (already cached server-side at 60s, client-side under the shared ['feature-flags'] query key) and skip the mutation entirely when 'enabled' or 'briefing' is false. The fail-open default in useFeatureFlags means a flags-endpoint hiccup still renders the advisor — the gate only takes effect when the operator has explicitly turned the surface off. Also update the per-metric InsightStatusCard's empty-state copy from the diagnostic 'KI-Provider nicht konfiguriert' / 'AI provider not configured' to the neutral 'Auswertung nicht verfügbar' / 'Assessment unavailable'. The diagnostic phrasing read as a setup failure even though the surface degrades cleanly; the neutral phrasing matches the rest of the empty-state language. Per .planning/round-v1433-audit-runtime.md F18.
This commit is contained in:
1 parent
b07143b07c
commit
7b78a4bf39
3 files changed
+23
-8
No files matched your search
@@ -4,6 +4,7 @@ import { useMemo, type ReactNode } from "react";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
|
||||
import { useAuth } from "@/hooks/use-auth";
|
||||
import { useFeatureFlags } from "@/hooks/use-feature-flags";
|
||||
import { useWorkouts } from "@/hooks/use-workouts";
|
||||
import { InsightsTabStrip } from "@/components/insights/insights-tab-strip";
|
||||
import { useInsightsAdvisorQuery } from "@/components/insights/use-insights-advisor";
|
||||
@@ -41,7 +42,22 @@ interface ComprehensivePayload {
|
||||
|
||||
export function InsightsLayoutShell({ children }: { children: ReactNode }) {
|
||||
const { isAuthenticated } = useAuth();
|
||||
const advisor = useInsightsAdvisorQuery(isAuthenticated);
|
||||
// v1.4.33 F18 — gate the advisor POST on the operator's assistant
|
||||
// feature flag. Pre-fix, every /insights mount fired POST
|
||||
// /api/insights/generate even when the operator had disabled the
|
||||
// briefing surface or the user had no AI provider configured. The
|
||||
// server returned 422 in that case and the regenerate button on the
|
||||
// tab strip rendered a non-functional spinner. Reading the flag
|
||||
// matrix off `/api/feature-flags` keeps the hot path one fetch
|
||||
// (shared `["feature-flags"]` cache, 60s staleTime) and skips the
|
||||
// advisor request entirely when the operator has the briefing gate
|
||||
// off. The fail-open default in `useFeatureFlags` means a network
|
||||
// hiccup still renders the advisor — the gate only takes effect when
|
||||
// the operator has explicitly turned the surface off.
|
||||
const flags = useFeatureFlags();
|
||||
const advisorEnabled =
|
||||
isAuthenticated && flags.enabled && flags.briefing;
|
||||
const advisor = useInsightsAdvisorQuery(advisorEnabled);
|
||||
|
||||
// Shared analytics fetch — sub-pages consume the same cache key.
|
||||
const analyticsQuery = useQuery({
|
||||
@@ -96,7 +112,7 @@ export function InsightsLayoutShell({ children }: { children: ReactNode }) {
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<InsightsTabStrip
|
||||
onRegenerate={isAuthenticated ? advisor.regenerate : undefined}
|
||||
onRegenerate={advisorEnabled ? advisor.regenerate : undefined}
|
||||
regenerating={advisor.isRegenerating}
|
||||
availability={availability}
|
||||
/>
|
||||
|
||||
Reference in new issue
Block a user