{"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-ba13082b3a01c71b", "name": "Stray `console.log` in TS/JS \u2014 frontend/scripts/gen-icons.js:41", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/scripts/gen-icons.js:41"}, "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-2c613488a4cfb621", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/Battle.jsx:85", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/Battle.jsx:85"}, "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-bb26c78dafecca99", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/AITeacher.jsx:151", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/AITeacher.jsx:151"}, "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-fdffeeae4638b617", "name": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/admin.jsx:591", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/admin.jsx:591"}, "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-a4c4dcb7f8ce1c99", "name": "Stray `console.log` in TS/JS \u2014 mcp/test-client.js:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 mcp/test-client.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-41e2b7160358d5ce", "name": "Stray `console.log` in TS/JS \u2014 agents/src/index.js:42", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 agents/src/index.js:42"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-af73f7eef3a6510e", "name": "Stray `console.log` in TS/JS \u2014 agents/src/observability/logger.js:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 agents/src/observability/logger.js:35"}, "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-60792e64cf72c811", "name": "Stray `console.log` in TS/JS \u2014 backend/seed.js:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/seed.js:19"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-60a363047edc130a", "name": "Stray `console.log` in TS/JS \u2014 backend/src/db.js:56", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/db.js:56"}, "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-488a67c7a23f1f39", "name": "Stray `console.log` in TS/JS \u2014 backend/src/index.js:247", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/index.js:247"}, "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-b78e1f87acdd383c", "name": "Stray `console.log` in TS/JS \u2014 backend/src/middleware/threatDetector.js:246", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/middleware/threatDetector.js:246"}, "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-be84e7d62252c2e9", "name": "Stray `console.log` in TS/JS \u2014 backend/src/lib/migrate.js:198", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/lib/migrate.js:198"}, "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-cc31d9a7ccf8e515", "name": "Stray `console.log` in TS/JS \u2014 backend/src/lib/email.js:31", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/lib/email.js:31"}, "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-449061e64a59123f", "name": "Stray `console.log` in TS/JS \u2014 backend/src/lib/r2.js:48", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/lib/r2.js:48"}, "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-ef344ca62b39f1fe", "name": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.js:37", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.js:37"}, "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-cd2467559e8baa82", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/pages/Battle.jsx:85", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/pages/Battle.jsx:85"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ecc436f774c03f5e", "name": "Insecure pattern 'local_storage_auth_token' in frontend/src/pages/register.jsx:66", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/pages/register.jsx:66"}, "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-f09d8f9bbcf4d042", "name": "Insecure pattern 'local_storage_auth_token' in frontend/src/pages/login.jsx:62", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/pages/login.jsx:62"}, "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-d5938a6346ceca5e", "name": "Insecure pattern 'node_child_process' in mcp/test-client.js:4", "shortDescription": {"text": "Insecure pattern 'node_child_process' in mcp/test-client.js:4"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-48ce2a97f8c56487", "name": "Insecure pattern 'eval_used' in agents/src/tools/index.js:38", "shortDescription": {"text": "Insecure pattern 'eval_used' in agents/src/tools/index.js:38"}, "fullDescription": {"text": "Found a known-risky pattern (eval_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4b65f4b7359a6dbf", "name": "Insecure pattern 'node_child_process' in agents/src/tools/index.js:6", "shortDescription": {"text": "Insecure pattern 'node_child_process' in agents/src/tools/index.js:6"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4c57901ed63b01b2", "name": "Possible secret in backend/scripts/seed-demo.cjs", "shortDescription": {"text": "Possible secret in backend/scripts/seed-demo.cjs"}, "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-20d19b94f47ed35c", "name": "Possible secret in backend/scripts/test-security.cjs", "shortDescription": {"text": "Possible secret in backend/scripts/test-security.cjs"}, "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-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-b9408e48b8e975f1", "name": "Very large file: frontend/src/pages/Battle.jsx (1492 lines)", "shortDescription": {"text": "Very large file: frontend/src/pages/Battle.jsx (1492 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-17af6119f48c1244", "name": "Very large file: frontend/src/pages/admin.jsx (2299 lines)", "shortDescription": {"text": "Very large file: frontend/src/pages/admin.jsx (2299 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-3206152af9b65afd", "name": "Very large file: backend/src/routes/battle.js (1300 lines)", "shortDescription": {"text": "Very large file: backend/src/routes/battle.js (1300 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": "9 test file(s) for 136 source file(s) (ratio 0.07). 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 109 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 91 placeholder/mock markers across 36 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: 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-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-30bb085fb3c5ec98", "name": "Commented-code block (7 lines) in frontend/eslint.config.js:31", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/eslint.config.js:31"}, "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-2dce0d944f497b8a", "name": "Commented-code block (5 lines) in frontend/src/lib/api.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/lib/api.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-351c1757ac8aafdd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/TeacherDashboard.jsx:160", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/TeacherDashboard.jsx:160"}, "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-df10b6f0f10a3558", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Daily.jsx:95", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Daily.jsx:95"}, "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-027f55b30a766319", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Battle.jsx:423", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Battle.jsx:423"}, "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-a4378ee3b061fa94", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Lesson.jsx:115", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Lesson.jsx:115"}, "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-2d35fd43b3be618d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/coursedetail.jsx:82", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/coursedetail.jsx:82"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cd501210a693dfb4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/ModuleTest.jsx:49", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/ModuleTest.jsx:49"}, "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-91b7e3397dc51be1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 agents/src/llm/groq.js:19", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 agents/src/llm/groq.js:19"}, "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-d6daebb889f5b754", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/scripts/setup-telegram.cjs:71", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/scripts/setup-telegram.cjs:71"}, "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-e723bf222fe9db14", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/scripts/test-security.cjs:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/scripts/test-security.cjs:20"}, "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-a6638c814acb1898", "name": "Commented-code block (6 lines) in backend/src/middleware/attackShield.js:3", "shortDescription": {"text": "Commented-code block (6 lines) in backend/src/middleware/attackShield.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-60ae61fd1f94c93f", "name": "Commented-code block (10 lines) in backend/src/lib/r2.js:1", "shortDescription": {"text": "Commented-code block (10 lines) in backend/src/lib/r2.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-cc10973dbd530903", "name": "Commented-code block (5 lines) in backend/src/routes/admin.js:210", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/routes/admin.js:210"}, "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-bfbce27249e1ca61", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/routes/admin.js:233", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/routes/admin.js:233"}, "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-04928c4169ed516e", "name": "Commented-code block (5 lines) in backend/src/routes/auth.js:363", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/routes/auth.js:363"}, "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-ad1f2c0971b89ce0", "name": "10 env vars used in code but missing from .env.example", "shortDescription": {"text": "10 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `AGENT_TEMPERATURE`, `API_URL`, `BACKEND_URL`, `DATABASE_URL`, `GITHUB_REPO`, `GITHUB_TOKEN`, `NODE_ENV`, `RENDER_EXTERNAL_URL` + 2 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e864cf02de4f5409", "name": "Frontend route `/reset-password` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/reset-password` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-33be38c8ca096e2f", "name": "Frontend route `/verify-email` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/verify-email` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-320c121a2db1b257", "name": "Frontend route `/courses/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/courses/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a2d35c4a6bffac8f", "name": "Frontend route `/certificate-demo` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/certificate-demo` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5c66e7d6df5cd839", "name": "Frontend route `/verify/:code` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/verify/:code` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-0e09ab0cb0b36c76", "name": "Frontend route `/portfolio/:userId` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/portfolio/:userId` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-23b31c6ab23bd1a2", "name": "Frontend route `/portfolio` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/portfolio` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5146f7694490b7b0", "name": "Frontend route `/messages` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/messages` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-de52956dca5a2f69", "name": "Frontend route `/certificate/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/certificate/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5d9318ec3311c6d7", "name": "Frontend route `/courses/:courseId/lessons/:lessonIndex` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/courses/:courseId/lessons/:lessonIndex` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-bb2d984aab2f5bb1", "name": "Frontend route `/courses/:courseId/module-test/:moduleIndex` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/courses/:courseId/module-test/:moduleIndex` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e51da000b1ec1444", "name": "Frontend route `/admin` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/admin` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a1570c76445447dc", "name": "Dangling fetch: POST https://api.groq.com/openai/v1/chat/completions (agents/src/llm/groq.js:19)", "shortDescription": {"text": "Dangling fetch: POST https://api.groq.com/openai/v1/chat/completions (agents/src/llm/groq.js:19)"}, "fullDescription": {"text": "`agents/src/llm/groq.js:19` calls `POST https://api.groq.com/openai/v1/chat/completions` 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.groq.com/openai/v1/chat/completions`\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-e6cdd68e5cc617a8", "name": "Dangling fetch: GET https://api.telegram.org/bot${TOKEN}/getUpdates (backend/scripts/setup-telegram.cjs:27)", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${TOKEN}/getUpdates (backend/scripts/setup-telegram.cjs:27)"}, "fullDescription": {"text": "`backend/scripts/setup-telegram.cjs:27` calls `GET https://api.telegram.org/bot${TOKEN}/getUpdates` 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.telegram.org/bot/<p>/getupdates`\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-010e9357913be116", "name": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/scripts/setup-telegram.cjs:71)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/scripts/setup-telegram.cjs:71)"}, "fullDescription": {"text": "`backend/scripts/setup-telegram.cjs:71` calls `POST https://api.telegram.org/bot${TOKEN}/sendMessage` 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.telegram.org/bot/<p>/sendmessage`\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-a6bd0fbc9f84e035", "name": "Dangling fetch: POST https://api.groq.com/openai/v1/chat/completions (backend/src/lib/groq.js:8)", "shortDescription": {"text": "Dangling fetch: POST https://api.groq.com/openai/v1/chat/completions (backend/src/lib/groq.js:8)"}, "fullDescription": {"text": "`backend/src/lib/groq.js:8` calls `POST https://api.groq.com/openai/v1/chat/completions` 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.groq.com/openai/v1/chat/completions`\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-f409398e02602770", "name": "Dangling fetch: GET https://ipapi.co/${encodeURIComponent(ip)}/json/ (backend/src/lib/geoip.js:62)", "shortDescription": {"text": "Dangling fetch: GET https://ipapi.co/${encodeURIComponent(ip)}/json/ (backend/src/lib/geoip.js:62)"}, "fullDescription": {"text": "`backend/src/lib/geoip.js:62` calls `GET https://ipapi.co/${encodeURIComponent(ip)}/json/` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/ipapi.co/<p>/json`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c032acc9778d59b5", "name": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (backend/src/lib/email.js:83)", "shortDescription": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (backend/src/lib/email.js:83)"}, "fullDescription": {"text": "`backend/src/lib/email.js:83` calls `POST https://api.brevo.com/v3/smtp/email` 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.brevo.com/v3/smtp/email`\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-deb8e47380e89903", "name": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:33)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:33)"}, "fullDescription": {"text": "`backend/src/lib/telegram.js:33` calls `POST https://api.telegram.org/bot${TOKEN}/sendMessage` 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.telegram.org/bot/<p>/sendmessage`\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-ec92947fec34bb75", "name": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendLocation (backend/src/lib/telegram.js:74)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendLocation (backend/src/lib/telegram.js:74)"}, "fullDescription": {"text": "`backend/src/lib/telegram.js:74` calls `POST https://api.telegram.org/bot${TOKEN}/sendLocation` 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.telegram.org/bot/<p>/sendlocation`\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-db4e748517e68ac1", "name": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:176)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:176)"}, "fullDescription": {"text": "`backend/src/lib/telegram.js:176` calls `POST https://api.telegram.org/bot${TOKEN}/sendMessage` 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.telegram.org/bot/<p>/sendmessage`\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-3dbdbc03884bb5f1", "name": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/setWebhook (backend/src/lib/telegram.js:223)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/setWebhook (backend/src/lib/telegram.js:223)"}, "fullDescription": {"text": "`backend/src/lib/telegram.js:223` calls `POST https://api.telegram.org/bot${TOKEN}/setWebhook` 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.telegram.org/bot/<p>/setwebhook`\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-92bffeb784f73504", "name": "Dangling fetch: GET https://api.telegram.org/bot${TOKEN}/getWebhookInfo (backend/src/lib/telegram.js:239)", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${TOKEN}/getWebhookInfo (backend/src/lib/telegram.js:239)"}, "fullDescription": {"text": "`backend/src/lib/telegram.js:239` calls `GET https://api.telegram.org/bot${TOKEN}/getWebhookInfo` 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.telegram.org/bot/<p>/getwebhookinfo`\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-113d31294f39bb32", "name": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:256)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:256)"}, "fullDescription": {"text": "`backend/src/lib/telegram.js:256` calls `POST https://api.telegram.org/bot${TOKEN}/sendMessage` 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.telegram.org/bot/<p>/sendmessage`\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-d11eadf7871fb8d1", "name": "Dangling fetch: GET https://api.github.com/repos/${GITHUB_REPO}/pulls?state=all&per_page=50&sort=created&direction=desc ", "shortDescription": {"text": "Dangling fetch: GET https://api.github.com/repos/${GITHUB_REPO}/pulls?state=all&per_page=50&sort=created&direction=desc (backend/src/routes/admin.js:233)"}, "fullDescription": {"text": "`backend/src/routes/admin.js:233` calls `GET https://api.github.com/repos/${GITHUB_REPO}/pulls?state=all&per_page=50&sort=created&direction=desc` 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.github.com/repos/<p>/pulls`\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-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`agents/src/agents/fixDeveloper.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-76889df7c8e240c5", "name": "Unused endpoint: USE /api/", "shortDescription": {"text": "Unused endpoint: USE /api/"}, "fullDescription": {"text": "`backend/src/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": "`backend/src/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-def16861a13564b0", "name": "Unused endpoint: USE /api/auth/register", "shortDescription": {"text": "Unused endpoint: USE /api/auth/register"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/auth/register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0bfca63377edb533", "name": "Unused endpoint: USE /api/auth/forgot-password", "shortDescription": {"text": "Unused endpoint: USE /api/auth/forgot-password"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/auth/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-5c528a0ebb7992e6", "name": "Unused endpoint: USE /api/auth/reset-password", "shortDescription": {"text": "Unused endpoint: USE /api/auth/reset-password"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/auth/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-8b1557090369fcc5", "name": "Unused endpoint: USE /api/ai/", "shortDescription": {"text": "Unused endpoint: USE /api/ai/"}, "fullDescription": {"text": "`backend/src/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-621af77f9d7779a2", "name": "Unused endpoint: USE /api/onboarding/chat", "shortDescription": {"text": "Unused endpoint: USE /api/onboarding/chat"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/onboarding/chat` 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-5a702771d025cb5d", "name": "Unused endpoint: USE /api/daily/submit", "shortDescription": {"text": "Unused endpoint: USE /api/daily/submit"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/daily/submit` 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-3e864cee5a76d8ee", "name": "Unused endpoint: USE /api/module-test/generate", "shortDescription": {"text": "Unused endpoint: USE /api/module-test/generate"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/module-test/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-93277ab8e95a1e63", "name": "Unused endpoint: USE /api/battle/submit", "shortDescription": {"text": "Unused endpoint: USE /api/battle/submit"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/battle/submit` 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-1bc898b3b7565990", "name": "Unused endpoint: USE /uploads", "shortDescription": {"text": "Unused endpoint: USE /uploads"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /uploads` 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/src/index.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-6eb452fbfb454d20", "name": "Unused endpoint: USE /api/auth", "shortDescription": {"text": "Unused endpoint: USE /api/auth"}, "fullDescription": {"text": "`backend/src/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-e185b0afa062eded", "name": "Unused endpoint: USE /api/courses", "shortDescription": {"text": "Unused endpoint: USE /api/courses"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/courses` 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": "`backend/src/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-316c43db307befc3", "name": "Unused endpoint: USE /api/ai", "shortDescription": {"text": "Unused endpoint: USE /api/ai"}, "fullDescription": {"text": "`backend/src/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-f96b54f134593267", "name": "Unused endpoint: USE /api/teacher", "shortDescription": {"text": "Unused endpoint: USE /api/teacher"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/teacher` 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-ccb74f44f6aadda0", "name": "Unused endpoint: USE /api/battle", "shortDescription": {"text": "Unused endpoint: USE /api/battle"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/battle` 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-6f643fbf10ab5803", "name": "Unused endpoint: USE /api/upload", "shortDescription": {"text": "Unused endpoint: USE /api/upload"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/upload` 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-68d5a54ccf244b7c", "name": "Unused endpoint: USE /api/leaderboard", "shortDescription": {"text": "Unused endpoint: USE /api/leaderboard"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/leaderboard` 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-1c75c6f40d00cae7", "name": "Unused endpoint: USE /api/onboarding", "shortDescription": {"text": "Unused endpoint: USE /api/onboarding"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/onboarding` 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-24f3b1539124d098", "name": "Unused endpoint: USE /api/daily", "shortDescription": {"text": "Unused endpoint: USE /api/daily"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/daily` 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-522b4a1ef7120a10", "name": "Unused endpoint: USE /api/module-test", "shortDescription": {"text": "Unused endpoint: USE /api/module-test"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/module-test` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-03a12ea70a6b9d7a", "name": "Unused endpoint: USE /api/security", "shortDescription": {"text": "Unused endpoint: USE /api/security"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/security` 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-35cf7f0d1c31e59e", "name": "Unused endpoint: USE /api/telegram", "shortDescription": {"text": "Unused endpoint: USE /api/telegram"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/telegram` 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-d3d2df7bfb761887", "name": "Unused endpoint: USE /api/contact", "shortDescription": {"text": "Unused endpoint: USE /api/contact"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/contact` 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-c3a8b7932f72b92f", "name": "Unused endpoint: USE /api/notifications", "shortDescription": {"text": "Unused endpoint: USE /api/notifications"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/notifications` 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-a3093860a0c1e709", "name": "Unused endpoint: USE /api/lesson-notes", "shortDescription": {"text": "Unused endpoint: USE /api/lesson-notes"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/lesson-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-f182cb25186b8496", "name": "Unused endpoint: USE /api/video-progress", "shortDescription": {"text": "Unused endpoint: USE /api/video-progress"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/video-progress` 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-5db7b58b2b75bef3", "name": "Unused endpoint: USE /api/course-ratings", "shortDescription": {"text": "Unused endpoint: USE /api/course-ratings"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/course-ratings` 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-f4d1e4913af237f2", "name": "Unused endpoint: USE /api/lesson-qa", "shortDescription": {"text": "Unused endpoint: USE /api/lesson-qa"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/lesson-qa` 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-fc25acb2ffa6d0ab", "name": "Unused endpoint: USE /api/certificate", "shortDescription": {"text": "Unused endpoint: USE /api/certificate"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/certificate` 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/src/index.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-dbdbc13210e7149b", "name": "Unused endpoint: USE /api/dashboard", "shortDescription": {"text": "Unused endpoint: USE /api/dashboard"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/dashboard` 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-454e5ba6b67ab18b", "name": "Unused endpoint: USE /api/subscription", "shortDescription": {"text": "Unused endpoint: USE /api/subscription"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/subscription` 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-ec940d1f587fece3", "name": "Unused endpoint: USE /api/social", "shortDescription": {"text": "Unused endpoint: USE /api/social"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/social` 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-dd652300faf6f4b9", "name": "Unused endpoint: USE /api/portfolio", "shortDescription": {"text": "Unused endpoint: USE /api/portfolio"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/portfolio` 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-9a300508c4edb651", "name": "Unused endpoint: USE /api/messages", "shortDescription": {"text": "Unused endpoint: USE /api/messages"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /api/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-24941ef3375b376a", "name": "Unused endpoint: POST /issue/:courseId", "shortDescription": {"text": "Unused endpoint: POST /issue/:courseId"}, "fullDescription": {"text": "`backend/src/routes/certificate.js` declares `POST /issue/:courseId` 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-bc043602ec3592ed", "name": "Unused endpoint: GET /my", "shortDescription": {"text": "Unused endpoint: GET /my"}, "fullDescription": {"text": "`backend/src/routes/certificate.js` declares `GET /my` 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-8e804ae6fc05e617", "name": "Unused endpoint: GET /verify/:code", "shortDescription": {"text": "Unused endpoint: GET /verify/:code"}, "fullDescription": {"text": "`backend/src/routes/certificate.js` declares `GET /verify/:code` 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-ac8da91a19e3e7ab", "name": "Unused endpoint: GET /:courseId", "shortDescription": {"text": "Unused endpoint: GET /:courseId"}, "fullDescription": {"text": "`backend/src/routes/courseRatings.js` declares `GET /:courseId` 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-97f2badb6b05c6af", "name": "Unused endpoint: GET /:courseId/my", "shortDescription": {"text": "Unused endpoint: GET /:courseId/my"}, "fullDescription": {"text": "`backend/src/routes/courseRatings.js` declares `GET /:courseId/my` 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-ee17bb637614287d", "name": "Unused endpoint: POST /:courseId", "shortDescription": {"text": "Unused endpoint: POST /:courseId"}, "fullDescription": {"text": "`backend/src/routes/courseRatings.js` declares `POST /:courseId` 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-bc51d43445110bb6", "name": "Unused endpoint: DELETE /:courseId/my", "shortDescription": {"text": "Unused endpoint: DELETE /:courseId/my"}, "fullDescription": {"text": "`backend/src/routes/courseRatings.js` declares `DELETE /:courseId/my` 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-9a88e32ba95dda7c", "name": "Unused endpoint: POST /apply", "shortDescription": {"text": "Unused endpoint: POST /apply"}, "fullDescription": {"text": "`backend/src/routes/teacher.js` declares `POST /apply` 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-0f5d7c9d94231603", "name": "Unused endpoint: GET /my-status", "shortDescription": {"text": "Unused endpoint: GET /my-status"}, "fullDescription": {"text": "`backend/src/routes/teacher.js` declares `GET /my-status` 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-42719ea76f9ecae3", "name": "Unused endpoint: GET /requests", "shortDescription": {"text": "Unused endpoint: GET /requests"}, "fullDescription": {"text": "`backend/src/routes/teacher.js` declares `GET /requests` 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-8b9296ddade1932e", "name": "Unused endpoint: PUT /requests/:id", "shortDescription": {"text": "Unused endpoint: PUT /requests/:id"}, "fullDescription": {"text": "`backend/src/routes/teacher.js` declares `PUT /requests/: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}}]}}, "automationDetails": {"id": "repobility/19549"}, "properties": {"repository": "ShoxjaxonUZ/idrokai", "repoUrl": "https://github.com/ShoxjaxonUZ/idrokai", "branch": "main"}, "results": [{"ruleId": "scanner-ba13082b3a01c71b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/scripts/gen-icons.js:41"}, "properties": {"repobilityId": "cd42d58c34c64b09", "scanner": "scanner-primary", "fingerprint": "ba13082b3a01c71b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2c613488a4cfb621", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/Battle.jsx:85"}, "properties": {"repobilityId": "11a2dc6f48f7a079", "scanner": "scanner-primary", "fingerprint": "2c613488a4cfb621", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bb26c78dafecca99", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/AITeacher.jsx:151"}, "properties": {"repobilityId": "dc072c8a9b31560e", "scanner": "scanner-primary", "fingerprint": "bb26c78dafecca99", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fdffeeae4638b617", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/src/pages/admin.jsx:591"}, "properties": {"repobilityId": "b95d1fcb2f220396", "scanner": "scanner-primary", "fingerprint": "fdffeeae4638b617", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a4c4dcb7f8ce1c99", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 mcp/test-client.js:26"}, "properties": {"repobilityId": "ac106d994badb27c", "scanner": "scanner-primary", "fingerprint": "a4c4dcb7f8ce1c99", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-41e2b7160358d5ce", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 agents/src/index.js:42"}, "properties": {"repobilityId": "0d993d643b9c9490", "scanner": "scanner-primary", "fingerprint": "41e2b7160358d5ce", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-af73f7eef3a6510e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 agents/src/observability/logger.js:35"}, "properties": {"repobilityId": "8fae787b80ca40dd", "scanner": "scanner-primary", "fingerprint": "af73f7eef3a6510e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-60792e64cf72c811", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/seed.js:19"}, "properties": {"repobilityId": "39959ae5a7d06d0f", "scanner": "scanner-primary", "fingerprint": "60792e64cf72c811", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-60a363047edc130a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/db.js:56"}, "properties": {"repobilityId": "149cecece2f6d4d8", "scanner": "scanner-primary", "fingerprint": "60a363047edc130a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-488a67c7a23f1f39", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/index.js:247"}, "properties": {"repobilityId": "03d5d680343d7d14", "scanner": "scanner-primary", "fingerprint": "488a67c7a23f1f39", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b78e1f87acdd383c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/middleware/threatDetector.js:246"}, "properties": {"repobilityId": "0245848488e743b1", "scanner": "scanner-primary", "fingerprint": "b78e1f87acdd383c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-be84e7d62252c2e9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/lib/migrate.js:198"}, "properties": {"repobilityId": "ede46b890c240b12", "scanner": "scanner-primary", "fingerprint": "be84e7d62252c2e9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cc31d9a7ccf8e515", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/lib/email.js:31"}, "properties": {"repobilityId": "f1d17d270b65aec7", "scanner": "scanner-primary", "fingerprint": "cc31d9a7ccf8e515", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-449061e64a59123f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/lib/r2.js:48"}, "properties": {"repobilityId": "6eeb89776790393f", "scanner": "scanner-primary", "fingerprint": "449061e64a59123f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ef344ca62b39f1fe", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/lib/api.js:37"}, "properties": {"repobilityId": "c8b2a4977794b8bd", "scanner": "scanner-primary", "fingerprint": "ef344ca62b39f1fe", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/lib/api.js"}, "region": {"startLine": 37}}}]}, {"ruleId": "scanner-cd2467559e8baa82", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/src/pages/Battle.jsx:85"}, "properties": {"repobilityId": "9fb851c875957db3", "scanner": "scanner-primary", "fingerprint": "cd2467559e8baa82", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/pages/Battle.jsx"}, "region": {"startLine": 85}}}]}, {"ruleId": "scanner-ecc436f774c03f5e", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/pages/register.jsx:66"}, "properties": {"repobilityId": "0f0645b1597629f2", "scanner": "scanner-primary", "fingerprint": "ecc436f774c03f5e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/pages/register.jsx"}, "region": {"startLine": 66}}}]}, {"ruleId": "scanner-f09d8f9bbcf4d042", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/src/pages/login.jsx:62"}, "properties": {"repobilityId": "cf300313e0cb66fb", "scanner": "scanner-primary", "fingerprint": "f09d8f9bbcf4d042", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/pages/login.jsx"}, "region": {"startLine": 62}}}]}, {"ruleId": "scanner-d5938a6346ceca5e", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in mcp/test-client.js:4"}, "properties": {"repobilityId": "0a0aab6806d01e92", "scanner": "scanner-primary", "fingerprint": "d5938a6346ceca5e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mcp/test-client.js"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-48ce2a97f8c56487", "level": "error", "message": {"text": "Insecure pattern 'eval_used' in agents/src/tools/index.js:38"}, "properties": {"repobilityId": "bad7f142b4beba3e", "scanner": "scanner-primary", "fingerprint": "48ce2a97f8c56487", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "eval_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agents/src/tools/index.js"}, "region": {"startLine": 38}}}]}, {"ruleId": "scanner-4b65f4b7359a6dbf", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in agents/src/tools/index.js:6"}, "properties": {"repobilityId": "cea00fc2ec604c2b", "scanner": "scanner-primary", "fingerprint": "4b65f4b7359a6dbf", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agents/src/tools/index.js"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-4c57901ed63b01b2", "level": "error", "message": {"text": "Possible secret in backend/scripts/seed-demo.cjs"}, "properties": {"repobilityId": "ac296c0efd644219", "scanner": "scanner-primary", "fingerprint": "4c57901ed63b01b2", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/seed-demo.cjs"}, "region": {"startLine": 105}}}]}, {"ruleId": "scanner-4c57901ed63b01b2", "level": "error", "message": {"text": "Possible secret in backend/scripts/seed-demo.cjs"}, "properties": {"repobilityId": "ac296c0efd644219", "scanner": "scanner-primary", "fingerprint": "4c57901ed63b01b2", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/seed-demo.cjs"}, "region": {"startLine": 106}}}]}, {"ruleId": "scanner-4c57901ed63b01b2", "level": "error", "message": {"text": "Possible secret in backend/scripts/seed-demo.cjs"}, "properties": {"repobilityId": "ac296c0efd644219", "scanner": "scanner-primary", "fingerprint": "4c57901ed63b01b2", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/seed-demo.cjs"}, "region": {"startLine": 107}}}]}, {"ruleId": "scanner-20d19b94f47ed35c", "level": "error", "message": {"text": "Possible secret in backend/scripts/test-security.cjs"}, "properties": {"repobilityId": "d2b51a893b4c116c", "scanner": "scanner-primary", "fingerprint": "20d19b94f47ed35c", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/test-security.cjs"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-20d19b94f47ed35c", "level": "error", "message": {"text": "Possible secret in backend/scripts/test-security.cjs"}, "properties": {"repobilityId": "d2b51a893b4c116c", "scanner": "scanner-primary", "fingerprint": "20d19b94f47ed35c", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/test-security.cjs"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-20d19b94f47ed35c", "level": "error", "message": {"text": "Possible secret in backend/scripts/test-security.cjs"}, "properties": {"repobilityId": "d2b51a893b4c116c", "scanner": "scanner-primary", "fingerprint": "20d19b94f47ed35c", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/test-security.cjs"}, "region": {"startLine": 56}}}]}, {"ruleId": "scanner-20d19b94f47ed35c", "level": "error", "message": {"text": "Possible secret in backend/scripts/test-security.cjs"}, "properties": {"repobilityId": "d2b51a893b4c116c", "scanner": "scanner-primary", "fingerprint": "20d19b94f47ed35c", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/test-security.cjs"}, "region": {"startLine": 116}}}]}, {"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-b9408e48b8e975f1", "level": "note", "message": {"text": "Very large file: frontend/src/pages/Battle.jsx (1492 lines)"}, "properties": {"repobilityId": "232bd8593f419a6f", "scanner": "scanner-primary", "fingerprint": "b9408e48b8e975f1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-17af6119f48c1244", "level": "note", "message": {"text": "Very large file: frontend/src/pages/admin.jsx (2299 lines)"}, "properties": {"repobilityId": "1e8f76f007013cba", "scanner": "scanner-primary", "fingerprint": "17af6119f48c1244", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3206152af9b65afd", "level": "note", "message": {"text": "Very large file: backend/src/routes/battle.js (1300 lines)"}, "properties": {"repobilityId": "3667a6c7e8f5d461", "scanner": "scanner-primary", "fingerprint": "3206152af9b65afd", "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": "ad3ac2beec933336", "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": "edab5bac58af2545", "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": "3a248a9e205c3438", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "9218585c2f3465f8", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "9207b927e657eb41", "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": "e91d38a171edd1dd", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "4b1bd4beabdb480d", "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": "e5c6071b5d161180", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-30bb085fb3c5ec98", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/eslint.config.js:31"}, "properties": {"repobilityId": "dff23f390f3837f7", "scanner": "scanner-primary", "fingerprint": "30bb085fb3c5ec98", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2dce0d944f497b8a", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/lib/api.js:3"}, "properties": {"repobilityId": "b94bda33b15ab8cb", "scanner": "scanner-primary", "fingerprint": "2dce0d944f497b8a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-351c1757ac8aafdd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/TeacherDashboard.jsx:160"}, "properties": {"repobilityId": "235edea202ddaba5", "scanner": "scanner-primary", "fingerprint": "351c1757ac8aafdd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-df10b6f0f10a3558", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Daily.jsx:95"}, "properties": {"repobilityId": "071c48bde1661588", "scanner": "scanner-primary", "fingerprint": "df10b6f0f10a3558", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-027f55b30a766319", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Battle.jsx:423"}, "properties": {"repobilityId": "bf9994c208fcc6e5", "scanner": "scanner-primary", "fingerprint": "027f55b30a766319", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a4378ee3b061fa94", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/Lesson.jsx:115"}, "properties": {"repobilityId": "d54eada23c7ff15c", "scanner": "scanner-primary", "fingerprint": "a4378ee3b061fa94", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2d35fd43b3be618d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/coursedetail.jsx:82"}, "properties": {"repobilityId": "2b672dd7571c6676", "scanner": "scanner-primary", "fingerprint": "2d35fd43b3be618d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cd501210a693dfb4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/ModuleTest.jsx:49"}, "properties": {"repobilityId": "f185eb950ea7e835", "scanner": "scanner-primary", "fingerprint": "cd501210a693dfb4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-91b7e3397dc51be1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 agents/src/llm/groq.js:19"}, "properties": {"repobilityId": "7d46afe549ee03ff", "scanner": "scanner-primary", "fingerprint": "91b7e3397dc51be1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d6daebb889f5b754", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/scripts/setup-telegram.cjs:71"}, "properties": {"repobilityId": "a40e8f8a4f6f8427", "scanner": "scanner-primary", "fingerprint": "d6daebb889f5b754", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e723bf222fe9db14", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/scripts/test-security.cjs:20"}, "properties": {"repobilityId": "cefa835f682977e9", "scanner": "scanner-primary", "fingerprint": "e723bf222fe9db14", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a6638c814acb1898", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/src/middleware/attackShield.js:3"}, "properties": {"repobilityId": "9a9e9f50332ec22d", "scanner": "scanner-primary", "fingerprint": "a6638c814acb1898", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-60ae61fd1f94c93f", "level": "none", "message": {"text": "Commented-code block (10 lines) in backend/src/lib/r2.js:1"}, "properties": {"repobilityId": "83f30ae1d9dbd99e", "scanner": "scanner-primary", "fingerprint": "60ae61fd1f94c93f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cc10973dbd530903", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/routes/admin.js:210"}, "properties": {"repobilityId": "5f8015e61c4d3ff9", "scanner": "scanner-primary", "fingerprint": "cc10973dbd530903", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bfbce27249e1ca61", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/routes/admin.js:233"}, "properties": {"repobilityId": "4a71a6a5a57f4866", "scanner": "scanner-primary", "fingerprint": "bfbce27249e1ca61", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-04928c4169ed516e", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/routes/auth.js:363"}, "properties": {"repobilityId": "8ff02d1b5eae67de", "scanner": "scanner-primary", "fingerprint": "04928c4169ed516e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ad1f2c0971b89ce0", "level": "note", "message": {"text": "10 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "3bfdc60c61f1870e", "scanner": "scanner-primary", "fingerprint": "ad1f2c0971b89ce0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-e864cf02de4f5409", "level": "warning", "message": {"text": "Frontend route `/reset-password` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "e1cae2d17f680088", "scanner": "scanner-primary", "fingerprint": "e864cf02de4f5409", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-33be38c8ca096e2f", "level": "warning", "message": {"text": "Frontend route `/verify-email` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "09e54bcbcf687c10", "scanner": "scanner-primary", "fingerprint": "33be38c8ca096e2f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-320c121a2db1b257", "level": "warning", "message": {"text": "Frontend route `/courses/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "155c085140c192a7", "scanner": "scanner-primary", "fingerprint": "320c121a2db1b257", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a2d35c4a6bffac8f", "level": "warning", "message": {"text": "Frontend route `/certificate-demo` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "3083211ae3669806", "scanner": "scanner-primary", "fingerprint": "a2d35c4a6bffac8f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5c66e7d6df5cd839", "level": "warning", "message": {"text": "Frontend route `/verify/:code` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "0d7a55644b75dfb2", "scanner": "scanner-primary", "fingerprint": "5c66e7d6df5cd839", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-0e09ab0cb0b36c76", "level": "warning", "message": {"text": "Frontend route `/portfolio/:userId` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "314cbd7e750be2b6", "scanner": "scanner-primary", "fingerprint": "0e09ab0cb0b36c76", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-23b31c6ab23bd1a2", "level": "warning", "message": {"text": "Frontend route `/portfolio` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "22e94d8da2d4e0f0", "scanner": "scanner-primary", "fingerprint": "23b31c6ab23bd1a2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5146f7694490b7b0", "level": "warning", "message": {"text": "Frontend route `/messages` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "2c4bed5aceb417d4", "scanner": "scanner-primary", "fingerprint": "5146f7694490b7b0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-de52956dca5a2f69", "level": "warning", "message": {"text": "Frontend route `/certificate/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "d6800428c68ca79d", "scanner": "scanner-primary", "fingerprint": "de52956dca5a2f69", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5d9318ec3311c6d7", "level": "warning", "message": {"text": "Frontend route `/courses/:courseId/lessons/:lessonIndex` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "71ae244445fda027", "scanner": "scanner-primary", "fingerprint": "5d9318ec3311c6d7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-bb2d984aab2f5bb1", "level": "warning", "message": {"text": "Frontend route `/courses/:courseId/module-test/:moduleIndex` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "fcd342a2286cdb9c", "scanner": "scanner-primary", "fingerprint": "bb2d984aab2f5bb1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e51da000b1ec1444", "level": "warning", "message": {"text": "Frontend route `/admin` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "8276c7ee996625af", "scanner": "scanner-primary", "fingerprint": "e51da000b1ec1444", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a1570c76445447dc", "level": "error", "message": {"text": "Dangling fetch: POST https://api.groq.com/openai/v1/chat/completions (agents/src/llm/groq.js:19)"}, "properties": {"repobilityId": "a54dbf91bb652f59", "scanner": "scanner-primary", "fingerprint": "a1570c76445447dc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e6cdd68e5cc617a8", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${TOKEN}/getUpdates (backend/scripts/setup-telegram.cjs:27)"}, "properties": {"repobilityId": "eb648d34ccc5138b", "scanner": "scanner-primary", "fingerprint": "e6cdd68e5cc617a8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-010e9357913be116", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/scripts/setup-telegram.cjs:71)"}, "properties": {"repobilityId": "b6a8eb3b33ffd5ed", "scanner": "scanner-primary", "fingerprint": "010e9357913be116", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a6bd0fbc9f84e035", "level": "error", "message": {"text": "Dangling fetch: POST https://api.groq.com/openai/v1/chat/completions (backend/src/lib/groq.js:8)"}, "properties": {"repobilityId": "c42d880503d516cb", "scanner": "scanner-primary", "fingerprint": "a6bd0fbc9f84e035", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f409398e02602770", "level": "error", "message": {"text": "Dangling fetch: GET https://ipapi.co/${encodeURIComponent(ip)}/json/ (backend/src/lib/geoip.js:62)"}, "properties": {"repobilityId": "e2a2289343298f93", "scanner": "scanner-primary", "fingerprint": "f409398e02602770", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c032acc9778d59b5", "level": "error", "message": {"text": "Dangling fetch: POST https://api.brevo.com/v3/smtp/email (backend/src/lib/email.js:83)"}, "properties": {"repobilityId": "da45fae06c8e2a3d", "scanner": "scanner-primary", "fingerprint": "c032acc9778d59b5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-deb8e47380e89903", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:33)"}, "properties": {"repobilityId": "8ebcc5a33d2727a2", "scanner": "scanner-primary", "fingerprint": "deb8e47380e89903", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ec92947fec34bb75", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendLocation (backend/src/lib/telegram.js:74)"}, "properties": {"repobilityId": "3a4d8c143b7bd7c4", "scanner": "scanner-primary", "fingerprint": "ec92947fec34bb75", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-db4e748517e68ac1", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:176)"}, "properties": {"repobilityId": "12bb3209b877f9be", "scanner": "scanner-primary", "fingerprint": "db4e748517e68ac1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3dbdbc03884bb5f1", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/setWebhook (backend/src/lib/telegram.js:223)"}, "properties": {"repobilityId": "91354d37cd7d125a", "scanner": "scanner-primary", "fingerprint": "3dbdbc03884bb5f1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-92bffeb784f73504", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${TOKEN}/getWebhookInfo (backend/src/lib/telegram.js:239)"}, "properties": {"repobilityId": "d7cd7456c62c41c1", "scanner": "scanner-primary", "fingerprint": "92bffeb784f73504", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-113d31294f39bb32", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${TOKEN}/sendMessage (backend/src/lib/telegram.js:256)"}, "properties": {"repobilityId": "b07f32019e42c07c", "scanner": "scanner-primary", "fingerprint": "113d31294f39bb32", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d11eadf7871fb8d1", "level": "error", "message": {"text": "Dangling fetch: GET https://api.github.com/repos/${GITHUB_REPO}/pulls?state=all&per_page=50&sort=created&direction=desc (backend/src/routes/admin.js:233)"}, "properties": {"repobilityId": "137da157e09e9772", "scanner": "scanner-primary", "fingerprint": "d11eadf7871fb8d1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "40af93082b9fe644", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76889df7c8e240c5", "level": "note", "message": {"text": "Unused endpoint: USE /api/"}, "properties": {"repobilityId": "814aeaa832b206c4", "scanner": "scanner-primary", "fingerprint": "76889df7c8e240c5", "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": "78f2285c508af9f5", "scanner": "scanner-primary", "fingerprint": "8bf2f7ca3faa1f1b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-def16861a13564b0", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth/register"}, "properties": {"repobilityId": "ee1628b7cc7ad76f", "scanner": "scanner-primary", "fingerprint": "def16861a13564b0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0bfca63377edb533", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth/forgot-password"}, "properties": {"repobilityId": "477932996da78981", "scanner": "scanner-primary", "fingerprint": "0bfca63377edb533", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5c528a0ebb7992e6", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth/reset-password"}, "properties": {"repobilityId": "b074a81e5707c09b", "scanner": "scanner-primary", "fingerprint": "5c528a0ebb7992e6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8b1557090369fcc5", "level": "note", "message": {"text": "Unused endpoint: USE /api/ai/"}, "properties": {"repobilityId": "436989b253dfb593", "scanner": "scanner-primary", "fingerprint": "8b1557090369fcc5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-621af77f9d7779a2", "level": "note", "message": {"text": "Unused endpoint: USE /api/onboarding/chat"}, "properties": {"repobilityId": "cf87abc84e86892d", "scanner": "scanner-primary", "fingerprint": "621af77f9d7779a2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5a702771d025cb5d", "level": "note", "message": {"text": "Unused endpoint: USE /api/daily/submit"}, "properties": {"repobilityId": "142795d5dd3b1376", "scanner": "scanner-primary", "fingerprint": "5a702771d025cb5d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3e864cee5a76d8ee", "level": "note", "message": {"text": "Unused endpoint: USE /api/module-test/generate"}, "properties": {"repobilityId": "4bfc11cb0a155e80", "scanner": "scanner-primary", "fingerprint": "3e864cee5a76d8ee", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-93277ab8e95a1e63", "level": "note", "message": {"text": "Unused endpoint: USE /api/battle/submit"}, "properties": {"repobilityId": "e21ad6a9b50246a0", "scanner": "scanner-primary", "fingerprint": "93277ab8e95a1e63", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1bc898b3b7565990", "level": "note", "message": {"text": "Unused endpoint: USE /uploads"}, "properties": {"repobilityId": "6a761febc97f84d3", "scanner": "scanner-primary", "fingerprint": "1bc898b3b7565990", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "bdafcfb850f81e55", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "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": "0f796847ea791306", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e185b0afa062eded", "level": "note", "message": {"text": "Unused endpoint: USE /api/courses"}, "properties": {"repobilityId": "e4e3640b0e7ccdb8", "scanner": "scanner-primary", "fingerprint": "e185b0afa062eded", "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": "d55ff0364e63b06e", "scanner": "scanner-primary", "fingerprint": "d93a530ce10d47d9", "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": "814042f1edb2159e", "scanner": "scanner-primary", "fingerprint": "316c43db307befc3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f96b54f134593267", "level": "note", "message": {"text": "Unused endpoint: USE /api/teacher"}, "properties": {"repobilityId": "7deb63875ca3342e", "scanner": "scanner-primary", "fingerprint": "f96b54f134593267", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ccb74f44f6aadda0", "level": "note", "message": {"text": "Unused endpoint: USE /api/battle"}, "properties": {"repobilityId": "9ab54a4918507a58", "scanner": "scanner-primary", "fingerprint": "ccb74f44f6aadda0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6f643fbf10ab5803", "level": "note", "message": {"text": "Unused endpoint: USE /api/upload"}, "properties": {"repobilityId": "3f9ae36101ac4efc", "scanner": "scanner-primary", "fingerprint": "6f643fbf10ab5803", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-68d5a54ccf244b7c", "level": "note", "message": {"text": "Unused endpoint: USE /api/leaderboard"}, "properties": {"repobilityId": "8a4e7d21be0021d6", "scanner": "scanner-primary", "fingerprint": "68d5a54ccf244b7c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1c75c6f40d00cae7", "level": "note", "message": {"text": "Unused endpoint: USE /api/onboarding"}, "properties": {"repobilityId": "f9e348bca8aa9557", "scanner": "scanner-primary", "fingerprint": "1c75c6f40d00cae7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-24f3b1539124d098", "level": "note", "message": {"text": "Unused endpoint: USE /api/daily"}, "properties": {"repobilityId": "b6f5b0250ab33ff0", "scanner": "scanner-primary", "fingerprint": "24f3b1539124d098", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-522b4a1ef7120a10", "level": "note", "message": {"text": "Unused endpoint: USE /api/module-test"}, "properties": {"repobilityId": "ab0583e971ed2d7b", "scanner": "scanner-primary", "fingerprint": "522b4a1ef7120a10", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-03a12ea70a6b9d7a", "level": "note", "message": {"text": "Unused endpoint: USE /api/security"}, "properties": {"repobilityId": "f3ca4a02d3d682cf", "scanner": "scanner-primary", "fingerprint": "03a12ea70a6b9d7a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-35cf7f0d1c31e59e", "level": "note", "message": {"text": "Unused endpoint: USE /api/telegram"}, "properties": {"repobilityId": "67215366abcbe39c", "scanner": "scanner-primary", "fingerprint": "35cf7f0d1c31e59e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d3d2df7bfb761887", "level": "note", "message": {"text": "Unused endpoint: USE /api/contact"}, "properties": {"repobilityId": "1658b3c62221676d", "scanner": "scanner-primary", "fingerprint": "d3d2df7bfb761887", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c3a8b7932f72b92f", "level": "note", "message": {"text": "Unused endpoint: USE /api/notifications"}, "properties": {"repobilityId": "54797051e7cc5140", "scanner": "scanner-primary", "fingerprint": "c3a8b7932f72b92f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a3093860a0c1e709", "level": "note", "message": {"text": "Unused endpoint: USE /api/lesson-notes"}, "properties": {"repobilityId": "c93b5873278845c7", "scanner": "scanner-primary", "fingerprint": "a3093860a0c1e709", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f182cb25186b8496", "level": "note", "message": {"text": "Unused endpoint: USE /api/video-progress"}, "properties": {"repobilityId": "d38491364184127e", "scanner": "scanner-primary", "fingerprint": "f182cb25186b8496", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5db7b58b2b75bef3", "level": "note", "message": {"text": "Unused endpoint: USE /api/course-ratings"}, "properties": {"repobilityId": "7938081785aa0f06", "scanner": "scanner-primary", "fingerprint": "5db7b58b2b75bef3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f4d1e4913af237f2", "level": "note", "message": {"text": "Unused endpoint: USE /api/lesson-qa"}, "properties": {"repobilityId": "0259b3032ba9794a", "scanner": "scanner-primary", "fingerprint": "f4d1e4913af237f2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fc25acb2ffa6d0ab", "level": "note", "message": {"text": "Unused endpoint: USE /api/certificate"}, "properties": {"repobilityId": "98a7da65523d9a54", "scanner": "scanner-primary", "fingerprint": "fc25acb2ffa6d0ab", "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": "34bcba6db2850bb6", "scanner": "scanner-primary", "fingerprint": "06c88a2e2dc65557", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dbdbc13210e7149b", "level": "note", "message": {"text": "Unused endpoint: USE /api/dashboard"}, "properties": {"repobilityId": "4952989c6e2f3526", "scanner": "scanner-primary", "fingerprint": "dbdbc13210e7149b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-454e5ba6b67ab18b", "level": "note", "message": {"text": "Unused endpoint: USE /api/subscription"}, "properties": {"repobilityId": "3ddde4025eb5e29f", "scanner": "scanner-primary", "fingerprint": "454e5ba6b67ab18b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ec940d1f587fece3", "level": "note", "message": {"text": "Unused endpoint: USE /api/social"}, "properties": {"repobilityId": "d52d109c5aef5f1e", "scanner": "scanner-primary", "fingerprint": "ec940d1f587fece3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dd652300faf6f4b9", "level": "note", "message": {"text": "Unused endpoint: USE /api/portfolio"}, "properties": {"repobilityId": "b6a3d59747bb9cf0", "scanner": "scanner-primary", "fingerprint": "dd652300faf6f4b9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9a300508c4edb651", "level": "note", "message": {"text": "Unused endpoint: USE /api/messages"}, "properties": {"repobilityId": "c42a442b7aff1eb1", "scanner": "scanner-primary", "fingerprint": "9a300508c4edb651", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-24941ef3375b376a", "level": "note", "message": {"text": "Unused endpoint: POST /issue/:courseId"}, "properties": {"repobilityId": "3ac2e64ab86d4fe8", "scanner": "scanner-primary", "fingerprint": "24941ef3375b376a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bc043602ec3592ed", "level": "note", "message": {"text": "Unused endpoint: GET /my"}, "properties": {"repobilityId": "3741ac2c94b108de", "scanner": "scanner-primary", "fingerprint": "bc043602ec3592ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8e804ae6fc05e617", "level": "note", "message": {"text": "Unused endpoint: GET /verify/:code"}, "properties": {"repobilityId": "30ada218e00c06f9", "scanner": "scanner-primary", "fingerprint": "8e804ae6fc05e617", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ac8da91a19e3e7ab", "level": "note", "message": {"text": "Unused endpoint: GET /:courseId"}, "properties": {"repobilityId": "00999ed1b4d3ec11", "scanner": "scanner-primary", "fingerprint": "ac8da91a19e3e7ab", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-97f2badb6b05c6af", "level": "note", "message": {"text": "Unused endpoint: GET /:courseId/my"}, "properties": {"repobilityId": "05475ea0a535dd72", "scanner": "scanner-primary", "fingerprint": "97f2badb6b05c6af", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ee17bb637614287d", "level": "note", "message": {"text": "Unused endpoint: POST /:courseId"}, "properties": {"repobilityId": "25191a7d951d514f", "scanner": "scanner-primary", "fingerprint": "ee17bb637614287d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bc51d43445110bb6", "level": "note", "message": {"text": "Unused endpoint: DELETE /:courseId/my"}, "properties": {"repobilityId": "9021cd86b87d5efa", "scanner": "scanner-primary", "fingerprint": "bc51d43445110bb6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9a88e32ba95dda7c", "level": "note", "message": {"text": "Unused endpoint: POST /apply"}, "properties": {"repobilityId": "eed88914c1f3c4b1", "scanner": "scanner-primary", "fingerprint": "9a88e32ba95dda7c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0f5d7c9d94231603", "level": "note", "message": {"text": "Unused endpoint: GET /my-status"}, "properties": {"repobilityId": "270e4a96596e3ba9", "scanner": "scanner-primary", "fingerprint": "0f5d7c9d94231603", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-42719ea76f9ecae3", "level": "note", "message": {"text": "Unused endpoint: GET /requests"}, "properties": {"repobilityId": "7e6a17a2772cf068", "scanner": "scanner-primary", "fingerprint": "42719ea76f9ecae3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8b9296ddade1932e", "level": "note", "message": {"text": "Unused endpoint: PUT /requests/:id"}, "properties": {"repobilityId": "b4e008144d483bcb", "scanner": "scanner-primary", "fingerprint": "8b9296ddade1932e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}