diff --git a/components/shared/nav-bar.tsx b/components/shared/nav-bar.tsx
index d6dba25..f039e67 100644
--- a/components/shared/nav-bar.tsx
+++ b/components/shared/nav-bar.tsx
@@ -183,7 +183,7 @@ export function NavBar({
{/* Rechts: solo-status + notifications + account-menu */}
-
+
diff --git a/components/solo/nav-status-indicators.tsx b/components/solo/nav-status-indicators.tsx
index 7ee614e..e370540 100644
--- a/components/solo/nav-status-indicators.tsx
+++ b/components/solo/nav-status-indicators.tsx
@@ -1,13 +1,10 @@
'use client'
-import { usePathname } from 'next/navigation'
import { useSoloStore } from '@/stores/solo-store'
import type { RealtimeStatus } from '@/stores/solo-store'
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip'
import { cn } from '@/lib/utils'
-const SOLO_PATH_RE = /^\/products\/[^/]+\/solo$/
-
function RealtimeIndicator({
status,
showConnectingIndicator,
@@ -43,13 +40,12 @@ function RealtimeIndicator({
)
}
-export function SoloNavStatusIndicators() {
- const pathname = usePathname()
+export function SoloNavStatusIndicators({ hasActiveProduct }: { hasActiveProduct: boolean }) {
const realtimeStatus = useSoloStore((s) => s.realtimeStatus)
const showConnectingIndicator = useSoloStore((s) => s.showConnectingIndicator)
const connectedWorkers = useSoloStore((s) => s.connectedWorkers)
- if (!pathname || !SOLO_PATH_RE.test(pathname)) return null
+ if (!hasActiveProduct) return null
return (
diff --git a/components/solo/realtime-bridge.tsx b/components/solo/realtime-bridge.tsx
index bd04f69..37cc14b 100644
--- a/components/solo/realtime-bridge.tsx
+++ b/components/solo/realtime-bridge.tsx
@@ -1,21 +1,17 @@
// SoloRealtimeBridge — mount in de (app)-layout zodat de SSE-verbinding
-// blijft staan over Server Action-refreshes van de Solo-page heen.
+// blijft staan over Server Action-refreshes heen.
//
-// Leest het huidige product-id uit de URL (`/products/[id]/solo`).
-// Wanneer de gebruiker niet op het Solo Paneel zit, wordt de stream
-// gesloten — geen onnodige verbinding open houden.
+// Stream opent zodra er een actief product is (ongeacht het pad), zodat
+// de Live-status-dot en worker-presence-indicator in de NavBar overal
+// werken. Buiten /solo is de solo-store leeg en zijn task-events no-ops
+// (zie stores/solo-store.ts handleRealtimeEvent), dus de stream gedraagt
+// zich automatisch als lichte presence-stream tot SoloBoard mount.
'use client'
-import { usePathname } from 'next/navigation'
import { useSoloRealtime } from '@/lib/realtime/use-solo-realtime'
-const SOLO_PATH_RE = /^\/products\/([^/]+)\/solo$/
-
-export function SoloRealtimeBridge() {
- const pathname = usePathname()
- const match = pathname?.match(SOLO_PATH_RE)
- const productId = match?.[1] ?? null
+export function SoloRealtimeBridge({ productId }: { productId: string | null }) {
useSoloRealtime(productId)
return null
}
diff --git a/docs/scrum4me-architecture.md b/docs/scrum4me-architecture.md
index 4d0a2ce..bc1234d 100644
--- a/docs/scrum4me-architecture.md
+++ b/docs/scrum4me-architecture.md
@@ -986,7 +986,7 @@ Niet-matchende events worden server-side gedropt zodat de browser geen irrelevan
### Connection lifecycle
-- **Open**: `EventSource('/api/realtime/solo?product_id=...')` zodra de gebruiker op `/solo` is.
+- **Open**: `EventSource('/api/realtime/solo?product_id=...')` zodra de gebruiker een actief product heeft. `SoloRealtimeBridge` mount in `(app)/layout` en krijgt het `productId` via prop, zodat de stream over de hele app open staat — niet alleen op `/solo`. Zo kunnen de Live-status-dot en worker-presence-indicator in de NavBar overal werken. Buiten `/solo` is de solo-store leeg en zijn binnenkomende task-events no-ops (`stores/solo-store.ts handleRealtimeEvent` skipt onbekende ids), dus de stream gedraagt zich automatisch als lichte presence-stream tot `SoloBoard` mount.
- **Reconnect**: exponential backoff bij `onerror` (1s → 30s, reset bij `ready` event).
- **Pause op tab-hidden**: `document.visibilityState === 'hidden'` sluit de stream actief. Bij `visible` wordt opnieuw verbonden. Dit voorkomt dat inactieve tabs DB-connecties open houden.
- **Hard close**: server sluit zelf na 240s (Vercel `maxDuration` is 300s); client herconnect transparant.