{"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-50ef8d8ba677d2b1", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/DebtApp.jsx:71", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/DebtApp.jsx:71"}, "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-0859a6aedd9998bb", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/DashboardApp.jsx:12", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/DashboardApp.jsx:12"}, "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-05dc6a5a5e7e3590", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/PassportApp.jsx:305", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/PassportApp.jsx:305"}, "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-07206c7987be5a47", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/AirlinesApp.jsx:85", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/AirlinesApp.jsx:85"}, "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-c5275afd451eb9e4", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/TourApp.jsx:250", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/TourApp.jsx:250"}, "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-5ee6e70c6b813837", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/UpcomingFlightsApp.jsx:78", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/UpcomingFlightsApp.jsx:78"}, "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-99117c53c9de7c4a", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/FareCheckApp.jsx:169", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/FareCheckApp.jsx:169"}, "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-523d30cf02149aaa", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/TicketWatchApp.jsx:252", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/TicketWatchApp.jsx:252"}, "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-b2f04004431a19de", "name": "`truncate` class without `title=` for hover reveal \u2014 website/src/components/Layout.jsx:81", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/components/Layout.jsx:81"}, "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-cea6743327d1aa8b", "name": "\"active\" state uses light bg in a dark theme \u2014 website/src/components/Layout.jsx:49", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 website/src/components/Layout.jsx:49"}, "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-c4d5b1989f7eb105", "name": "Stray `console.log` in TS/JS \u2014 backend/test-bcrypt.js:8", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/test-bcrypt.js:8"}, "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-d40865d55f4d4be1", "name": "Stray `console.log` in TS/JS \u2014 backend/setup-admin.js:8", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/setup-admin.js:8"}, "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-d91197b837c2e33d", "name": "Stray `console.log` in TS/JS \u2014 backend/config/env.js:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/config/env.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-c439df49bcbaa016", "name": "Stray `console.log` in TS/JS \u2014 backend/routes/debtController.js:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/routes/debtController.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-14b3990f132ff9d8", "name": "Stray `console.log` in TS/JS \u2014 backend/workers/test-adapter.js:15", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/workers/test-adapter.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-b63aced91fcd4905", "name": "Stray `console.log` in TS/JS \u2014 backend/controllers/passportController.js:119", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/controllers/passportController.js:119"}, "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-819f5885da934fd9", "name": "Insecure pattern 'local_storage_auth_token' in website/src/DebtApp.jsx:263", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/DebtApp.jsx:263"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-24dcc47904178c59", "name": "Insecure pattern 'local_storage_auth_token' in website/src/auth/AuthContext.jsx:24", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/auth/AuthContext.jsx:24"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-db6292f63031a093", "name": "Insecure pattern 'local_storage_auth_token' in website/src/backup/DebtApp.jsx:134", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/backup/DebtApp.jsx:134"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-816edb8ea1d5045f", "name": "Insecure pattern 'local_storage_auth_token' in website/src/backup/App copy.jsx:134", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/backup/App copy.jsx:134"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d928df7e02bc2df", "name": "Insecure pattern 'local_storage_auth_token' in website/src/backup/DebtApp copy.jsx:134", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/backup/DebtApp copy.jsx:134"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6285166df6b19eff", "name": "Possible secret in backend/test-bcrypt.js", "shortDescription": {"text": "Possible secret in backend/test-bcrypt.js"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-fc36465e17a5438d", "name": "Possible secret in backend/setup-admin.js", "shortDescription": {"text": "Possible secret in backend/setup-admin.js"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-f010c4ec8c7221b3", "name": "Very large file: website/src/DebtApp.jsx (1617 lines)", "shortDescription": {"text": "Very large file: website/src/DebtApp.jsx (1617 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": "2 test file(s) for 98 source file(s) (ratio 0.02). 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 23 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 129 placeholder/mock markers across 19 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-11825279136b53a3", "name": "CI is configured but no tests are detected", "shortDescription": {"text": "CI is configured but no tests are detected"}, "fullDescription": {"text": "A CI pipeline exists, but the scan found no test files to gate. Opus labeled this generated-code pattern as config theater: release machinery exists, but it has little behavioral signal."}, "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, tests. 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, tests. 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-9e58280a7d431f1e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/DebtApp.jsx:215", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/DebtApp.jsx:215"}, "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-cf46cb67f600e65d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/PassportApp.jsx:216", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/PassportApp.jsx:216"}, "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-0143bd5c5a4a79a2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/DebtApp.jsx:107", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/DebtApp.jsx:107"}, "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-5c667051cd6424ef", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/App copy.jsx:107", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/App copy.jsx:107"}, "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-044e8d6e310e8811", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/DebtApp copy.jsx:107", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/DebtApp copy.jsx:107"}, "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-39995dab897439b0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/services/client.js:22", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/services/client.js:22"}, "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-4d38286c74b40d9b", "name": "Commented-code block (5 lines) in backend/middleware/scope.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/middleware/scope.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-ba7a3c65c9f33c46", "name": "Commented-code block (5 lines) in backend/workers/fareWatcher.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in backend/workers/fareWatcher.js:3"}, "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-2ad3a0901dfecbf0", "name": "Commented-code block (12 lines) in backend/workers/adapters/vietnamairlines.js:1", "shortDescription": {"text": "Commented-code block (12 lines) in backend/workers/adapters/vietnamairlines.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-2eafc3188c36bb02", "name": "3 env vars used in code but missing from .env.example", "shortDescription": {"text": "3 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `DATABASE_URL`, `SERPAPI_TIMEOUT_MS`, `TRUST_PROXY`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9d13a798f1c8c33b", "name": "Frontend route `/passport` has no Link/navigate to it \u2014 website/src/backup/main copy 2.jsx", "shortDescription": {"text": "Frontend route `/passport` has no Link/navigate to it \u2014 website/src/backup/main copy 2.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-373c5d89871120b3", "name": "Dangling fetch: POST https://api.resend.com/emails (backend/config/email.js:27)", "shortDescription": {"text": "Dangling fetch: POST https://api.resend.com/emails (backend/config/email.js:27)"}, "fullDescription": {"text": "`backend/config/email.js:27` calls `POST https://api.resend.com/emails` 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.resend.com/emails`\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-f62de1892f9909d1", "name": "Dangling fetch: GET https://serpapi.com/search?${params} (backend/workers/lib/serpapi.js:73)", "shortDescription": {"text": "Dangling fetch: GET https://serpapi.com/search?${params} (backend/workers/lib/serpapi.js:73)"}, "fullDescription": {"text": "`backend/workers/lib/serpapi.js:73` calls `GET https://serpapi.com/search?${params}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/serpapi.com/search`\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-8fdbacfe9430a6ed", "name": "Unused endpoint: POST /auth/login", "shortDescription": {"text": "Unused endpoint: POST /auth/login"}, "fullDescription": {"text": "`website/services/api.js` declares `POST /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-8292c0931391749a", "name": "Unused endpoint: POST /auth/register", "shortDescription": {"text": "Unused endpoint: POST /auth/register"}, "fullDescription": {"text": "`website/services/api.js` declares `POST /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-b119bb52041e0c8d", "name": "Unused endpoint: GET /auth/profile", "shortDescription": {"text": "Unused endpoint: GET /auth/profile"}, "fullDescription": {"text": "`website/services/api.js` declares `GET /auth/profile` 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-c987c6624ab77861", "name": "Unused endpoint: POST /debts", "shortDescription": {"text": "Unused endpoint: POST /debts"}, "fullDescription": {"text": "`website/services/api.js` declares `POST /debts` 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-7ca22bc3c62e9e7b", "name": "Unused endpoint: POST /debts/bulk", "shortDescription": {"text": "Unused endpoint: POST /debts/bulk"}, "fullDescription": {"text": "`website/services/api.js` declares `POST /debts/bulk` 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-a35ce3e9c9f59e0a", "name": "Unused endpoint: GET /companies", "shortDescription": {"text": "Unused endpoint: GET /companies"}, "fullDescription": {"text": "`website/services/api.js` declares `GET /companies` 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-ec39abb0b24cc5b2", "name": "Unused endpoint: POST /companies", "shortDescription": {"text": "Unused endpoint: POST /companies"}, "fullDescription": {"text": "`website/services/api.js` declares `POST /companies` 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-af75cdebd6061f00", "name": "Unused endpoint: GET /routes", "shortDescription": {"text": "Unused endpoint: GET /routes"}, "fullDescription": {"text": "`website/services/api.js` declares `GET /routes` 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-034336dc074efeb4", "name": "Unused endpoint: POST /routes", "shortDescription": {"text": "Unused endpoint: POST /routes"}, "fullDescription": {"text": "`website/services/api.js` declares `POST /routes` 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": "`backend/server.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-6bf5ff45910f6823", "name": "Unused endpoint: USE /api/debts", "shortDescription": {"text": "Unused endpoint: USE /api/debts"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/debts` 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-345a2e4a2569c114", "name": "Unused endpoint: USE /api/passports", "shortDescription": {"text": "Unused endpoint: USE /api/passports"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/passports` 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-bb789cf847f59e24", "name": "Unused endpoint: USE /api/companies", "shortDescription": {"text": "Unused endpoint: USE /api/companies"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/companies` 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-530274a2ae45a5dc", "name": "Unused endpoint: USE /api/customers", "shortDescription": {"text": "Unused endpoint: USE /api/customers"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/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-f8242ba07247d2f8", "name": "Unused endpoint: USE /api/payments", "shortDescription": {"text": "Unused endpoint: USE /api/payments"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/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-4ff40cb10f7c8519", "name": "Unused endpoint: USE /api/users", "shortDescription": {"text": "Unused endpoint: USE /api/users"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/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-1e1ec70ce9b71de8", "name": "Unused endpoint: USE /api/invoices", "shortDescription": {"text": "Unused endpoint: USE /api/invoices"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/invoices` 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-1557fa2fbbe6dbf0", "name": "Unused endpoint: USE /api/deposits", "shortDescription": {"text": "Unused endpoint: USE /api/deposits"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/deposits` 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-06c88a2e2dc65557", "name": "Unused endpoint: USE /api/stats", "shortDescription": {"text": "Unused endpoint: USE /api/stats"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/stats` 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-36eed93c8c3e8347", "name": "Unused endpoint: USE /api/routes", "shortDescription": {"text": "Unused endpoint: USE /api/routes"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/routes` 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-1b6c609850c719b2", "name": "Unused endpoint: USE /api/notes", "shortDescription": {"text": "Unused endpoint: USE /api/notes"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/notes` 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-df7a560e6317b91e", "name": "Unused endpoint: USE /api/ticket-watches", "shortDescription": {"text": "Unused endpoint: USE /api/ticket-watches"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/ticket-watches` 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-831a8492063bbefd", "name": "Unused endpoint: USE /api/fares", "shortDescription": {"text": "Unused endpoint: USE /api/fares"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/fares` 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-ae183eec2aaab054", "name": "Unused endpoint: USE /api/airlines", "shortDescription": {"text": "Unused endpoint: USE /api/airlines"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/airlines` 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-4ec078e95fb5c261", "name": "Unused endpoint: USE /api/train-tickets", "shortDescription": {"text": "Unused endpoint: USE /api/train-tickets"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/train-tickets` 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-14ed0a77b92f819f", "name": "Unused endpoint: USE /api/tours", "shortDescription": {"text": "Unused endpoint: USE /api/tours"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/tours` 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-4756b4c4da7d2088", "name": "Unused endpoint: GET /api/health", "shortDescription": {"text": "Unused endpoint: GET /api/health"}, "fullDescription": {"text": "`backend/server.js` declares `GET /api/health` 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": "`backend/routes/customers.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-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`backend/routes/customers.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-8d5b2b188d08ca82", "name": "Unused endpoint: PUT /:id", "shortDescription": {"text": "Unused endpoint: PUT /:id"}, "fullDescription": {"text": "`backend/routes/customers.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": "`backend/routes/customers.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-b1c6b43f820b8518", "name": "Unused endpoint: POST /bulk-delete", "shortDescription": {"text": "Unused endpoint: POST /bulk-delete"}, "fullDescription": {"text": "`backend/routes/customers.js` declares `POST /bulk-delete` 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-be4cb5e3cabcce80", "name": "Unused endpoint: POST /import", "shortDescription": {"text": "Unused endpoint: POST /import"}, "fullDescription": {"text": "`backend/routes/customers.js` declares `POST /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-ca5756175765b49d", "name": "Unused endpoint: GET /:id", "shortDescription": {"text": "Unused endpoint: GET /:id"}, "fullDescription": {"text": "`backend/routes/invoices.js` declares `GET /: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-8f214fd3b826a0dd", "name": "Unused endpoint: DELETE /:routeName", "shortDescription": {"text": "Unused endpoint: DELETE /:routeName"}, "fullDescription": {"text": "`backend/routes/routes.js` declares `DELETE /:routeName` 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-d7fa8929da9cbe3f", "name": "Unused endpoint: GET /balance", "shortDescription": {"text": "Unused endpoint: GET /balance"}, "fullDescription": {"text": "`backend/routes/deposits.js` declares `GET /balance` 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-bc62f6dc09a6abc3", "name": "Unused endpoint: PUT /:id/checkin", "shortDescription": {"text": "Unused endpoint: PUT /:id/checkin"}, "fullDescription": {"text": "`backend/routes/debts.js` declares `PUT /:id/checkin` 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-90631dcf4fb49f54", "name": "Unused endpoint: POST /bulk", "shortDescription": {"text": "Unused endpoint: POST /bulk"}, "fullDescription": {"text": "`backend/routes/debts.js` declares `POST /bulk` 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": "`backend/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-304b6f2b403d93f7", "name": "Unused endpoint: POST /register", "shortDescription": {"text": "Unused endpoint: POST /register"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `POST /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-4257ec01219aa99a", "name": "Unused endpoint: POST /forgot-password", "shortDescription": {"text": "Unused endpoint: POST /forgot-password"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `POST /forgot-password` 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-68a5d356c0cac9e3", "name": "Unused endpoint: POST /reset-password", "shortDescription": {"text": "Unused endpoint: POST /reset-password"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `POST /reset-password` 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-2595b39638e5c045", "name": "Unused endpoint: GET /profile", "shortDescription": {"text": "Unused endpoint: GET /profile"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `GET /profile` 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-911492554a68d0c1", "name": "Unused endpoint: PUT /profile", "shortDescription": {"text": "Unused endpoint: PUT /profile"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `PUT /profile` 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-a569171ffb8378de", "name": "Unused endpoint: PUT /password", "shortDescription": {"text": "Unused endpoint: PUT /password"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `PUT /password` 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-db0993b39976b123", "name": "Unused endpoint: GET /:id/snapshots", "shortDescription": {"text": "Unused endpoint: GET /:id/snapshots"}, "fullDescription": {"text": "`backend/routes/ticketWatches.js` declares `GET /:id/snapshots` 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-f2e0c1565accb359", "name": "Unused endpoint: POST /:id/check-now", "shortDescription": {"text": "Unused endpoint: POST /:id/check-now"}, "fullDescription": {"text": "`backend/routes/ticketWatches.js` declares `POST /:id/check-now` 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-b6ddbcbab4f01790", "name": "Unused endpoint: PUT /:id/trial", "shortDescription": {"text": "Unused endpoint: PUT /:id/trial"}, "fullDescription": {"text": "`backend/routes/users.js` declares `PUT /:id/trial` 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-060056f7b8b68374", "name": "Unused endpoint: POST /quote", "shortDescription": {"text": "Unused endpoint: POST /quote"}, "fullDescription": {"text": "`backend/routes/fares.js` declares `POST /quote` 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/20783"}, "properties": {"repository": "taloc0111/quanlycongno", "repoUrl": "https://github.com/taloc0111/quanlycongno", "branch": "main"}, "results": [{"ruleId": "scanner-50ef8d8ba677d2b1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/DebtApp.jsx:71"}, "properties": {"repobilityId": "8ed47d17151055c6", "scanner": "scanner-primary", "fingerprint": "50ef8d8ba677d2b1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0859a6aedd9998bb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/DashboardApp.jsx:12"}, "properties": {"repobilityId": "30a0e299f211736c", "scanner": "scanner-primary", "fingerprint": "0859a6aedd9998bb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-05dc6a5a5e7e3590", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/PassportApp.jsx:305"}, "properties": {"repobilityId": "8317b8d669ea4232", "scanner": "scanner-primary", "fingerprint": "05dc6a5a5e7e3590", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-07206c7987be5a47", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/AirlinesApp.jsx:85"}, "properties": {"repobilityId": "ce01b86d2a6d3bba", "scanner": "scanner-primary", "fingerprint": "07206c7987be5a47", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c5275afd451eb9e4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/TourApp.jsx:250"}, "properties": {"repobilityId": "c82406e53799bf31", "scanner": "scanner-primary", "fingerprint": "c5275afd451eb9e4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5ee6e70c6b813837", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/UpcomingFlightsApp.jsx:78"}, "properties": {"repobilityId": "1f25c03daabc9885", "scanner": "scanner-primary", "fingerprint": "5ee6e70c6b813837", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-99117c53c9de7c4a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/FareCheckApp.jsx:169"}, "properties": {"repobilityId": "3b87ef4d24045770", "scanner": "scanner-primary", "fingerprint": "99117c53c9de7c4a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-523d30cf02149aaa", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/TicketWatchApp.jsx:252"}, "properties": {"repobilityId": "849f3825ed7f9f7c", "scanner": "scanner-primary", "fingerprint": "523d30cf02149aaa", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b2f04004431a19de", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 website/src/components/Layout.jsx:81"}, "properties": {"repobilityId": "ee100795211dc084", "scanner": "scanner-primary", "fingerprint": "b2f04004431a19de", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cea6743327d1aa8b", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 website/src/components/Layout.jsx:49"}, "properties": {"repobilityId": "35954aa591321e65", "scanner": "scanner-primary", "fingerprint": "cea6743327d1aa8b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-c4d5b1989f7eb105", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/test-bcrypt.js:8"}, "properties": {"repobilityId": "444f4b3125482032", "scanner": "scanner-primary", "fingerprint": "c4d5b1989f7eb105", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d40865d55f4d4be1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/setup-admin.js:8"}, "properties": {"repobilityId": "09b712b51d787df2", "scanner": "scanner-primary", "fingerprint": "d40865d55f4d4be1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d91197b837c2e33d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/config/env.js:16"}, "properties": {"repobilityId": "bcea0e25966f7d8f", "scanner": "scanner-primary", "fingerprint": "d91197b837c2e33d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c439df49bcbaa016", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/routes/debtController.js:26"}, "properties": {"repobilityId": "97acd5fb7cbf1b45", "scanner": "scanner-primary", "fingerprint": "c439df49bcbaa016", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-14b3990f132ff9d8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/workers/test-adapter.js:15"}, "properties": {"repobilityId": "7184ef85f67b8c23", "scanner": "scanner-primary", "fingerprint": "14b3990f132ff9d8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b63aced91fcd4905", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/controllers/passportController.js:119"}, "properties": {"repobilityId": "4dc209a30cc43311", "scanner": "scanner-primary", "fingerprint": "b63aced91fcd4905", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-819f5885da934fd9", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/DebtApp.jsx:263"}, "properties": {"repobilityId": "96e4715d02540a27", "scanner": "scanner-primary", "fingerprint": "819f5885da934fd9", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/DebtApp.jsx"}, "region": {"startLine": 263}}}]}, {"ruleId": "scanner-24dcc47904178c59", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/auth/AuthContext.jsx:24"}, "properties": {"repobilityId": "bc6e47806823b225", "scanner": "scanner-primary", "fingerprint": "24dcc47904178c59", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/auth/AuthContext.jsx"}, "region": {"startLine": 24}}}]}, {"ruleId": "scanner-db6292f63031a093", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/backup/DebtApp.jsx:134"}, "properties": {"repobilityId": "52ee8202d1218b59", "scanner": "scanner-primary", "fingerprint": "db6292f63031a093", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/backup/DebtApp.jsx"}, "region": {"startLine": 134}}}]}, {"ruleId": "scanner-816edb8ea1d5045f", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/backup/App copy.jsx:134"}, "properties": {"repobilityId": "1340c2e1a43d8be7", "scanner": "scanner-primary", "fingerprint": "816edb8ea1d5045f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/backup/App copy.jsx"}, "region": {"startLine": 134}}}]}, {"ruleId": "scanner-9d928df7e02bc2df", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/backup/DebtApp copy.jsx:134"}, "properties": {"repobilityId": "d7fce23baaca9614", "scanner": "scanner-primary", "fingerprint": "9d928df7e02bc2df", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/backup/DebtApp copy.jsx"}, "region": {"startLine": 134}}}]}, {"ruleId": "scanner-6285166df6b19eff", "level": "error", "message": {"text": "Possible secret in backend/test-bcrypt.js"}, "properties": {"repobilityId": "e5a9dfd55a59be76", "scanner": "scanner-primary", "fingerprint": "6285166df6b19eff", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/test-bcrypt.js"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-fc36465e17a5438d", "level": "error", "message": {"text": "Possible secret in backend/setup-admin.js"}, "properties": {"repobilityId": "82f01cd7c90f5819", "scanner": "scanner-primary", "fingerprint": "fc36465e17a5438d", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/setup-admin.js"}, "region": {"startLine": 11}}}]}, {"ruleId": "scanner-fc36465e17a5438d", "level": "error", "message": {"text": "Possible secret in backend/setup-admin.js"}, "properties": {"repobilityId": "82f01cd7c90f5819", "scanner": "scanner-primary", "fingerprint": "fc36465e17a5438d", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/setup-admin.js"}, "region": {"startLine": 12}}}]}, {"ruleId": "scanner-f010c4ec8c7221b3", "level": "note", "message": {"text": "Very large file: website/src/DebtApp.jsx (1617 lines)"}, "properties": {"repobilityId": "6c01152f0770166e", "scanner": "scanner-primary", "fingerprint": "f010c4ec8c7221b3", "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": "f36b3b5a91db9f06", "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": "98aefcab6942c42d", "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": "7aa13588471f1847", "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": "b9bd6e12a136ae6a", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-11825279136b53a3", "level": "warning", "message": {"text": "CI is configured but no tests are detected"}, "properties": {"repobilityId": "96de25d23397a8db", "scanner": "scanner-primary", "fingerprint": "11825279136b53a3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "ci", "config-theater", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "865342ed6ea42201", "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": "e660e6b343dee38b", "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": "86f4d7b8e1804bf4", "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": "d22a33ca2282d414", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-9e58280a7d431f1e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/DebtApp.jsx:215"}, "properties": {"repobilityId": "83d401f79c10f2e9", "scanner": "scanner-primary", "fingerprint": "9e58280a7d431f1e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cf46cb67f600e65d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/PassportApp.jsx:216"}, "properties": {"repobilityId": "5ccc7a4abd3a1782", "scanner": "scanner-primary", "fingerprint": "cf46cb67f600e65d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0143bd5c5a4a79a2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/DebtApp.jsx:107"}, "properties": {"repobilityId": "b7060a1d886288bd", "scanner": "scanner-primary", "fingerprint": "0143bd5c5a4a79a2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5c667051cd6424ef", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/App copy.jsx:107"}, "properties": {"repobilityId": "c56491f04befedb4", "scanner": "scanner-primary", "fingerprint": "5c667051cd6424ef", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-044e8d6e310e8811", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/backup/DebtApp copy.jsx:107"}, "properties": {"repobilityId": "3a3ae3c7991376ce", "scanner": "scanner-primary", "fingerprint": "044e8d6e310e8811", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-39995dab897439b0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/services/client.js:22"}, "properties": {"repobilityId": "06bfb9b4820e3cbd", "scanner": "scanner-primary", "fingerprint": "39995dab897439b0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4d38286c74b40d9b", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/middleware/scope.js:1"}, "properties": {"repobilityId": "d18d2f3cb9e6fbd0", "scanner": "scanner-primary", "fingerprint": "4d38286c74b40d9b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ba7a3c65c9f33c46", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/workers/fareWatcher.js:3"}, "properties": {"repobilityId": "e923af6a7603c67c", "scanner": "scanner-primary", "fingerprint": "ba7a3c65c9f33c46", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2ad3a0901dfecbf0", "level": "none", "message": {"text": "Commented-code block (12 lines) in backend/workers/adapters/vietnamairlines.js:1"}, "properties": {"repobilityId": "51d36844b457239c", "scanner": "scanner-primary", "fingerprint": "2ad3a0901dfecbf0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2eafc3188c36bb02", "level": "none", "message": {"text": "3 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "bd934ba112b02ffa", "scanner": "scanner-primary", "fingerprint": "2eafc3188c36bb02", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-9d13a798f1c8c33b", "level": "warning", "message": {"text": "Frontend route `/passport` has no Link/navigate to it \u2014 website/src/backup/main copy 2.jsx"}, "properties": {"repobilityId": "bb60446b8017e0b6", "scanner": "scanner-primary", "fingerprint": "9d13a798f1c8c33b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-373c5d89871120b3", "level": "error", "message": {"text": "Dangling fetch: POST https://api.resend.com/emails (backend/config/email.js:27)"}, "properties": {"repobilityId": "a4ab3ebc9e57e488", "scanner": "scanner-primary", "fingerprint": "373c5d89871120b3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f62de1892f9909d1", "level": "error", "message": {"text": "Dangling fetch: GET https://serpapi.com/search?${params} (backend/workers/lib/serpapi.js:73)"}, "properties": {"repobilityId": "0d0fcdbf3a7c70e2", "scanner": "scanner-primary", "fingerprint": "f62de1892f9909d1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8fdbacfe9430a6ed", "level": "note", "message": {"text": "Unused endpoint: POST /auth/login"}, "properties": {"repobilityId": "a94ca27972131daf", "scanner": "scanner-primary", "fingerprint": "8fdbacfe9430a6ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8292c0931391749a", "level": "note", "message": {"text": "Unused endpoint: POST /auth/register"}, "properties": {"repobilityId": "80f9e0c57f9853a3", "scanner": "scanner-primary", "fingerprint": "8292c0931391749a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b119bb52041e0c8d", "level": "note", "message": {"text": "Unused endpoint: GET /auth/profile"}, "properties": {"repobilityId": "f3e9bd0c637bbe3d", "scanner": "scanner-primary", "fingerprint": "b119bb52041e0c8d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c987c6624ab77861", "level": "note", "message": {"text": "Unused endpoint: POST /debts"}, "properties": {"repobilityId": "5ec839ebf1612efc", "scanner": "scanner-primary", "fingerprint": "c987c6624ab77861", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7ca22bc3c62e9e7b", "level": "note", "message": {"text": "Unused endpoint: POST /debts/bulk"}, "properties": {"repobilityId": "0b266103c9c24971", "scanner": "scanner-primary", "fingerprint": "7ca22bc3c62e9e7b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a35ce3e9c9f59e0a", "level": "note", "message": {"text": "Unused endpoint: GET /companies"}, "properties": {"repobilityId": "52e6b7448e327435", "scanner": "scanner-primary", "fingerprint": "a35ce3e9c9f59e0a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ec39abb0b24cc5b2", "level": "note", "message": {"text": "Unused endpoint: POST /companies"}, "properties": {"repobilityId": "051ee495de16b45c", "scanner": "scanner-primary", "fingerprint": "ec39abb0b24cc5b2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-af75cdebd6061f00", "level": "note", "message": {"text": "Unused endpoint: GET /routes"}, "properties": {"repobilityId": "30c17bb1098819c9", "scanner": "scanner-primary", "fingerprint": "af75cdebd6061f00", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-034336dc074efeb4", "level": "note", "message": {"text": "Unused endpoint: POST /routes"}, "properties": {"repobilityId": "c0825adfac9182d6", "scanner": "scanner-primary", "fingerprint": "034336dc074efeb4", "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": "0a5793afc5ea0a13", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6bf5ff45910f6823", "level": "note", "message": {"text": "Unused endpoint: USE /api/debts"}, "properties": {"repobilityId": "fe9c62ddffa8612f", "scanner": "scanner-primary", "fingerprint": "6bf5ff45910f6823", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-345a2e4a2569c114", "level": "note", "message": {"text": "Unused endpoint: USE /api/passports"}, "properties": {"repobilityId": "d78089c941cba413", "scanner": "scanner-primary", "fingerprint": "345a2e4a2569c114", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bb789cf847f59e24", "level": "note", "message": {"text": "Unused endpoint: USE /api/companies"}, "properties": {"repobilityId": "743d09b6b1d9f3d6", "scanner": "scanner-primary", "fingerprint": "bb789cf847f59e24", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-530274a2ae45a5dc", "level": "note", "message": {"text": "Unused endpoint: USE /api/customers"}, "properties": {"repobilityId": "341dedcedf0609bd", "scanner": "scanner-primary", "fingerprint": "530274a2ae45a5dc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f8242ba07247d2f8", "level": "note", "message": {"text": "Unused endpoint: USE /api/payments"}, "properties": {"repobilityId": "5b917736e2ff1307", "scanner": "scanner-primary", "fingerprint": "f8242ba07247d2f8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4ff40cb10f7c8519", "level": "note", "message": {"text": "Unused endpoint: USE /api/users"}, "properties": {"repobilityId": "1e0c310b0a343b69", "scanner": "scanner-primary", "fingerprint": "4ff40cb10f7c8519", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1e1ec70ce9b71de8", "level": "note", "message": {"text": "Unused endpoint: USE /api/invoices"}, "properties": {"repobilityId": "5e7d85edab144a73", "scanner": "scanner-primary", "fingerprint": "1e1ec70ce9b71de8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1557fa2fbbe6dbf0", "level": "note", "message": {"text": "Unused endpoint: USE /api/deposits"}, "properties": {"repobilityId": "115736c1945612b4", "scanner": "scanner-primary", "fingerprint": "1557fa2fbbe6dbf0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-06c88a2e2dc65557", "level": "note", "message": {"text": "Unused endpoint: USE /api/stats"}, "properties": {"repobilityId": "f6bc559e0e595e7a", "scanner": "scanner-primary", "fingerprint": "06c88a2e2dc65557", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-36eed93c8c3e8347", "level": "note", "message": {"text": "Unused endpoint: USE /api/routes"}, "properties": {"repobilityId": "1b290d7d5564d22d", "scanner": "scanner-primary", "fingerprint": "36eed93c8c3e8347", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1b6c609850c719b2", "level": "note", "message": {"text": "Unused endpoint: USE /api/notes"}, "properties": {"repobilityId": "f496a2cdaa8c941a", "scanner": "scanner-primary", "fingerprint": "1b6c609850c719b2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-df7a560e6317b91e", "level": "note", "message": {"text": "Unused endpoint: USE /api/ticket-watches"}, "properties": {"repobilityId": "3825dda22654aacf", "scanner": "scanner-primary", "fingerprint": "df7a560e6317b91e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-831a8492063bbefd", "level": "note", "message": {"text": "Unused endpoint: USE /api/fares"}, "properties": {"repobilityId": "817987cc22fe3fa2", "scanner": "scanner-primary", "fingerprint": "831a8492063bbefd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ae183eec2aaab054", "level": "note", "message": {"text": "Unused endpoint: USE /api/airlines"}, "properties": {"repobilityId": "a7b52fd6a8e984a5", "scanner": "scanner-primary", "fingerprint": "ae183eec2aaab054", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4ec078e95fb5c261", "level": "note", "message": {"text": "Unused endpoint: USE /api/train-tickets"}, "properties": {"repobilityId": "433bb3487192b070", "scanner": "scanner-primary", "fingerprint": "4ec078e95fb5c261", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-14ed0a77b92f819f", "level": "note", "message": {"text": "Unused endpoint: USE /api/tours"}, "properties": {"repobilityId": "fac5223737fee1fe", "scanner": "scanner-primary", "fingerprint": "14ed0a77b92f819f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4756b4c4da7d2088", "level": "note", "message": {"text": "Unused endpoint: GET /api/health"}, "properties": {"repobilityId": "1e5295e69c6e06d8", "scanner": "scanner-primary", "fingerprint": "4756b4c4da7d2088", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "8fcb9b2737c3b064", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "863d18a46dd8cbc0", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8d5b2b188d08ca82", "level": "note", "message": {"text": "Unused endpoint: PUT /:id"}, "properties": {"repobilityId": "57afc4bb9f6d52bf", "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": "c620f502e9342a9f", "scanner": "scanner-primary", "fingerprint": "7a61c112b611f4bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b1c6b43f820b8518", "level": "note", "message": {"text": "Unused endpoint: POST /bulk-delete"}, "properties": {"repobilityId": "220f57b2aceb9dab", "scanner": "scanner-primary", "fingerprint": "b1c6b43f820b8518", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-be4cb5e3cabcce80", "level": "note", "message": {"text": "Unused endpoint: POST /import"}, "properties": {"repobilityId": "073f67169a3e5465", "scanner": "scanner-primary", "fingerprint": "be4cb5e3cabcce80", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca5756175765b49d", "level": "note", "message": {"text": "Unused endpoint: GET /:id"}, "properties": {"repobilityId": "fc66110da60ebcb8", "scanner": "scanner-primary", "fingerprint": "ca5756175765b49d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8f214fd3b826a0dd", "level": "note", "message": {"text": "Unused endpoint: DELETE /:routeName"}, "properties": {"repobilityId": "54eb94ec9d7f75f0", "scanner": "scanner-primary", "fingerprint": "8f214fd3b826a0dd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d7fa8929da9cbe3f", "level": "note", "message": {"text": "Unused endpoint: GET /balance"}, "properties": {"repobilityId": "89b343e00f8dad80", "scanner": "scanner-primary", "fingerprint": "d7fa8929da9cbe3f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bc62f6dc09a6abc3", "level": "note", "message": {"text": "Unused endpoint: PUT /:id/checkin"}, "properties": {"repobilityId": "0b32e3c4dd41e051", "scanner": "scanner-primary", "fingerprint": "bc62f6dc09a6abc3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-90631dcf4fb49f54", "level": "note", "message": {"text": "Unused endpoint: POST /bulk"}, "properties": {"repobilityId": "e6b9043bf7fda495", "scanner": "scanner-primary", "fingerprint": "90631dcf4fb49f54", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "0739200902492336", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-304b6f2b403d93f7", "level": "note", "message": {"text": "Unused endpoint: POST /register"}, "properties": {"repobilityId": "75111c8cb20116c6", "scanner": "scanner-primary", "fingerprint": "304b6f2b403d93f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4257ec01219aa99a", "level": "note", "message": {"text": "Unused endpoint: POST /forgot-password"}, "properties": {"repobilityId": "9dffa8bcecc5b191", "scanner": "scanner-primary", "fingerprint": "4257ec01219aa99a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-68a5d356c0cac9e3", "level": "note", "message": {"text": "Unused endpoint: POST /reset-password"}, "properties": {"repobilityId": "91c20811987986d1", "scanner": "scanner-primary", "fingerprint": "68a5d356c0cac9e3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2595b39638e5c045", "level": "note", "message": {"text": "Unused endpoint: GET /profile"}, "properties": {"repobilityId": "90cc5a916462fce9", "scanner": "scanner-primary", "fingerprint": "2595b39638e5c045", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-911492554a68d0c1", "level": "note", "message": {"text": "Unused endpoint: PUT /profile"}, "properties": {"repobilityId": "ece36e785ef6d6cf", "scanner": "scanner-primary", "fingerprint": "911492554a68d0c1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a569171ffb8378de", "level": "note", "message": {"text": "Unused endpoint: PUT /password"}, "properties": {"repobilityId": "fcf5c9ed6eb9ef83", "scanner": "scanner-primary", "fingerprint": "a569171ffb8378de", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-db0993b39976b123", "level": "note", "message": {"text": "Unused endpoint: GET /:id/snapshots"}, "properties": {"repobilityId": "919b12e1deda398e", "scanner": "scanner-primary", "fingerprint": "db0993b39976b123", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f2e0c1565accb359", "level": "note", "message": {"text": "Unused endpoint: POST /:id/check-now"}, "properties": {"repobilityId": "3ef4fa42dad93fed", "scanner": "scanner-primary", "fingerprint": "f2e0c1565accb359", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b6ddbcbab4f01790", "level": "note", "message": {"text": "Unused endpoint: PUT /:id/trial"}, "properties": {"repobilityId": "e2407e63983e0b42", "scanner": "scanner-primary", "fingerprint": "b6ddbcbab4f01790", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-060056f7b8b68374", "level": "note", "message": {"text": "Unused endpoint: POST /quote"}, "properties": {"repobilityId": "d58a0d45f8371405", "scanner": "scanner-primary", "fingerprint": "060056f7b8b68374", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}