{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-bd006da33fa410c7", "name": "Stray `console.log` in TS/JS \u2014 frontend/public/meta-config.js:136", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/public/meta-config.js:136"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-178cf2ba6fb55cea", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/config/runtimeConfig.js:71", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/config/runtimeConfig.js:71"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3fa8bbf33724ac28", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/TopCamerasWidget.jsx:72", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/TopCamerasWidget.jsx:72"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-668468287bc4abc7", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/SponsorBadge.jsx:56", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/SponsorBadge.jsx:56"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e3b82f069dc8a428", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/LocationPicker.jsx:93", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/LocationPicker.jsx:93"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bb2cfec8976ea12e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/CameraPerformanceTable.jsx:80", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/CameraPerformanceTable.jsx:80"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0c57e07f1334600c", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/VideoPopup.jsx:1205", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/VideoPopup.jsx:1205"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-55cd0aba04d9ca21", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/components/MultiView/VideoPopup.jsx:135", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/components/MultiView/VideoPopup.jsx:135"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a7df8dc2ff0d108c", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/RelatedCamerasStrip.jsx:45", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/RelatedCamerasStrip.jsx:45"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7728b51b1137aa71", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/MultiViewVideoItem.jsx:1021", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/MultiViewVideoItem.jsx:1021"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-75b08f5f7361546e", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/components/MultiView/MultiViewVideoItem.jsx:552", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/components/MultiView/MultiViewVideoItem.jsx:552"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0045898a2dab2280", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/CameraDetailPanel.jsx:36", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/CameraDetailPanel.jsx:36"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0f111d44117c3798", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/settings/TelegramSettingsPanel.jsx:65", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/settings/TelegramSettingsPanel.jsx:652"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e12dd78cf0555c65", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/admin/settings/GeneralSettingsTab.jsx:193", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/admin/settings/GeneralSettingsTab.jsx:193"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2ce9e4fa1ca10aa8", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/analytics/AnalyticsPrimitives.jsx:140", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/analytics/AnalyticsPrimitives.jsx:140"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8d64800f0fcc0196", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/analytics/TopCamerasCard.jsx:21", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/analytics/TopCamerasCard.jsx:21"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0eb33ce5a76943c0", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/dashboard/DashboardStreams.jsx:215", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/dashboard/DashboardStreams.jsx:215"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c1af8eddff2ca9b6", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/playback-tokens/PlaybackTokenForm.jsx", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/playback-tokens/PlaybackTokenForm.jsx:99"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6393252bea9c80d8", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/PaymentsTab.jsx:134", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/PaymentsTab.jsx:134"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-90d0ce36ff0f9307", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/CustomersTab.jsx:178", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/CustomersTab.jsx:178"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-fdcc5ea3dd6fe646", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/SubscriptionsTab.jsx:156", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/SubscriptionsTab.jsx:156"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-196f4262901eada6", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/areas/BulkPolicyPreview.jsx:44", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/areas/BulkPolicyPreview.jsx:44"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bd1c82d186ea45d0", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/feedback/FeedbackListPanel.jsx:37", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/feedback/FeedbackListPanel.jsx:37"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6c64b11180f8ccae", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingFilterDropdown.jsx:57", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingFilterDropdown.jsx:57"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b0d79a679b5a60ca", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingMobileDock.jsx:125", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingMobileDock.jsx:125"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-636cab004ac9a486", "name": "\"active\" state uses light bg in a dark theme \u2014 frontend/src/components/landing/LandingMobileDock.jsx:132", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 frontend/src/components/landing/LandingMobileDock.jsx:132"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ba58917c2d37d9e4", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingTrendingCameras.jsx:37", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingTrendingCameras.jsx:37"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-098af7448d2de839", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingCameraCard.jsx:215", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingCameraCard.jsx:215"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8d7d45b627ea80e3", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingDiscoveryStrip.jsx:32", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingDiscoveryStrip.jsx:32"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-eb0540f2b221c138", "name": "\"active\" state uses light bg in a dark theme \u2014 frontend/src/components/landing/LandingDiscoveryStrip.jsx:103", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 frontend/src/components/landing/LandingDiscoveryStrip.jsx:103"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b4b07dc8ecd10a0a", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingCamerasSection.jsx:115", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingCamerasSection.jsx:115"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5636a99e1f149684", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingSmartFeed.jsx:27", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingSmartFeed.jsx:27"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-118e87d9fc0af4aa", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingQuickAccessStrip.jsx:22", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingQuickAccessStrip.jsx:22"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2eff651bdc90f0ba", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/landing/LandingHero.jsx:78", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/landing/LandingHero.jsx:78"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-26124d6289e4d40e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingStatsBar.jsx:134", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingStatsBar.jsx:134"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7d8bab3830c7029f", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/playback/PlaybackSegmentList.jsx:66", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/playback/PlaybackSegmentList.jsx:66"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c2c98d4a67e43fee", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/AreaPublicPage.jsx:94", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/AreaPublicPage.jsx:94"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1e08bdb067aedd01", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/CustomerCameraIPs.jsx:174", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/CustomerCameraIPs.jsx:174"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1ce9cbe01978ef9b", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/SponsorManagement.jsx:747", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/SponsorManagement.jsx:747"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-070327b4bd4c45ab", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/VoucherManagement.jsx:335", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/VoucherManagement.jsx:335"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-12f03542c1127e8c", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/customer/MyCameras.jsx:224", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/customer/MyCameras.jsx:224"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c1f90f76bc6393e2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/customer/MyWallet.jsx:542", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/customer/MyWallet.jsx:542"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bf1a8c5ca495ced1", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/ImportExport.jsx:671", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/ImportExport.jsx:671"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6b994f45bf3e04e7", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/services/viewerService.js:57", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/services/viewerService.js:57"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-400c1bba34337b17", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/services/apiClient.js:336", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/services/apiClient.js:336"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9162e4cd6ee8e5ea", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/layouts/AdminLayout.jsx:68", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/layouts/AdminLayout.jsx:68"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b2ce14aceb2575d2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/layouts/CustomerLayout.jsx:65", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/layouts/CustomerLayout.jsx:65"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e726e6ea3b2353e2", "name": "Stray `console.log` in TS/JS \u2014 backend/server.js:414", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/server.js:414"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-46ebf193cb54b68e", "name": "Stray `console.log` in TS/JS \u2014 backend/middleware/cacheMiddleware.js:101", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/middleware/cacheMiddleware.js:101"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-eab43af336f52d6d", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/extractSurabayaSits.js:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/extractSurabayaSits.js:21"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7654e1e7dfe7c4a6", "name": "Stray `console.log` in TS/JS \u2014 backend/database/setup.js:20", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/setup.js:20"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2323b3bd01c4d449", "name": "Stray `console.log` in TS/JS \u2014 backend/database/run-all-migrations.js:61", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/run-all-migrations.js:61"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-052672cd016df820", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrate_areas.js:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrate_areas.js:12"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-80f617e9a1943fbe", "name": "Stray `console.log` in TS/JS \u2014 backend/database/database.js:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/database.js:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b62b86e617d3b166", "name": "Stray `console.log` in TS/JS \u2014 backend/database/connectionPool.js:60", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/connectionPool.js:60"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c73368e9070443d9", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505c_add_playback_token_sessions.js:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505c_add_playback_token_sessions.js:23"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9f221a5b8bcfe2cc", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611b_add_billing_tables.js:25", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611b_add_billing_tables.js:25"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-29159b16420c3b57", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_settings_table.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_settings_table.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-db91fb5be985edbc", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_watermark_settings.js:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_watermark_settings.js:9"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0272dee76741160b", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_grid_default_limit.js:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_grid_default_limit.js:21"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ef8e0a9d0480a025", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260613_add_promo_codes.js:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260613_add_promo_codes.js:22"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2ce72c70e555c0f7", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_add_recording_segment_filename_index.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_add_recording_segment_filename_index.js:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0263f9e3a14e22b7", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260507_add_area_slug_indexes.js:40", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260507_add_area_slug_indexes.js:40"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ff64cf2d690fc187", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_runtime_state_and_history_retention.js:39", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_runtime_state_and_history_retention.js:39"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3b189e16a31b0e30", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505b_add_playback_token_audit_and_share_keys.js:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505b_add_playback_token_audit_and_share_keys.js:23"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-40f9614ca8686e8f", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260522_add_camera_telegram_alert_state.js:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260522_add_camera_telegram_alert_state.js:18"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e65ccc3b32986ee1", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_landing_page_settings.js:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_landing_page_settings.js:17"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cae78007dc4d15e5", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_saweria_settings.js:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_saweria_settings.js:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3a399f31294cadf2", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_playback_viewer_sessions.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_playback_viewer_sessions.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-127136c19710ad60", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/fix_thumbnail_paths.js:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/fix_thumbnail_paths.js:9"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c4c1254d3dd49c84", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_health_mode.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_health_mode.js:13"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7de7bf38aaa17b7b", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_viewer_sessions.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_viewer_sessions.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ba32cb065de9c4e6", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260614b_add_voucher_orders.js:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260614b_add_voucher_orders.js:21"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2276ac814693ae61", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260612c_add_camera_is_public.js:20", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260612c_add_camera_is_public.js:20"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d312c2e3041f9eb8", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_delivery_types.js:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_delivery_types.js:9"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-87ad01bcacf45ba5", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/backfill_camera_delivery_types.js:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/backfill_camera_delivery_types.js:22"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-903611edf089dbd1", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_proxy_controls.js:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_proxy_controls.js:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-eb781cbb3857f695", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611_add_subscriber_tenancy.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611_add_subscriber_tenancy.js:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-958fcdcd086920e4", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_feedbacks_table.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_feedbacks_table.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-137a069a39466411", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260513_add_playback_token_camera_rules.js:34", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260513_add_playback_token_camera_rules.js:34"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b881ecda32872d27", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_analytics_indexes.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_analytics_indexes.js:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-af2aba1e553a39c9", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260614_add_voucher_access.js:29", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260614_add_voucher_access.js:29"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1fc660fc62d73280", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_health_override.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_health_override.js:13"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d680c96d70ec5344", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260523_add_sponsor_packages_and_camera_limit.js:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260523_add_sponsor_packages_and_camera_limit.js:22"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fed5ff2d071b7959", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_video_codec.js:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_video_codec.js:19"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-749808c4693be14b", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260524_add_whatsapp_message_template.js:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260524_add_whatsapp_message_template.js:26"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-47f649966b8f6550", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_online_status.js:15", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_online_status.js:15"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-301e22739cbc2ace", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_public_playback_controls.js:49", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_public_playback_controls.js:49"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-259c2d1a327c2eb3", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_coordinates.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_coordinates.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8f8dbc6f39ad5aa4", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_coordinates.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_coordinates.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4e024df78374de6c", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260511_add_recording_recovery_diagnostics.js:44", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260511_add_recording_recovery_diagnostics.js:44"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1e16b54f70c7f819", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_drop_failed_remux_files.js:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_drop_failed_remux_files.js:18"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-914f0e55a4feb593", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505_add_camera_view_stats.js:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505_add_camera_view_stats.js:19"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-022175184c194597", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_branding_settings.js:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_branding_settings.js:12"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c3deadaa88aea6f5", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_status.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_status.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1a24098cc8f2dde5", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/create_camera_discovery_table.js:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/create_camera_discovery_table.js:12"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-389d2d5b685ea0b6", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_core_indexes.js:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_core_indexes.js:19"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ba9bb622b73ffe99", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_internal_ingest_policy.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_internal_ingest_policy.js:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-67734d504c575b17", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260517_add_recording_recovery_attempt_fields.js:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260517_add_recording_recovery_attempt_fields.js:28"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fc1b26d9e4559416", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260512_add_recording_segments_global_start_index.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260512_add_recording_segments_global_start_index.js:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8520bef3d534e600", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_thumbnail_path.js:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_thumbnail_path.js:9"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2293d3851f48c049", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/001_migrate_security.js:11", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/001_migrate_security.js:11"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-96019a608a48e3da", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_coverage_scope.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_coverage_scope.js:13"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0a7a0daa78636876", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_grid_default_visibility.js:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_grid_default_visibility.js:12"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7ee660bbb4b95929", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_stream_key.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_stream_key.js:13"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0293046ccaadaf90", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611c_add_billing_plans.js:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611c_add_billing_plans.js:23"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-809ce38db62a94fd", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_sponsor_fields.js:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_sponsor_fields.js:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a69252748d2c6450", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/create_recordings_table.js:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/create_recordings_table.js:12"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-925c94c8f3336a98", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_recording_system.js:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_recording_system.js:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-46dafcae957d12e4", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/202605110001_create_notification_diagnostic_runs.js:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/202605110001_create_notification_diagnostic_runs.js:19"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-23da1584d4721209", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_repair_recording_segment_timezone.js:154", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_repair_recording_segment_timezone.js:154"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-68646427b507fd60", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260612_add_account_approval.js:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260612_add_account_approval.js:22"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e98becae29f0c40f", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505_add_playback_tokens.js:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505_add_playback_tokens.js:19"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-89038a41efb20756", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260503_add_recording_segment_uniqueness.js:47", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260503_add_recording_segment_uniqueness.js:47"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2380e53174652a18", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_add_recording_maintenance_state.js:45", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_add_recording_maintenance_state.js:45"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2ada3343ae3c9cba", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_thumbnail_strategy.js:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_thumbnail_strategy.js:17"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8af80fd1aaebbded", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_is_tunnel_field.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_is_tunnel_field.js:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-770c51fb666add5a", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_internal_rtsp_transport_policy.js:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_internal_rtsp_transport_policy.js:32"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-56e139da1ceb0388", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260510_add_camera_source_lifecycle.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260510_add_camera_source_lifecycle.js:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-60664a84edcf0e3d", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260613b_add_payment_failure_reason.js:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260613b_add_payment_failure_reason.js:21"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7869ae99d9d169d1", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_stream.js:15", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_stream.js:15"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-73f9dc3a0d8dbc62", "name": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_timezone_settings.js:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_timezone_settings.js:22"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-135bdf554a6787cc", "name": "Stray `console.log` in TS/JS \u2014 backend/routes/adminRoutes.js:236", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/routes/adminRoutes.js:236"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-011880557c736be9", "name": "Stray `console.log` in TS/JS \u2014 backend/controllers/recordingController.js:111", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/controllers/recordingController.js:111"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d0228b09f1cdee69", "name": "Stray `console.log` in TS/JS \u2014 backend/services/telegramService.js:579", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/telegramService.js:579"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1eb478a725df045f", "name": "Stray `console.log` in TS/JS \u2014 backend/services/telegramBotService.js:60", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/telegramBotService.js:60"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2695216e838e3ad4", "name": "Stray `console.log` in TS/JS \u2014 backend/services/playbackViewerSessionService.js:139", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/playbackViewerSessionService.js:139"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4746d23087110a73", "name": "Stray `console.log` in TS/JS \u2014 backend/services/mediaMtxService.js:62", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/mediaMtxService.js:62"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b6ca6b0231437324", "name": "Stray `console.log` in TS/JS \u2014 backend/services/securityAuditLogger.js:114", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/securityAuditLogger.js:114"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2203657dabae8d4c", "name": "Stray `console.log` in TS/JS \u2014 backend/services/billingService.js:431", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/billingService.js:431"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-efc2a600b17f1ce1", "name": "Stray `console.log` in TS/JS \u2014 backend/services/discoveryService.js:87", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/discoveryService.js:87"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-507cec3e38866966", "name": "Stray `console.log` in TS/JS \u2014 backend/services/cacheService.js:193", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/cacheService.js:193"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-66b8fafd719bd9f3", "name": "Stray `console.log` in TS/JS \u2014 backend/services/cameraService.js:1344", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/cameraService.js:1344"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-365e83a5eb106a8c", "name": "Stray `console.log` in TS/JS \u2014 backend/services/streamWarmer.js:42", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/streamWarmer.js:42"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-99f1e19cdf313061", "name": "Stray `console.log` in TS/JS \u2014 backend/services/viewerSessionService.js:139", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/viewerSessionService.js:139"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4173daaeab53a13d", "name": "Stray `console.log` in TS/JS \u2014 backend/services/setupNotificationService.js:50", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/setupNotificationService.js:50"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3cfa12bfbcb3f62c", "name": "Stray `console.log` in TS/JS \u2014 backend/services/recordingProcessManager.js:199", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/recordingProcessManager.js:199"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f9407f367727110d", "name": "Stray `console.log` in TS/JS \u2014 backend/services/sessionManager.js:283", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/sessionManager.js:283"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1724a77ee588f90f", "name": "Stray `console.log` in TS/JS \u2014 backend/services/thumbnailService.js:42", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/thumbnailService.js:42"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b795bf39e207eee6", "name": "Stray `console.log` in TS/JS \u2014 backend/services/cameraHealthService.js:1242", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/cameraHealthService.js:1242"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8c4e357f161684ca", "name": "Stray `console.log` in TS/JS \u2014 backend/services/recordingService.js:147", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/recordingService.js:147"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-71f5df32910fb528", "name": "Stray `console.log` in TS/JS \u2014 backend/services/areaService.js:203", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/areaService.js:203"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-83fa507c2acdd7c2", "name": "Stray `console.log` in TS/JS \u2014 backend/services/scrapers/jogjaScraper.js:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/scrapers/jogjaScraper.js:22"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9ea10d9651be2274", "name": "Privileged port 800 in use", "shortDescription": {"text": "Privileged port 800 in use"}, "fullDescription": {"text": "Port 800 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea0faf563ebab4db", "name": "Privileged port 554 in use", "shortDescription": {"text": "Privileged port 554 in use"}, "fullDescription": {"text": "Port 554 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8987d6d1c30c7202", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e39ae4bfd993828d", "name": "Docker base image uses a mutable or implicit tag: alpine:latest", "shortDescription": {"text": "Docker base image uses a mutable or implicit tag: alpine:latest"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ef951b0789368a24", "name": "Insecure pattern 'domparser_html_parse' in frontend/src/utils/sanitizePublicHtml.js:78", "shortDescription": {"text": "Insecure pattern 'domparser_html_parse' in frontend/src/utils/sanitizePublicHtml.js:78"}, "fullDescription": {"text": "Found a known-risky pattern (domparser_html_parse). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6b09be8eab66e992", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/AdBanner.jsx:44", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/AdBanner.jsx:44"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d828451808a80336", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/ads/InlineAdSlot.jsx:17", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/ads/InlineAdSlot.jsx:17"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f7b8a85414c7473c", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/ads/GlobalAdScript.jsx:13", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/ads/GlobalAdScript.jsx:13"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-de2b1a62fb5049a3", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/admin/settings/GeneralSettingsTab.jsx:193", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/admin/settings/GeneralSettingsTab.jsx:193"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4b0a3f1e601e127a", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/landing/LandingHero.jsx:78", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/landing/LandingHero.jsx:78"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1d1c6d46d0ed2c20", "name": "Insecure pattern 'weak_hash' in backend/__tests__/cameraHealthService.test.js:511", "shortDescription": {"text": "Insecure pattern 'weak_hash' in backend/__tests__/cameraHealthService.test.js:511"}, "fullDescription": {"text": "Found a known-risky pattern (weak_hash). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4f74bd680589c756", "name": "Insecure pattern 'node_child_process' in backend/database/run-all-migrations.js:9", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/database/run-all-migrations.js:9"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1fee650ee7a3ab5e", "name": "Insecure pattern 'exec_used' in backend/services/recordingDiskSpaceService.js:17", "shortDescription": {"text": "Insecure pattern 'exec_used' in backend/services/recordingDiskSpaceService.js:17"}, "fullDescription": {"text": "Found a known-risky pattern (exec_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4cf36f920048d8d3", "name": "Insecure pattern 'node_child_process' in backend/services/recordingDiskSpaceService.js:8", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingDiskSpaceService.js:8"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-df839bdd2030e1bf", "name": "Insecure pattern 'node_child_process' in backend/services/surabayaSitsExtractor.js:7", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/services/surabayaSitsExtractor.js:7"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-268d13a90c3f0c2f", "name": "Insecure pattern 'node_child_process' in backend/services/recordingRemuxer.js:7", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingRemuxer.js:7"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4f29d56c1065b57f", "name": "Insecure pattern 'node_child_process' in backend/services/recordingProcessManager.js:7", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingProcessManager.js:7"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6cbfe5eeb93f727b", "name": "Insecure pattern 'node_child_process' in backend/services/thumbnailService.js:9", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/services/thumbnailService.js:9"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-75a393b8f2f99f6a", "name": "Insecure pattern 'node_child_process' in backend/services/recordingService.js:11", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingService.js:11"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d75ad3d2b203fb3c", "name": "Insecure pattern 'node_child_process' in backend/services/recordingMediaProbe.js:7", "shortDescription": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingMediaProbe.js:7"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-dc04af509bf72b03", "name": "Very large file: frontend/src/components/MultiView/VideoPopup.jsx (1608 lines)", "shortDescription": {"text": "Very large file: frontend/src/components/MultiView/VideoPopup.jsx (1608 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5f1141664a1b11f9", "name": "Very large file: frontend/src/components/MultiView/MultiViewVideoItem.jsx (1196 lines)", "shortDescription": {"text": "Very large file: frontend/src/components/MultiView/MultiViewVideoItem.jsx (1196 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fa19ab53878f199d", "name": "Very large file: frontend/src/pages/AreaManagement.jsx (847 lines)", "shortDescription": {"text": "Very large file: frontend/src/pages/AreaManagement.jsx (847 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2dd0dd335036c87d", "name": "Very large file: backend/__tests__/cameraHealthService.test.js (2286 lines)", "shortDescription": {"text": "Very large file: backend/__tests__/cameraHealthService.test.js (2286 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ee4b6edeb85e64aa", "name": "Very large file: backend/services/cameraService.js (3174 lines)", "shortDescription": {"text": "Very large file: backend/services/cameraService.js (3174 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f707ba2693546884", "name": "Very large file: backend/services/cameraHealthService.js (3697 lines)", "shortDescription": {"text": "Very large file: backend/services/cameraHealthService.js (3697 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7973408a417a674b", "name": "Very large file: backend/services/hlsProxyService.js (1581 lines)", "shortDescription": {"text": "Very large file: backend/services/hlsProxyService.js (1581 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0e8a76eb13fd3249", "name": "Node manifest has dependencies but no lockfile: frontend/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: frontend/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3a092b5c39e242a1", "name": "Node manifest has dependencies but no lockfile: backend/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: backend/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 681 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 186 placeholder/mock markers across 49 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: ci, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing ci, lockfile. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e725d2ab884fbd49", "name": "Multiple root agent instruction files without precedence", "shortDescription": {"text": "Multiple root agent instruction files without precedence"}, "fullDescription": {"text": "The repo has multiple top-level AI-coder instruction files. Without precedence rules, different agents may follow different policies."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8cc43e52f0615b39", "name": "Commented-code block (5 lines) in frontend/vite.config.js:7", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/vite.config.js:7"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-79c6c63a49af24d0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/public/meta-config.js:190", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/public/meta-config.js:190"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-bd58c136007ce526", "name": "Commented-code block (8 lines) in frontend/public/sw.js:80", "shortDescription": {"text": "Commented-code block (8 lines) in frontend/public/sw.js:80"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-31b4b2db9641d0f4", "name": "Commented-code block (6 lines) in frontend/src/utils/publicPopupLayout.js:59", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/src/utils/publicPopupLayout.js:59"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1d74d6d93fd5845f", "name": "Legacy-named symbol `withLegacy` in frontend/src/utils/publicPopupLayout.test.js:222", "shortDescription": {"text": "Legacy-named symbol `withLegacy` in frontend/src/utils/publicPopupLayout.test.js:222"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f535df574b46898a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/utils/connectionTester.js:51", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/utils/connectionTester.js:51"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f4edef90aeac878f", "name": "Commented-code block (5 lines) in frontend/src/utils/directStreamHelper.js:27", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/utils/directStreamHelper.js:27"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0a6d053138b53063", "name": "Commented-code block (5 lines) in frontend/src/components/LayoutToggleFAB.jsx:4", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/LayoutToggleFAB.jsx:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0115f5d90057df5e", "name": "Commented-code block (6 lines) in frontend/src/components/MultiView/MultiViewButton.jsx:12", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/src/components/MultiView/MultiViewButton.jsx:12"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0938c1d799ce18d6", "name": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.test.jsx:156", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.test.jsx:156"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d0f68c4f38dbff76", "name": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.stability.test.js:171", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.stability.test.js:171"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-dccd2ba6aca026af", "name": "Commented-code block (5 lines) in frontend/src/components/MultiView/VideoPopup.jsx:181", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/VideoPopup.jsx:181"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-945d2691bb9e32ca", "name": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.jsx:78", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.jsx:78"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2c6c4af8f18659f0", "name": "Commented-code block (6 lines) in frontend/src/components/landing/LandingCamerasSection.jsx:228", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/src/components/landing/LandingCamerasSection.jsx:228"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7cbf64a543315fc4", "name": "Commented-code block (5 lines) in frontend/src/hooks/admin/useCameraManagementPage.js:196", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/hooks/admin/useCameraManagementPage.js:196"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5e0a0a2836be25f9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/hooks/admin/useCameraManagementPage.js:51", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/hooks/admin/useCameraManagementPage.js:51"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6b264a6645187364", "name": "Commented-code block (8 lines) in backend/server.js:18", "shortDescription": {"text": "Commented-code block (8 lines) in backend/server.js:18"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-681986dd32c82130", "name": "Commented-code block (5 lines) in backend/__tests__/cameraHealthService.test.js:128", "shortDescription": {"text": "Commented-code block (5 lines) in backend/__tests__/cameraHealthService.test.js:128"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3b3ac70ee4a066d0", "name": "Commented-code block (8 lines) in backend/__tests__/externalStreamProxyRoutes.test.js:271", "shortDescription": {"text": "Commented-code block (8 lines) in backend/__tests__/externalStreamProxyRoutes.test.js:271"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3c162eb606d83c8a", "name": "Commented-code block (5 lines) in backend/__tests__/streamService.test.js:110", "shortDescription": {"text": "Commented-code block (5 lines) in backend/__tests__/streamService.test.js:110"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-21ba2a3ebcfc86c3", "name": "Commented-code block (8 lines) in backend/__tests__/recordingPlaybackService.test.js:350", "shortDescription": {"text": "Commented-code block (8 lines) in backend/__tests__/recordingPlaybackService.test.js:350"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7435bdb7fd9ea8f7", "name": "Commented-code block (5 lines) in backend/__tests__/externalStreamProxyRoutes.viewerSession.stability.test.js:89", "shortDescription": {"text": "Commented-code block (5 lines) in backend/__tests__/externalStreamProxyRoutes.viewerSession.stability.test.js:89"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5ef37fcac83f44a0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/__tests__/externalStreamProxyRoutes.importIntegrity.test.js:127", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/__tests__/externalStreamProxyRoutes.importIntegrity.test.js:127"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b0e3b075cbca8e29", "name": "Commented-code block (5 lines) in backend/config/constants.js:9", "shortDescription": {"text": "Commented-code block (5 lines) in backend/config/constants.js:9"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-cb213a532c597c19", "name": "Commented-code block (6 lines) in backend/middleware/schemaValidators.js:845", "shortDescription": {"text": "Commented-code block (6 lines) in backend/middleware/schemaValidators.js:845"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-70596770ad5c14e8", "name": "Commented-code block (7 lines) in backend/middleware/apiKeyValidator.js:41", "shortDescription": {"text": "Commented-code block (7 lines) in backend/middleware/apiKeyValidator.js:41"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9f52a7addf2c69cf", "name": "Commented-code block (6 lines) in backend/database/database.js:41", "shortDescription": {"text": "Commented-code block (6 lines) in backend/database/database.js:41"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b09fa6ef6ddff9b9", "name": "Commented-code block (5 lines) in backend/database/migrations/zz_20260518_drop_failed_remux_files.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/database/migrations/zz_20260518_drop_failed_remux_files.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6d7e02f54b1ce5ce", "name": "Commented-code block (8 lines) in backend/database/migrations/add_sponsor_fields.js:57", "shortDescription": {"text": "Commented-code block (8 lines) in backend/database/migrations/add_sponsor_fields.js:57"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d82e2eedeabc2dbd", "name": "Commented-code block (5 lines) in backend/database/migrations/zz_20260503_add_recording_segment_uniqueness.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/database/migrations/zz_20260503_add_recording_segment_uniqueness.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e318da7b9869cf80", "name": "Commented-code block (6 lines) in backend/routes/hlsProxyRoutes.js:71", "shortDescription": {"text": "Commented-code block (6 lines) in backend/routes/hlsProxyRoutes.js:71"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1a0b63c7ea1d9631", "name": "Commented-code block (5 lines) in backend/controllers/playbackTokenController.js:39", "shortDescription": {"text": "Commented-code block (5 lines) in backend/controllers/playbackTokenController.js:39"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-db263c6aaf242f6b", "name": "Commented-code block (5 lines) in backend/services/telegramService.js:173", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/telegramService.js:173"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-09000f3f761fdffe", "name": "Commented-code block (5 lines) in backend/services/billingPlanService.js:417", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/billingPlanService.js:417"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-93a637e3fe732a9a", "name": "Commented-code block (5 lines) in backend/services/streamService.js:35", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/streamService.js:35"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e45c247c7e59fa13", "name": "Commented-code block (6 lines) in backend/services/telegramBotService.js:24", "shortDescription": {"text": "Commented-code block (6 lines) in backend/services/telegramBotService.js:24"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5ba7a06a4bf90c89", "name": "Commented-code block (5 lines) in backend/services/recordingPaths.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingPaths.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-64194ea4a134411c", "name": "Commented-code block (7 lines) in backend/services/recordingRecoveryRunner.js:1", "shortDescription": {"text": "Commented-code block (7 lines) in backend/services/recordingRecoveryRunner.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-597c24bab5c1b048", "name": "Commented-code block (5 lines) in backend/services/recordingStderrParser.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingStderrParser.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c42a88f437f97fbe", "name": "Commented-code block (10 lines) in backend/services/recordingMaintenanceCoordinator.js:1", "shortDescription": {"text": "Commented-code block (10 lines) in backend/services/recordingMaintenanceCoordinator.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-79117a73bb246d21", "name": "Commented-code block (6 lines) in backend/services/recordingStarter.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in backend/services/recordingStarter.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2727af7d40c2db88", "name": "Commented-code block (5 lines) in backend/services/cameraRuntimeStateService.js:22", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/cameraRuntimeStateService.js:22"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0ba868af8db0e853", "name": "Commented-code block (5 lines) in backend/services/paymentService.js:209", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/paymentService.js:209"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1144c947f35ddc84", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/paymentService.js:418", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/paymentService.js:418"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-fcf8e7a413879da7", "name": "Commented-code block (5 lines) in backend/services/recordingLifecycleReconciler.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingLifecycleReconciler.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-263667211e55b9c5", "name": "Commented-code block (7 lines) in backend/services/recordingHealthMonitor.js:1", "shortDescription": {"text": "Commented-code block (7 lines) in backend/services/recordingHealthMonitor.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-100444f079b453f7", "name": "Commented-code block (5 lines) in backend/services/recordingRemuxer.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingRemuxer.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-063cab50a1c3c07d", "name": "Commented-code block (9 lines) in backend/services/recordingRecoveryService.js:1", "shortDescription": {"text": "Commented-code block (9 lines) in backend/services/recordingRecoveryService.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6ae4fe0183b66bc8", "name": "Commented-code block (7 lines) in backend/services/recordingCleanupShared.js:1", "shortDescription": {"text": "Commented-code block (7 lines) in backend/services/recordingCleanupShared.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-cbc1665ad817a6e6", "name": "Commented-code block (5 lines) in backend/services/customerCameraService.js:24", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/customerCameraService.js:24"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-06491b0a5977c70c", "name": "Commented-code block (5 lines) in backend/services/paymentSettingsService.js:34", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/paymentSettingsService.js:34"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0187b4498e2c0119", "name": "Commented-code block (5 lines) in backend/services/voucherService.js:514", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/voucherService.js:514"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b946bb61d00a45f0", "name": "Commented-code block (5 lines) in backend/services/viewerSessionService.js:121", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/viewerSessionService.js:121"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f1bf478c1aac05ec", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/setupNotificationService.js:82", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/setupNotificationService.js:82"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ce7c0f8e51cc34d8", "name": "Commented-code block (5 lines) in backend/services/recordingProcessManager.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingProcessManager.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-864d8d801d579d56", "name": "Commented-code block (5 lines) in backend/services/recordingLifecyclePolicy.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingLifecyclePolicy.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-244180d27bd435ba", "name": "Commented-code block (7 lines) in backend/services/recordingFilesystemOrphanCleanup.js:1", "shortDescription": {"text": "Commented-code block (7 lines) in backend/services/recordingFilesystemOrphanCleanup.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ab10e6f5a9e90e0c", "name": "Commented-code block (5 lines) in backend/services/recordingExpiredDbSegmentCleanup.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingExpiredDbSegmentCleanup.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2c740d8e7a183597", "name": "Commented-code block (8 lines) in backend/services/recordingHealthAlertService.js:1", "shortDescription": {"text": "Commented-code block (8 lines) in backend/services/recordingHealthAlertService.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b844ca4d18bd6969", "name": "Commented-code block (8 lines) in backend/services/recordingHealthDashboardService.js:1", "shortDescription": {"text": "Commented-code block (8 lines) in backend/services/recordingHealthDashboardService.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-53266f6081cdf9f4", "name": "Commented-code block (7 lines) in backend/services/cameraHealthService.js:197", "shortDescription": {"text": "Commented-code block (7 lines) in backend/services/cameraHealthService.js:197"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b2a6c518476debe0", "name": "Commented-code block (5 lines) in backend/services/recordingIntervalsPolicy.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/services/recordingIntervalsPolicy.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c8a5ee454d6dbe58", "name": "Commented-code block (6 lines) in backend/services/recordingAutoStarter.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in backend/services/recordingAutoStarter.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e0a7ccff5b8adde4", "name": "Commented-code block (6 lines) in backend/services/recordingService.js:113", "shortDescription": {"text": "Commented-code block (6 lines) in backend/services/recordingService.js:113"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1fd53a61af16442e", "name": "Commented-code block (6 lines) in backend/services/recordingRecoveryQueue.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in backend/services/recordingRecoveryQueue.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6e24d0039e1c5bdd", "name": "Commented-code block (12 lines) in backend/services/hlsProxyService.js:811", "shortDescription": {"text": "Commented-code block (12 lines) in backend/services/hlsProxyService.js:811"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b589d4a4c15ad3b6", "name": "Commented-code block (16 lines) in backend/services/externalStreamProxyService.js:45", "shortDescription": {"text": "Commented-code block (16 lines) in backend/services/externalStreamProxyService.js:45"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-792bec58a66ec446", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/externalStreamProxyService.js:111", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/externalStreamProxyService.js:111"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-42eaf2969a6a5f1d", "name": "Commented-code block (8 lines) in backend/services/recordingPlaybackService.js:282", "shortDescription": {"text": "Commented-code block (8 lines) in backend/services/recordingPlaybackService.js:282"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-226522e03cfab62d", "name": "45 env vars used in code but missing from .env.example", "shortDescription": {"text": "45 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADS_CONNECT_ALLOWED_HOSTS`, `ADS_FRAME_ALLOWED_HOSTS`, `ADS_SCRIPT_ALLOWED_HOSTS`, `API_KEY_REQUIRE_KEYS`, `APP_BUILD_ID`, `APP_VERSION`, `BILLING_GATEWAY`, `BILLING_PUBLIC_BASE_URL` + 37 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-46fb4cc685716211", "name": "Frontend route `/area/:areaSlug` has no Link/navigate to it \u2014 frontend/src/pages/AreaPublicPage.test.jsx", "shortDescription": {"text": "Frontend route `/area/:areaSlug` has no Link/navigate to it \u2014 frontend/src/pages/AreaPublicPage.test.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-29c22f6d06c67d25", "name": "Frontend route `/playback` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/playback` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e51da000b1ec1444", "name": "Frontend route `/admin` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/admin` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d5ecfb1bd4d970ce", "name": "Dangling fetch: GET http://localhost:9997/v3/paths/list (backend/routes/adminRoutes.js:139)", "shortDescription": {"text": "Dangling fetch: GET http://localhost:9997/v3/paths/list (backend/routes/adminRoutes.js:139)"}, "fullDescription": {"text": "`backend/routes/adminRoutes.js:139` calls `GET http://localhost:9997/v3/paths/list` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/http:/localhost:9997/v3/paths/list`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ebf58d2a5bb34c6f", "name": "Dangling fetch: GET http://localhost:9997/v3/config/paths/list (backend/routes/adminRoutes.js:184)", "shortDescription": {"text": "Dangling fetch: GET http://localhost:9997/v3/config/paths/list (backend/routes/adminRoutes.js:184)"}, "fullDescription": {"text": "`backend/routes/adminRoutes.js:184` calls `GET http://localhost:9997/v3/config/paths/list` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/http:/localhost:9997/v3/config/paths/list`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6284df49598767d0", "name": "Dangling fetch: GET http://cariloka.com/atcscctvindon/cctvatcsindonlengkap/soloCCTV.json (backend/services/cameraService", "shortDescription": {"text": "Dangling fetch: GET http://cariloka.com/atcscctvindon/cctvatcsindonlengkap/soloCCTV.json (backend/services/cameraService.js:2641)"}, "fullDescription": {"text": "`backend/services/cameraService.js:2641` calls `GET http://cariloka.com/atcscctvindon/cctvatcsindonlengkap/soloCCTV.json` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/http:/cariloka.com/atcscctvindon/cctvatcsindonlengkap/solocctv.json`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5f54b81fc135abff", "name": "Dangling fetch: GET https://cctv.jombangkab.go.id/v2/ (backend/services/cameraService.js:2684)", "shortDescription": {"text": "Dangling fetch: GET https://cctv.jombangkab.go.id/v2/ (backend/services/cameraService.js:2684)"}, "fullDescription": {"text": "`backend/services/cameraService.js:2684` calls `GET https://cctv.jombangkab.go.id/v2/` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/cctv.jombangkab.go.id/v2`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-67d28fa8cd6bb12f", "name": "Unused endpoint: PUT /", "shortDescription": {"text": "Unused endpoint: PUT /"}, "fullDescription": {"text": "`frontend/public/sw.js` declares `PUT /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f2227339ba6f0744", "name": "Unused endpoint: GET /api/admin/settings/timezone", "shortDescription": {"text": "Unused endpoint: GET /api/admin/settings/timezone"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/TimezoneSettingsTab.jsx` declares `GET /api/admin/settings/timezone` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-97e3067dbb71e985", "name": "Unused endpoint: PUT /api/admin/settings/timezone", "shortDescription": {"text": "Unused endpoint: PUT /api/admin/settings/timezone"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/TimezoneSettingsTab.jsx` declares `PUT /api/admin/settings/timezone` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5dbcb694eaa1507a", "name": "Unused endpoint: GET /api/admin/backup/export", "shortDescription": {"text": "Unused endpoint: GET /api/admin/backup/export"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/BackupSettingsTab.jsx` declares `GET /api/admin/backup/export` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9afa784f9e37c190", "name": "Unused endpoint: POST /api/admin/backup/preview", "shortDescription": {"text": "Unused endpoint: POST /api/admin/backup/preview"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/BackupSettingsTab.jsx` declares `POST /api/admin/backup/preview` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9aa11ff6c9abc165", "name": "Unused endpoint: POST /api/admin/backup/import", "shortDescription": {"text": "Unused endpoint: POST /api/admin/backup/import"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/BackupSettingsTab.jsx` declares `POST /api/admin/backup/import` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-27dc99e37647a00c", "name": "Unused endpoint: PUT /api/settings/landing_area_coverage", "shortDescription": {"text": "Unused endpoint: PUT /api/settings/landing_area_coverage"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/GeneralSettingsTab.jsx` declares `PUT /api/settings/landing_area_coverage` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-303d7e4d4443ca89", "name": "Unused endpoint: PUT /api/settings/landing_hero_badge", "shortDescription": {"text": "Unused endpoint: PUT /api/settings/landing_hero_badge"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/GeneralSettingsTab.jsx` declares `PUT /api/settings/landing_hero_badge` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-86e22efc7fa89e42", "name": "Unused endpoint: PUT /api/settings/landing_section_title", "shortDescription": {"text": "Unused endpoint: PUT /api/settings/landing_section_title"}, "fullDescription": {"text": "`frontend/src/components/admin/settings/GeneralSettingsTab.jsx` declares `PUT /api/settings/landing_section_title` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4b7db9b556b4e709", "name": "Unused endpoint: GET /api/settings/timezone", "shortDescription": {"text": "Unused endpoint: GET /api/settings/timezone"}, "fullDescription": {"text": "`frontend/src/contexts/TimezoneContext.jsx` declares `GET /api/settings/timezone` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0ea970b5f55020de", "name": "Unused endpoint: GET /api/stream", "shortDescription": {"text": "Unused endpoint: GET /api/stream"}, "fullDescription": {"text": "`frontend/src/services/streamService.js` declares `GET /api/stream` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6daa54d9802f3950", "name": "Unused endpoint: GET /api/settings/map-center", "shortDescription": {"text": "Unused endpoint: GET /api/settings/map-center"}, "fullDescription": {"text": "`frontend/src/services/settingsService.js` declares `GET /api/settings/map-center` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bdb5b9c4ac73a300", "name": "Unused endpoint: GET /api/settings/landing-page", "shortDescription": {"text": "Unused endpoint: GET /api/settings/landing-page"}, "fullDescription": {"text": "`frontend/src/services/settingsService.js` declares `GET /api/settings/landing-page` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2d1ddd4b07a45aef", "name": "Unused endpoint: GET /api/settings/public-ads", "shortDescription": {"text": "Unused endpoint: GET /api/settings/public-ads"}, "fullDescription": {"text": "`frontend/src/services/settingsService.js` declares `GET /api/settings/public-ads` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-379b09f9de636500", "name": "Unused endpoint: GET /api/settings", "shortDescription": {"text": "Unused endpoint: GET /api/settings"}, "fullDescription": {"text": "`frontend/src/services/settingsService.js` declares `GET /api/settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3855bce018689ebc", "name": "Unused endpoint: PUT /api/settings/map_default_center", "shortDescription": {"text": "Unused endpoint: PUT /api/settings/map_default_center"}, "fullDescription": {"text": "`frontend/src/services/settingsService.js` declares `PUT /api/settings/map_default_center` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dc0512bb01741d78", "name": "Unused endpoint: GET /api/customer/cameras", "shortDescription": {"text": "Unused endpoint: GET /api/customer/cameras"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/cameras` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ae9ca89227c3fbf4", "name": "Unused endpoint: GET /api/customer/summary", "shortDescription": {"text": "Unused endpoint: GET /api/customer/summary"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/summary` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4d2e0afd9c489581", "name": "Unused endpoint: GET /api/customer/wallet", "shortDescription": {"text": "Unused endpoint: GET /api/customer/wallet"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/wallet` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fc94bc1c148afcfc", "name": "Unused endpoint: GET /api/customer/payments", "shortDescription": {"text": "Unused endpoint: GET /api/customer/payments"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/payments` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d3b1b04f7dac8ba3", "name": "Unused endpoint: GET /api/customer/payment-options", "shortDescription": {"text": "Unused endpoint: GET /api/customer/payment-options"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/payment-options` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-28362f452a5b49b8", "name": "Unused endpoint: POST /api/customer/topup", "shortDescription": {"text": "Unused endpoint: POST /api/customer/topup"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `POST /api/customer/topup` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d615918e7d8d61f5", "name": "Unused endpoint: GET /api/customer/promo/validate", "shortDescription": {"text": "Unused endpoint: GET /api/customer/promo/validate"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/promo/validate` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8d4ad8fb2a32cd9e", "name": "Unused endpoint: POST /api/customer/promo/redeem", "shortDescription": {"text": "Unused endpoint: POST /api/customer/promo/redeem"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `POST /api/customer/promo/redeem` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-94c3395076d13dda", "name": "Unused endpoint: GET /api/customer/plan", "shortDescription": {"text": "Unused endpoint: GET /api/customer/plan"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/plan` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2881ea5303f38556", "name": "Unused endpoint: GET /api/customer/plans", "shortDescription": {"text": "Unused endpoint: GET /api/customer/plans"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/plans` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a5085729b9e46cc8", "name": "Unused endpoint: POST /api/customer/plan", "shortDescription": {"text": "Unused endpoint: POST /api/customer/plan"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `POST /api/customer/plan` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d140d27d4767af32", "name": "Unused endpoint: POST /api/customer/cameras", "shortDescription": {"text": "Unused endpoint: POST /api/customer/cameras"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `POST /api/customer/cameras` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8ed0dbbe548e6c92", "name": "Unused endpoint: GET /api/customer/areas", "shortDescription": {"text": "Unused endpoint: GET /api/customer/areas"}, "fullDescription": {"text": "`frontend/src/services/customerService.js` declares `GET /api/customer/areas` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fd55aa0818a7c897", "name": "Unused endpoint: POST /api/auth/login", "shortDescription": {"text": "Unused endpoint: POST /api/auth/login"}, "fullDescription": {"text": "`frontend/src/services/authService.js` declares `POST /api/auth/login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a5b3437e64c8f7b4", "name": "Unused endpoint: POST /api/auth/register", "shortDescription": {"text": "Unused endpoint: POST /api/auth/register"}, "fullDescription": {"text": "`frontend/src/services/authService.js` declares `POST /api/auth/register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-208f088dc8233edd", "name": "Unused endpoint: GET /api/auth/register-info", "shortDescription": {"text": "Unused endpoint: GET /api/auth/register-info"}, "fullDescription": {"text": "`frontend/src/services/authService.js` declares `GET /api/auth/register-info` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d5a39262ac205120", "name": "Unused endpoint: POST /api/auth/logout", "shortDescription": {"text": "Unused endpoint: POST /api/auth/logout"}, "fullDescription": {"text": "`frontend/src/services/authService.js` declares `POST /api/auth/logout` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-49ac19bb61ef30a3", "name": "Unused endpoint: POST /api/auth/refresh", "shortDescription": {"text": "Unused endpoint: POST /api/auth/refresh"}, "fullDescription": {"text": "`frontend/src/services/authService.js` declares `POST /api/auth/refresh` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-33a5daa01dd022c8", "name": "Unused endpoint: GET /api/auth/verify", "shortDescription": {"text": "Unused endpoint: GET /api/auth/verify"}, "fullDescription": {"text": "`frontend/src/services/authService.js` declares `GET /api/auth/verify` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fdf125fe0eae374a", "name": "Unused endpoint: GET /api/admin/billing/customers", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/customers"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/customers` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4b4c2ed8661c1d8b", "name": "Unused endpoint: POST /api/admin/billing/topup-manual", "shortDescription": {"text": "Unused endpoint: POST /api/admin/billing/topup-manual"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `POST /api/admin/billing/topup-manual` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-25a4f1174ced6380", "name": "Unused endpoint: POST /api/admin/billing/wallet-adjust", "shortDescription": {"text": "Unused endpoint: POST /api/admin/billing/wallet-adjust"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `POST /api/admin/billing/wallet-adjust` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1aa7a60fcc0a7d8c", "name": "Unused endpoint: GET /api/admin/billing/subscriptions", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/subscriptions"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/subscriptions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-61aca3d8035d00cb", "name": "Unused endpoint: POST /api/admin/billing/subscriptions", "shortDescription": {"text": "Unused endpoint: POST /api/admin/billing/subscriptions"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `POST /api/admin/billing/subscriptions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a7e2387e6a23b925", "name": "Unused endpoint: GET /api/admin/billing/payments", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/payments"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/payments` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-240441c5e44f7087", "name": "Unused endpoint: POST /api/admin/billing/charges/run", "shortDescription": {"text": "Unused endpoint: POST /api/admin/billing/charges/run"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `POST /api/admin/billing/charges/run` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b35e8364bbb6e0e1", "name": "Unused endpoint: GET /api/admin/billing/plans", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/plans"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/plans` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-91ec3ed2c835df30", "name": "Unused endpoint: POST /api/admin/billing/plans", "shortDescription": {"text": "Unused endpoint: POST /api/admin/billing/plans"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `POST /api/admin/billing/plans` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1e78e13f07d24c95", "name": "Unused endpoint: GET /api/admin/billing/payment-gateway", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/payment-gateway"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/payment-gateway` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-34b6c956709f05a4", "name": "Unused endpoint: PUT /api/admin/billing/payment-gateway", "shortDescription": {"text": "Unused endpoint: PUT /api/admin/billing/payment-gateway"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `PUT /api/admin/billing/payment-gateway` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-330b23379b2d18ff", "name": "Unused endpoint: POST /api/admin/billing/payment-gateway/test", "shortDescription": {"text": "Unused endpoint: POST /api/admin/billing/payment-gateway/test"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `POST /api/admin/billing/payment-gateway/test` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8a96b7338d292dce", "name": "Unused endpoint: GET /api/admin/billing/payment-gateway/channels", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/payment-gateway/channels"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/payment-gateway/channels` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0c19982634a0a361", "name": "Unused endpoint: GET /api/admin/billing/camera-ips", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/camera-ips"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/camera-ips` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-11b62f3abeb23142", "name": "Unused endpoint: GET /api/admin/billing/promos", "shortDescription": {"text": "Unused endpoint: GET /api/admin/billing/promos"}, "fullDescription": {"text": "`frontend/src/services/billingAdminService.js` declares `GET /api/admin/billing/promos` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/17728"}, "properties": {"repository": "rafall04/cctv", "repoUrl": "https://github.com/rafall04/cctv", "branch": "main"}, "results": [{"ruleId": "scanner-bd006da33fa410c7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/public/meta-config.js:136"}, "properties": {"repobilityId": "bdec2e4f168d0755", "scanner": "scanner-primary", "fingerprint": "bd006da33fa410c7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-178cf2ba6fb55cea", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/config/runtimeConfig.js:71"}, "properties": {"repobilityId": "1538554212908619", "scanner": "scanner-primary", "fingerprint": "178cf2ba6fb55cea", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3fa8bbf33724ac28", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/TopCamerasWidget.jsx:72"}, "properties": {"repobilityId": "0fd5a9968b59c9b1", "scanner": "scanner-primary", "fingerprint": "3fa8bbf33724ac28", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-668468287bc4abc7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/SponsorBadge.jsx:56"}, "properties": {"repobilityId": "732cd5d4b91a0ab6", "scanner": "scanner-primary", "fingerprint": "668468287bc4abc7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e3b82f069dc8a428", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/LocationPicker.jsx:93"}, "properties": {"repobilityId": "1fa8654429c44928", "scanner": "scanner-primary", "fingerprint": "e3b82f069dc8a428", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bb2cfec8976ea12e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/CameraPerformanceTable.jsx:80"}, "properties": {"repobilityId": "f0b9c9702987b694", "scanner": "scanner-primary", "fingerprint": "bb2cfec8976ea12e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0c57e07f1334600c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/VideoPopup.jsx:1205"}, "properties": {"repobilityId": "2250d6cfc7fafc54", "scanner": "scanner-primary", "fingerprint": "0c57e07f1334600c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-55cd0aba04d9ca21", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/components/MultiView/VideoPopup.jsx:135"}, "properties": {"repobilityId": "b77691cc0e741759", "scanner": "scanner-primary", "fingerprint": "55cd0aba04d9ca21", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a7df8dc2ff0d108c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/RelatedCamerasStrip.jsx:45"}, "properties": {"repobilityId": "1b0bc8ca3100e8dc", "scanner": "scanner-primary", "fingerprint": "a7df8dc2ff0d108c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7728b51b1137aa71", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/MultiViewVideoItem.jsx:1021"}, "properties": {"repobilityId": "1700283fed86d2c9", "scanner": "scanner-primary", "fingerprint": "7728b51b1137aa71", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-75b08f5f7361546e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/components/MultiView/MultiViewVideoItem.jsx:552"}, "properties": {"repobilityId": "f447f151ce516ed3", "scanner": "scanner-primary", "fingerprint": "75b08f5f7361546e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0045898a2dab2280", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/MultiView/CameraDetailPanel.jsx:36"}, "properties": {"repobilityId": "88c0ed20ae4a2ef9", "scanner": "scanner-primary", "fingerprint": "0045898a2dab2280", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0f111d44117c3798", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/settings/TelegramSettingsPanel.jsx:652"}, "properties": {"repobilityId": "5a679938cfa9f74e", "scanner": "scanner-primary", "fingerprint": "0f111d44117c3798", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e12dd78cf0555c65", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/admin/settings/GeneralSettingsTab.jsx:193"}, "properties": {"repobilityId": "e849d37e71e222a2", "scanner": "scanner-primary", "fingerprint": "e12dd78cf0555c65", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-2ce9e4fa1ca10aa8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/analytics/AnalyticsPrimitives.jsx:140"}, "properties": {"repobilityId": "155aadbcfd0f7f41", "scanner": "scanner-primary", "fingerprint": "2ce9e4fa1ca10aa8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8d64800f0fcc0196", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/analytics/TopCamerasCard.jsx:21"}, "properties": {"repobilityId": "84b9a9d6cc026839", "scanner": "scanner-primary", "fingerprint": "8d64800f0fcc0196", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0eb33ce5a76943c0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/dashboard/DashboardStreams.jsx:215"}, "properties": {"repobilityId": "053807309b4703e8", "scanner": "scanner-primary", "fingerprint": "0eb33ce5a76943c0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c1af8eddff2ca9b6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/playback-tokens/PlaybackTokenForm.jsx:99"}, "properties": {"repobilityId": "ade6acb2b3bf84f3", "scanner": "scanner-primary", "fingerprint": "c1af8eddff2ca9b6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6393252bea9c80d8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/PaymentsTab.jsx:134"}, "properties": {"repobilityId": "edcfe73c5d79d459", "scanner": "scanner-primary", "fingerprint": "6393252bea9c80d8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-90d0ce36ff0f9307", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/CustomersTab.jsx:178"}, "properties": {"repobilityId": "496ce3afb9a604e2", "scanner": "scanner-primary", "fingerprint": "90d0ce36ff0f9307", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fdcc5ea3dd6fe646", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/billing/SubscriptionsTab.jsx:156"}, "properties": {"repobilityId": "50f2c725181ec714", "scanner": "scanner-primary", "fingerprint": "fdcc5ea3dd6fe646", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-196f4262901eada6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/areas/BulkPolicyPreview.jsx:44"}, "properties": {"repobilityId": "f6361cccd88a6924", "scanner": "scanner-primary", "fingerprint": "196f4262901eada6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bd1c82d186ea45d0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/admin/feedback/FeedbackListPanel.jsx:37"}, "properties": {"repobilityId": "7345e3b59d960d0b", "scanner": "scanner-primary", "fingerprint": "bd1c82d186ea45d0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6c64b11180f8ccae", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingFilterDropdown.jsx:57"}, "properties": {"repobilityId": "e7d177239fd4bced", "scanner": "scanner-primary", "fingerprint": "6c64b11180f8ccae", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b0d79a679b5a60ca", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingMobileDock.jsx:125"}, "properties": {"repobilityId": "8341a5273f214108", "scanner": "scanner-primary", "fingerprint": "b0d79a679b5a60ca", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-636cab004ac9a486", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 frontend/src/components/landing/LandingMobileDock.jsx:132"}, "properties": {"repobilityId": "c8be32e3888b4813", "scanner": "scanner-primary", "fingerprint": "636cab004ac9a486", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-ba58917c2d37d9e4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingTrendingCameras.jsx:37"}, "properties": {"repobilityId": "d7f165b44a5a9e4a", "scanner": "scanner-primary", "fingerprint": "ba58917c2d37d9e4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-098af7448d2de839", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingCameraCard.jsx:215"}, "properties": {"repobilityId": "66dcba2f93189c77", "scanner": "scanner-primary", "fingerprint": "098af7448d2de839", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8d7d45b627ea80e3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingDiscoveryStrip.jsx:32"}, "properties": {"repobilityId": "fdf1285a1f33fe6b", "scanner": "scanner-primary", "fingerprint": "8d7d45b627ea80e3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eb0540f2b221c138", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 frontend/src/components/landing/LandingDiscoveryStrip.jsx:103"}, "properties": {"repobilityId": "d0e09ecf50eab385", "scanner": "scanner-primary", "fingerprint": "eb0540f2b221c138", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-b4b07dc8ecd10a0a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingCamerasSection.jsx:115"}, "properties": {"repobilityId": "9856e7b29175239e", "scanner": "scanner-primary", "fingerprint": "b4b07dc8ecd10a0a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5636a99e1f149684", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingSmartFeed.jsx:27"}, "properties": {"repobilityId": "262e1c61e7e97f94", "scanner": "scanner-primary", "fingerprint": "5636a99e1f149684", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-118e87d9fc0af4aa", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingQuickAccessStrip.jsx:22"}, "properties": {"repobilityId": "3e18afb717b85544", "scanner": "scanner-primary", "fingerprint": "118e87d9fc0af4aa", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2eff651bdc90f0ba", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/components/landing/LandingHero.jsx:78"}, "properties": {"repobilityId": "2fc7d14b341733b1", "scanner": "scanner-primary", "fingerprint": "2eff651bdc90f0ba", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-26124d6289e4d40e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/landing/LandingStatsBar.jsx:134"}, "properties": {"repobilityId": "d59f057fed100e29", "scanner": "scanner-primary", "fingerprint": "26124d6289e4d40e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7d8bab3830c7029f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/playback/PlaybackSegmentList.jsx:66"}, "properties": {"repobilityId": "b25b4b23efbfbda9", "scanner": "scanner-primary", "fingerprint": "7d8bab3830c7029f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c2c98d4a67e43fee", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/AreaPublicPage.jsx:94"}, "properties": {"repobilityId": "f5d15c3e073b5084", "scanner": "scanner-primary", "fingerprint": "c2c98d4a67e43fee", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1e08bdb067aedd01", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/CustomerCameraIPs.jsx:174"}, "properties": {"repobilityId": "e0529186abce77e2", "scanner": "scanner-primary", "fingerprint": "1e08bdb067aedd01", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1ce9cbe01978ef9b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/SponsorManagement.jsx:747"}, "properties": {"repobilityId": "ac9a344982376e25", "scanner": "scanner-primary", "fingerprint": "1ce9cbe01978ef9b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-070327b4bd4c45ab", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/VoucherManagement.jsx:335"}, "properties": {"repobilityId": "7f1c90f5e755a18e", "scanner": "scanner-primary", "fingerprint": "070327b4bd4c45ab", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-12f03542c1127e8c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/customer/MyCameras.jsx:224"}, "properties": {"repobilityId": "b00ee0c4b91312ed", "scanner": "scanner-primary", "fingerprint": "12f03542c1127e8c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c1f90f76bc6393e2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/customer/MyWallet.jsx:542"}, "properties": {"repobilityId": "e0c0fdb1f1576d20", "scanner": "scanner-primary", "fingerprint": "c1f90f76bc6393e2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bf1a8c5ca495ced1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/ImportExport.jsx:671"}, "properties": {"repobilityId": "f4f98d2fcce03cda", "scanner": "scanner-primary", "fingerprint": "bf1a8c5ca495ced1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6b994f45bf3e04e7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/services/viewerService.js:57"}, "properties": {"repobilityId": "b63b485466aa06d1", "scanner": "scanner-primary", "fingerprint": "6b994f45bf3e04e7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-400c1bba34337b17", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/services/apiClient.js:336"}, "properties": {"repobilityId": "4f84b08142d595b8", "scanner": "scanner-primary", "fingerprint": "400c1bba34337b17", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9162e4cd6ee8e5ea", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/layouts/AdminLayout.jsx:68"}, "properties": {"repobilityId": "1157d8c19ffae59f", "scanner": "scanner-primary", "fingerprint": "9162e4cd6ee8e5ea", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b2ce14aceb2575d2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/layouts/CustomerLayout.jsx:65"}, "properties": {"repobilityId": "787ae779d5a0d974", "scanner": "scanner-primary", "fingerprint": "b2ce14aceb2575d2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e726e6ea3b2353e2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/server.js:414"}, "properties": {"repobilityId": "ec6c625862fd9ddc", "scanner": "scanner-primary", "fingerprint": "e726e6ea3b2353e2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-46ebf193cb54b68e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/middleware/cacheMiddleware.js:101"}, "properties": {"repobilityId": "9f8250be49264b55", "scanner": "scanner-primary", "fingerprint": "46ebf193cb54b68e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-eab43af336f52d6d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/extractSurabayaSits.js:21"}, "properties": {"repobilityId": "65ffbd8af2a8432c", "scanner": "scanner-primary", "fingerprint": "eab43af336f52d6d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7654e1e7dfe7c4a6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/setup.js:20"}, "properties": {"repobilityId": "af2cc149fca0add0", "scanner": "scanner-primary", "fingerprint": "7654e1e7dfe7c4a6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2323b3bd01c4d449", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/run-all-migrations.js:61"}, "properties": {"repobilityId": "2c4cbbda5bbdb2dd", "scanner": "scanner-primary", "fingerprint": "2323b3bd01c4d449", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-052672cd016df820", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrate_areas.js:12"}, "properties": {"repobilityId": "1b386e7d12e72454", "scanner": "scanner-primary", "fingerprint": "052672cd016df820", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-80f617e9a1943fbe", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/database.js:14"}, "properties": {"repobilityId": "88dbe00f9176577e", "scanner": "scanner-primary", "fingerprint": "80f617e9a1943fbe", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b62b86e617d3b166", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/connectionPool.js:60"}, "properties": {"repobilityId": "dac46565395c819b", "scanner": "scanner-primary", "fingerprint": "b62b86e617d3b166", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c73368e9070443d9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505c_add_playback_token_sessions.js:23"}, "properties": {"repobilityId": "3ab531bce36695ee", "scanner": "scanner-primary", "fingerprint": "c73368e9070443d9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9f221a5b8bcfe2cc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611b_add_billing_tables.js:25"}, "properties": {"repobilityId": "2dfdebfb76001392", "scanner": "scanner-primary", "fingerprint": "9f221a5b8bcfe2cc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-29159b16420c3b57", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_settings_table.js:16"}, "properties": {"repobilityId": "5c9df6938d32e81d", "scanner": "scanner-primary", "fingerprint": "29159b16420c3b57", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-db91fb5be985edbc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_watermark_settings.js:9"}, "properties": {"repobilityId": "10705b3cd8e60abf", "scanner": "scanner-primary", "fingerprint": "db91fb5be985edbc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0272dee76741160b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_grid_default_limit.js:21"}, "properties": {"repobilityId": "ee419f117b5c5848", "scanner": "scanner-primary", "fingerprint": "0272dee76741160b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ef8e0a9d0480a025", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260613_add_promo_codes.js:22"}, "properties": {"repobilityId": "81e005769bcb4ab4", "scanner": "scanner-primary", "fingerprint": "ef8e0a9d0480a025", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2ce72c70e555c0f7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_add_recording_segment_filename_index.js:24"}, "properties": {"repobilityId": "723960286ec32c7b", "scanner": "scanner-primary", "fingerprint": "2ce72c70e555c0f7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0263f9e3a14e22b7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260507_add_area_slug_indexes.js:40"}, "properties": {"repobilityId": "43865410e02a053d", "scanner": "scanner-primary", "fingerprint": "0263f9e3a14e22b7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ff64cf2d690fc187", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_runtime_state_and_history_retention.js:39"}, "properties": {"repobilityId": "8875755bc23a7589", "scanner": "scanner-primary", "fingerprint": "ff64cf2d690fc187", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3b189e16a31b0e30", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505b_add_playback_token_audit_and_share_keys.js:23"}, "properties": {"repobilityId": "82c22902398ee84c", "scanner": "scanner-primary", "fingerprint": "3b189e16a31b0e30", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-40f9614ca8686e8f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260522_add_camera_telegram_alert_state.js:18"}, "properties": {"repobilityId": "09749cb68939a5bf", "scanner": "scanner-primary", "fingerprint": "40f9614ca8686e8f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e65ccc3b32986ee1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_landing_page_settings.js:17"}, "properties": {"repobilityId": "fd32ec7b7bfe923b", "scanner": "scanner-primary", "fingerprint": "e65ccc3b32986ee1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cae78007dc4d15e5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_saweria_settings.js:14"}, "properties": {"repobilityId": "02c5054152008d78", "scanner": "scanner-primary", "fingerprint": "cae78007dc4d15e5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3a399f31294cadf2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_playback_viewer_sessions.js:16"}, "properties": {"repobilityId": "7e65005980fc5cc7", "scanner": "scanner-primary", "fingerprint": "3a399f31294cadf2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-127136c19710ad60", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/fix_thumbnail_paths.js:9"}, "properties": {"repobilityId": "f34dfdb1717e4c95", "scanner": "scanner-primary", "fingerprint": "127136c19710ad60", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c4c1254d3dd49c84", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_health_mode.js:13"}, "properties": {"repobilityId": "554522f1e39c5355", "scanner": "scanner-primary", "fingerprint": "c4c1254d3dd49c84", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7de7bf38aaa17b7b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_viewer_sessions.js:16"}, "properties": {"repobilityId": "e64a3508824a4391", "scanner": "scanner-primary", "fingerprint": "7de7bf38aaa17b7b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ba32cb065de9c4e6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260614b_add_voucher_orders.js:21"}, "properties": {"repobilityId": "f1243c05db3e1a29", "scanner": "scanner-primary", "fingerprint": "ba32cb065de9c4e6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2276ac814693ae61", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260612c_add_camera_is_public.js:20"}, "properties": {"repobilityId": "255a66e3bd3c3e1a", "scanner": "scanner-primary", "fingerprint": "2276ac814693ae61", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d312c2e3041f9eb8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_delivery_types.js:9"}, "properties": {"repobilityId": "24195a7288d97604", "scanner": "scanner-primary", "fingerprint": "d312c2e3041f9eb8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-87ad01bcacf45ba5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/backfill_camera_delivery_types.js:22"}, "properties": {"repobilityId": "510bba52604122d7", "scanner": "scanner-primary", "fingerprint": "87ad01bcacf45ba5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-903611edf089dbd1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_proxy_controls.js:14"}, "properties": {"repobilityId": "dad0e74e0828f4c2", "scanner": "scanner-primary", "fingerprint": "903611edf089dbd1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-eb781cbb3857f695", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611_add_subscriber_tenancy.js:24"}, "properties": {"repobilityId": "f23ac6f086a5be20", "scanner": "scanner-primary", "fingerprint": "eb781cbb3857f695", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-958fcdcd086920e4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_feedbacks_table.js:16"}, "properties": {"repobilityId": "7e58ac14e5e6158b", "scanner": "scanner-primary", "fingerprint": "958fcdcd086920e4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-137a069a39466411", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260513_add_playback_token_camera_rules.js:34"}, "properties": {"repobilityId": "8d6eaed32716ac57", "scanner": "scanner-primary", "fingerprint": "137a069a39466411", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b881ecda32872d27", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_analytics_indexes.js:24"}, "properties": {"repobilityId": "65016c6939f31958", "scanner": "scanner-primary", "fingerprint": "b881ecda32872d27", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-af2aba1e553a39c9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260614_add_voucher_access.js:29"}, "properties": {"repobilityId": "771597ded88f3e03", "scanner": "scanner-primary", "fingerprint": "af2aba1e553a39c9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1fc660fc62d73280", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_health_override.js:13"}, "properties": {"repobilityId": "f3781366bfe51c22", "scanner": "scanner-primary", "fingerprint": "1fc660fc62d73280", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d680c96d70ec5344", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260523_add_sponsor_packages_and_camera_limit.js:22"}, "properties": {"repobilityId": "0a43c0f8d2180559", "scanner": "scanner-primary", "fingerprint": "d680c96d70ec5344", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fed5ff2d071b7959", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_video_codec.js:19"}, "properties": {"repobilityId": "d53bb8500f4b9d21", "scanner": "scanner-primary", "fingerprint": "fed5ff2d071b7959", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-749808c4693be14b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260524_add_whatsapp_message_template.js:26"}, "properties": {"repobilityId": "45c20e3d035e123d", "scanner": "scanner-primary", "fingerprint": "749808c4693be14b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-47f649966b8f6550", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_online_status.js:15"}, "properties": {"repobilityId": "961f8c54594ea754", "scanner": "scanner-primary", "fingerprint": "47f649966b8f6550", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-301e22739cbc2ace", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_public_playback_controls.js:49"}, "properties": {"repobilityId": "8470d72a39dd2b85", "scanner": "scanner-primary", "fingerprint": "301e22739cbc2ace", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-259c2d1a327c2eb3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_coordinates.js:16"}, "properties": {"repobilityId": "0aeaaf22dde0d837", "scanner": "scanner-primary", "fingerprint": "259c2d1a327c2eb3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8f8dbc6f39ad5aa4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_coordinates.js:16"}, "properties": {"repobilityId": "76cb09a72a626d32", "scanner": "scanner-primary", "fingerprint": "8f8dbc6f39ad5aa4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4e024df78374de6c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260511_add_recording_recovery_diagnostics.js:44"}, "properties": {"repobilityId": "7b766855447bbf1e", "scanner": "scanner-primary", "fingerprint": "4e024df78374de6c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1e16b54f70c7f819", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_drop_failed_remux_files.js:18"}, "properties": {"repobilityId": "9f63c08f51d2d30c", "scanner": "scanner-primary", "fingerprint": "1e16b54f70c7f819", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-914f0e55a4feb593", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505_add_camera_view_stats.js:19"}, "properties": {"repobilityId": "0869f6f7c070bc86", "scanner": "scanner-primary", "fingerprint": "914f0e55a4feb593", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-022175184c194597", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_branding_settings.js:12"}, "properties": {"repobilityId": "a9848cea7ce1891e", "scanner": "scanner-primary", "fingerprint": "022175184c194597", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c3deadaa88aea6f5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_status.js:16"}, "properties": {"repobilityId": "d339dfd8eec27479", "scanner": "scanner-primary", "fingerprint": "c3deadaa88aea6f5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1a24098cc8f2dde5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/create_camera_discovery_table.js:12"}, "properties": {"repobilityId": "c4779bc81f05ee9f", "scanner": "scanner-primary", "fingerprint": "1a24098cc8f2dde5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-389d2d5b685ea0b6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_core_indexes.js:19"}, "properties": {"repobilityId": "c333f8367a1e7f42", "scanner": "scanner-primary", "fingerprint": "389d2d5b685ea0b6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ba9bb622b73ffe99", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_internal_ingest_policy.js:24"}, "properties": {"repobilityId": "b4134db3c1dba099", "scanner": "scanner-primary", "fingerprint": "ba9bb622b73ffe99", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-67734d504c575b17", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260517_add_recording_recovery_attempt_fields.js:28"}, "properties": {"repobilityId": "df8a72083280ce1c", "scanner": "scanner-primary", "fingerprint": "67734d504c575b17", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fc1b26d9e4559416", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260512_add_recording_segments_global_start_index.js:24"}, "properties": {"repobilityId": "da763c90c8692b49", "scanner": "scanner-primary", "fingerprint": "fc1b26d9e4559416", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8520bef3d534e600", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_thumbnail_path.js:9"}, "properties": {"repobilityId": "7202ead944afe074", "scanner": "scanner-primary", "fingerprint": "8520bef3d534e600", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2293d3851f48c049", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/001_migrate_security.js:11"}, "properties": {"repobilityId": "fe5bec11bc357ed1", "scanner": "scanner-primary", "fingerprint": "2293d3851f48c049", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-96019a608a48e3da", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_coverage_scope.js:13"}, "properties": {"repobilityId": "a22f6a1c1137a9d7", "scanner": "scanner-primary", "fingerprint": "96019a608a48e3da", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0a7a0daa78636876", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_area_grid_default_visibility.js:12"}, "properties": {"repobilityId": "2cc8dac0c3f01ce0", "scanner": "scanner-primary", "fingerprint": "0a7a0daa78636876", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7ee660bbb4b95929", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_stream_key.js:13"}, "properties": {"repobilityId": "afb9c8081dab3d9f", "scanner": "scanner-primary", "fingerprint": "7ee660bbb4b95929", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0293046ccaadaf90", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260611c_add_billing_plans.js:23"}, "properties": {"repobilityId": "bd71e07f00a3a139", "scanner": "scanner-primary", "fingerprint": "0293046ccaadaf90", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-809ce38db62a94fd", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_sponsor_fields.js:14"}, "properties": {"repobilityId": "443272314331222e", "scanner": "scanner-primary", "fingerprint": "809ce38db62a94fd", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a69252748d2c6450", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/create_recordings_table.js:12"}, "properties": {"repobilityId": "958aca93775dd504", "scanner": "scanner-primary", "fingerprint": "a69252748d2c6450", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-925c94c8f3336a98", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_recording_system.js:14"}, "properties": {"repobilityId": "897c9b773c10c9d9", "scanner": "scanner-primary", "fingerprint": "925c94c8f3336a98", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-46dafcae957d12e4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/202605110001_create_notification_diagnostic_runs.js:19"}, "properties": {"repobilityId": "c1a569b7e4457b9a", "scanner": "scanner-primary", "fingerprint": "46dafcae957d12e4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-23da1584d4721209", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_repair_recording_segment_timezone.js:154"}, "properties": {"repobilityId": "a303266be39ac9b8", "scanner": "scanner-primary", "fingerprint": "23da1584d4721209", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-68646427b507fd60", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260612_add_account_approval.js:22"}, "properties": {"repobilityId": "5d563bfcdcd8c34c", "scanner": "scanner-primary", "fingerprint": "68646427b507fd60", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e98becae29f0c40f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260505_add_playback_tokens.js:19"}, "properties": {"repobilityId": "247e444bd2c85bb4", "scanner": "scanner-primary", "fingerprint": "e98becae29f0c40f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-89038a41efb20756", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260503_add_recording_segment_uniqueness.js:47"}, "properties": {"repobilityId": "23d0301ab09de5ae", "scanner": "scanner-primary", "fingerprint": "89038a41efb20756", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2380e53174652a18", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260518_add_recording_maintenance_state.js:45"}, "properties": {"repobilityId": "95953c6f08f9efae", "scanner": "scanner-primary", "fingerprint": "2380e53174652a18", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2ada3343ae3c9cba", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_camera_thumbnail_strategy.js:17"}, "properties": {"repobilityId": "33f39b6be34d431d", "scanner": "scanner-primary", "fingerprint": "2ada3343ae3c9cba", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8af80fd1aaebbded", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_is_tunnel_field.js:16"}, "properties": {"repobilityId": "dcf008324293f3a1", "scanner": "scanner-primary", "fingerprint": "8af80fd1aaebbded", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-770c51fb666add5a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_internal_rtsp_transport_policy.js:32"}, "properties": {"repobilityId": "6623193795519a63", "scanner": "scanner-primary", "fingerprint": "770c51fb666add5a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-56e139da1ceb0388", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260510_add_camera_source_lifecycle.js:24"}, "properties": {"repobilityId": "57e1e33d97e53f0b", "scanner": "scanner-primary", "fingerprint": "56e139da1ceb0388", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-60664a84edcf0e3d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/zz_20260613b_add_payment_failure_reason.js:21"}, "properties": {"repobilityId": "46693e34ed8161a7", "scanner": "scanner-primary", "fingerprint": "60664a84edcf0e3d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7869ae99d9d169d1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_external_stream.js:15"}, "properties": {"repobilityId": "9d8c40391d1e3a45", "scanner": "scanner-primary", "fingerprint": "7869ae99d9d169d1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-73f9dc3a0d8dbc62", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/database/migrations/add_timezone_settings.js:22"}, "properties": {"repobilityId": "b0c27b4f25853bcb", "scanner": "scanner-primary", "fingerprint": "73f9dc3a0d8dbc62", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-135bdf554a6787cc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/routes/adminRoutes.js:236"}, "properties": {"repobilityId": "3b4c7c7f2e2bb146", "scanner": "scanner-primary", "fingerprint": "135bdf554a6787cc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-011880557c736be9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/controllers/recordingController.js:111"}, "properties": {"repobilityId": "edf2abbee6ba68e4", "scanner": "scanner-primary", "fingerprint": "011880557c736be9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d0228b09f1cdee69", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/telegramService.js:579"}, "properties": {"repobilityId": "12b1697c9b9fc366", "scanner": "scanner-primary", "fingerprint": "d0228b09f1cdee69", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1eb478a725df045f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/telegramBotService.js:60"}, "properties": {"repobilityId": "1206097c0ea75e18", "scanner": "scanner-primary", "fingerprint": "1eb478a725df045f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2695216e838e3ad4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/playbackViewerSessionService.js:139"}, "properties": {"repobilityId": "bc4451e9e5ef7d50", "scanner": "scanner-primary", "fingerprint": "2695216e838e3ad4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4746d23087110a73", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/mediaMtxService.js:62"}, "properties": {"repobilityId": "c0c79454cdec361d", "scanner": "scanner-primary", "fingerprint": "4746d23087110a73", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b6ca6b0231437324", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/securityAuditLogger.js:114"}, "properties": {"repobilityId": "e93d99dc96da3ae2", "scanner": "scanner-primary", "fingerprint": "b6ca6b0231437324", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2203657dabae8d4c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/billingService.js:431"}, "properties": {"repobilityId": "48ec5f73ca560806", "scanner": "scanner-primary", "fingerprint": "2203657dabae8d4c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-efc2a600b17f1ce1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/discoveryService.js:87"}, "properties": {"repobilityId": "980c797f0cf3a8b3", "scanner": "scanner-primary", "fingerprint": "efc2a600b17f1ce1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-507cec3e38866966", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/cacheService.js:193"}, "properties": {"repobilityId": "a03b38e42607c762", "scanner": "scanner-primary", "fingerprint": "507cec3e38866966", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-66b8fafd719bd9f3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/cameraService.js:1344"}, "properties": {"repobilityId": "6cd7c3a8c39cca02", "scanner": "scanner-primary", "fingerprint": "66b8fafd719bd9f3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-365e83a5eb106a8c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/streamWarmer.js:42"}, "properties": {"repobilityId": "693cbdb7c0b2386f", "scanner": "scanner-primary", "fingerprint": "365e83a5eb106a8c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-99f1e19cdf313061", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/viewerSessionService.js:139"}, "properties": {"repobilityId": "6a7a832753babeff", "scanner": "scanner-primary", "fingerprint": "99f1e19cdf313061", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4173daaeab53a13d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/setupNotificationService.js:50"}, "properties": {"repobilityId": "c364478a1cf471bd", "scanner": "scanner-primary", "fingerprint": "4173daaeab53a13d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3cfa12bfbcb3f62c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/recordingProcessManager.js:199"}, "properties": {"repobilityId": "aaf4fc120ca688c1", "scanner": "scanner-primary", "fingerprint": "3cfa12bfbcb3f62c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f9407f367727110d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/sessionManager.js:283"}, "properties": {"repobilityId": "815d4f7bf7a2b939", "scanner": "scanner-primary", "fingerprint": "f9407f367727110d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1724a77ee588f90f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/thumbnailService.js:42"}, "properties": {"repobilityId": "173ae1582017e51d", "scanner": "scanner-primary", "fingerprint": "1724a77ee588f90f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b795bf39e207eee6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/cameraHealthService.js:1242"}, "properties": {"repobilityId": "4297d2321ffb9ac8", "scanner": "scanner-primary", "fingerprint": "b795bf39e207eee6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8c4e357f161684ca", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/recordingService.js:147"}, "properties": {"repobilityId": "6c409f211cd1b022", "scanner": "scanner-primary", "fingerprint": "8c4e357f161684ca", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-71f5df32910fb528", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/areaService.js:203"}, "properties": {"repobilityId": "f9efe6190c4ff8fe", "scanner": "scanner-primary", "fingerprint": "71f5df32910fb528", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-83fa507c2acdd7c2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/services/scrapers/jogjaScraper.js:22"}, "properties": {"repobilityId": "5b6c1d09ade11db4", "scanner": "scanner-primary", "fingerprint": "83fa507c2acdd7c2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9ea10d9651be2274", "level": "warning", "message": {"text": "Privileged port 800 in use"}, "properties": {"repobilityId": "44d4dae1c94a9aca", "scanner": "scanner-primary", "fingerprint": "9ea10d9651be2274", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ea0faf563ebab4db", "level": "warning", "message": {"text": "Privileged port 554 in use"}, "properties": {"repobilityId": "6639d60eed047e74", "scanner": "scanner-primary", "fingerprint": "ea0faf563ebab4db", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/__tests__/customerCameraIpService.test.js"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-8987d6d1c30c7202", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "825746176d9c4e8a", "scanner": "scanner-primary", "fingerprint": "8987d6d1c30c7202", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-e39ae4bfd993828d", "level": "warning", "message": {"text": "Docker base image uses a mutable or implicit tag: alpine:latest"}, "properties": {"repobilityId": "46bc23a31e1f1196", "scanner": "scanner-primary", "fingerprint": "e39ae4bfd993828d", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-ef951b0789368a24", "level": "warning", "message": {"text": "Insecure pattern 'domparser_html_parse' in frontend/src/utils/sanitizePublicHtml.js:78"}, "properties": {"repobilityId": "1e1eb925bd13fe6d", "scanner": "scanner-primary", "fingerprint": "ef951b0789368a24", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "domparser_html_parse"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/utils/sanitizePublicHtml.js"}, "region": {"startLine": 78}}}]}, {"ruleId": "scanner-6b09be8eab66e992", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/AdBanner.jsx:44"}, "properties": {"repobilityId": "964f4d9d39452e79", "scanner": "scanner-primary", "fingerprint": "6b09be8eab66e992", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/AdBanner.jsx"}, "region": {"startLine": 44}}}]}, {"ruleId": "scanner-d828451808a80336", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/ads/InlineAdSlot.jsx:17"}, "properties": {"repobilityId": "553e4c5947746612", "scanner": "scanner-primary", "fingerprint": "d828451808a80336", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/ads/InlineAdSlot.jsx"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-f7b8a85414c7473c", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/components/ads/GlobalAdScript.jsx:13"}, "properties": {"repobilityId": "054eb52915cd551f", "scanner": "scanner-primary", "fingerprint": "f7b8a85414c7473c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/ads/GlobalAdScript.jsx"}, "region": {"startLine": 13}}}]}, {"ruleId": "scanner-de2b1a62fb5049a3", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/admin/settings/GeneralSettingsTab.jsx:193"}, "properties": {"repobilityId": "c851cbafb8bf6b5b", "scanner": "scanner-primary", "fingerprint": "de2b1a62fb5049a3", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/admin/settings/GeneralSettingsTab.jsx"}, "region": {"startLine": 193}}}]}, {"ruleId": "scanner-4b0a3f1e601e127a", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/components/landing/LandingHero.jsx:78"}, "properties": {"repobilityId": "c94a03c18052d852", "scanner": "scanner-primary", "fingerprint": "4b0a3f1e601e127a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/components/landing/LandingHero.jsx"}, "region": {"startLine": 78}}}]}, {"ruleId": "scanner-1d1c6d46d0ed2c20", "level": "warning", "message": {"text": "Insecure pattern 'weak_hash' in backend/__tests__/cameraHealthService.test.js:511"}, "properties": {"repobilityId": "0d53778076f3e64a", "scanner": "scanner-primary", "fingerprint": "1d1c6d46d0ed2c20", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "weak_hash"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/__tests__/cameraHealthService.test.js"}, "region": {"startLine": 511}}}]}, {"ruleId": "scanner-4f74bd680589c756", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/database/run-all-migrations.js:9"}, "properties": {"repobilityId": "cef79937b9766ef9", "scanner": "scanner-primary", "fingerprint": "4f74bd680589c756", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/database/run-all-migrations.js"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-1fee650ee7a3ab5e", "level": "error", "message": {"text": "Insecure pattern 'exec_used' in backend/services/recordingDiskSpaceService.js:17"}, "properties": {"repobilityId": "3239e604c1ec528b", "scanner": "scanner-primary", "fingerprint": "1fee650ee7a3ab5e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "exec_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/recordingDiskSpaceService.js"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-4cf36f920048d8d3", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingDiskSpaceService.js:8"}, "properties": {"repobilityId": "93f67a9bc12dd603", "scanner": "scanner-primary", "fingerprint": "4cf36f920048d8d3", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/recordingDiskSpaceService.js"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-df839bdd2030e1bf", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/services/surabayaSitsExtractor.js:7"}, "properties": {"repobilityId": "c5d78e2fde10c16e", "scanner": "scanner-primary", "fingerprint": "df839bdd2030e1bf", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/surabayaSitsExtractor.js"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-268d13a90c3f0c2f", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingRemuxer.js:7"}, "properties": {"repobilityId": "2775bf8d4c8eefb1", "scanner": "scanner-primary", "fingerprint": "268d13a90c3f0c2f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/recordingRemuxer.js"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-4f29d56c1065b57f", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingProcessManager.js:7"}, "properties": {"repobilityId": "45337860a39e7cc3", "scanner": "scanner-primary", "fingerprint": "4f29d56c1065b57f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/recordingProcessManager.js"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-6cbfe5eeb93f727b", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/services/thumbnailService.js:9"}, "properties": {"repobilityId": "1ee409200c798470", "scanner": "scanner-primary", "fingerprint": "6cbfe5eeb93f727b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/thumbnailService.js"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-75a393b8f2f99f6a", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingService.js:11"}, "properties": {"repobilityId": "becfd0804b034006", "scanner": "scanner-primary", "fingerprint": "75a393b8f2f99f6a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/recordingService.js"}, "region": {"startLine": 11}}}]}, {"ruleId": "scanner-d75ad3d2b203fb3c", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in backend/services/recordingMediaProbe.js:7"}, "properties": {"repobilityId": "0d23c1e267d0ce8f", "scanner": "scanner-primary", "fingerprint": "d75ad3d2b203fb3c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/services/recordingMediaProbe.js"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-dc04af509bf72b03", "level": "note", "message": {"text": "Very large file: frontend/src/components/MultiView/VideoPopup.jsx (1608 lines)"}, "properties": {"repobilityId": "fb8119f2f98b311e", "scanner": "scanner-primary", "fingerprint": "dc04af509bf72b03", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-5f1141664a1b11f9", "level": "note", "message": {"text": "Very large file: frontend/src/components/MultiView/MultiViewVideoItem.jsx (1196 lines)"}, "properties": {"repobilityId": "758bb064d954df30", "scanner": "scanner-primary", "fingerprint": "5f1141664a1b11f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-fa19ab53878f199d", "level": "note", "message": {"text": "Very large file: frontend/src/pages/AreaManagement.jsx (847 lines)"}, "properties": {"repobilityId": "f393172e16fdfe54", "scanner": "scanner-primary", "fingerprint": "fa19ab53878f199d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-2dd0dd335036c87d", "level": "note", "message": {"text": "Very large file: backend/__tests__/cameraHealthService.test.js (2286 lines)"}, "properties": {"repobilityId": "fc2b9c842c174687", "scanner": "scanner-primary", "fingerprint": "2dd0dd335036c87d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ee4b6edeb85e64aa", "level": "note", "message": {"text": "Very large file: backend/services/cameraService.js (3174 lines)"}, "properties": {"repobilityId": "05f65e9abb32210b", "scanner": "scanner-primary", "fingerprint": "ee4b6edeb85e64aa", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-f707ba2693546884", "level": "note", "message": {"text": "Very large file: backend/services/cameraHealthService.js (3697 lines)"}, "properties": {"repobilityId": "2b2c599aa9c6c324", "scanner": "scanner-primary", "fingerprint": "f707ba2693546884", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-7973408a417a674b", "level": "note", "message": {"text": "Very large file: backend/services/hlsProxyService.js (1581 lines)"}, "properties": {"repobilityId": "32d5b4c68b7c544b", "scanner": "scanner-primary", "fingerprint": "7973408a417a674b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-0e8a76eb13fd3249", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: frontend/package.json"}, "properties": {"repobilityId": "d8c65da5b68ee95b", "scanner": "scanner-primary", "fingerprint": "0e8a76eb13fd3249", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3a092b5c39e242a1", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: backend/package.json"}, "properties": {"repobilityId": "fc853e57ce7048c4", "scanner": "scanner-primary", "fingerprint": "3a092b5c39e242a1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "eb764c63e28abeef", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "a6406ea809235dc3", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "2c2e2b88592a3cd9", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "647caa41d6214d47", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "a4010653714d7eb8", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "8637df6eecd1d53b", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "75fcd409661f6995", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "f56220f4aa3634d9", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-e725d2ab884fbd49", "level": "note", "message": {"text": "Multiple root agent instruction files without precedence"}, "properties": {"repobilityId": "1953db6c89508d22", "scanner": "scanner-primary", "fingerprint": "e725d2ab884fbd49", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["agent-instructions", "governance"]}}, {"ruleId": "scanner-8cc43e52f0615b39", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/vite.config.js:7"}, "properties": {"repobilityId": "ea9e4bcbd2b59059", "scanner": "scanner-primary", "fingerprint": "8cc43e52f0615b39", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-79c6c63a49af24d0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/public/meta-config.js:190"}, "properties": {"repobilityId": "9fba3f3562315e07", "scanner": "scanner-primary", "fingerprint": "79c6c63a49af24d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bd58c136007ce526", "level": "none", "message": {"text": "Commented-code block (8 lines) in frontend/public/sw.js:80"}, "properties": {"repobilityId": "5518427077dec88c", "scanner": "scanner-primary", "fingerprint": "bd58c136007ce526", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-31b4b2db9641d0f4", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/src/utils/publicPopupLayout.js:59"}, "properties": {"repobilityId": "5d34022940b57114", "scanner": "scanner-primary", "fingerprint": "31b4b2db9641d0f4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1d74d6d93fd5845f", "level": "note", "message": {"text": "Legacy-named symbol `withLegacy` in frontend/src/utils/publicPopupLayout.test.js:222"}, "properties": {"repobilityId": "bbc538f6296bda29", "scanner": "scanner-primary", "fingerprint": "1d74d6d93fd5845f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f535df574b46898a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/utils/connectionTester.js:51"}, "properties": {"repobilityId": "7270612bad652414", "scanner": "scanner-primary", "fingerprint": "f535df574b46898a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f4edef90aeac878f", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/utils/directStreamHelper.js:27"}, "properties": {"repobilityId": "a06f93556e643b97", "scanner": "scanner-primary", "fingerprint": "f4edef90aeac878f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0a6d053138b53063", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/LayoutToggleFAB.jsx:4"}, "properties": {"repobilityId": "b0a063234fa9647f", "scanner": "scanner-primary", "fingerprint": "0a6d053138b53063", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0115f5d90057df5e", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/src/components/MultiView/MultiViewButton.jsx:12"}, "properties": {"repobilityId": "a03057afb47445d0", "scanner": "scanner-primary", "fingerprint": "0115f5d90057df5e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0938c1d799ce18d6", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.test.jsx:156"}, "properties": {"repobilityId": "4dffda9d82075e87", "scanner": "scanner-primary", "fingerprint": "0938c1d799ce18d6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d0f68c4f38dbff76", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.stability.test.js:171"}, "properties": {"repobilityId": "3a0c67c296dd49e6", "scanner": "scanner-primary", "fingerprint": "d0f68c4f38dbff76", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dccd2ba6aca026af", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/VideoPopup.jsx:181"}, "properties": {"repobilityId": "91487c431ae41c7d", "scanner": "scanner-primary", "fingerprint": "dccd2ba6aca026af", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-945d2691bb9e32ca", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/MultiView/MultiViewVideoItem.jsx:78"}, "properties": {"repobilityId": "54b5e67cdee969e6", "scanner": "scanner-primary", "fingerprint": "945d2691bb9e32ca", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2c6c4af8f18659f0", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/src/components/landing/LandingCamerasSection.jsx:228"}, "properties": {"repobilityId": "6a8611b9a0c8eb3f", "scanner": "scanner-primary", "fingerprint": "2c6c4af8f18659f0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7cbf64a543315fc4", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/hooks/admin/useCameraManagementPage.js:196"}, "properties": {"repobilityId": "7bcbb6b33ddd438a", "scanner": "scanner-primary", "fingerprint": "7cbf64a543315fc4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5e0a0a2836be25f9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/hooks/admin/useCameraManagementPage.js:51"}, "properties": {"repobilityId": "84b97da0099b14a6", "scanner": "scanner-primary", "fingerprint": "5e0a0a2836be25f9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6b264a6645187364", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/server.js:18"}, "properties": {"repobilityId": "5639b42145223f1b", "scanner": "scanner-primary", "fingerprint": "6b264a6645187364", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-681986dd32c82130", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/__tests__/cameraHealthService.test.js:128"}, "properties": {"repobilityId": "a23b28b03eff4100", "scanner": "scanner-primary", "fingerprint": "681986dd32c82130", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3b3ac70ee4a066d0", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/__tests__/externalStreamProxyRoutes.test.js:271"}, "properties": {"repobilityId": "f8c3c2117baf5da6", "scanner": "scanner-primary", "fingerprint": "3b3ac70ee4a066d0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3c162eb606d83c8a", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/__tests__/streamService.test.js:110"}, "properties": {"repobilityId": "2028ee9d686e1620", "scanner": "scanner-primary", "fingerprint": "3c162eb606d83c8a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-21ba2a3ebcfc86c3", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/__tests__/recordingPlaybackService.test.js:350"}, "properties": {"repobilityId": "2bfbb1142e41bb74", "scanner": "scanner-primary", "fingerprint": "21ba2a3ebcfc86c3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7435bdb7fd9ea8f7", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/__tests__/externalStreamProxyRoutes.viewerSession.stability.test.js:89"}, "properties": {"repobilityId": "a8344c9582d2c51c", "scanner": "scanner-primary", "fingerprint": "7435bdb7fd9ea8f7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5ef37fcac83f44a0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/__tests__/externalStreamProxyRoutes.importIntegrity.test.js:127"}, "properties": {"repobilityId": "5e32e0217a98b3a6", "scanner": "scanner-primary", "fingerprint": "5ef37fcac83f44a0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b0e3b075cbca8e29", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/config/constants.js:9"}, "properties": {"repobilityId": "d5062be445ef56f5", "scanner": "scanner-primary", "fingerprint": "b0e3b075cbca8e29", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cb213a532c597c19", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/middleware/schemaValidators.js:845"}, "properties": {"repobilityId": "7cd4667e5326e6e0", "scanner": "scanner-primary", "fingerprint": "cb213a532c597c19", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-70596770ad5c14e8", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/middleware/apiKeyValidator.js:41"}, "properties": {"repobilityId": "2a5c4e47b82e416f", "scanner": "scanner-primary", "fingerprint": "70596770ad5c14e8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9f52a7addf2c69cf", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/database/database.js:41"}, "properties": {"repobilityId": "73e62269b32835aa", "scanner": "scanner-primary", "fingerprint": "9f52a7addf2c69cf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b09fa6ef6ddff9b9", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/database/migrations/zz_20260518_drop_failed_remux_files.js:1"}, "properties": {"repobilityId": "8923cf589094422f", "scanner": "scanner-primary", "fingerprint": "b09fa6ef6ddff9b9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6d7e02f54b1ce5ce", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/database/migrations/add_sponsor_fields.js:57"}, "properties": {"repobilityId": "a9b4f5f48d58ee48", "scanner": "scanner-primary", "fingerprint": "6d7e02f54b1ce5ce", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d82e2eedeabc2dbd", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/database/migrations/zz_20260503_add_recording_segment_uniqueness.js:1"}, "properties": {"repobilityId": "c69861cf1ba29b33", "scanner": "scanner-primary", "fingerprint": "d82e2eedeabc2dbd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e318da7b9869cf80", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/routes/hlsProxyRoutes.js:71"}, "properties": {"repobilityId": "89dda09c1a561a90", "scanner": "scanner-primary", "fingerprint": "e318da7b9869cf80", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1a0b63c7ea1d9631", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/controllers/playbackTokenController.js:39"}, "properties": {"repobilityId": "52be03d97905d8d8", "scanner": "scanner-primary", "fingerprint": "1a0b63c7ea1d9631", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-db263c6aaf242f6b", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/telegramService.js:173"}, "properties": {"repobilityId": "cebdbc17121bfd2b", "scanner": "scanner-primary", "fingerprint": "db263c6aaf242f6b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-09000f3f761fdffe", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/billingPlanService.js:417"}, "properties": {"repobilityId": "7782486d725a595e", "scanner": "scanner-primary", "fingerprint": "09000f3f761fdffe", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-93a637e3fe732a9a", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/streamService.js:35"}, "properties": {"repobilityId": "03e750fff4e9a37d", "scanner": "scanner-primary", "fingerprint": "93a637e3fe732a9a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e45c247c7e59fa13", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/services/telegramBotService.js:24"}, "properties": {"repobilityId": "031dcaed6bcfd64d", "scanner": "scanner-primary", "fingerprint": "e45c247c7e59fa13", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5ba7a06a4bf90c89", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingPaths.js:1"}, "properties": {"repobilityId": "7d955c189979939a", "scanner": "scanner-primary", "fingerprint": "5ba7a06a4bf90c89", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-64194ea4a134411c", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/services/recordingRecoveryRunner.js:1"}, "properties": {"repobilityId": "7a74bb3f1011ce7f", "scanner": "scanner-primary", "fingerprint": "64194ea4a134411c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-597c24bab5c1b048", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingStderrParser.js:1"}, "properties": {"repobilityId": "aa18bd177266359d", "scanner": "scanner-primary", "fingerprint": "597c24bab5c1b048", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c42a88f437f97fbe", "level": "none", "message": {"text": "Commented-code block (10 lines) in backend/services/recordingMaintenanceCoordinator.js:1"}, "properties": {"repobilityId": "773b72045d781d37", "scanner": "scanner-primary", "fingerprint": "c42a88f437f97fbe", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-79117a73bb246d21", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/services/recordingStarter.js:1"}, "properties": {"repobilityId": "7f4fc2fa07fca6e1", "scanner": "scanner-primary", "fingerprint": "79117a73bb246d21", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2727af7d40c2db88", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/cameraRuntimeStateService.js:22"}, "properties": {"repobilityId": "5faa149e29314ca5", "scanner": "scanner-primary", "fingerprint": "2727af7d40c2db88", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0ba868af8db0e853", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/paymentService.js:209"}, "properties": {"repobilityId": "194324517ef212b6", "scanner": "scanner-primary", "fingerprint": "0ba868af8db0e853", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1144c947f35ddc84", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/paymentService.js:418"}, "properties": {"repobilityId": "aab45b4fca15217d", "scanner": "scanner-primary", "fingerprint": "1144c947f35ddc84", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fcf8e7a413879da7", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingLifecycleReconciler.js:1"}, "properties": {"repobilityId": "ff782c1677d9034b", "scanner": "scanner-primary", "fingerprint": "fcf8e7a413879da7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-263667211e55b9c5", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/services/recordingHealthMonitor.js:1"}, "properties": {"repobilityId": "a3de985d0dff8784", "scanner": "scanner-primary", "fingerprint": "263667211e55b9c5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-100444f079b453f7", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingRemuxer.js:1"}, "properties": {"repobilityId": "32f7e3bb1250dac3", "scanner": "scanner-primary", "fingerprint": "100444f079b453f7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-063cab50a1c3c07d", "level": "none", "message": {"text": "Commented-code block (9 lines) in backend/services/recordingRecoveryService.js:1"}, "properties": {"repobilityId": "126e0320a4f56090", "scanner": "scanner-primary", "fingerprint": "063cab50a1c3c07d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6ae4fe0183b66bc8", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/services/recordingCleanupShared.js:1"}, "properties": {"repobilityId": "b74392a936fce111", "scanner": "scanner-primary", "fingerprint": "6ae4fe0183b66bc8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cbc1665ad817a6e6", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/customerCameraService.js:24"}, "properties": {"repobilityId": "407813f4ccb3b303", "scanner": "scanner-primary", "fingerprint": "cbc1665ad817a6e6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-06491b0a5977c70c", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/paymentSettingsService.js:34"}, "properties": {"repobilityId": "75db438df13d56f0", "scanner": "scanner-primary", "fingerprint": "06491b0a5977c70c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0187b4498e2c0119", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/voucherService.js:514"}, "properties": {"repobilityId": "461dab4a344ccde7", "scanner": "scanner-primary", "fingerprint": "0187b4498e2c0119", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b946bb61d00a45f0", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/viewerSessionService.js:121"}, "properties": {"repobilityId": "c110e5b7765a3db3", "scanner": "scanner-primary", "fingerprint": "b946bb61d00a45f0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f1bf478c1aac05ec", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/setupNotificationService.js:82"}, "properties": {"repobilityId": "187e9330b660e4f4", "scanner": "scanner-primary", "fingerprint": "f1bf478c1aac05ec", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ce7c0f8e51cc34d8", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingProcessManager.js:1"}, "properties": {"repobilityId": "a08d691ef7ca009c", "scanner": "scanner-primary", "fingerprint": "ce7c0f8e51cc34d8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-864d8d801d579d56", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingLifecyclePolicy.js:1"}, "properties": {"repobilityId": "dcb197a31696eebe", "scanner": "scanner-primary", "fingerprint": "864d8d801d579d56", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-244180d27bd435ba", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/services/recordingFilesystemOrphanCleanup.js:1"}, "properties": {"repobilityId": "a9c2cb638a67bf81", "scanner": "scanner-primary", "fingerprint": "244180d27bd435ba", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ab10e6f5a9e90e0c", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingExpiredDbSegmentCleanup.js:1"}, "properties": {"repobilityId": "78764e3fa91487f2", "scanner": "scanner-primary", "fingerprint": "ab10e6f5a9e90e0c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2c740d8e7a183597", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/services/recordingHealthAlertService.js:1"}, "properties": {"repobilityId": "8d6779eb82afb119", "scanner": "scanner-primary", "fingerprint": "2c740d8e7a183597", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b844ca4d18bd6969", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/services/recordingHealthDashboardService.js:1"}, "properties": {"repobilityId": "b27200ee97b38c07", "scanner": "scanner-primary", "fingerprint": "b844ca4d18bd6969", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-53266f6081cdf9f4", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/services/cameraHealthService.js:197"}, "properties": {"repobilityId": "2580d819b0c4a71b", "scanner": "scanner-primary", "fingerprint": "53266f6081cdf9f4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b2a6c518476debe0", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/services/recordingIntervalsPolicy.js:1"}, "properties": {"repobilityId": "02a9a51217f68ab1", "scanner": "scanner-primary", "fingerprint": "b2a6c518476debe0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c8a5ee454d6dbe58", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/services/recordingAutoStarter.js:1"}, "properties": {"repobilityId": "b9e0b719d56b41df", "scanner": "scanner-primary", "fingerprint": "c8a5ee454d6dbe58", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e0a7ccff5b8adde4", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/services/recordingService.js:113"}, "properties": {"repobilityId": "1e2428bbc6cae64e", "scanner": "scanner-primary", "fingerprint": "e0a7ccff5b8adde4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1fd53a61af16442e", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/services/recordingRecoveryQueue.js:1"}, "properties": {"repobilityId": "90a63f8c98568db7", "scanner": "scanner-primary", "fingerprint": "1fd53a61af16442e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6e24d0039e1c5bdd", "level": "none", "message": {"text": "Commented-code block (12 lines) in backend/services/hlsProxyService.js:811"}, "properties": {"repobilityId": "f2571686ca4726dc", "scanner": "scanner-primary", "fingerprint": "6e24d0039e1c5bdd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b589d4a4c15ad3b6", "level": "none", "message": {"text": "Commented-code block (16 lines) in backend/services/externalStreamProxyService.js:45"}, "properties": {"repobilityId": "f20581823755e5e2", "scanner": "scanner-primary", "fingerprint": "b589d4a4c15ad3b6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-792bec58a66ec446", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/services/externalStreamProxyService.js:111"}, "properties": {"repobilityId": "d8aa4f34fd4a3084", "scanner": "scanner-primary", "fingerprint": "792bec58a66ec446", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-42eaf2969a6a5f1d", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/services/recordingPlaybackService.js:282"}, "properties": {"repobilityId": "e6bdc721afef5055", "scanner": "scanner-primary", "fingerprint": "42eaf2969a6a5f1d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-226522e03cfab62d", "level": "note", "message": {"text": "45 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "147ecc9c5b87abb5", "scanner": "scanner-primary", "fingerprint": "226522e03cfab62d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-46fb4cc685716211", "level": "warning", "message": {"text": "Frontend route `/area/:areaSlug` has no Link/navigate to it \u2014 frontend/src/pages/AreaPublicPage.test.jsx"}, "properties": {"repobilityId": "332c9b9513309998", "scanner": "scanner-primary", "fingerprint": "46fb4cc685716211", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-29c22f6d06c67d25", "level": "warning", "message": {"text": "Frontend route `/playback` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "eef1942249b7ba7b", "scanner": "scanner-primary", "fingerprint": "29c22f6d06c67d25", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e51da000b1ec1444", "level": "warning", "message": {"text": "Frontend route `/admin` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "8276c7ee996625af", "scanner": "scanner-primary", "fingerprint": "e51da000b1ec1444", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-d5ecfb1bd4d970ce", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:9997/v3/paths/list (backend/routes/adminRoutes.js:139)"}, "properties": {"repobilityId": "0ad059059684f125", "scanner": "scanner-primary", "fingerprint": "d5ecfb1bd4d970ce", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-ebf58d2a5bb34c6f", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:9997/v3/config/paths/list (backend/routes/adminRoutes.js:184)"}, "properties": {"repobilityId": "b30fff6e20a2d8e0", "scanner": "scanner-primary", "fingerprint": "ebf58d2a5bb34c6f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-6284df49598767d0", "level": "error", "message": {"text": "Dangling fetch: GET http://cariloka.com/atcscctvindon/cctvatcsindonlengkap/soloCCTV.json (backend/services/cameraService.js:2641)"}, "properties": {"repobilityId": "97fbfcaa3b45892a", "scanner": "scanner-primary", "fingerprint": "6284df49598767d0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-5f54b81fc135abff", "level": "error", "message": {"text": "Dangling fetch: GET https://cctv.jombangkab.go.id/v2/ (backend/services/cameraService.js:2684)"}, "properties": {"repobilityId": "f99045a8708685f9", "scanner": "scanner-primary", "fingerprint": "5f54b81fc135abff", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-67d28fa8cd6bb12f", "level": "note", "message": {"text": "Unused endpoint: PUT /"}, "properties": {"repobilityId": "35b9a00876ce5950", "scanner": "scanner-primary", "fingerprint": "67d28fa8cd6bb12f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f2227339ba6f0744", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/settings/timezone"}, "properties": {"repobilityId": "52815ca5a3143715", "scanner": "scanner-primary", "fingerprint": "f2227339ba6f0744", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-97e3067dbb71e985", "level": "note", "message": {"text": "Unused endpoint: PUT /api/admin/settings/timezone"}, "properties": {"repobilityId": "f670a022af06d2b6", "scanner": "scanner-primary", "fingerprint": "97e3067dbb71e985", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5dbcb694eaa1507a", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/backup/export"}, "properties": {"repobilityId": "2df85f32a3204577", "scanner": "scanner-primary", "fingerprint": "5dbcb694eaa1507a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9afa784f9e37c190", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/backup/preview"}, "properties": {"repobilityId": "68271f9a039a0bd7", "scanner": "scanner-primary", "fingerprint": "9afa784f9e37c190", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9aa11ff6c9abc165", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/backup/import"}, "properties": {"repobilityId": "c42d9ce0bb499bd6", "scanner": "scanner-primary", "fingerprint": "9aa11ff6c9abc165", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-27dc99e37647a00c", "level": "note", "message": {"text": "Unused endpoint: PUT /api/settings/landing_area_coverage"}, "properties": {"repobilityId": "faf899cdcd948130", "scanner": "scanner-primary", "fingerprint": "27dc99e37647a00c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-303d7e4d4443ca89", "level": "note", "message": {"text": "Unused endpoint: PUT /api/settings/landing_hero_badge"}, "properties": {"repobilityId": "d14cc2a7ef43a394", "scanner": "scanner-primary", "fingerprint": "303d7e4d4443ca89", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-86e22efc7fa89e42", "level": "note", "message": {"text": "Unused endpoint: PUT /api/settings/landing_section_title"}, "properties": {"repobilityId": "0ff79d16468b6f1a", "scanner": "scanner-primary", "fingerprint": "86e22efc7fa89e42", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4b7db9b556b4e709", "level": "note", "message": {"text": "Unused endpoint: GET /api/settings/timezone"}, "properties": {"repobilityId": "7c0b7eb41b28d53b", "scanner": "scanner-primary", "fingerprint": "4b7db9b556b4e709", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0ea970b5f55020de", "level": "note", "message": {"text": "Unused endpoint: GET /api/stream"}, "properties": {"repobilityId": "6a54363ddebc2c71", "scanner": "scanner-primary", "fingerprint": "0ea970b5f55020de", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6daa54d9802f3950", "level": "note", "message": {"text": "Unused endpoint: GET /api/settings/map-center"}, "properties": {"repobilityId": "3f4cd8ae8a892ce6", "scanner": "scanner-primary", "fingerprint": "6daa54d9802f3950", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bdb5b9c4ac73a300", "level": "note", "message": {"text": "Unused endpoint: GET /api/settings/landing-page"}, "properties": {"repobilityId": "c1efa86a00866c56", "scanner": "scanner-primary", "fingerprint": "bdb5b9c4ac73a300", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2d1ddd4b07a45aef", "level": "note", "message": {"text": "Unused endpoint: GET /api/settings/public-ads"}, "properties": {"repobilityId": "5c4d1e18739d83f7", "scanner": "scanner-primary", "fingerprint": "2d1ddd4b07a45aef", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-379b09f9de636500", "level": "note", "message": {"text": "Unused endpoint: GET /api/settings"}, "properties": {"repobilityId": "7fed6a0727287cd7", "scanner": "scanner-primary", "fingerprint": "379b09f9de636500", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3855bce018689ebc", "level": "note", "message": {"text": "Unused endpoint: PUT /api/settings/map_default_center"}, "properties": {"repobilityId": "46a7fe57707f01ed", "scanner": "scanner-primary", "fingerprint": "3855bce018689ebc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dc0512bb01741d78", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/cameras"}, "properties": {"repobilityId": "ca2b75397a7cea1f", "scanner": "scanner-primary", "fingerprint": "dc0512bb01741d78", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ae9ca89227c3fbf4", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/summary"}, "properties": {"repobilityId": "95402408c8aed0fc", "scanner": "scanner-primary", "fingerprint": "ae9ca89227c3fbf4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4d2e0afd9c489581", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/wallet"}, "properties": {"repobilityId": "33b23b25cbaf6f04", "scanner": "scanner-primary", "fingerprint": "4d2e0afd9c489581", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fc94bc1c148afcfc", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/payments"}, "properties": {"repobilityId": "c53e00dad706566e", "scanner": "scanner-primary", "fingerprint": "fc94bc1c148afcfc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d3b1b04f7dac8ba3", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/payment-options"}, "properties": {"repobilityId": "8addf6480bab012c", "scanner": "scanner-primary", "fingerprint": "d3b1b04f7dac8ba3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-28362f452a5b49b8", "level": "note", "message": {"text": "Unused endpoint: POST /api/customer/topup"}, "properties": {"repobilityId": "56c1c9d51ca7c6e6", "scanner": "scanner-primary", "fingerprint": "28362f452a5b49b8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d615918e7d8d61f5", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/promo/validate"}, "properties": {"repobilityId": "cbf1e98547d74508", "scanner": "scanner-primary", "fingerprint": "d615918e7d8d61f5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8d4ad8fb2a32cd9e", "level": "note", "message": {"text": "Unused endpoint: POST /api/customer/promo/redeem"}, "properties": {"repobilityId": "a39cfe02dd7a96bf", "scanner": "scanner-primary", "fingerprint": "8d4ad8fb2a32cd9e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-94c3395076d13dda", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/plan"}, "properties": {"repobilityId": "980fda0230b8dc4a", "scanner": "scanner-primary", "fingerprint": "94c3395076d13dda", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2881ea5303f38556", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/plans"}, "properties": {"repobilityId": "71c22f0c22620936", "scanner": "scanner-primary", "fingerprint": "2881ea5303f38556", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a5085729b9e46cc8", "level": "note", "message": {"text": "Unused endpoint: POST /api/customer/plan"}, "properties": {"repobilityId": "14adef0eacc815b5", "scanner": "scanner-primary", "fingerprint": "a5085729b9e46cc8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d140d27d4767af32", "level": "note", "message": {"text": "Unused endpoint: POST /api/customer/cameras"}, "properties": {"repobilityId": "de276122690d40ab", "scanner": "scanner-primary", "fingerprint": "d140d27d4767af32", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8ed0dbbe548e6c92", "level": "note", "message": {"text": "Unused endpoint: GET /api/customer/areas"}, "properties": {"repobilityId": "9dd1d6d9d6d74bf1", "scanner": "scanner-primary", "fingerprint": "8ed0dbbe548e6c92", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd55aa0818a7c897", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/login"}, "properties": {"repobilityId": "85a72bfafde98822", "scanner": "scanner-primary", "fingerprint": "fd55aa0818a7c897", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a5b3437e64c8f7b4", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/register"}, "properties": {"repobilityId": "ad40cd49ae49d490", "scanner": "scanner-primary", "fingerprint": "a5b3437e64c8f7b4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-208f088dc8233edd", "level": "note", "message": {"text": "Unused endpoint: GET /api/auth/register-info"}, "properties": {"repobilityId": "ecba22277e5ae0a1", "scanner": "scanner-primary", "fingerprint": "208f088dc8233edd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d5a39262ac205120", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/logout"}, "properties": {"repobilityId": "ad8bc8ccd6901032", "scanner": "scanner-primary", "fingerprint": "d5a39262ac205120", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-49ac19bb61ef30a3", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/refresh"}, "properties": {"repobilityId": "b7f04090e998a112", "scanner": "scanner-primary", "fingerprint": "49ac19bb61ef30a3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-33a5daa01dd022c8", "level": "note", "message": {"text": "Unused endpoint: GET /api/auth/verify"}, "properties": {"repobilityId": "f91367124fcaa4bd", "scanner": "scanner-primary", "fingerprint": "33a5daa01dd022c8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fdf125fe0eae374a", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/customers"}, "properties": {"repobilityId": "646588d5a7d7a767", "scanner": "scanner-primary", "fingerprint": "fdf125fe0eae374a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4b4c2ed8661c1d8b", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/billing/topup-manual"}, "properties": {"repobilityId": "ba802f32601c09d2", "scanner": "scanner-primary", "fingerprint": "4b4c2ed8661c1d8b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-25a4f1174ced6380", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/billing/wallet-adjust"}, "properties": {"repobilityId": "95da57c2c6b2eb5d", "scanner": "scanner-primary", "fingerprint": "25a4f1174ced6380", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1aa7a60fcc0a7d8c", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/subscriptions"}, "properties": {"repobilityId": "5204f62acefde4b7", "scanner": "scanner-primary", "fingerprint": "1aa7a60fcc0a7d8c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-61aca3d8035d00cb", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/billing/subscriptions"}, "properties": {"repobilityId": "6ee04bfb89578ac0", "scanner": "scanner-primary", "fingerprint": "61aca3d8035d00cb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a7e2387e6a23b925", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/payments"}, "properties": {"repobilityId": "6d2ed76cad45e5b7", "scanner": "scanner-primary", "fingerprint": "a7e2387e6a23b925", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-240441c5e44f7087", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/billing/charges/run"}, "properties": {"repobilityId": "9a142327f5988655", "scanner": "scanner-primary", "fingerprint": "240441c5e44f7087", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b35e8364bbb6e0e1", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/plans"}, "properties": {"repobilityId": "4165b44804226130", "scanner": "scanner-primary", "fingerprint": "b35e8364bbb6e0e1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-91ec3ed2c835df30", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/billing/plans"}, "properties": {"repobilityId": "b4c5f0154d727246", "scanner": "scanner-primary", "fingerprint": "91ec3ed2c835df30", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1e78e13f07d24c95", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/payment-gateway"}, "properties": {"repobilityId": "91e4918115ab430a", "scanner": "scanner-primary", "fingerprint": "1e78e13f07d24c95", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-34b6c956709f05a4", "level": "note", "message": {"text": "Unused endpoint: PUT /api/admin/billing/payment-gateway"}, "properties": {"repobilityId": "6f620bdb61156386", "scanner": "scanner-primary", "fingerprint": "34b6c956709f05a4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-330b23379b2d18ff", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/billing/payment-gateway/test"}, "properties": {"repobilityId": "f4fede45ff44178d", "scanner": "scanner-primary", "fingerprint": "330b23379b2d18ff", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8a96b7338d292dce", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/payment-gateway/channels"}, "properties": {"repobilityId": "98bc1465c61d9ef4", "scanner": "scanner-primary", "fingerprint": "8a96b7338d292dce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0c19982634a0a361", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/camera-ips"}, "properties": {"repobilityId": "4a81a6930b564c6f", "scanner": "scanner-primary", "fingerprint": "0c19982634a0a361", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-11b62f3abeb23142", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/billing/promos"}, "properties": {"repobilityId": "0582183eadcf13b8", "scanner": "scanner-primary", "fingerprint": "11b62f3abeb23142", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}