diff --git a/src/PowderCoating.Web/Controllers/KioskController.cs b/src/PowderCoating.Web/Controllers/KioskController.cs
index fa6686d..31689f9 100644
--- a/src/PowderCoating.Web/Controllers/KioskController.cs
+++ b/src/PowderCoating.Web/Controllers/KioskController.cs
@@ -68,7 +68,8 @@ public class KioskController : Controller
///
/// Idle branded screen displayed on the front-desk tablet.
/// Validates the KioskDevice cookie; returns 403 if missing or token mismatch.
- /// The view connects to KioskHub and listens for StartIntake events.
+ /// The view polls /Kiosk/PollSession every 3 seconds and navigates when staff
+ /// triggers a session via the Dashboard "Start Intake" button.
///
[AllowAnonymous]
public async Task Welcome()
@@ -86,6 +87,35 @@ public class KioskController : Controller
return View();
}
+ ///
+ /// Lightweight polling endpoint called every 3 seconds by the kiosk Welcome screen.
+ /// Returns the most recent InPerson KioskSession created in the last 60 seconds so
+ /// the tablet can navigate without relying on SignalR (which Azure App Service blocks
+ /// for anonymous WebSocket/SSE connections through its ingress proxy).
+ ///
+ [AllowAnonymous, HttpGet]
+ [ResponseCache(NoStore = true, Location = ResponseCacheLocation.None)]
+ public async Task PollSession()
+ {
+ var cookie = ReadKioskCookie();
+ if (cookie == null) return Json(new { hasSession = false });
+
+ var company = await _unitOfWork.Companies.GetByIdAsync(cookie.Value.companyId, ignoreQueryFilters: true);
+ if (company == null || company.KioskActivationToken != cookie.Value.token)
+ return Json(new { hasSession = false });
+
+ var window = DateTime.UtcNow.AddSeconds(-60);
+ var session = await _unitOfWork.KioskSessions.FirstOrDefaultAsync(
+ s => s.CompanyId == cookie.Value.companyId
+ && s.SessionType == KioskSessionType.InPerson
+ && s.Status == KioskSessionStatus.Active
+ && s.CreatedAt >= window,
+ ignoreQueryFilters: true);
+
+ if (session == null) return Json(new { hasSession = false });
+ return Json(new { hasSession = true, sessionToken = session.SessionToken });
+ }
+
///
/// Serves the company logo for anonymous kiosk pages. Resolves the company from the
/// KioskDevice cookie so no tenant context is needed on the anonymous request.
diff --git a/src/PowderCoating.Web/Views/Shared/_KioskLayout.cshtml b/src/PowderCoating.Web/Views/Shared/_KioskLayout.cshtml
index a6e6598..729ba05 100644
--- a/src/PowderCoating.Web/Views/Shared/_KioskLayout.cshtml
+++ b/src/PowderCoating.Web/Views/Shared/_KioskLayout.cshtml
@@ -85,7 +85,6 @@
}
-
@await RenderSectionAsync("Scripts", required: false)