@optifye/dashboard-core 6.12.2 → 6.12.4

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/index.mjs CHANGED
@@ -2599,19 +2599,206 @@ function getSentry() {
2599
2599
  return null;
2600
2600
  }
2601
2601
  }
2602
+ var SENTRY_HANDLED_EVENT_WINDOW_MS = 10 * 60 * 1e3;
2603
+ var SENTRY_HANDLED_EVENT_SESSION_LIMIT = 20;
2604
+ var SENTRY_QUOTA_STORAGE_KEY = "optifye:sentry-handled-quota:v1";
2605
+ var sentryFingerprintSentAt = /* @__PURE__ */ new Map();
2606
+ var handledSentryEventCount = 0;
2607
+ var UUID_PATTERN = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/gi;
2608
+ var LONG_HEX_PATTERN = /\b[0-9a-f]{24,}\b/gi;
2609
+ var EMAIL_PATTERN = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi;
2610
+ var BEARER_PATTERN = /\bBearer\s+[A-Za-z0-9._~+/=-]+/gi;
2611
+ var URI_PATTERN = /\b[a-z][a-z0-9+.-]{1,31}:\/\/[^\s)]+/gi;
2612
+ var MEDIA_PATH_PATTERN = /\b[^\s)]+\.m3u8(?:\?[^\s)]*)?/gi;
2613
+ var SENSITIVE_ASSIGNMENT_PATTERN = /\b([A-Za-z0-9_.-]*(?:authorization|cookie|password|secret|token|session|email|api[_-]?key)[A-Za-z0-9_.-]*)\b\s*[:=]\s*["']?[^"'\s,;)}\]]+/gi;
2614
+ var SENSITIVE_KEY_PATTERN = /(authorization|cookie|password|secret|token|session|email|api[_-]?key|url|stream|playlist|media)/i;
2615
+ function resetSentryQuotaForTests() {
2616
+ sentryFingerprintSentAt.clear();
2617
+ handledSentryEventCount = 0;
2618
+ const storage = getBrowserSessionStorage();
2619
+ storage?.removeItem(SENTRY_QUOTA_STORAGE_KEY);
2620
+ }
2621
+ var sanitizeString = (value) => {
2622
+ return value.replace(BEARER_PATTERN, "Bearer [redacted]").replace(SENSITIVE_ASSIGNMENT_PATTERN, (_match, key) => `${key}=[redacted]`).replace(URI_PATTERN, "[url]").replace(MEDIA_PATH_PATTERN, "[media]").replace(EMAIL_PATTERN, "[email]").replace(UUID_PATTERN, ":uuid").replace(LONG_HEX_PATTERN, ":id").replace(/\?.*$/, "").replace(/\s+/g, " ").trim();
2623
+ };
2624
+ var sanitizeRoute = (value) => {
2625
+ if (typeof value !== "string" || value.trim().length === 0) return void 0;
2626
+ try {
2627
+ const parsed = new URL(value, "https://optifye.local");
2628
+ return sanitizeString(parsed.pathname);
2629
+ } catch {
2630
+ return sanitizeString(value.split("?")[0] || value);
2631
+ }
2632
+ };
2633
+ var sanitizeValue = (value, depth = 0) => {
2634
+ if (depth > 3) return "[truncated]";
2635
+ if (typeof value === "string") return sanitizeString(value);
2636
+ if (typeof value === "number" || typeof value === "boolean" || value === null || value === void 0) return value;
2637
+ if (Array.isArray(value)) {
2638
+ return value.slice(0, 20).map((item) => sanitizeValue(item, depth + 1));
2639
+ }
2640
+ if (typeof value === "object") {
2641
+ const sanitized = {};
2642
+ Object.entries(value).forEach(([key, item]) => {
2643
+ sanitized[key] = SENSITIVE_KEY_PATTERN.test(key) ? "[redacted]" : sanitizeValue(item, depth + 1);
2644
+ });
2645
+ return sanitized;
2646
+ }
2647
+ return String(value);
2648
+ };
2649
+ var sanitizeStack = (stack) => {
2650
+ return stack.split("\n").map((line) => sanitizeString(line)).join("\n");
2651
+ };
2652
+ var sanitizeExtras = (extras) => {
2653
+ if (!extras) return void 0;
2654
+ return sanitizeValue(extras);
2655
+ };
2656
+ var getBrowserSessionStorage = () => {
2657
+ if (typeof window === "undefined") return null;
2658
+ try {
2659
+ return window.sessionStorage;
2660
+ } catch {
2661
+ return null;
2662
+ }
2663
+ };
2664
+ var loadSentryQuotaFromStorage = (now4) => {
2665
+ const storage = getBrowserSessionStorage();
2666
+ if (!storage) return;
2667
+ const rawState = storage.getItem(SENTRY_QUOTA_STORAGE_KEY);
2668
+ if (!rawState) return;
2669
+ try {
2670
+ const parsed = JSON.parse(rawState);
2671
+ const persistedCount = Number(parsed.handledEventCount);
2672
+ handledSentryEventCount = Number.isFinite(persistedCount) && persistedCount > 0 ? Math.floor(persistedCount) : 0;
2673
+ sentryFingerprintSentAt.clear();
2674
+ if (parsed.fingerprintSentAt && typeof parsed.fingerprintSentAt === "object") {
2675
+ Object.entries(parsed.fingerprintSentAt).forEach(([fingerprint, sentAt]) => {
2676
+ const sentAtMs = Number(sentAt);
2677
+ if (Number.isFinite(sentAtMs) && now4 - sentAtMs < SENTRY_HANDLED_EVENT_WINDOW_MS) {
2678
+ sentryFingerprintSentAt.set(fingerprint, sentAtMs);
2679
+ }
2680
+ });
2681
+ }
2682
+ } catch {
2683
+ storage.removeItem(SENTRY_QUOTA_STORAGE_KEY);
2684
+ }
2685
+ };
2686
+ var persistSentryQuotaToStorage = () => {
2687
+ const storage = getBrowserSessionStorage();
2688
+ if (!storage) return;
2689
+ try {
2690
+ storage.setItem(
2691
+ SENTRY_QUOTA_STORAGE_KEY,
2692
+ JSON.stringify({
2693
+ handledEventCount: handledSentryEventCount,
2694
+ fingerprintSentAt: Object.fromEntries(sentryFingerprintSentAt)
2695
+ })
2696
+ );
2697
+ } catch {
2698
+ }
2699
+ };
2700
+ var normalizeMessage = (error) => {
2701
+ const message = error instanceof Error ? error.message : String(error ?? "unknown");
2702
+ return sanitizeString(message.toLowerCase()).slice(0, 180) || "unknown";
2703
+ };
2704
+ var getErrorName = (error) => {
2705
+ if (error && typeof error === "object" && "name" in error) {
2706
+ const name = error.name;
2707
+ if (typeof name === "string" && name.trim()) return sanitizeString(name);
2708
+ }
2709
+ return error instanceof Error ? error.constructor.name : typeof error;
2710
+ };
2711
+ var getStatusFromError = (error) => {
2712
+ const message = error instanceof Error ? error.message : String(error ?? "");
2713
+ const statusMatch = message.match(/\((\d{3})\)/) || message.match(/http\s+(\d{3})/i) || message.match(/status:\s*(\d{3})/i);
2714
+ if (!statusMatch) return null;
2715
+ const status = Number.parseInt(statusMatch[1], 10);
2716
+ return Number.isFinite(status) ? status : null;
2717
+ };
2718
+ var hasCaptureOptionShape = (value) => {
2719
+ return "surface" in value || "route" in value || "status" in value || "severity" in value || "quotaKey" in value || "extras" in value;
2720
+ };
2721
+ var normalizeCaptureOptions = (options) => {
2722
+ if (!options) return {};
2723
+ const optionRecord = options;
2724
+ if (!hasCaptureOptionShape(optionRecord)) {
2725
+ return { extras: optionRecord };
2726
+ }
2727
+ const {
2728
+ surface,
2729
+ route,
2730
+ status,
2731
+ severity,
2732
+ quotaKey,
2733
+ extras,
2734
+ ...rest
2735
+ } = options;
2736
+ return {
2737
+ surface: typeof surface === "string" ? surface : void 0,
2738
+ route: typeof route === "string" ? route : void 0,
2739
+ status: typeof status === "number" ? status : null,
2740
+ severity: severity === "info" || severity === "warning" || severity === "error" ? severity : void 0,
2741
+ quotaKey: typeof quotaKey === "string" ? quotaKey : void 0,
2742
+ extras: {
2743
+ ...rest,
2744
+ ...extras && typeof extras === "object" && !Array.isArray(extras) ? extras : {}
2745
+ }
2746
+ };
2747
+ };
2748
+ var buildSentryFingerprint = (error, options) => {
2749
+ if (options.quotaKey) return sanitizeString(options.quotaKey);
2750
+ const surface = sanitizeString(options.surface || "frontend");
2751
+ const route = sanitizeRoute(options.route || options.extras?.route || options.extras?.endpoint || options.extras?.url) || "unknown-route";
2752
+ const status = options.status ?? getStatusFromError(error) ?? "unknown-status";
2753
+ return [
2754
+ surface,
2755
+ route,
2756
+ String(status),
2757
+ getErrorName(error),
2758
+ normalizeMessage(error)
2759
+ ].join("|");
2760
+ };
2761
+ var shouldSendHandledSentryEvent = (fingerprint) => {
2762
+ const now4 = Date.now();
2763
+ loadSentryQuotaFromStorage(now4);
2764
+ const lastSentAt = sentryFingerprintSentAt.get(fingerprint);
2765
+ if (lastSentAt !== void 0 && now4 - lastSentAt < SENTRY_HANDLED_EVENT_WINDOW_MS) {
2766
+ return false;
2767
+ }
2768
+ if (handledSentryEventCount >= SENTRY_HANDLED_EVENT_SESSION_LIMIT) {
2769
+ return false;
2770
+ }
2771
+ sentryFingerprintSentAt.set(fingerprint, now4);
2772
+ handledSentryEventCount += 1;
2773
+ persistSentryQuotaToStorage();
2774
+ return true;
2775
+ };
2776
+ var createSanitizedSentryException = (error) => {
2777
+ if (error instanceof Error) {
2778
+ const sanitizedError = new Error(sanitizeString(error.message) || getErrorName(error) || "Error");
2779
+ sanitizedError.name = getErrorName(error) || "Error";
2780
+ if (typeof error.stack === "string") {
2781
+ sanitizedError.stack = sanitizeStack(error.stack);
2782
+ }
2783
+ return sanitizedError;
2784
+ }
2785
+ if (typeof error === "string") {
2786
+ return sanitizeString(error) || "unknown";
2787
+ }
2788
+ return sanitizeValue(error);
2789
+ };
2602
2790
  function isIgnorableFrontendError(error) {
2603
2791
  const name = error && typeof error === "object" ? error.name || "" : "";
2604
2792
  const message = error instanceof Error ? error.message : String(error ?? "");
2605
2793
  const lowerMessage = message.toLowerCase();
2606
- return name === "AbortError" || lowerMessage.includes("the operation was aborted") || lowerMessage.includes("signal is aborted") || lowerMessage.includes("resizeobserver loop");
2794
+ return name === "AbortError" || name === "NotAllowedError" || lowerMessage.includes("the operation was aborted") || lowerMessage.includes("signal is aborted") || lowerMessage.includes("resizeobserver loop") || lowerMessage.includes("play() failed") || lowerMessage.includes("play request was interrupted") || lowerMessage.includes("autoplay") || lowerMessage.includes("not allowed by the user agent") || lowerMessage.includes("recoverable hls") || lowerMessage.includes("non-fatal hls") || lowerMessage.includes("fragloaderror") || lowerMessage.includes("frag load error") || lowerMessage.includes("fragloadtimeout") || lowerMessage.includes("bufferstallederror") || lowerMessage.includes("buffer stalled") || lowerMessage.includes("media error recovered") || lowerMessage.includes("recovermediaerror");
2607
2795
  }
2608
2796
  function setSentryUserContext(user) {
2609
2797
  const sentry = getSentry();
2610
2798
  if (!sentry) return;
2611
2799
  if (user) {
2612
2800
  sentry.setUser({
2613
- id: user.id,
2614
- email: user.email
2801
+ id: user.id
2615
2802
  });
2616
2803
  sentry.setTags({
2617
2804
  company_id: user.company_id || "unknown",
@@ -2662,28 +2849,60 @@ function applyScopeExtras(scope, extras) {
2662
2849
  function captureSentryMessage(message, level = "warning", extras) {
2663
2850
  const sentry = getSentry();
2664
2851
  if (!sentry || !sentry.captureMessage) return;
2852
+ const options = normalizeCaptureOptions({ ...normalizeCaptureOptions(extras), severity: level });
2853
+ const fingerprint = buildSentryFingerprint(new Error(message), options);
2854
+ if (!shouldSendHandledSentryEvent(fingerprint)) return;
2855
+ const sanitizedExtras = sanitizeExtras({
2856
+ ...options.extras,
2857
+ sentry_quota_key: fingerprint,
2858
+ sentry_capture_policy: "quota_controlled"
2859
+ });
2860
+ const route = sanitizeRoute(options.route || options.extras?.route || options.extras?.endpoint || options.extras?.url);
2861
+ const sanitizedMessage = sanitizeString(message) || "Sentry message";
2665
2862
  if (sentry.withScope) {
2666
2863
  sentry.withScope((scope) => {
2667
2864
  scope.setLevel?.(level);
2668
- applyScopeExtras(scope, extras);
2669
- sentry.captureMessage?.(message);
2865
+ scope.setFingerprint?.([fingerprint]);
2866
+ if (options.surface) scope.setTag?.("surface", sanitizeString(options.surface));
2867
+ if (route) scope.setTag?.("route", route);
2868
+ if (options.status !== void 0 && options.status !== null) scope.setTag?.("status", options.status);
2869
+ applyScopeExtras(scope, sanitizedExtras);
2870
+ sentry.captureMessage?.(sanitizedMessage);
2670
2871
  });
2671
2872
  return;
2672
2873
  }
2673
- sentry.captureMessage(message, level);
2874
+ sentry.captureMessage(sanitizedMessage, level);
2674
2875
  }
2675
2876
  function captureSentryException(error, extras) {
2877
+ if (isIgnorableFrontendError(error)) {
2878
+ return;
2879
+ }
2676
2880
  const sentry = getSentry();
2677
2881
  if (!sentry || !sentry.captureException) return;
2882
+ const options = normalizeCaptureOptions(extras);
2883
+ const fingerprint = buildSentryFingerprint(error, options);
2884
+ if (!shouldSendHandledSentryEvent(fingerprint)) return;
2885
+ const sanitizedExtras = sanitizeExtras({
2886
+ ...options.extras,
2887
+ sentry_quota_key: fingerprint,
2888
+ sentry_capture_policy: "quota_controlled"
2889
+ });
2890
+ const route = sanitizeRoute(options.route || options.extras?.route || options.extras?.endpoint || options.extras?.url);
2891
+ const status = options.status ?? getStatusFromError(error);
2892
+ const sanitizedError = createSanitizedSentryException(error);
2678
2893
  if (sentry.withScope) {
2679
2894
  sentry.withScope((scope) => {
2680
- scope.setLevel?.("error");
2681
- applyScopeExtras(scope, extras);
2682
- sentry.captureException?.(error);
2895
+ scope.setLevel?.(options.severity || "error");
2896
+ scope.setFingerprint?.([fingerprint]);
2897
+ if (options.surface) scope.setTag?.("surface", sanitizeString(options.surface));
2898
+ if (route) scope.setTag?.("route", route);
2899
+ if (status !== null && status !== void 0) scope.setTag?.("status", status);
2900
+ applyScopeExtras(scope, sanitizedExtras);
2901
+ sentry.captureException?.(sanitizedError);
2683
2902
  });
2684
2903
  return;
2685
2904
  }
2686
- sentry.captureException(error);
2905
+ sentry.captureException(sanitizedError);
2687
2906
  }
2688
2907
  function captureHandledFrontendException(error, extras) {
2689
2908
  if (isIgnorableFrontendError(error)) {
@@ -2691,6 +2910,23 @@ function captureHandledFrontendException(error, extras) {
2691
2910
  }
2692
2911
  captureSentryException(error, extras);
2693
2912
  }
2913
+ function addSentryBreadcrumb(message, options = {}) {
2914
+ const sentry = getSentry();
2915
+ if (!sentry?.addBreadcrumb) return;
2916
+ const route = sanitizeRoute(options.route || options.extras?.route || options.extras?.endpoint || options.extras?.url);
2917
+ const data = sanitizeExtras({
2918
+ surface: options.surface,
2919
+ route,
2920
+ status: options.status,
2921
+ ...options.extras
2922
+ });
2923
+ sentry.addBreadcrumb({
2924
+ category: options.category || options.surface || "frontend",
2925
+ message: sanitizeString(message),
2926
+ level: options.severity || "info",
2927
+ data
2928
+ });
2929
+ }
2694
2930
 
2695
2931
  // src/lib/services/backendClient.ts
2696
2932
  var ACCESS_TOKEN_REFRESH_BUFFER_MS = 6e4;
@@ -2758,7 +2994,7 @@ var createAbortError = () => {
2758
2994
  return error;
2759
2995
  }
2760
2996
  };
2761
- var getStatusFromError = (error) => {
2997
+ var getStatusFromError2 = (error) => {
2762
2998
  const message = error instanceof Error ? error.message : String(error ?? "");
2763
2999
  const statusMatch = message.match(/\((\d{3})\)/) || message.match(/http\s+(\d{3})/i);
2764
3000
  if (!statusMatch) {
@@ -2774,7 +3010,7 @@ var isRetryableError = (error) => {
2774
3010
  if (isAbortError(error)) {
2775
3011
  return false;
2776
3012
  }
2777
- const status = getStatusFromError(error);
3013
+ const status = getStatusFromError2(error);
2778
3014
  if (status !== null) {
2779
3015
  return status >= 500 || status === 408 || status === 425 || status === 429;
2780
3016
  }
@@ -2798,6 +3034,7 @@ var fetchBackendJson = async (supabase, endpoint, options = {}) => {
2798
3034
  timeoutMs = DEFAULT_TIMEOUT_MS,
2799
3035
  retries = 0,
2800
3036
  retryDelayMs = DEFAULT_RETRY_DELAY_MS,
3037
+ sentry,
2801
3038
  signal: externalSignal,
2802
3039
  ...fetchOptions
2803
3040
  } = options;
@@ -2835,14 +3072,22 @@ var fetchBackendJson = async (supabase, endpoint, options = {}) => {
2835
3072
  } catch (error) {
2836
3073
  const wrappedError = externalSignal?.aborted || controller.signal.aborted && !isAbortError(error) ? createAbortError() : error;
2837
3074
  if (attempt >= retries || !isRetryableError(wrappedError)) {
2838
- captureHandledFrontendException(wrappedError, {
2839
- surface: "backend_client",
2840
- url,
2841
- method,
2842
- retry_attempt: attempt,
2843
- retries,
2844
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
2845
- });
3075
+ if (sentry && sentry.capture !== false) {
3076
+ captureHandledFrontendException(wrappedError, {
3077
+ surface: sentry.surface || "backend_client",
3078
+ route: sentry.route || endpoint,
3079
+ status: sentry.status ?? getStatusFromError2(wrappedError),
3080
+ severity: sentry.severity || "error",
3081
+ quotaKey: sentry.quotaKey,
3082
+ extras: {
3083
+ method,
3084
+ retry_attempt: attempt,
3085
+ retries,
3086
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown",
3087
+ ...sentry.extras
3088
+ }
3089
+ });
3090
+ }
2846
3091
  throw wrappedError;
2847
3092
  }
2848
3093
  await new Promise((resolve) => globalThis.setTimeout(resolve, retryDelayMs));
@@ -2928,6 +3173,7 @@ var ApiClient = class {
2928
3173
  retryDelay = 1e3,
2929
3174
  silentErrors = true,
2930
3175
  fallbackData = null,
3176
+ sentry,
2931
3177
  ...fetchOptions
2932
3178
  } = options;
2933
3179
  let lastError = null;
@@ -2961,24 +3207,36 @@ var ApiClient = class {
2961
3207
  await new Promise((resolve) => setTimeout(resolve, retryDelay));
2962
3208
  continue;
2963
3209
  }
2964
- if (silentErrors) {
3210
+ if (sentry && sentry.capture !== false) {
2965
3211
  captureHandledFrontendException(lastError, {
3212
+ surface: sentry.surface || "api_client",
3213
+ route: sentry.route || url,
3214
+ status: sentry.status,
3215
+ severity: sentry.severity || "error",
3216
+ quotaKey: sentry.quotaKey,
3217
+ extras: {
3218
+ retries,
3219
+ silent_errors: silentErrors,
3220
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown",
3221
+ ...sentry.extras
3222
+ }
3223
+ });
3224
+ } else {
3225
+ addSentryBreadcrumb("API client request failed", {
2966
3226
  surface: "api_client",
2967
- url,
2968
- retries,
2969
- silent_errors: true,
2970
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
3227
+ route: url,
3228
+ severity: silentErrors ? "info" : "warning",
3229
+ extras: {
3230
+ retries,
3231
+ silent_errors: silentErrors,
3232
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
3233
+ }
2971
3234
  });
3235
+ }
3236
+ if (silentErrors) {
2972
3237
  console.warn("[ApiClient] All retries exhausted, returning fallback data");
2973
3238
  return fallbackData;
2974
3239
  } else {
2975
- captureHandledFrontendException(lastError, {
2976
- surface: "api_client",
2977
- url,
2978
- retries,
2979
- silent_errors: false,
2980
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
2981
- });
2982
3240
  throw lastError;
2983
3241
  }
2984
3242
  }
@@ -3230,8 +3488,12 @@ var AuthService = class {
3230
3488
  timeout: 1e4,
3231
3489
  // 10 seconds
3232
3490
  retries: 1,
3233
- silentErrors: false
3491
+ silentErrors: false,
3234
3492
  // We want to know about auth errors
3493
+ sentry: {
3494
+ surface: "auth_session_request",
3495
+ route: "/api/auth/session"
3496
+ }
3235
3497
  }
3236
3498
  );
3237
3499
  console.log("[AuthService] Session loaded:", {
@@ -3301,7 +3563,11 @@ var AuthService = class {
3301
3563
  timeout: 1e4,
3302
3564
  // 10 seconds
3303
3565
  retries: 1,
3304
- silentErrors: false
3566
+ silentErrors: false,
3567
+ sentry: {
3568
+ surface: "auth_permissions_request",
3569
+ route: "/api/auth/permissions"
3570
+ }
3305
3571
  }
3306
3572
  );
3307
3573
  console.log("[AuthService] Permissions loaded for role:", data.role);
@@ -5943,12 +6209,16 @@ var workspaceService = {
5943
6209
  return displayNamesMap;
5944
6210
  } catch (error) {
5945
6211
  console.error("Error fetching workspace display names:", error);
5946
- captureSentryException(error, {
6212
+ addSentryBreadcrumb("Workspace display-name fallback failed", {
5947
6213
  surface: "workspace_display_names",
5948
6214
  route: "/api/workspaces/display-names",
5949
- company_id: companyId || null,
5950
- line_id: lineId || null,
5951
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
6215
+ severity: "warning",
6216
+ extras: {
6217
+ company_id: companyId || null,
6218
+ line_id: lineId || null,
6219
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown",
6220
+ error_message: error instanceof Error ? error.message : String(error)
6221
+ }
5952
6222
  });
5953
6223
  throw error;
5954
6224
  }
@@ -7552,11 +7822,28 @@ var shouldReportMixpanel = (key, isError) => {
7552
7822
  };
7553
7823
  var reportMixpanelWarning = (key, message, extras) => {
7554
7824
  if (!shouldReportMixpanel(key, false)) return;
7555
- captureSentryMessage(message, "warning", { ...baseMixpanelExtras(), ...extras });
7825
+ addSentryBreadcrumb(message, {
7826
+ surface: "mixpanel",
7827
+ severity: "warning",
7828
+ extras: {
7829
+ key,
7830
+ ...baseMixpanelExtras(),
7831
+ ...extras
7832
+ }
7833
+ });
7556
7834
  };
7557
7835
  var reportMixpanelError = (key, error, extras) => {
7558
7836
  if (!shouldReportMixpanel(key, true)) return;
7559
- captureSentryException(error, { ...baseMixpanelExtras(), ...extras });
7837
+ addSentryBreadcrumb("Mixpanel operation failed", {
7838
+ surface: "mixpanel",
7839
+ severity: "warning",
7840
+ extras: {
7841
+ key,
7842
+ error_message: error instanceof Error ? error.message : String(error ?? "unknown"),
7843
+ ...baseMixpanelExtras(),
7844
+ ...extras
7845
+ }
7846
+ });
7560
7847
  };
7561
7848
  var normalizeCoreEventName = (eventName) => {
7562
7849
  const canonicalName = MIXPANEL_EVENT_NAME_ALIASES[eventName] || eventName;
@@ -9573,11 +9860,15 @@ var LinesService = class {
9573
9860
  }));
9574
9861
  } catch (error) {
9575
9862
  console.error("Error fetching lines:", error);
9576
- captureHandledFrontendException(error, {
9863
+ addSentryBreadcrumb("Lines service request failed", {
9577
9864
  surface: "lines_service",
9578
- operation: "getLinesByCompanyId",
9579
- company_id: companyId,
9580
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
9865
+ route: "/api/lines",
9866
+ severity: "warning",
9867
+ extras: {
9868
+ operation: "getLinesByCompanyId",
9869
+ company_id: companyId,
9870
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
9871
+ }
9581
9872
  });
9582
9873
  throw new Error(`Failed to fetch lines: ${error.message}`);
9583
9874
  }
@@ -9628,10 +9919,14 @@ var LinesService = class {
9628
9919
  }));
9629
9920
  } catch (error) {
9630
9921
  console.error("Error fetching all lines:", error);
9631
- captureHandledFrontendException(error, {
9922
+ addSentryBreadcrumb("Lines service request failed", {
9632
9923
  surface: "lines_service",
9633
- operation: "getAllLines",
9634
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
9924
+ route: "/api/lines",
9925
+ severity: "warning",
9926
+ extras: {
9927
+ operation: "getAllLines",
9928
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
9929
+ }
9635
9930
  });
9636
9931
  throw new Error(`Failed to fetch lines: ${error.message}`);
9637
9932
  }
@@ -9691,11 +9986,15 @@ var LinesService = class {
9691
9986
  };
9692
9987
  } catch (error) {
9693
9988
  console.error("Error fetching line:", error);
9694
- captureHandledFrontendException(error, {
9989
+ addSentryBreadcrumb("Lines service request failed", {
9695
9990
  surface: "lines_service",
9696
- operation: "getLineById",
9697
- line_id: lineId,
9698
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
9991
+ route: "/api/lines/:id",
9992
+ severity: "warning",
9993
+ extras: {
9994
+ operation: "getLineById",
9995
+ line_id: lineId,
9996
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
9997
+ }
9699
9998
  });
9700
9999
  throw new Error(`Failed to fetch line: ${error.message}`);
9701
10000
  }
@@ -13170,6 +13469,17 @@ var useWorkspaceDetailedMetrics = (workspaceId, date, shiftId, options) => {
13170
13469
  workspaceMetricsStore.setDetailed(transformedData);
13171
13470
  } catch (err) {
13172
13471
  console.error("Error fetching workspace metrics:", err);
13472
+ captureHandledFrontendException(err, {
13473
+ surface: "workspace_detail_metrics",
13474
+ route: "/api/dashboard/workspace/:workspaceId/metrics",
13475
+ extras: {
13476
+ workspace_id: workspaceId,
13477
+ company_id: companyId,
13478
+ date,
13479
+ shift_id: shiftId,
13480
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
13481
+ }
13482
+ });
13173
13483
  setError({ message: err.message, code: err.code });
13174
13484
  } finally {
13175
13485
  isFetchingRef.current = false;
@@ -14310,6 +14620,7 @@ var transformMonitorWorkspaceMetrics = ({
14310
14620
  recent_flow_window_minutes: item.recent_flow_window_minutes ?? null,
14311
14621
  recent_flow_effective_end_at: item.recent_flow_effective_end_at ?? null,
14312
14622
  recent_flow_computed_at: item.recent_flow_computed_at ?? null,
14623
+ recent_flow_forced_zero_after_shift: item.recent_flow_forced_zero_after_shift ?? null,
14313
14624
  scheduled_break_active: item.scheduled_break_active ?? false,
14314
14625
  incoming_wip_current: item.incoming_wip_current ?? null,
14315
14626
  incoming_wip_effective_at: item.incoming_wip_effective_at ?? null,
@@ -21436,20 +21747,26 @@ var apiUtils = {
21436
21747
  const token = sessionResponse.data.session?.access_token;
21437
21748
  if (!token) {
21438
21749
  console.error("API Util: No authentication token available.");
21439
- captureHandledFrontendException(new Error("Authentication required."), {
21750
+ addSentryBreadcrumb("API utility request skipped without auth token", {
21440
21751
  surface: "api_utils",
21441
- endpoint: relativeEndpoint,
21442
- reason: "missing_auth_token"
21752
+ route: relativeEndpoint,
21753
+ severity: "warning",
21754
+ extras: {
21755
+ reason: "missing_auth_token"
21756
+ }
21443
21757
  });
21444
21758
  throw new Error("Authentication required.");
21445
21759
  }
21446
21760
  const baseUrl = config.apiBaseUrl;
21447
21761
  if (!baseUrl) {
21448
21762
  console.error("API Util: apiBaseUrl is not configured.");
21449
- captureHandledFrontendException(new Error("API base URL is not configured."), {
21763
+ addSentryBreadcrumb("API utility request skipped without base URL", {
21450
21764
  surface: "api_utils",
21451
- endpoint: relativeEndpoint,
21452
- reason: "missing_api_base_url"
21765
+ route: relativeEndpoint,
21766
+ severity: "warning",
21767
+ extras: {
21768
+ reason: "missing_api_base_url"
21769
+ }
21453
21770
  });
21454
21771
  throw new Error("API base URL is not configured.");
21455
21772
  }
@@ -21479,11 +21796,14 @@ var apiUtils = {
21479
21796
  return await response.json();
21480
21797
  } catch (error) {
21481
21798
  console.error(`Network or fetch error calling ${endpoint}:`, error);
21482
- captureHandledFrontendException(error, {
21799
+ addSentryBreadcrumb("API utility request failed", {
21483
21800
  surface: "api_utils",
21484
- endpoint,
21485
- method: options.method || "GET",
21486
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
21801
+ route: endpoint,
21802
+ severity: "warning",
21803
+ extras: {
21804
+ method: options.method || "GET",
21805
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
21806
+ }
21487
21807
  });
21488
21808
  if (error instanceof Error) {
21489
21809
  throw error;
@@ -36933,7 +37253,7 @@ HourlyOutputChart.displayName = "HourlyOutputChart";
36933
37253
 
36934
37254
  // src/components/dashboard/grid/videoGridMetricUtils.ts
36935
37255
  var MAP_GRID_LEGEND_LABEL = "Efficiency";
36936
- var MIXED_VIDEO_GRID_LEGEND_LABEL = "Flow Efficiency";
37256
+ var MIXED_VIDEO_GRID_LEGEND_LABEL = "Live Efficiency";
36937
37257
  var isFiniteNumber2 = (value) => typeof value === "number" && Number.isFinite(value);
36938
37258
  var isVideoGridRecentFlowEnabled = (workspace) => isRecentFlowVideoGridMetricMode(
36939
37259
  workspace.video_grid_metric_mode,
@@ -36967,6 +37287,9 @@ var isLowWipGreenOverride = (workspace, legend = DEFAULT_EFFICIENCY_LEGEND) => {
36967
37287
  if (workspace.scheduled_break_active === true) {
36968
37288
  return false;
36969
37289
  }
37290
+ if (workspace.recent_flow_forced_zero_after_shift === true) {
37291
+ return false;
37292
+ }
36970
37293
  if (!hasVideoGridRecentFlow(workspace) || !isVideoGridWipGated(workspace)) {
36971
37294
  return false;
36972
37295
  }
@@ -37212,7 +37535,7 @@ var VideoCard = React144__default.memo(({
37212
37535
  }
37213
37536
  );
37214
37537
  }, (prevProps, nextProps) => {
37215
- if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
37538
+ if (prevProps.workspace.efficiency !== nextProps.workspace.efficiency || prevProps.workspace.assembly_enabled !== nextProps.workspace.assembly_enabled || prevProps.workspace.video_grid_metric_mode !== nextProps.workspace.video_grid_metric_mode || prevProps.workspace.recent_flow_percent !== nextProps.workspace.recent_flow_percent || prevProps.workspace.recent_flow_effective_end_at !== nextProps.workspace.recent_flow_effective_end_at || prevProps.workspace.recent_flow_forced_zero_after_shift !== nextProps.workspace.recent_flow_forced_zero_after_shift || prevProps.workspace.scheduled_break_active !== nextProps.workspace.scheduled_break_active || prevProps.workspace.incoming_wip_current !== nextProps.workspace.incoming_wip_current || prevProps.workspace.incoming_wip_buffer_name !== nextProps.workspace.incoming_wip_buffer_name || prevProps.workspace.trend !== nextProps.workspace.trend || prevProps.workspace.performance_score !== nextProps.workspace.performance_score || prevProps.workspace.pph !== nextProps.workspace.pph) {
37216
37539
  return false;
37217
37540
  }
37218
37541
  if (prevProps.workspace.workspace_uuid !== nextProps.workspace.workspace_uuid || prevProps.workspace.workspace_name !== nextProps.workspace.workspace_name || prevProps.workspace.line_id !== nextProps.workspace.line_id) {
@@ -37531,6 +37854,15 @@ var VideoGridView = React144__default.memo(({
37531
37854
  }
37532
37855
  console.error(`[VideoGridView] Stream failed for workspace: ${workspaceId}`);
37533
37856
  setFailedStreams((prev) => new Set(prev).add(workspaceId));
37857
+ captureHandledFrontendException(new Error("Video stream failed after recovery attempts"), {
37858
+ surface: "video_grid_stream",
37859
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
37860
+ extras: {
37861
+ workspace_id: workspaceId,
37862
+ stream_source: isR2Stream ? "r2" : "media_config",
37863
+ has_fallback: hasFallback
37864
+ }
37865
+ });
37534
37866
  trackCoreEvent("Video Stream Error", {
37535
37867
  workspace_id: workspaceId,
37536
37868
  view_type: "video_grid",
@@ -42198,11 +42530,14 @@ var SilentErrorBoundary = class extends React144__default.Component {
42198
42530
  componentStack: errorInfo.componentStack,
42199
42531
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
42200
42532
  });
42201
- captureSentryException(error, {
42533
+ captureHandledFrontendException(error, {
42202
42534
  surface: "react_error_boundary",
42203
- component_stack: errorInfo.componentStack,
42204
- error_count: this.state.errorCount + 1,
42205
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
42535
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
42536
+ severity: "error",
42537
+ extras: {
42538
+ component_stack: errorInfo.componentStack,
42539
+ error_count: this.state.errorCount + 1
42540
+ }
42206
42541
  });
42207
42542
  this.setState((prev) => ({
42208
42543
  errorCount: prev.errorCount + 1,
@@ -44739,6 +45074,11 @@ var OVERLAY_ICON_COLOR_BY_PALETTE = {
44739
45074
  cyan: "text-cyan-300",
44740
45075
  slate: "text-slate-200"
44741
45076
  };
45077
+ var buildPlaybackCaptureError = (recoverable) => {
45078
+ return new Error(
45079
+ recoverable ? "Clip playback failed after retry exhaustion" : "Clip playback failed with non-recoverable media error"
45080
+ );
45081
+ };
44742
45082
  var BottlenecksContent = ({
44743
45083
  workspaceId,
44744
45084
  workspaceName,
@@ -45193,6 +45533,16 @@ var BottlenecksContent = ({
45193
45533
  }
45194
45534
  } catch (err) {
45195
45535
  console.error("Error loading first video for category:", err);
45536
+ captureHandledFrontendException(err, {
45537
+ surface: "clips_initial_load",
45538
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
45539
+ extras: {
45540
+ workspace_id: workspaceId,
45541
+ category: targetCategory,
45542
+ date: effectiveDateString,
45543
+ shift_id: effectiveShiftId
45544
+ }
45545
+ });
45196
45546
  if (isMountedRef.current) {
45197
45547
  setError({
45198
45548
  type: "fatal",
@@ -45730,6 +46080,15 @@ var BottlenecksContent = ({
45730
46080
  console.log(`[BottlenecksContent] Loaded clip ${clipId} (${clickedClipIndex + 1}/${metadataArray.length})`);
45731
46081
  } catch (error2) {
45732
46082
  console.error(`[BottlenecksContent] Error loading clip by ID (${clipId}):`, error2);
46083
+ captureHandledFrontendException(error2, {
46084
+ surface: "clips_selected_load",
46085
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
46086
+ extras: {
46087
+ workspace_id: workspaceId,
46088
+ clip_id: clipId,
46089
+ category: categoryId
46090
+ }
46091
+ });
45733
46092
  if (isMountedRef.current) {
45734
46093
  setError({
45735
46094
  type: "fatal",
@@ -46329,6 +46688,18 @@ var BottlenecksContent = ({
46329
46688
  errorCode,
46330
46689
  errorMessage
46331
46690
  });
46691
+ captureHandledFrontendException(buildPlaybackCaptureError(false), {
46692
+ surface: "clips_video_playback",
46693
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
46694
+ extras: {
46695
+ workspace_id: workspaceId,
46696
+ category: activeFilterRef.current,
46697
+ video_id: currentVideo?.id,
46698
+ error_code: errorCode,
46699
+ player_error_message: errorMessage,
46700
+ recoverable: false
46701
+ }
46702
+ });
46332
46703
  return;
46333
46704
  }
46334
46705
  if (videoRetryCountRef.current < 3 && currentVideo) {
@@ -46372,6 +46743,19 @@ var BottlenecksContent = ({
46372
46743
  errorMessage,
46373
46744
  attempts: 3
46374
46745
  });
46746
+ captureHandledFrontendException(buildPlaybackCaptureError(true), {
46747
+ surface: "clips_video_playback",
46748
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
46749
+ extras: {
46750
+ workspace_id: workspaceId,
46751
+ category: activeFilterRef.current,
46752
+ video_id: currentVideo?.id,
46753
+ error_code: errorCode,
46754
+ player_error_message: errorMessage,
46755
+ recoverable: true,
46756
+ attempts: 3
46757
+ }
46758
+ });
46375
46759
  }
46376
46760
  }, [currentVideo, workspaceId, clearLoadingState, clearRetryTimeout, restartCurrentClipPlayback]);
46377
46761
  useEffect(() => {
@@ -48703,6 +49087,14 @@ var LinePdfExportButton = ({
48703
49087
  pdf.save(`${fileName}.pdf`);
48704
49088
  } catch (error) {
48705
49089
  console.error("PDF Export Error:", error);
49090
+ captureHandledFrontendException(error, {
49091
+ surface: "line_pdf_export",
49092
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
49093
+ extras: {
49094
+ file_name: fileName,
49095
+ target_type: typeof targetElement === "string" ? "selector" : "element"
49096
+ }
49097
+ });
48706
49098
  alert("An error occurred while exporting to PDF. Please try again.");
48707
49099
  } finally {
48708
49100
  setIsExporting(false);
@@ -50525,6 +50917,16 @@ var LineMonthlyPdfGenerator = ({
50525
50917
  doc.save(fileName);
50526
50918
  } catch (error) {
50527
50919
  console.error("Line Monthly PDF generation failed:", error);
50920
+ captureHandledFrontendException(error, {
50921
+ surface: "line_monthly_pdf_generation",
50922
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
50923
+ extras: {
50924
+ line_name: lineName || null,
50925
+ selected_month: selectedMonth,
50926
+ selected_year: selectedYear,
50927
+ selected_shift_id: selectedShiftId
50928
+ }
50929
+ });
50528
50930
  } finally {
50529
50931
  setIsGenerating(false);
50530
50932
  }
@@ -51307,6 +51709,15 @@ var LinePdfGenerator = ({
51307
51709
  doc.save(fileName);
51308
51710
  } catch (error) {
51309
51711
  console.error("PDF generation failed:", error);
51712
+ captureHandledFrontendException(error, {
51713
+ surface: "line_pdf_generation",
51714
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
51715
+ extras: {
51716
+ line_id: lineInfo.line_id,
51717
+ date: lineInfo.date,
51718
+ shift_id: lineInfo.shift_id
51719
+ }
51720
+ });
51310
51721
  } finally {
51311
51722
  setIsGenerating(false);
51312
51723
  }
@@ -51379,6 +51790,14 @@ var WorkspacePdfExportButton = ({
51379
51790
  pdf.save(`${fileName}.pdf`);
51380
51791
  } catch (error) {
51381
51792
  console.error("PDF Export Error:", error);
51793
+ captureHandledFrontendException(error, {
51794
+ surface: "workspace_pdf_export",
51795
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
51796
+ extras: {
51797
+ file_name: fileName,
51798
+ target_type: typeof targetElement === "string" ? "selector" : "element"
51799
+ }
51800
+ });
51382
51801
  alert("An error occurred while exporting to PDF. Please try again.");
51383
51802
  } finally {
51384
51803
  setIsExporting(false);
@@ -53228,6 +53647,16 @@ var WorkspacePdfGenerator = ({
53228
53647
  doc.save(fileName);
53229
53648
  } catch (error) {
53230
53649
  console.error("PDF generation failed:", error);
53650
+ captureHandledFrontendException(error, {
53651
+ surface: "workspace_pdf_generation",
53652
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
53653
+ extras: {
53654
+ workspace_id: workspace.workspace_id,
53655
+ line_id: workspace.line_id,
53656
+ date: workspace.date,
53657
+ shift_id: workspace.shift_id
53658
+ }
53659
+ });
53231
53660
  } finally {
53232
53661
  setIsGenerating(false);
53233
53662
  }
@@ -53635,6 +54064,18 @@ var WorkspaceMonthlyPdfGenerator = ({
53635
54064
  doc.save(fileName);
53636
54065
  } catch (error) {
53637
54066
  console.error("Monthly PDF generation failed:", error);
54067
+ captureHandledFrontendException(error, {
54068
+ surface: "workspace_monthly_pdf_generation",
54069
+ route: typeof window !== "undefined" ? window.location.pathname : "unknown",
54070
+ extras: {
54071
+ workspace_id: workspaceId,
54072
+ workspace_name: workspaceName,
54073
+ line_name: lineName || null,
54074
+ selected_month: selectedMonth,
54075
+ selected_year: selectedYear,
54076
+ selected_shift_id: selectedShiftId
54077
+ }
54078
+ });
53638
54079
  } finally {
53639
54080
  setIsGenerating(false);
53640
54081
  }
@@ -62907,6 +63348,16 @@ var useLiveMonitorBootstrap = ({
62907
63348
  if (requestId !== activeRequestIdRef.current) {
62908
63349
  return;
62909
63350
  }
63351
+ captureHandledFrontendException(fetchError, {
63352
+ surface: "live_monitor_bootstrap",
63353
+ route: "/api/dashboard/monitor-bootstrap",
63354
+ extras: {
63355
+ company_id: resolvedCompanyId,
63356
+ line_ids: normalizedLineIds,
63357
+ force_refresh: force,
63358
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
63359
+ }
63360
+ });
62910
63361
  setError(fetchError instanceof Error ? fetchError : new Error("Failed to load live monitor bootstrap"));
62911
63362
  } finally {
62912
63363
  if (requestId === activeRequestIdRef.current) {
@@ -63219,11 +63670,14 @@ var NotificationService = class {
63219
63670
  }
63220
63671
  return response;
63221
63672
  } catch (error) {
63222
- captureHandledFrontendException(error, {
63673
+ addSentryBreadcrumb("Notification service request failed", {
63223
63674
  surface: "notification_service",
63224
- url,
63225
- method: options.method || "GET",
63226
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
63675
+ route: url,
63676
+ severity: "warning",
63677
+ extras: {
63678
+ method: options.method || "GET",
63679
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
63680
+ }
63227
63681
  });
63228
63682
  throw error;
63229
63683
  }
@@ -77378,11 +77832,14 @@ var TicketService = class {
77378
77832
  }
77379
77833
  return response;
77380
77834
  } catch (error) {
77381
- captureHandledFrontendException(error, {
77835
+ addSentryBreadcrumb("Ticket service request failed", {
77382
77836
  surface: "ticket_service",
77383
- url,
77384
- method: options.method || "GET",
77385
- pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
77837
+ route: url,
77838
+ severity: "warning",
77839
+ extras: {
77840
+ method: options.method || "GET",
77841
+ pathname: typeof window !== "undefined" ? window.location.pathname : "unknown"
77842
+ }
77386
77843
  });
77387
77844
  throw error;
77388
77845
  }
@@ -83162,10 +83619,33 @@ var useOperationsOverviewRefresh = ({
83162
83619
  if (controller.signal.aborted || requestIdsRef.current[section] !== requestId || isAbortError2(error)) {
83163
83620
  return;
83164
83621
  }
83622
+ const sentryContext = {
83623
+ surface: "operations_overview_refresh",
83624
+ route: `/api/dashboard/operations-overview/${section}`,
83625
+ extras: {
83626
+ section,
83627
+ reason,
83628
+ company_id: companyId,
83629
+ line_ids: lineIds,
83630
+ start_date: startKey,
83631
+ end_date: endKey,
83632
+ trend_mode: trendMode,
83633
+ comparison_strategy: comparisonStrategy || null
83634
+ }
83635
+ };
83636
+ if (section === "improvements") {
83637
+ addSentryBreadcrumb("Operations overview optional improvements refresh failed", {
83638
+ ...sentryContext,
83639
+ severity: "warning",
83640
+ category: "operations_overview"
83641
+ });
83642
+ } else {
83643
+ captureHandledFrontendException(error, sentryContext);
83644
+ }
83165
83645
  onError(error instanceof Error ? error.message : `Failed to refresh ${section}`);
83166
83646
  }
83167
83647
  },
83168
- [companyId, enabled, lineIds.length, supabase]
83648
+ [companyId, comparisonStrategy, enabled, endKey, lineIds, startKey, supabase, trendMode]
83169
83649
  );
83170
83650
  const refreshSnapshot = React144__default.useCallback(
83171
83651
  async (reason) => {
@@ -84608,4 +85088,4 @@ var streamProxyConfig = {
84608
85088
  }
84609
85089
  };
84610
85090
 
84611
- export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildLineSkuBreakdown, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureHandledFrontendException, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, combineLineMetricsRows, countRealSkus, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, fetchLineDummySkuId, fetchLineSkuCatalog, filterDataByDateKeyRange, filterRealSkuBreakdown, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDateKeyFromValue, getDayDateKey, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getMonthlyTrendComparisonLabel, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isIgnorableFrontendError, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRealSku, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, pickPreferredLineMetricsRow, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSubscriptionManager, resolveDefaultSkuId, resolveLiveSkuId, s3VideoPreloader, selectPreferredLineMetricsRow, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };
85091
+ export { ACTION_FAMILIES, ACTION_NAMES, AIAgentView_default as AIAgentView, AcceptInvite, AcceptInviteView_default as AcceptInviteView, AdvancedFilterDialog, AdvancedFilterPanel, AudioService, AuthCallback, AuthCallbackView_default as AuthCallbackView, AuthProvider, AuthService, AuthenticatedBottleneckClipsView, AuthenticatedFactoryView, AuthenticatedHelpView, AuthenticatedHomeView, AuthenticatedShiftsView, AuthenticatedTargetsView, AuthenticatedTicketsView, AuthenticatedWorkspaceHealthView, AvatarUpload, AxelNotificationPopup, AxelOrb, BackButton, BackButtonMinimal, BarChart, BaseHistoryCalendar, BottleneckClipsModal, BottleneckClipsView_default as BottleneckClipsView, BottlenecksContent, BreakNotificationPopup, CachePrefetchStatus, Card2 as Card, CardContent2 as CardContent, CardDescription2 as CardDescription, CardFooter2 as CardFooter, CardHeader2 as CardHeader, CardTitle2 as CardTitle, ChangeRoleDialog, ClipFilterProvider, ClipsCostView_default as ClipsCostView, CompactWorkspaceHealthCard, ConfirmRemoveUserDialog, CongratulationsOverlay, CroppedHlsVideoPlayer, CroppedVideoPlayer, CycleTimeChart, CycleTimeOverTimeChart, DEFAULT_ANALYTICS_CONFIG, DEFAULT_AUTH_CONFIG, DEFAULT_CONFIG, DEFAULT_DATABASE_CONFIG, DEFAULT_DATE_TIME_CONFIG, DEFAULT_ENDPOINTS_CONFIG, DEFAULT_ENTITY_CONFIG, DEFAULT_HOME_VIEW_CONFIG, DEFAULT_MAP_VIEW_CONFIG, DEFAULT_SHIFT_CONFIG, DEFAULT_SHIFT_DATA, DEFAULT_THEME_CONFIG, DEFAULT_VIDEO_CONFIG, DEFAULT_WORKSPACE_CONFIG, DEFAULT_WORKSPACE_POSITIONS, DashboardHeader, DashboardLayout, DashboardOverridesProvider, DashboardProvider, DateDisplay_default as DateDisplay, DateTimeDisplay, DebugAuth, DebugAuthView_default as DebugAuthView, DetailedHealthStatus, DiagnosisVideoModal, EFFICIENCY_ON_TRACK_THRESHOLD, EmptyStateMessage, EncouragementOverlay, FactoryAssignmentDropdown, FactoryView_default as FactoryView, FileManagerFilters, FilterDialogTrigger, FirstTimeLoginDebug, FirstTimeLoginHandler, FittingTitle, GaugeChart, GridComponentsPlaceholder, HamburgerButton, Header, HealthDateShiftSelector, HealthStatusGrid, HealthStatusIndicator, HelpView_default as HelpView, HlsVideoPlayer, HomeView_default as HomeView, HourlyOutputChart2 as HourlyOutputChart, HourlyUptimeChart, ISTTimer_default as ISTTimer, IdleTimeVlmConfigProvider, ImprovementCenterView_default as ImprovementCenterView, InlineEditableText, InteractiveOnboardingTour, InvitationService, InvitationsTable, InviteUserDialog, KPICard, KPIDetailView_default as KPIDetailView, KPIGrid, KPIHeader, KPISection, KPIsOverviewView_default as KPIsOverviewView, LINE_1_UUID, LINE_2_UUID, LargeOutputProgressChart, LeaderboardDetailView_default as LeaderboardDetailView, Legend5 as Legend, LineAssignmentDropdown, LineChart, LineHistoryCalendar, LineMonthlyHistory, LineMonthlyPdfGenerator, LinePdfExportButton, LinePdfGenerator, LineWhatsAppShareButton, LinesService, LiveTimer, LoadingInline, LoadingOverlay_default as LoadingOverlay, LoadingPage_default as LoadingPage, LoadingSkeleton, LoadingState, LoginPage, LoginView_default as LoginView, Logo, MainLayout, MapGridView, MetricCard_default as MetricCard, MinimalOnboardingPopup, MobileMenuProvider, NewClipsNotification, NoWorkspaceData, OnboardingDemo, OnboardingTour, OptifyeAgentClient, OptifyeLogoLoader_default as OptifyeLogoLoader, OutputProgressChart, PageHeader, PieChart4 as PieChart, PlantHeadView_default as PlantHeadView, PlayPauseIndicator, PrefetchConfigurationError, PrefetchError, PrefetchEvents, PrefetchStatus, PrefetchTimeoutError, ProfileView_default as ProfileView, ROOT_DASHBOARD_EVENT_NAMES, RegistryProvider, RoleBadge, S3ClipsSupabaseService as S3ClipsService, S3Service, SENTRY_HANDLED_EVENT_SESSION_LIMIT, SENTRY_HANDLED_EVENT_WINDOW_MS, SENTRY_QUOTA_STORAGE_KEY, SKUManagementView, SOPComplianceChart, SSEChatClient, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SessionTracker, SessionTrackingContext, SessionTrackingProvider, SettingsPopup, ShiftDisplay_default as ShiftDisplay, ShiftsView_default as ShiftsView, SideNavBar, SignupWithInvitation, SilentErrorBoundary, SimpleOnboardingPopup, SingleVideoStream_default as SingleVideoStream, Skeleton, SubscriptionManager, SubscriptionManagerProvider, SupabaseProvider, SupervisorDropdown_default as SupervisorDropdown, SupervisorManagementView_default as SupervisorManagementView, SupervisorService, TargetWorkspaceGrid, TargetsView_default as TargetsView, TeamManagementView_default as TeamManagementView, ThreadSidebar, TicketHistory_default as TicketHistory, TicketHistoryService, TicketsView_default as TicketsView, TimeDisplay_default as TimeDisplay, TimePickerDropdown, Timer_default as Timer, TimezoneProvider, TimezoneService, UptimeDonutChart, UptimeLineChart, UptimeMetricCards, UserAvatar, UserManagementService, UserManagementTable, UserService, UserUsageDetailModal, UserUsageStats, VideoCard, VideoGridView, VideoPlayer, VideoPreloader, WORKSPACE_POSITIONS, WhatsAppShareButton, WorkspaceCard, WorkspaceCycleTimeMetricCards, WorkspaceDetailView_default as WorkspaceDetailView, WorkspaceDisplayNameExample, WorkspaceGrid, WorkspaceGridItem, WorkspaceHealthCard, WorkspaceHealthView_default as WorkspaceHealthView, WorkspaceHistoryCalendar, WorkspaceMetricCards, WorkspaceMetricCardsImpl, WorkspaceMonthlyDataFetcher, WorkspaceMonthlyHistory, WorkspaceMonthlyPdfGenerator, WorkspacePdfExportButton, WorkspacePdfGenerator, WorkspaceWhatsAppShareButton, actionService, addSentryBreadcrumb, aggregateKPIsFromLineMetricsRows, alertsService, apiUtils, areAllLinesOnSameShift, authCoreService, authOTPService, authRateLimitService, awardsService, buildDateKey, buildKPIsFromLineMetricsRow, buildLineSkuBreakdown, buildShiftGroupsKey, canRoleAccessDashboardPath, canRoleAccessTeamManagement, canRoleAssignFactories, canRoleAssignLines, canRoleChangeRole, canRoleInviteRole, canRoleManageCompany, canRoleManageTargets, canRoleManageUsers, canRoleRemoveUser, canRoleViewClipsCost, canRoleViewUsageStats, captureHandledFrontendException, captureSentryException, captureSentryMessage, checkRateLimit2 as checkRateLimit, clearAllRateLimits2 as clearAllRateLimits, clearRateLimit2 as clearRateLimit, clearS3VideoCache, clearS3VideoFromCache, clearSentryContext, clearWorkspaceDisplayNamesCache, cn, combineLineMetricsRows, countRealSkus, createDefaultKPIs, createInvitationService, createLinesService, createSessionTracker, createStorageService, createStreamProxyHandler, createSupabaseClient, createSupervisorService, createThrottledReload, createUserManagementService, createUserService, dashboardService, deleteThread, fetchIdleTimeReasons, fetchLineDummySkuId, fetchLineSkuCatalog, filterDataByDateKeyRange, filterRealSkuBreakdown, forceRefreshWorkspaceDisplayNames, formatAwardMonth, formatDateInZone, formatDateKeyForDisplay, formatDateTimeInZone, formatDuration2 as formatDuration, formatISTDate, formatIdleTime, formatRangeLabel, formatReasonLabel, formatRelativeTime, formatTimeInZone, fromUrlFriendlyName, getActionDisplayName, getActiveShift, getAllLineDisplayNames, getAllThreadMessages, getAllWorkspaceDisplayNamesAsync, getAllWorkspaceDisplayNamesSnapshot, getAnonClient, getAssignableRoles, getAssignmentColumnLabel, getAvailableShiftIds, getAwardBadgeType, getAwardDescription, getAwardTitle, getBrowserName, getCameraNumber, getCompanyMetricsTableName, getConfigurableShortWorkspaceDisplayName, getConfigurableWorkspaceDisplayName, getConfiguredLineIds, getCoreSessionRecordingProperties, getCoreSessionReplayUrl, getCurrentShift, getCurrentShiftForLine, getCurrentTimeInZone, getCurrentWeekFullRange, getCurrentWeekToDateRange, getDashboardHeaderTimeInZone, getDateKeyFromDate, getDateKeyFromValue, getDayDateKey, getDaysDifferenceInZone, getDefaultCameraStreamUrl, getDefaultLineId, getDefaultTabForWorkspace, getInitials, getLineDisplayName, getManufacturingInsights, getMetricsTablePrefix, getMonthKeyBounds, getMonthWeekRanges, getMonthlyTrendComparisonLabel, getNextUpdateInterval, getOperationalDate, getRoleAssignmentKind, getRoleDescription, getRoleLabel, getRoleMetadata, getRoleNavPaths, getS3SignedUrl, getS3VideoSrc, getShiftData, getShiftNameById, getShiftWorkDurationSeconds, getShortShiftName, getShortWorkspaceDisplayName, getShortWorkspaceDisplayNameAsync, getStoredWorkspaceMappings, getSubscriptionManager, getThreadMessages, getUniformShiftGroup, getUserThreads, getUserThreadsPaginated, getVisibleRolesForCurrentUser, getWorkspaceDisplayName, getWorkspaceDisplayNameAsync, getWorkspaceDisplayNamesMap, getWorkspaceFromUrl, getWorkspaceNavigationParams, groupLinesByShift, hasAnyShiftData, identifyCoreUser, initializeCoreMixpanel, isEfficiencyOnTrack, isFactoryScopedRole, isFullMonthRange, isIgnorableFrontendError, isLegacyConfiguration, isLoopbackHostname, isPrefetchError, isRealSku, isRecentFlowVideoGridMetricMode, isSafari, isSupervisorRole, isTransitionPeriod, isUrlPermanentlyFailed, isValidFactoryViewConfiguration, isValidLineInfoPayload, isValidPrefetchParams, isValidPrefetchStatus, isValidWorkspaceDetailedMetricsPayload, isValidWorkspaceMetricsPayload, isWipGatedVideoGridMetricMode, isWorkspaceDisplayNamesLoaded, isWorkspaceDisplayNamesLoading, lineLeaderboardService, linesService, mergeWithDefaultConfig, migrateLegacyConfiguration, normalizeActionFamily, normalizeDateKeyRange, normalizeRoleLevel, normalizeVideoGridMetricMode, optifyeAgentClient, parseDateKeyToDate, parseS3Uri, pickPreferredLineMetricsRow, preInitializeWorkspaceDisplayNames, preloadS3Video, preloadS3VideoUrl, preloadS3VideosUrl, preloadVideoUrl, preloadVideosUrl, qualityService, realtimeService, refreshWorkspaceDisplayNames, resetCoreMixpanel, resetFailedUrl, resetSentryQuotaForTests, resetSubscriptionManager, resolveDefaultSkuId, resolveLiveSkuId, s3VideoPreloader, selectPreferredLineMetricsRow, setSentryUserContext, setSentryWorkspaceContext, shouldEnableLocalDevTestLogin, shuffleArray, simulateApiDelay, skuService, startCoreSessionRecording, stopCoreSessionRecording, storeWorkspaceMapping, streamProxyConfig, subscribeWorkspaceDisplayNames, throttledReloadDashboard, toUrlFriendlyName, trackCoreEvent, trackCorePageView, transformToChartData, updateThreadTitle, upsertWorkspaceDisplayNameInCache, useAccessControl, useActiveBreaks, useActiveLineId, useAllWorkspaceMetrics, useAnalyticsConfig, useAppTimezone, useAudioService, useAuth, useAuthConfig, useAxelNotifications, useCanSaveTargets, useClipFilter, useClipTypes, useClipTypesWithCounts, useClipsInit, useCompanyClipsCost, useCompanyFastSlowClipFiltersEnabled, useCompanyHasVlmEnabledLine, useCompanyUsersUsage, useComponentOverride, useCustomConfig, useDashboardConfig, useDashboardMetrics, useDatabaseConfig, useDateFormatter, useDateTimeConfig, useDynamicShiftConfig, useEndpointsConfig, useEntityConfig, useFactoryOverviewMetrics, useFeatureFlags, useFormatNumber, useHasLineAccess, useHideMobileHeader, useHistoricWorkspaceMetrics, useHlsStream, useHlsStreamWithCropping, useHookOverride, useHourEndTimer, useHourlyTargetAchievements, useHourlyTargetMisses, useIdleTimeClipClassifications, useIdleTimeReasons, useIdleTimeVlmConfig, useKpiTrends, useLeaderboardMetrics, useLineDetailedMetrics, useLineKPIs, useLineMetrics, useLineShiftConfig, useLineSupervisor, useLineWorkspaceMetrics, useLines, useMessages, useMetrics, useMobileMenu, useMonthlyTrend, useMultiLineShiftConfigs, useNavigation, useOperationalShiftKey, useOptionalSupabase, useOverrides, usePageOverride, usePrefetchClipCounts, useRealtimeLineMetrics, useRegistry, useSKUs, useSessionKeepAlive, useSessionTracking, useSessionTrackingContext, useShiftConfig, useShiftGroups, useShifts, useSubscriptionManager, useSubscriptionManagerSafe, useSupabase, useSupabaseClient, useSupervisorsByLineIds, useTargets, useTeamManagementPermissions, useTheme, useThemeConfig, useThreads, useTicketHistory, useTimezoneContext, useUserLineAccess, useUserUsage, useVideoConfig, useWorkspaceConfig, useWorkspaceDetailedMetrics, useWorkspaceDisplayName, useWorkspaceDisplayNames, useWorkspaceDisplayNamesMap, useWorkspaceHealthById, useWorkspaceHealthLastSeen, useWorkspaceHealthStatus, useWorkspaceMetrics, useWorkspaceNavigation, useWorkspaceOperators, useWorkspaceUptimeTimeline, useWorkspaceVideoStreams, userService, videoPrefetchManager, videoPreloader, weeklyTopPerformerService, whatsappService, withAccessControl, withAuth, withRegistry, withTimezone, workspaceHealthService, workspaceService };