{"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-9a7f9c7514092a03", "name": "`truncate` class without `title=` for hover reveal \u2014 App.tsx:231", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 App.tsx:231"}, "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-57d1d596415c50a8", "name": "Stray `console.log` in TS/JS \u2014 geminiService.ts:890", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 geminiService.ts:890"}, "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-fd4c44615045d4c5", "name": "`truncate` class without `title=` for hover reveal \u2014 components/ClientsList.tsx:164", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ClientsList.tsx:164"}, "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-4942c6bf74ee163f", "name": "`truncate` class without `title=` for hover reveal \u2014 components/WorkroomDashboard.tsx:146", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/WorkroomDashboard.tsx:146"}, "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-ace53590d5d4e712", "name": "`truncate` class without `title=` for hover reveal \u2014 components/ComboPicker.tsx:74", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ComboPicker.tsx:74"}, "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-3251c4a6fa1bed01", "name": "`truncate` class without `title=` for hover reveal \u2014 components/MessagesList.tsx:247", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/MessagesList.tsx:247"}, "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-434ef9e869f46e94", "name": "`truncate` class without `title=` for hover reveal \u2014 components/Inventory.tsx:205", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Inventory.tsx:205"}, "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-a836fecdff6ea298", "name": "`truncate` class without `title=` for hover reveal \u2014 components/TechAnalytics.tsx:99", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/TechAnalytics.tsx: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-61c011525dcfecec", "name": "`truncate` class without `title=` for hover reveal \u2014 components/JobWizard.tsx:323", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/JobWizard.tsx:323"}, "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-857f5f90a274f0ed", "name": "`truncate` class without `title=` for hover reveal \u2014 components/Dashboard.tsx:741", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Dashboard.tsx:741"}, "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-6a826b6797c9f547", "name": "`truncate` class without `title=` for hover reveal \u2014 components/JobsList.tsx:192", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/JobsList.tsx:192"}, "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-35fd0ca88e4edd54", "name": "`truncate` class without `title=` for hover reveal \u2014 components/Accounting.tsx:455", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Accounting.tsx:455"}, "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-59c6de0ddb67438d", "name": "`truncate` class without `title=` for hover reveal \u2014 components/Sidebar.tsx:108", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Sidebar.tsx:108"}, "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-e006c9fa9b58fa3c", "name": "`truncate` class without `title=` for hover reveal \u2014 components/AutoKey.tsx:208", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AutoKey.tsx:208"}, "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-a3bc527465c38f54", "name": "`truncate` class without `title=` for hover reveal \u2014 components/TechPicker.tsx:109", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/TechPicker.tsx:109"}, "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-9fa997e0a3f350f0", "name": "`truncate` class without `title=` for hover reveal \u2014 components/Settings.tsx:626", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Settings.tsx:626"}, "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-4417c9ed0333d9f5", "name": "`truncate` class without `title=` for hover reveal \u2014 components/JobDetail.tsx:757", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/JobDetail.tsx:757"}, "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-d6456160f871e855", "name": "`truncate` class without `title=` for hover reveal \u2014 components/CallsList.tsx:184", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/CallsList.tsx:184"}, "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-355443453158c776", "name": "Stray `console.log` in TS/JS \u2014 server/db.js:87", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/db.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-33fda50fa84b962a", "name": "Stray `console.log` in TS/JS \u2014 server/index.js:103", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/index.js:103"}, "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-95a3ccf80577cfaf", "name": "Stray `console.log` in TS/JS \u2014 server/routes/openphone.js:70", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/openphone.js:70"}, "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-cb19c06110b7a436", "name": "Insecure pattern 'document_write' in components/JobDetail.tsx:654", "shortDescription": {"text": "Insecure pattern 'document_write' in components/JobDetail.tsx:654"}, "fullDescription": {"text": "Found a known-risky pattern (document_write). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "low", "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-5712a64cf4b1fef7", "name": "Very large file: components/Dashboard.tsx (914 lines)", "shortDescription": {"text": "Very large file: components/Dashboard.tsx (914 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-42688eab3fd16aaa", "name": "Very large file: components/JobDetail.tsx (2024 lines)", "shortDescription": {"text": "Very large file: components/JobDetail.tsx (2024 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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "1 test file(s) for 68 source file(s) (ratio 0.01). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "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 16 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 125 placeholder/mock markers across 16 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-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: license, ci. 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 license, ci. 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-866fd5be5b2d4459", "name": "Commented-code block (5 lines) in vehicleKeyStore.ts:4", "shortDescription": {"text": "Commented-code block (5 lines) in vehicleKeyStore.ts: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-d9ed3f0b6875927e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 store.ts:289", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 store.ts:289"}, "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-9483c47c297f7f8b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 translateService.ts:24", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 translateService.ts:24"}, "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-6e498e2828e31be9", "name": "Commented-code block (5 lines) in geminiService.ts:761", "shortDescription": {"text": "Commented-code block (5 lines) in geminiService.ts:761"}, "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-07da0455dc29e3a8", "name": "Legacy-named symbol `tk_install_hint_snooze_v2` in components/InstallHint.tsx:8", "shortDescription": {"text": "Legacy-named symbol `tk_install_hint_snooze_v2` in components/InstallHint.tsx:8"}, "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-f73deeea1a679e7f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/dispatch.js:14", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/dispatch.js:14"}, "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-0742163ecd4cf3c6", "name": "Commented-code block (6 lines) in server/routes/openphone.js:76", "shortDescription": {"text": "Commented-code block (6 lines) in server/routes/openphone.js:76"}, "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-0053edddbceb5bdd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/openphone.js:186", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/openphone.js:186"}, "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-fe90d114d24c3128", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/openphone.js:27", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/openphone.js:27"}, "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-50a464e3341813ed", "name": "Dangling fetch: POST https://api.openphone.com/v1/messages (server/routes/openphone.js:186)", "shortDescription": {"text": "Dangling fetch: POST https://api.openphone.com/v1/messages (server/routes/openphone.js:186)"}, "fullDescription": {"text": "`server/routes/openphone.js:186` calls `POST https://api.openphone.com/v1/messages` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.openphone.com/v1/messages`\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-69aff8e35e48134e", "name": "Dangling fetch: GET https://api.openphone.com/v1/phone-numbers (server/routes/openphone.js:221)", "shortDescription": {"text": "Dangling fetch: GET https://api.openphone.com/v1/phone-numbers (server/routes/openphone.js:221)"}, "fullDescription": {"text": "`server/routes/openphone.js:221` calls `GET https://api.openphone.com/v1/phone-numbers` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.openphone.com/v1/phone-numbers`\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-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`server/index.js` declares `USE /api` 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-8bf2f7ca3faa1f1b", "name": "Unused endpoint: USE /api/auth/login", "shortDescription": {"text": "Unused endpoint: USE /api/auth/login"}, "fullDescription": {"text": "`server/index.js` declares `USE /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-fc94ad34d8357cf5", "name": "Unused endpoint: USE /api/jobs/inbound", "shortDescription": {"text": "Unused endpoint: USE /api/jobs/inbound"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/jobs/inbound` 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-5e7a5defccca98a7", "name": "Unused endpoint: USE /openphone", "shortDescription": {"text": "Unused endpoint: USE /openphone"}, "fullDescription": {"text": "`server/index.js` declares `USE /openphone` 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-d35c596b1eb924a0", "name": "Unused endpoint: USE /api/openphone", "shortDescription": {"text": "Unused endpoint: USE /api/openphone"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/openphone` 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-6eb452fbfb454d20", "name": "Unused endpoint: USE /api/auth", "shortDescription": {"text": "Unused endpoint: USE /api/auth"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/auth` 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-8ca4664c9cda1cd6", "name": "Unused endpoint: USE /api/settings", "shortDescription": {"text": "Unused endpoint: USE /api/settings"}, "fullDescription": {"text": "`server/index.js` declares `USE /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-316c43db307befc3", "name": "Unused endpoint: USE /api/ai", "shortDescription": {"text": "Unused endpoint: USE /api/ai"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/ai` 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-61519720bbf44ebe", "name": "Unused endpoint: USE /api/jobs", "shortDescription": {"text": "Unused endpoint: USE /api/jobs"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/jobs` 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-99725bd06fb56b62", "name": "Unused endpoint: USE /api/inventory", "shortDescription": {"text": "Unused endpoint: USE /api/inventory"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/inventory` 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-d93a530ce10d47d9", "name": "Unused endpoint: USE /api/admin", "shortDescription": {"text": "Unused endpoint: USE /api/admin"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/admin` 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-a9ddcc4edea2dec1", "name": "Unused endpoint: USE /api/geocode", "shortDescription": {"text": "Unused endpoint: USE /api/geocode"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/geocode` 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-c4792d15a8be669e", "name": "Unused endpoint: USE /api/dispatch", "shortDescription": {"text": "Unused endpoint: USE /api/dispatch"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/dispatch` 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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`server/routes/settings.js` declares `GET /` 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-67d28fa8cd6bb12f", "name": "Unused endpoint: PUT /", "shortDescription": {"text": "Unused endpoint: PUT /"}, "fullDescription": {"text": "`server/routes/settings.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-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`server/routes/leads.js` declares `POST /` 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-a7a776760f85a3e7", "name": "Unused endpoint: POST /reset", "shortDescription": {"text": "Unused endpoint: POST /reset"}, "fullDescription": {"text": "`server/routes/admin.js` declares `POST /reset` 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-970eb92d6ec2bfaa", "name": "Unused endpoint: POST /generate", "shortDescription": {"text": "Unused endpoint: POST /generate"}, "fullDescription": {"text": "`server/routes/ai.js` declares `POST /generate` 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-5cb26b537962e3ee", "name": "Unused endpoint: POST /live-token", "shortDescription": {"text": "Unused endpoint: POST /live-token"}, "fullDescription": {"text": "`server/routes/ai.js` declares `POST /live-token` 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-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /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-841e50bf821e4158", "name": "Unused endpoint: GET /users", "shortDescription": {"text": "Unused endpoint: GET /users"}, "fullDescription": {"text": "`server/routes/auth.js` declares `GET /users` 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-41aa9e92da3f14ad", "name": "Unused endpoint: GET /users/:id", "shortDescription": {"text": "Unused endpoint: GET /users/:id"}, "fullDescription": {"text": "`server/routes/auth.js` declares `GET /users/:id` 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-1bca8100a44f7f25", "name": "Unused endpoint: POST /users", "shortDescription": {"text": "Unused endpoint: POST /users"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /users` 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-bdd9111e1cbd2899", "name": "Unused endpoint: PUT /users/:id", "shortDescription": {"text": "Unused endpoint: PUT /users/:id"}, "fullDescription": {"text": "`server/routes/auth.js` declares `PUT /users/:id` 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-79406b9fd85263bf", "name": "Unused endpoint: DELETE /users/:id", "shortDescription": {"text": "Unused endpoint: DELETE /users/:id"}, "fullDescription": {"text": "`server/routes/auth.js` declares `DELETE /users/:id` 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-b24b942a96315073", "name": "Unused endpoint: POST /master-reset", "shortDescription": {"text": "Unused endpoint: POST /master-reset"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /master-reset` 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-fa413208496243a5", "name": "Unused endpoint: POST /sync", "shortDescription": {"text": "Unused endpoint: POST /sync"}, "fullDescription": {"text": "`server/routes/inventory.js` declares `POST /sync` 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-8d5b2b188d08ca82", "name": "Unused endpoint: PUT /:id", "shortDescription": {"text": "Unused endpoint: PUT /:id"}, "fullDescription": {"text": "`server/routes/inventory.js` declares `PUT /:id` 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-7a61c112b611f4bb", "name": "Unused endpoint: DELETE /:id", "shortDescription": {"text": "Unused endpoint: DELETE /:id"}, "fullDescription": {"text": "`server/routes/inventory.js` declares `DELETE /:id` 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-6a1e8967a87dfcaf", "name": "Unused endpoint: GET /route", "shortDescription": {"text": "Unused endpoint: GET /route"}, "fullDescription": {"text": "`server/routes/dispatch.js` declares `GET /route` 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-0a7ee251196f605a", "name": "Unused endpoint: GET /weather", "shortDescription": {"text": "Unused endpoint: GET /weather"}, "fullDescription": {"text": "`server/routes/dispatch.js` declares `GET /weather` 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-0ae38010c60493f1", "name": "Unused endpoint: POST /webhook", "shortDescription": {"text": "Unused endpoint: POST /webhook"}, "fullDescription": {"text": "`server/routes/openphone.js` declares `POST /webhook` 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-9e0b360c59d868e1", "name": "Unused endpoint: GET /calls", "shortDescription": {"text": "Unused endpoint: GET /calls"}, "fullDescription": {"text": "`server/routes/openphone.js` declares `GET /calls` 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-e934dba02d2877a1", "name": "Unused endpoint: GET /messages", "shortDescription": {"text": "Unused endpoint: GET /messages"}, "fullDescription": {"text": "`server/routes/openphone.js` declares `GET /messages` 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-7113bff74e57805e", "name": "Unused endpoint: POST /messages/send", "shortDescription": {"text": "Unused endpoint: POST /messages/send"}, "fullDescription": {"text": "`server/routes/openphone.js` declares `POST /messages/send` 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-ef2f9c8560106e13", "name": "Unused endpoint: GET /phone-numbers", "shortDescription": {"text": "Unused endpoint: GET /phone-numbers"}, "fullDescription": {"text": "`server/routes/openphone.js` declares `GET /phone-numbers` 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-6f4386b886fb5803", "name": "Unused endpoint: GET /pending-jobs", "shortDescription": {"text": "Unused endpoint: GET /pending-jobs"}, "fullDescription": {"text": "`server/routes/openphone.js` declares `GET /pending-jobs` 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-50e2dc2865abe6db", "name": "Unused endpoint: DELETE /pending-jobs/:callId", "shortDescription": {"text": "Unused endpoint: DELETE /pending-jobs/:callId"}, "fullDescription": {"text": "`server/routes/openphone.js` declares `DELETE /pending-jobs/:callId` 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/20474"}, "properties": {"repository": "sulaibragim/techAI", "repoUrl": "https://github.com/sulaibragim/techAI", "branch": "main"}, "results": [{"ruleId": "scanner-9a7f9c7514092a03", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 App.tsx:231"}, "properties": {"repobilityId": "533c25d20bc3c00e", "scanner": "scanner-primary", "fingerprint": "9a7f9c7514092a03", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-57d1d596415c50a8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 geminiService.ts:890"}, "properties": {"repobilityId": "f7637337de0675cc", "scanner": "scanner-primary", "fingerprint": "57d1d596415c50a8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fd4c44615045d4c5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ClientsList.tsx:164"}, "properties": {"repobilityId": "93714b9fab44f934", "scanner": "scanner-primary", "fingerprint": "fd4c44615045d4c5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4942c6bf74ee163f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/WorkroomDashboard.tsx:146"}, "properties": {"repobilityId": "736a0088b7807d6b", "scanner": "scanner-primary", "fingerprint": "4942c6bf74ee163f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ace53590d5d4e712", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ComboPicker.tsx:74"}, "properties": {"repobilityId": "f3601eb0efbfb72c", "scanner": "scanner-primary", "fingerprint": "ace53590d5d4e712", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3251c4a6fa1bed01", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/MessagesList.tsx:247"}, "properties": {"repobilityId": "73ca3def2435dbaf", "scanner": "scanner-primary", "fingerprint": "3251c4a6fa1bed01", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-434ef9e869f46e94", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Inventory.tsx:205"}, "properties": {"repobilityId": "28547121636123e9", "scanner": "scanner-primary", "fingerprint": "434ef9e869f46e94", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a836fecdff6ea298", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/TechAnalytics.tsx:99"}, "properties": {"repobilityId": "9b0b1c97a1deab88", "scanner": "scanner-primary", "fingerprint": "a836fecdff6ea298", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-61c011525dcfecec", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/JobWizard.tsx:323"}, "properties": {"repobilityId": "3e2ae9f2712b96c2", "scanner": "scanner-primary", "fingerprint": "61c011525dcfecec", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-857f5f90a274f0ed", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Dashboard.tsx:741"}, "properties": {"repobilityId": "109529451598aa54", "scanner": "scanner-primary", "fingerprint": "857f5f90a274f0ed", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6a826b6797c9f547", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/JobsList.tsx:192"}, "properties": {"repobilityId": "f833f451d6063eb3", "scanner": "scanner-primary", "fingerprint": "6a826b6797c9f547", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-35fd0ca88e4edd54", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Accounting.tsx:455"}, "properties": {"repobilityId": "6f3a3bf28b194450", "scanner": "scanner-primary", "fingerprint": "35fd0ca88e4edd54", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-59c6de0ddb67438d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Sidebar.tsx:108"}, "properties": {"repobilityId": "0401ab5eaa62b445", "scanner": "scanner-primary", "fingerprint": "59c6de0ddb67438d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e006c9fa9b58fa3c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AutoKey.tsx:208"}, "properties": {"repobilityId": "eb7c15444ace551d", "scanner": "scanner-primary", "fingerprint": "e006c9fa9b58fa3c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a3bc527465c38f54", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/TechPicker.tsx:109"}, "properties": {"repobilityId": "d5e262bfd2c4ef26", "scanner": "scanner-primary", "fingerprint": "a3bc527465c38f54", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9fa997e0a3f350f0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/Settings.tsx:626"}, "properties": {"repobilityId": "218d82431def0334", "scanner": "scanner-primary", "fingerprint": "9fa997e0a3f350f0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4417c9ed0333d9f5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/JobDetail.tsx:757"}, "properties": {"repobilityId": "045dd4ecc89ad105", "scanner": "scanner-primary", "fingerprint": "4417c9ed0333d9f5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d6456160f871e855", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/CallsList.tsx:184"}, "properties": {"repobilityId": "3b9160f0c67a782d", "scanner": "scanner-primary", "fingerprint": "d6456160f871e855", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-355443453158c776", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/db.js:87"}, "properties": {"repobilityId": "0c27e1750d84b73e", "scanner": "scanner-primary", "fingerprint": "355443453158c776", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-33fda50fa84b962a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/index.js:103"}, "properties": {"repobilityId": "21e6b3de2b3dd856", "scanner": "scanner-primary", "fingerprint": "33fda50fa84b962a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-95a3ccf80577cfaf", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/openphone.js:70"}, "properties": {"repobilityId": "37f21156227c0cb2", "scanner": "scanner-primary", "fingerprint": "95a3ccf80577cfaf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cb19c06110b7a436", "level": "note", "message": {"text": "Insecure pattern 'document_write' in components/JobDetail.tsx:654"}, "properties": {"repobilityId": "f1ca27a8e457fa40", "scanner": "scanner-primary", "fingerprint": "cb19c06110b7a436", "layer": "security", "severity": "low", "confidence": 1.0, "tags": ["owasp", "document_write"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "components/JobDetail.tsx"}, "region": {"startLine": 654}}}]}, {"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-5712a64cf4b1fef7", "level": "note", "message": {"text": "Very large file: components/Dashboard.tsx (914 lines)"}, "properties": {"repobilityId": "20cf55b51ba0f3d9", "scanner": "scanner-primary", "fingerprint": "5712a64cf4b1fef7", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-42688eab3fd16aaa", "level": "note", "message": {"text": "Very large file: components/JobDetail.tsx (2024 lines)"}, "properties": {"repobilityId": "9d8f67f83a44b2ef", "scanner": "scanner-primary", "fingerprint": "42688eab3fd16aaa", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "5257c7f2f9d96960", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "a0d0e1eeb58e80c1", "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": "ad41ef3c6851ebe9", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "e03128242aaac80b", "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": "3b3130c4f930c154", "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": "a21c291cd1c2d911", "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": "5f733964e2dcd549", "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": "fb0b35a31688dd5a", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-866fd5be5b2d4459", "level": "none", "message": {"text": "Commented-code block (5 lines) in vehicleKeyStore.ts:4"}, "properties": {"repobilityId": "cd5b7ecae68be3ee", "scanner": "scanner-primary", "fingerprint": "866fd5be5b2d4459", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d9ed3f0b6875927e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 store.ts:289"}, "properties": {"repobilityId": "668ceba5105ed9d9", "scanner": "scanner-primary", "fingerprint": "d9ed3f0b6875927e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9483c47c297f7f8b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 translateService.ts:24"}, "properties": {"repobilityId": "81b69875a96828f2", "scanner": "scanner-primary", "fingerprint": "9483c47c297f7f8b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6e498e2828e31be9", "level": "none", "message": {"text": "Commented-code block (5 lines) in geminiService.ts:761"}, "properties": {"repobilityId": "3d34b57cc2669ad4", "scanner": "scanner-primary", "fingerprint": "6e498e2828e31be9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-07da0455dc29e3a8", "level": "note", "message": {"text": "Legacy-named symbol `tk_install_hint_snooze_v2` in components/InstallHint.tsx:8"}, "properties": {"repobilityId": "0de5b7f9af09dcda", "scanner": "scanner-primary", "fingerprint": "07da0455dc29e3a8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f73deeea1a679e7f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/dispatch.js:14"}, "properties": {"repobilityId": "b04f444406e30de3", "scanner": "scanner-primary", "fingerprint": "f73deeea1a679e7f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0742163ecd4cf3c6", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/routes/openphone.js:76"}, "properties": {"repobilityId": "7af7db7b36cc37ce", "scanner": "scanner-primary", "fingerprint": "0742163ecd4cf3c6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0053edddbceb5bdd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/openphone.js:186"}, "properties": {"repobilityId": "6b1c8384147c36be", "scanner": "scanner-primary", "fingerprint": "0053edddbceb5bdd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fe90d114d24c3128", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/openphone.js:27"}, "properties": {"repobilityId": "dda5e465cc7cf353", "scanner": "scanner-primary", "fingerprint": "fe90d114d24c3128", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-50a464e3341813ed", "level": "error", "message": {"text": "Dangling fetch: POST https://api.openphone.com/v1/messages (server/routes/openphone.js:186)"}, "properties": {"repobilityId": "bbcd12694795d209", "scanner": "scanner-primary", "fingerprint": "50a464e3341813ed", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-69aff8e35e48134e", "level": "error", "message": {"text": "Dangling fetch: GET https://api.openphone.com/v1/phone-numbers (server/routes/openphone.js:221)"}, "properties": {"repobilityId": "4d928ee2a1a58114", "scanner": "scanner-primary", "fingerprint": "69aff8e35e48134e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "8428537b70eeca77", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8bf2f7ca3faa1f1b", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth/login"}, "properties": {"repobilityId": "8c2541a687bad030", "scanner": "scanner-primary", "fingerprint": "8bf2f7ca3faa1f1b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fc94ad34d8357cf5", "level": "note", "message": {"text": "Unused endpoint: USE /api/jobs/inbound"}, "properties": {"repobilityId": "5f72c6d0ef0ce7b1", "scanner": "scanner-primary", "fingerprint": "fc94ad34d8357cf5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5e7a5defccca98a7", "level": "note", "message": {"text": "Unused endpoint: USE /openphone"}, "properties": {"repobilityId": "ca8b0048ab2aaa13", "scanner": "scanner-primary", "fingerprint": "5e7a5defccca98a7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d35c596b1eb924a0", "level": "note", "message": {"text": "Unused endpoint: USE /api/openphone"}, "properties": {"repobilityId": "6ec65e7e33df8ba6", "scanner": "scanner-primary", "fingerprint": "d35c596b1eb924a0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6eb452fbfb454d20", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth"}, "properties": {"repobilityId": "998ca44ee62afef2", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8ca4664c9cda1cd6", "level": "note", "message": {"text": "Unused endpoint: USE /api/settings"}, "properties": {"repobilityId": "de04cc0c686e6aae", "scanner": "scanner-primary", "fingerprint": "8ca4664c9cda1cd6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-316c43db307befc3", "level": "note", "message": {"text": "Unused endpoint: USE /api/ai"}, "properties": {"repobilityId": "48fd3d3d970f1a2f", "scanner": "scanner-primary", "fingerprint": "316c43db307befc3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-61519720bbf44ebe", "level": "note", "message": {"text": "Unused endpoint: USE /api/jobs"}, "properties": {"repobilityId": "464b154dad8a885f", "scanner": "scanner-primary", "fingerprint": "61519720bbf44ebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99725bd06fb56b62", "level": "note", "message": {"text": "Unused endpoint: USE /api/inventory"}, "properties": {"repobilityId": "c9155866e488f41f", "scanner": "scanner-primary", "fingerprint": "99725bd06fb56b62", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d93a530ce10d47d9", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin"}, "properties": {"repobilityId": "b0385d6f41c67e22", "scanner": "scanner-primary", "fingerprint": "d93a530ce10d47d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a9ddcc4edea2dec1", "level": "note", "message": {"text": "Unused endpoint: USE /api/geocode"}, "properties": {"repobilityId": "04729ff6af610a29", "scanner": "scanner-primary", "fingerprint": "a9ddcc4edea2dec1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c4792d15a8be669e", "level": "note", "message": {"text": "Unused endpoint: USE /api/dispatch"}, "properties": {"repobilityId": "e1e7ac576b523f13", "scanner": "scanner-primary", "fingerprint": "c4792d15a8be669e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "1de738f403b9d0fb", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-67d28fa8cd6bb12f", "level": "note", "message": {"text": "Unused endpoint: PUT /"}, "properties": {"repobilityId": "308d45285a205bd9", "scanner": "scanner-primary", "fingerprint": "67d28fa8cd6bb12f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "ea8f733a90e62fba", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a7a776760f85a3e7", "level": "note", "message": {"text": "Unused endpoint: POST /reset"}, "properties": {"repobilityId": "c53b14940bf9a2f6", "scanner": "scanner-primary", "fingerprint": "a7a776760f85a3e7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-970eb92d6ec2bfaa", "level": "note", "message": {"text": "Unused endpoint: POST /generate"}, "properties": {"repobilityId": "2414453e6815b17e", "scanner": "scanner-primary", "fingerprint": "970eb92d6ec2bfaa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5cb26b537962e3ee", "level": "note", "message": {"text": "Unused endpoint: POST /live-token"}, "properties": {"repobilityId": "7aadff04f81bf0f9", "scanner": "scanner-primary", "fingerprint": "5cb26b537962e3ee", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "2689f0f5e061c9d0", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-841e50bf821e4158", "level": "note", "message": {"text": "Unused endpoint: GET /users"}, "properties": {"repobilityId": "0f1b59408b16cf9b", "scanner": "scanner-primary", "fingerprint": "841e50bf821e4158", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-41aa9e92da3f14ad", "level": "note", "message": {"text": "Unused endpoint: GET /users/:id"}, "properties": {"repobilityId": "a41d448265be141a", "scanner": "scanner-primary", "fingerprint": "41aa9e92da3f14ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1bca8100a44f7f25", "level": "note", "message": {"text": "Unused endpoint: POST /users"}, "properties": {"repobilityId": "8c4fb53b50f97e8a", "scanner": "scanner-primary", "fingerprint": "1bca8100a44f7f25", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bdd9111e1cbd2899", "level": "note", "message": {"text": "Unused endpoint: PUT /users/:id"}, "properties": {"repobilityId": "6c444a62fef13c19", "scanner": "scanner-primary", "fingerprint": "bdd9111e1cbd2899", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-79406b9fd85263bf", "level": "note", "message": {"text": "Unused endpoint: DELETE /users/:id"}, "properties": {"repobilityId": "665e62f3a05c760f", "scanner": "scanner-primary", "fingerprint": "79406b9fd85263bf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b24b942a96315073", "level": "note", "message": {"text": "Unused endpoint: POST /master-reset"}, "properties": {"repobilityId": "a3cae159efdb9e95", "scanner": "scanner-primary", "fingerprint": "b24b942a96315073", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fa413208496243a5", "level": "note", "message": {"text": "Unused endpoint: POST /sync"}, "properties": {"repobilityId": "b03589e83c06e07b", "scanner": "scanner-primary", "fingerprint": "fa413208496243a5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8d5b2b188d08ca82", "level": "note", "message": {"text": "Unused endpoint: PUT /:id"}, "properties": {"repobilityId": "ed0a304f175a061e", "scanner": "scanner-primary", "fingerprint": "8d5b2b188d08ca82", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a61c112b611f4bb", "level": "note", "message": {"text": "Unused endpoint: DELETE /:id"}, "properties": {"repobilityId": "d240be8fa4b336e1", "scanner": "scanner-primary", "fingerprint": "7a61c112b611f4bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6a1e8967a87dfcaf", "level": "note", "message": {"text": "Unused endpoint: GET /route"}, "properties": {"repobilityId": "9bccd6402c23929f", "scanner": "scanner-primary", "fingerprint": "6a1e8967a87dfcaf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0a7ee251196f605a", "level": "note", "message": {"text": "Unused endpoint: GET /weather"}, "properties": {"repobilityId": "d00191252455512d", "scanner": "scanner-primary", "fingerprint": "0a7ee251196f605a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0ae38010c60493f1", "level": "note", "message": {"text": "Unused endpoint: POST /webhook"}, "properties": {"repobilityId": "6414c1584a8eb3cb", "scanner": "scanner-primary", "fingerprint": "0ae38010c60493f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9e0b360c59d868e1", "level": "note", "message": {"text": "Unused endpoint: GET /calls"}, "properties": {"repobilityId": "8f754aab3b052141", "scanner": "scanner-primary", "fingerprint": "9e0b360c59d868e1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e934dba02d2877a1", "level": "note", "message": {"text": "Unused endpoint: GET /messages"}, "properties": {"repobilityId": "7535d58600e170d1", "scanner": "scanner-primary", "fingerprint": "e934dba02d2877a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7113bff74e57805e", "level": "note", "message": {"text": "Unused endpoint: POST /messages/send"}, "properties": {"repobilityId": "4618c508598e0409", "scanner": "scanner-primary", "fingerprint": "7113bff74e57805e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ef2f9c8560106e13", "level": "note", "message": {"text": "Unused endpoint: GET /phone-numbers"}, "properties": {"repobilityId": "f118f3e386f5e086", "scanner": "scanner-primary", "fingerprint": "ef2f9c8560106e13", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6f4386b886fb5803", "level": "note", "message": {"text": "Unused endpoint: GET /pending-jobs"}, "properties": {"repobilityId": "1fa1ab374284c300", "scanner": "scanner-primary", "fingerprint": "6f4386b886fb5803", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-50e2dc2865abe6db", "level": "note", "message": {"text": "Unused endpoint: DELETE /pending-jobs/:callId"}, "properties": {"repobilityId": "ad3616c8d1ff5e6c", "scanner": "scanner-primary", "fingerprint": "50e2dc2865abe6db", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}