{"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-3dd0118f9ba9860f", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.js:65", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.js:65"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-771412ff953adb1c", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/(public)/concepts/[slug]/page.jsx:119", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/(public)/concepts/[slug]/page.jsx:119"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a247283571d3f99a", "name": "Insecure pattern 'cors_wildcard' in scripts/content/restapi.mjs:117", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in scripts/content/restapi.mjs:117"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ecd8ca0dd66f439d", "name": "Insecure pattern 'weak_hash' in scripts/content/system-design.mjs:791", "shortDescription": {"text": "Insecure pattern 'weak_hash' in scripts/content/system-design.mjs:791"}, "fullDescription": {"text": "Found a known-risky pattern (weak_hash). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-35985815108d8790", "name": "Insecure pattern 'cors_wildcard' in scripts/content/express.mjs:200", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in scripts/content/express.mjs:200"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d65a354463b18d76", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.js:65", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.js:65"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4372990ff4c3756d", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/(public)/concepts/[slug]/page.jsx:119", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/(public)/concepts/[slug]/page.jsx:119"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-6afcac758cc36a9f", "name": "Very large file: scripts/content/system-design.mjs (939 lines)", "shortDescription": {"text": "Very large file: scripts/content/system-design.mjs (939 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-165ab919407a4374", "name": "Very large file: scripts/content/javascript.mjs (1841 lines)", "shortDescription": {"text": "Very large file: scripts/content/javascript.mjs (1841 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-949e21bcc060c211", "name": "Very large file: scripts/content/ai-ml.mjs (853 lines)", "shortDescription": {"text": "Very large file: scripts/content/ai-ml.mjs (853 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-333d398f34a9a5fd", "name": "Very large file: scripts/content/dsa-javascript.mjs (894 lines)", "shortDescription": {"text": "Very large file: scripts/content/dsa-javascript.mjs (894 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-cd7f8229c552ffb9", "name": "Very large file: scripts/content/dsa.mjs (1617 lines)", "shortDescription": {"text": "Very large file: scripts/content/dsa.mjs (1617 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c742d2325b6d439e", "name": "Very large file: scripts/content/pandas.mjs (900 lines)", "shortDescription": {"text": "Very large file: scripts/content/pandas.mjs (900 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-afa7c926777aff49", "name": "Very large file: scripts/content/python.mjs (876 lines)", "shortDescription": {"text": "Very large file: scripts/content/python.mjs (876 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-dfbbc045aced83d2", "name": "Very large file: scripts/content/react.mjs (877 lines)", "shortDescription": {"text": "Very large file: scripts/content/react.mjs (877 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": "0 test file(s) for 162 source file(s) (ratio 0.00). 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 65 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 46 placeholder/mock markers across 20 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci, tests. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e725d2ab884fbd49", "name": "Multiple root agent instruction files without precedence", "shortDescription": {"text": "Multiple root agent instruction files without precedence"}, "fullDescription": {"text": "The repo has multiple top-level AI-coder instruction files. Without precedence rules, different agents may follow different policies."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1ac8e8c236eb52a1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/gen-ai.mjs:306", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/gen-ai.mjs:306"}, "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-c7d329be8f62c795", "name": "Legacy-named symbol `shop_backup` in scripts/content/mysql.mjs:586", "shortDescription": {"text": "Legacy-named symbol `shop_backup` in scripts/content/mysql.mjs:586"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a92f3933fb3a3bf9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/php.mjs:491", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/php.mjs:491"}, "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-4f35a7b8921a8680", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/redux.mjs:147", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/redux.mjs:147"}, "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-baf613c34ebfef74", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/nextjs.mjs:193", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/nextjs.mjs:193"}, "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-6f9e2aa3c9b25d31", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/ChallengeRunner.jsx:53", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/ChallengeRunner.jsx:53"}, "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-458e34c40fb43457", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/admin/ConceptForm.jsx:53", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/admin/ConceptForm.jsx:53"}, "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-f12ae4f01de7ab41", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/CommentsSection.jsx:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/CommentsSection.jsx: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-c6331a0d20ddbfbb", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/Quiz.jsx:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/Quiz.jsx:36"}, "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-92779a7cf5dd5d65", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/ConceptReader.jsx:54", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/ConceptReader.jsx:54"}, "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-c77f3248f4cbd89a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/interview-questions/page.jsx:23", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/interview-questions/page.jsx:23"}, "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-37de20b98fd08a73", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/concepts/page.jsx:12", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/concepts/page.jsx:12"}, "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-09f4dd8e5299923f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/courses/page.jsx:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/courses/page.jsx:13"}, "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-0668c4ab234cdf42", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/resume/page.jsx:39", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/resume/page.jsx:39"}, "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-6fdc54dfdc82bff7", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/courses/[slug]/discuss/page.jsx:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/courses/[slug]/discuss/page.jsx: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-7d22872fc7dbc846", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:19", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/courses/[slug]/discuss/[id]/page.jsx: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-621a76a83c6041b6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/register/page.jsx:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/register/page.jsx: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-24a794319541608d", "name": "Commented-code block (5 lines) in src/lib/i18n.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/i18n.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2eafc3188c36bb02", "name": "3 env vars used in code but missing from .env.example", "shortDescription": {"text": "3 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `API_KEY`, `JWT_SECRET`, `NODE_ENV`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-124bd05240b73de5", "name": "Dangling fetch: POST https://api.provider.com/v1/messages (scripts/content/gen-ai.mjs:306)", "shortDescription": {"text": "Dangling fetch: POST https://api.provider.com/v1/messages (scripts/content/gen-ai.mjs:306)"}, "fullDescription": {"text": "`scripts/content/gen-ai.mjs:306` calls `POST https://api.provider.com/v1/messages` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.provider.com/v1/messages`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-94d44928292a12de", "name": "Dangling fetch: GET https://api.example.com/courses (scripts/content/nextjs.mjs:200)", "shortDescription": {"text": "Dangling fetch: GET https://api.example.com/courses (scripts/content/nextjs.mjs:200)"}, "fullDescription": {"text": "`scripts/content/nextjs.mjs:200` calls `GET https://api.example.com/courses` 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.example.com/courses`\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-229d5f05f36215b6", "name": "Dangling fetch: GET https://api.example.com/prices (scripts/content/nextjs.mjs:200)", "shortDescription": {"text": "Dangling fetch: GET https://api.example.com/prices (scripts/content/nextjs.mjs:200)"}, "fullDescription": {"text": "`scripts/content/nextjs.mjs:200` calls `GET https://api.example.com/prices` 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.example.com/prices`\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-f90cd5c5124f69fe", "name": "Dangling fetch: GET /api/me/continue (src/components/ContinueLearning.jsx:13)", "shortDescription": {"text": "Dangling fetch: GET /api/me/continue (src/components/ContinueLearning.jsx:13)"}, "fullDescription": {"text": "`src/components/ContinueLearning.jsx:13` calls `GET /api/me/continue` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/me/continue`\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-73c2026041267270", "name": "Dangling fetch: GET /api/notifications (src/components/NotificationBell.jsx:15)", "shortDescription": {"text": "Dangling fetch: GET /api/notifications (src/components/NotificationBell.jsx:15)"}, "fullDescription": {"text": "`src/components/NotificationBell.jsx:15` calls `GET /api/notifications` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/notifications`\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-ac2adca7c77dea7c", "name": "Dangling fetch: POST /api/challenges/complete (src/components/ChallengeRunner.jsx:53)", "shortDescription": {"text": "Dangling fetch: POST /api/challenges/complete (src/components/ChallengeRunner.jsx:53)"}, "fullDescription": {"text": "`src/components/ChallengeRunner.jsx:53` calls `POST /api/challenges/complete` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/challenges/complete`\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-22cda5b3dd828e45", "name": "Dangling fetch: GET /api/topics?courseId=${form.courseId} (src/components/admin/ConceptForm.jsx:58)", "shortDescription": {"text": "Dangling fetch: GET /api/topics?courseId=${form.courseId} (src/components/admin/ConceptForm.jsx:58)"}, "fullDescription": {"text": "`src/components/admin/ConceptForm.jsx:58` calls `GET /api/topics?courseId=${form.courseId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/topics`\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-af5edcb069764130", "name": "Dangling fetch: GET /api/bookmarks (src/components/concept/BookmarkButton.jsx:15)", "shortDescription": {"text": "Dangling fetch: GET /api/bookmarks (src/components/concept/BookmarkButton.jsx:15)"}, "fullDescription": {"text": "`src/components/concept/BookmarkButton.jsx:15` calls `GET /api/bookmarks` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/bookmarks`\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-d78a1a20649bd333", "name": "Dangling fetch: POST /api/bookmarks (src/components/concept/BookmarkButton.jsx:27)", "shortDescription": {"text": "Dangling fetch: POST /api/bookmarks (src/components/concept/BookmarkButton.jsx:27)"}, "fullDescription": {"text": "`src/components/concept/BookmarkButton.jsx:27` calls `POST /api/bookmarks` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/bookmarks`\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-2e4d1910f2e7bb41", "name": "Dangling fetch: GET /api/comments?conceptId=${conceptId} (src/components/concept/CommentsSection.jsx:20)", "shortDescription": {"text": "Dangling fetch: GET /api/comments?conceptId=${conceptId} (src/components/concept/CommentsSection.jsx:20)"}, "fullDescription": {"text": "`src/components/concept/CommentsSection.jsx:20` calls `GET /api/comments?conceptId=${conceptId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/comments`\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-0630acd440906361", "name": "Dangling fetch: POST /api/comments (src/components/concept/CommentsSection.jsx:30)", "shortDescription": {"text": "Dangling fetch: POST /api/comments (src/components/concept/CommentsSection.jsx:30)"}, "fullDescription": {"text": "`src/components/concept/CommentsSection.jsx:30` calls `POST /api/comments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/comments`\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-75fd5d7bc89c3aca", "name": "Dangling fetch: POST /api/comments/${id}/vote (src/components/concept/CommentsSection.jsx:39)", "shortDescription": {"text": "Dangling fetch: POST /api/comments/${id}/vote (src/components/concept/CommentsSection.jsx:39)"}, "fullDescription": {"text": "`src/components/concept/CommentsSection.jsx:39` calls `POST /api/comments/${id}/vote` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/comments/<p>/vote`\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-da848c6e7960bd67", "name": "Dangling fetch: DELETE /api/comments/${id} (src/components/concept/CommentsSection.jsx:45)", "shortDescription": {"text": "Dangling fetch: DELETE /api/comments/${id} (src/components/concept/CommentsSection.jsx:45)"}, "fullDescription": {"text": "`src/components/concept/CommentsSection.jsx:45` calls `DELETE /api/comments/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/comments/<p>`\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-aeb4e075b6f6f975", "name": "Dangling fetch: GET /api/reactions?conceptId=${conceptId} (src/components/concept/Reactions.jsx:22)", "shortDescription": {"text": "Dangling fetch: GET /api/reactions?conceptId=${conceptId} (src/components/concept/Reactions.jsx:22)"}, "fullDescription": {"text": "`src/components/concept/Reactions.jsx:22` calls `GET /api/reactions?conceptId=${conceptId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/reactions`\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-08684640856e80c0", "name": "Dangling fetch: POST /api/reactions (src/components/concept/Reactions.jsx:30)", "shortDescription": {"text": "Dangling fetch: POST /api/reactions (src/components/concept/Reactions.jsx:30)"}, "fullDescription": {"text": "`src/components/concept/Reactions.jsx:30` calls `POST /api/reactions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/reactions`\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-a6ece0ad21a6147f", "name": "Dangling fetch: POST /api/quiz/submit (src/components/concept/Quiz.jsx:36)", "shortDescription": {"text": "Dangling fetch: POST /api/quiz/submit (src/components/concept/Quiz.jsx:36)"}, "fullDescription": {"text": "`src/components/concept/Quiz.jsx:36` calls `POST /api/quiz/submit` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/quiz/submit`\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-cb375da6d52d5f1c", "name": "Dangling fetch: GET /api/me/stats (src/components/concept/ConceptReader.jsx:34)", "shortDescription": {"text": "Dangling fetch: GET /api/me/stats (src/components/concept/ConceptReader.jsx:34)"}, "fullDescription": {"text": "`src/components/concept/ConceptReader.jsx:34` calls `GET /api/me/stats` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/me/stats`\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-a216a3f37a9c034c", "name": "Dangling fetch: POST /api/progress (src/components/concept/ConceptReader.jsx:54)", "shortDescription": {"text": "Dangling fetch: POST /api/progress (src/components/concept/ConceptReader.jsx:54)"}, "fullDescription": {"text": "`src/components/concept/ConceptReader.jsx:54` calls `POST /api/progress` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/progress`\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-1170d710c181eea0", "name": "Dangling fetch: GET /api/interview-questions (src/app/(admin)/admin/interview-questions/page.jsx:24)", "shortDescription": {"text": "Dangling fetch: GET /api/interview-questions (src/app/(admin)/admin/interview-questions/page.jsx:24)"}, "fullDescription": {"text": "`src/app/(admin)/admin/interview-questions/page.jsx:24` calls `GET /api/interview-questions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/interview-questions`\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-3729c7e772744c32", "name": "Dangling fetch: POST /api/interview-questions (src/app/(admin)/admin/interview-questions/page.jsx:45)", "shortDescription": {"text": "Dangling fetch: POST /api/interview-questions (src/app/(admin)/admin/interview-questions/page.jsx:45)"}, "fullDescription": {"text": "`src/app/(admin)/admin/interview-questions/page.jsx:45` calls `POST /api/interview-questions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/interview-questions`\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-c58e9ec043c02c05", "name": "Dangling fetch: DELETE /api/interview-questions/${id} (src/app/(admin)/admin/interview-questions/page.jsx:57)", "shortDescription": {"text": "Dangling fetch: DELETE /api/interview-questions/${id} (src/app/(admin)/admin/interview-questions/page.jsx:57)"}, "fullDescription": {"text": "`src/app/(admin)/admin/interview-questions/page.jsx:57` calls `DELETE /api/interview-questions/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/interview-questions/<p>`\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-6317b01a70504b41", "name": "Dangling fetch: GET /api/concepts?all=1 (src/app/(admin)/admin/concepts/page.jsx:12)", "shortDescription": {"text": "Dangling fetch: GET /api/concepts?all=1 (src/app/(admin)/admin/concepts/page.jsx:12)"}, "fullDescription": {"text": "`src/app/(admin)/admin/concepts/page.jsx:12` calls `GET /api/concepts?all=1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/concepts`\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-40cae3b5394792d8", "name": "Dangling fetch: DELETE /api/concepts/${id} (src/app/(admin)/admin/concepts/page.jsx:21)", "shortDescription": {"text": "Dangling fetch: DELETE /api/concepts/${id} (src/app/(admin)/admin/concepts/page.jsx:21)"}, "fullDescription": {"text": "`src/app/(admin)/admin/concepts/page.jsx:21` calls `DELETE /api/concepts/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/concepts/<p>`\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-6e802077cde158e9", "name": "Dangling fetch: GET /api/topics?courseId=${c._id} (src/app/(admin)/admin/courses/page.jsx:18)", "shortDescription": {"text": "Dangling fetch: GET /api/topics?courseId=${c._id} (src/app/(admin)/admin/courses/page.jsx:18)"}, "fullDescription": {"text": "`src/app/(admin)/admin/courses/page.jsx:18` calls `GET /api/topics?courseId=${c._id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/topics`\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-751e82e334d9b603", "name": "Dangling fetch: POST /api/topics (src/app/(admin)/admin/courses/page.jsx:45)", "shortDescription": {"text": "Dangling fetch: POST /api/topics (src/app/(admin)/admin/courses/page.jsx:45)"}, "fullDescription": {"text": "`src/app/(admin)/admin/courses/page.jsx:45` calls `POST /api/topics` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/topics`\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-015e10b074fd1204", "name": "Dangling fetch: GET /api/notifications (src/app/(public)/notifications/page.jsx:15)", "shortDescription": {"text": "Dangling fetch: GET /api/notifications (src/app/(public)/notifications/page.jsx:15)"}, "fullDescription": {"text": "`src/app/(public)/notifications/page.jsx:15` calls `GET /api/notifications` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/notifications`\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-2710704a79473619", "name": "Dangling fetch: POST /api/notifications (src/app/(public)/notifications/page.jsx:20)", "shortDescription": {"text": "Dangling fetch: POST /api/notifications (src/app/(public)/notifications/page.jsx:20)"}, "fullDescription": {"text": "`src/app/(public)/notifications/page.jsx:20` calls `POST /api/notifications` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/notifications`\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-13dadd696e4c215f", "name": "Dangling fetch: GET /api/me/dashboard (src/app/(public)/dashboard/page.jsx:15)", "shortDescription": {"text": "Dangling fetch: GET /api/me/dashboard (src/app/(public)/dashboard/page.jsx:15)"}, "fullDescription": {"text": "`src/app/(public)/dashboard/page.jsx:15` calls `GET /api/me/dashboard` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/me/dashboard`\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-c9c602ea0bc8b0bb", "name": "Dangling fetch: GET /api/leaderboard?scope=${scope} (src/app/(public)/leaderboard/page.jsx:14)", "shortDescription": {"text": "Dangling fetch: GET /api/leaderboard?scope=${scope} (src/app/(public)/leaderboard/page.jsx:14)"}, "fullDescription": {"text": "`src/app/(public)/leaderboard/page.jsx:14` calls `GET /api/leaderboard?scope=${scope}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/leaderboard`\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-4c3c8ce8468db248", "name": "Dangling fetch: GET /api/mock-interview?courseSlug=${slug} (src/app/(public)/mock-interview/[slug]/page.jsx:19)", "shortDescription": {"text": "Dangling fetch: GET /api/mock-interview?courseSlug=${slug} (src/app/(public)/mock-interview/[slug]/page.jsx:19)"}, "fullDescription": {"text": "`src/app/(public)/mock-interview/[slug]/page.jsx:19` calls `GET /api/mock-interview?courseSlug=${slug}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/mock-interview`\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-4845765f76430a19", "name": "Dangling fetch: GET /api/resume (src/app/(public)/resume/page.jsx:39)", "shortDescription": {"text": "Dangling fetch: GET /api/resume (src/app/(public)/resume/page.jsx:39)"}, "fullDescription": {"text": "`src/app/(public)/resume/page.jsx:39` calls `GET /api/resume` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/resume`\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-6852a2f42f90a359", "name": "Dangling fetch: PUT /api/resume (src/app/(public)/resume/page.jsx:75)", "shortDescription": {"text": "Dangling fetch: PUT /api/resume (src/app/(public)/resume/page.jsx:75)"}, "fullDescription": {"text": "`src/app/(public)/resume/page.jsx:75` calls `PUT /api/resume` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/resume`\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-b85bc5bf6e653c73", "name": "Dangling fetch: GET /api/me/dashboard (src/app/(public)/resume/page.jsx:92)", "shortDescription": {"text": "Dangling fetch: GET /api/me/dashboard (src/app/(public)/resume/page.jsx:92)"}, "fullDescription": {"text": "`src/app/(public)/resume/page.jsx:92` calls `GET /api/me/dashboard` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/me/dashboard`\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-0996c476b2d18c7d", "name": "Dangling fetch: GET /api/practice?courseSlug=${slug} (src/app/(public)/practice/[slug]/page.jsx:19)", "shortDescription": {"text": "Dangling fetch: GET /api/practice?courseSlug=${slug} (src/app/(public)/practice/[slug]/page.jsx:19)"}, "fullDescription": {"text": "`src/app/(public)/practice/[slug]/page.jsx:19` calls `GET /api/practice?courseSlug=${slug}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/practice`\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-0a543cb7e188ae46", "name": "Dangling fetch: GET /api/revise (src/app/(public)/revise/page.jsx:25)", "shortDescription": {"text": "Dangling fetch: GET /api/revise (src/app/(public)/revise/page.jsx:25)"}, "fullDescription": {"text": "`src/app/(public)/revise/page.jsx:25` calls `GET /api/revise` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/revise`\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-ff23db5c9f67aae5", "name": "Dangling fetch: POST /api/revise (src/app/(public)/revise/page.jsx:66)", "shortDescription": {"text": "Dangling fetch: POST /api/revise (src/app/(public)/revise/page.jsx:66)"}, "fullDescription": {"text": "`src/app/(public)/revise/page.jsx:66` calls `POST /api/revise` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/revise`\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-2a5e9edc4cdb115e", "name": "Dangling fetch: GET /api/discussions?courseSlug=${slug} (src/app/(public)/courses/[slug]/discuss/page.jsx:20)", "shortDescription": {"text": "Dangling fetch: GET /api/discussions?courseSlug=${slug} (src/app/(public)/courses/[slug]/discuss/page.jsx:20)"}, "fullDescription": {"text": "`src/app/(public)/courses/[slug]/discuss/page.jsx:20` calls `GET /api/discussions?courseSlug=${slug}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/discussions`\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-b208c37f6bfc3d84", "name": "Dangling fetch: POST /api/discussions (src/app/(public)/courses/[slug]/discuss/page.jsx:29)", "shortDescription": {"text": "Dangling fetch: POST /api/discussions (src/app/(public)/courses/[slug]/discuss/page.jsx:29)"}, "fullDescription": {"text": "`src/app/(public)/courses/[slug]/discuss/page.jsx:29` calls `POST /api/discussions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/discussions`\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-4328a33bba1c59f8", "name": "Dangling fetch: GET /api/discussions/${id} (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:19)", "shortDescription": {"text": "Dangling fetch: GET /api/discussions/${id} (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:19)"}, "fullDescription": {"text": "`src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:19` calls `GET /api/discussions/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/discussions/<p>`\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-899b96f75921a1bb", "name": "Dangling fetch: POST /api/discussions/${targetId}/vote (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:27)", "shortDescription": {"text": "Dangling fetch: POST /api/discussions/${targetId}/vote (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:27)"}, "fullDescription": {"text": "`src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:27` calls `POST /api/discussions/${targetId}/vote` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/discussions/<p>/vote`\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-82db0f9662bed2a8", "name": "Dangling fetch: POST /api/discussions/${id}/reply (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:34)", "shortDescription": {"text": "Dangling fetch: POST /api/discussions/${id}/reply (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:34)"}, "fullDescription": {"text": "`src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:34` calls `POST /api/discussions/${id}/reply` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/discussions/<p>/reply`\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-698a08b7ce357b02", "name": "Dangling fetch: DELETE /api/discussions/${targetId} (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:44)", "shortDescription": {"text": "Dangling fetch: DELETE /api/discussions/${targetId} (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:44)"}, "fullDescription": {"text": "`src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:44` calls `DELETE /api/discussions/${targetId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/discussions/<p>`\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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`scripts/content/restapi.mjs` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`scripts/content/restapi.mjs` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a61c112b611f4bb", "name": "Unused endpoint: DELETE /:id", "shortDescription": {"text": "Unused endpoint: DELETE /:id"}, "fullDescription": {"text": "`scripts/content/restapi.mjs` declares `DELETE /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-41aa9e92da3f14ad", "name": "Unused endpoint: GET /users/:id", "shortDescription": {"text": "Unused endpoint: GET /users/:id"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `GET /users/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1bca8100a44f7f25", "name": "Unused endpoint: POST /users", "shortDescription": {"text": "Unused endpoint: POST /users"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `POST /users` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ca5756175765b49d", "name": "Unused endpoint: GET /:id", "shortDescription": {"text": "Unused endpoint: GET /:id"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `GET /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4e480cf1bc736555", "name": "Unused endpoint: USE /users", "shortDescription": {"text": "Unused endpoint: USE /users"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `USE /users` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e3ddb7bd27267f3b", "name": "Unused endpoint: USE /path", "shortDescription": {"text": "Unused endpoint: USE /path"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `USE /path` 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-0c70359e360d801b", "name": "Unused endpoint: GET /todos", "shortDescription": {"text": "Unused endpoint: GET /todos"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `GET /todos` 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-31f38cf25278c564", "name": "Unused endpoint: POST /todos", "shortDescription": {"text": "Unused endpoint: POST /todos"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `POST /todos` 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-1ca3f257179f9b60", "name": "Unused endpoint: DELETE /todos/:id", "shortDescription": {"text": "Unused endpoint: DELETE /todos/:id"}, "fullDescription": {"text": "`scripts/content/express.mjs` declares `DELETE /todos/: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/17766"}, "properties": {"repository": "rajputboyars/learnverse", "repoUrl": "https://github.com/rajputboyars/learnverse", "branch": "main"}, "results": [{"ruleId": "scanner-3dd0118f9ba9860f", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/layout.js:65"}, "properties": {"repobilityId": "a41f49c33394e1db", "scanner": "scanner-primary", "fingerprint": "3dd0118f9ba9860f", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-771412ff953adb1c", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/(public)/concepts/[slug]/page.jsx:119"}, "properties": {"repobilityId": "a10ebca1f953dfe4", "scanner": "scanner-primary", "fingerprint": "771412ff953adb1c", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-a247283571d3f99a", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in scripts/content/restapi.mjs:117"}, "properties": {"repobilityId": "c35a30d1128836cd", "scanner": "scanner-primary", "fingerprint": "a247283571d3f99a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/content/restapi.mjs"}, "region": {"startLine": 117}}}]}, {"ruleId": "scanner-ecd8ca0dd66f439d", "level": "warning", "message": {"text": "Insecure pattern 'weak_hash' in scripts/content/system-design.mjs:791"}, "properties": {"repobilityId": "34968f2d449e4783", "scanner": "scanner-primary", "fingerprint": "ecd8ca0dd66f439d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "weak_hash"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/content/system-design.mjs"}, "region": {"startLine": 791}}}]}, {"ruleId": "scanner-35985815108d8790", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in scripts/content/express.mjs:200"}, "properties": {"repobilityId": "6d504477d8d3f967", "scanner": "scanner-primary", "fingerprint": "35985815108d8790", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/content/express.mjs"}, "region": {"startLine": 200}}}]}, {"ruleId": "scanner-d65a354463b18d76", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/layout.js:65"}, "properties": {"repobilityId": "59082a34ab092bcd", "scanner": "scanner-primary", "fingerprint": "d65a354463b18d76", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/layout.js"}, "region": {"startLine": 65}}}]}, {"ruleId": "scanner-4372990ff4c3756d", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/(public)/concepts/[slug]/page.jsx:119"}, "properties": {"repobilityId": "9a0b120902cd9775", "scanner": "scanner-primary", "fingerprint": "4372990ff4c3756d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/(public)/concepts/[slug]/page.jsx"}, "region": {"startLine": 119}}}]}, {"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-6afcac758cc36a9f", "level": "note", "message": {"text": "Very large file: scripts/content/system-design.mjs (939 lines)"}, "properties": {"repobilityId": "0211be79112dbcb8", "scanner": "scanner-primary", "fingerprint": "6afcac758cc36a9f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-165ab919407a4374", "level": "note", "message": {"text": "Very large file: scripts/content/javascript.mjs (1841 lines)"}, "properties": {"repobilityId": "4df9e95969c8dc95", "scanner": "scanner-primary", "fingerprint": "165ab919407a4374", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-949e21bcc060c211", "level": "note", "message": {"text": "Very large file: scripts/content/ai-ml.mjs (853 lines)"}, "properties": {"repobilityId": "766e5c73ed03ecf2", "scanner": "scanner-primary", "fingerprint": "949e21bcc060c211", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-333d398f34a9a5fd", "level": "note", "message": {"text": "Very large file: scripts/content/dsa-javascript.mjs (894 lines)"}, "properties": {"repobilityId": "10d285856c58f95f", "scanner": "scanner-primary", "fingerprint": "333d398f34a9a5fd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-cd7f8229c552ffb9", "level": "note", "message": {"text": "Very large file: scripts/content/dsa.mjs (1617 lines)"}, "properties": {"repobilityId": "1ab807bbbc371541", "scanner": "scanner-primary", "fingerprint": "cd7f8229c552ffb9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-c742d2325b6d439e", "level": "note", "message": {"text": "Very large file: scripts/content/pandas.mjs (900 lines)"}, "properties": {"repobilityId": "5a4628a65892ea9f", "scanner": "scanner-primary", "fingerprint": "c742d2325b6d439e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-afa7c926777aff49", "level": "note", "message": {"text": "Very large file: scripts/content/python.mjs (876 lines)"}, "properties": {"repobilityId": "b826593eb2330b5d", "scanner": "scanner-primary", "fingerprint": "afa7c926777aff49", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-dfbbc045aced83d2", "level": "note", "message": {"text": "Very large file: scripts/content/react.mjs (877 lines)"}, "properties": {"repobilityId": "89c40966d380a77f", "scanner": "scanner-primary", "fingerprint": "dfbbc045aced83d2", "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": "61e951355c52fa67", "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": "1d045eb6f1168588", "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": "9746eca6b40ece0a", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "2855f16ee4beddf1", "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": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "7a0a92b8b937377f", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "bd8107bbcd3a1cd2", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "0c30269089e123b2", "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": "5d4f552857404cf4", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-e725d2ab884fbd49", "level": "note", "message": {"text": "Multiple root agent instruction files without precedence"}, "properties": {"repobilityId": "1953db6c89508d22", "scanner": "scanner-primary", "fingerprint": "e725d2ab884fbd49", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["agent-instructions", "governance"]}}, {"ruleId": "scanner-1ac8e8c236eb52a1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/gen-ai.mjs:306"}, "properties": {"repobilityId": "7fca58d354d7c12d", "scanner": "scanner-primary", "fingerprint": "1ac8e8c236eb52a1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c7d329be8f62c795", "level": "note", "message": {"text": "Legacy-named symbol `shop_backup` in scripts/content/mysql.mjs:586"}, "properties": {"repobilityId": "a4ad9865613727d3", "scanner": "scanner-primary", "fingerprint": "c7d329be8f62c795", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-a92f3933fb3a3bf9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/php.mjs:491"}, "properties": {"repobilityId": "5d4dd1fbe1bc057d", "scanner": "scanner-primary", "fingerprint": "a92f3933fb3a3bf9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4f35a7b8921a8680", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/redux.mjs:147"}, "properties": {"repobilityId": "371d3d0ee9e953fa", "scanner": "scanner-primary", "fingerprint": "4f35a7b8921a8680", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-baf613c34ebfef74", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/content/nextjs.mjs:193"}, "properties": {"repobilityId": "2357ccd7b0794fa5", "scanner": "scanner-primary", "fingerprint": "baf613c34ebfef74", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6f9e2aa3c9b25d31", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/ChallengeRunner.jsx:53"}, "properties": {"repobilityId": "1a92790252bf10cb", "scanner": "scanner-primary", "fingerprint": "6f9e2aa3c9b25d31", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-458e34c40fb43457", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/admin/ConceptForm.jsx:53"}, "properties": {"repobilityId": "923ab7e5621bd8e7", "scanner": "scanner-primary", "fingerprint": "458e34c40fb43457", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f12ae4f01de7ab41", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/CommentsSection.jsx:20"}, "properties": {"repobilityId": "e6769ad1ca0e2dd7", "scanner": "scanner-primary", "fingerprint": "f12ae4f01de7ab41", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c6331a0d20ddbfbb", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/Quiz.jsx:36"}, "properties": {"repobilityId": "345f4181d506c11f", "scanner": "scanner-primary", "fingerprint": "c6331a0d20ddbfbb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-92779a7cf5dd5d65", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/concept/ConceptReader.jsx:54"}, "properties": {"repobilityId": "fbc65b7c0c58d0bd", "scanner": "scanner-primary", "fingerprint": "92779a7cf5dd5d65", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c77f3248f4cbd89a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/interview-questions/page.jsx:23"}, "properties": {"repobilityId": "1aebd747a443d96a", "scanner": "scanner-primary", "fingerprint": "c77f3248f4cbd89a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-37de20b98fd08a73", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/concepts/page.jsx:12"}, "properties": {"repobilityId": "41635e075e551c1d", "scanner": "scanner-primary", "fingerprint": "37de20b98fd08a73", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-09f4dd8e5299923f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(admin)/admin/courses/page.jsx:13"}, "properties": {"repobilityId": "85b8e0ff6c05ece3", "scanner": "scanner-primary", "fingerprint": "09f4dd8e5299923f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0668c4ab234cdf42", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/resume/page.jsx:39"}, "properties": {"repobilityId": "b6dc378cfc43954a", "scanner": "scanner-primary", "fingerprint": "0668c4ab234cdf42", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6fdc54dfdc82bff7", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/courses/[slug]/discuss/page.jsx:20"}, "properties": {"repobilityId": "eeba2e99b194d137", "scanner": "scanner-primary", "fingerprint": "6fdc54dfdc82bff7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7d22872fc7dbc846", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:19"}, "properties": {"repobilityId": "dc335b6faca84b12", "scanner": "scanner-primary", "fingerprint": "7d22872fc7dbc846", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-621a76a83c6041b6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/(public)/register/page.jsx:20"}, "properties": {"repobilityId": "6797bb231e109313", "scanner": "scanner-primary", "fingerprint": "621a76a83c6041b6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-24a794319541608d", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/i18n.js:1"}, "properties": {"repobilityId": "ba5d08d4c899cdcd", "scanner": "scanner-primary", "fingerprint": "24a794319541608d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2eafc3188c36bb02", "level": "none", "message": {"text": "3 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "bd934ba112b02ffa", "scanner": "scanner-primary", "fingerprint": "2eafc3188c36bb02", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-124bd05240b73de5", "level": "error", "message": {"text": "Dangling fetch: POST https://api.provider.com/v1/messages (scripts/content/gen-ai.mjs:306)"}, "properties": {"repobilityId": "762d91112c97811d", "scanner": "scanner-primary", "fingerprint": "124bd05240b73de5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-94d44928292a12de", "level": "error", "message": {"text": "Dangling fetch: GET https://api.example.com/courses (scripts/content/nextjs.mjs:200)"}, "properties": {"repobilityId": "affd10cecbe9c5ab", "scanner": "scanner-primary", "fingerprint": "94d44928292a12de", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-229d5f05f36215b6", "level": "error", "message": {"text": "Dangling fetch: GET https://api.example.com/prices (scripts/content/nextjs.mjs:200)"}, "properties": {"repobilityId": "f9437874f2df1f29", "scanner": "scanner-primary", "fingerprint": "229d5f05f36215b6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-94d44928292a12de", "level": "error", "message": {"text": "Dangling fetch: GET https://api.example.com/courses (scripts/content/nextjs.mjs:200)"}, "properties": {"repobilityId": "affd10cecbe9c5ab", "scanner": "scanner-primary", "fingerprint": "94d44928292a12de", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f90cd5c5124f69fe", "level": "error", "message": {"text": "Dangling fetch: GET /api/me/continue (src/components/ContinueLearning.jsx:13)"}, "properties": {"repobilityId": "2b6a1319dff8683e", "scanner": "scanner-primary", "fingerprint": "f90cd5c5124f69fe", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-73c2026041267270", "level": "error", "message": {"text": "Dangling fetch: GET /api/notifications (src/components/NotificationBell.jsx:15)"}, "properties": {"repobilityId": "6a0113f4c78eba50", "scanner": "scanner-primary", "fingerprint": "73c2026041267270", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ac2adca7c77dea7c", "level": "error", "message": {"text": "Dangling fetch: POST /api/challenges/complete (src/components/ChallengeRunner.jsx:53)"}, "properties": {"repobilityId": "ecab7e4b36fdfe27", "scanner": "scanner-primary", "fingerprint": "ac2adca7c77dea7c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-22cda5b3dd828e45", "level": "error", "message": {"text": "Dangling fetch: GET /api/topics?courseId=${form.courseId} (src/components/admin/ConceptForm.jsx:58)"}, "properties": {"repobilityId": "ad8b055887f472b6", "scanner": "scanner-primary", "fingerprint": "22cda5b3dd828e45", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-af5edcb069764130", "level": "error", "message": {"text": "Dangling fetch: GET /api/bookmarks (src/components/concept/BookmarkButton.jsx:15)"}, "properties": {"repobilityId": "be8f9022f88205ad", "scanner": "scanner-primary", "fingerprint": "af5edcb069764130", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d78a1a20649bd333", "level": "error", "message": {"text": "Dangling fetch: POST /api/bookmarks (src/components/concept/BookmarkButton.jsx:27)"}, "properties": {"repobilityId": "64b28314245386da", "scanner": "scanner-primary", "fingerprint": "d78a1a20649bd333", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2e4d1910f2e7bb41", "level": "error", "message": {"text": "Dangling fetch: GET /api/comments?conceptId=${conceptId} (src/components/concept/CommentsSection.jsx:20)"}, "properties": {"repobilityId": "0651293e77f21a38", "scanner": "scanner-primary", "fingerprint": "2e4d1910f2e7bb41", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0630acd440906361", "level": "error", "message": {"text": "Dangling fetch: POST /api/comments (src/components/concept/CommentsSection.jsx:30)"}, "properties": {"repobilityId": "ba385009a03f3ac0", "scanner": "scanner-primary", "fingerprint": "0630acd440906361", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-75fd5d7bc89c3aca", "level": "error", "message": {"text": "Dangling fetch: POST /api/comments/${id}/vote (src/components/concept/CommentsSection.jsx:39)"}, "properties": {"repobilityId": "3abbe0f455a7a5f5", "scanner": "scanner-primary", "fingerprint": "75fd5d7bc89c3aca", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-da848c6e7960bd67", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/comments/${id} (src/components/concept/CommentsSection.jsx:45)"}, "properties": {"repobilityId": "7e536472b754bd55", "scanner": "scanner-primary", "fingerprint": "da848c6e7960bd67", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-aeb4e075b6f6f975", "level": "error", "message": {"text": "Dangling fetch: GET /api/reactions?conceptId=${conceptId} (src/components/concept/Reactions.jsx:22)"}, "properties": {"repobilityId": "1cfaf23186d7afcb", "scanner": "scanner-primary", "fingerprint": "aeb4e075b6f6f975", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-08684640856e80c0", "level": "error", "message": {"text": "Dangling fetch: POST /api/reactions (src/components/concept/Reactions.jsx:30)"}, "properties": {"repobilityId": "96e838c15dc9308e", "scanner": "scanner-primary", "fingerprint": "08684640856e80c0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a6ece0ad21a6147f", "level": "error", "message": {"text": "Dangling fetch: POST /api/quiz/submit (src/components/concept/Quiz.jsx:36)"}, "properties": {"repobilityId": "d2bbdce71effd177", "scanner": "scanner-primary", "fingerprint": "a6ece0ad21a6147f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-cb375da6d52d5f1c", "level": "error", "message": {"text": "Dangling fetch: GET /api/me/stats (src/components/concept/ConceptReader.jsx:34)"}, "properties": {"repobilityId": "e2cdbd4af308b4a1", "scanner": "scanner-primary", "fingerprint": "cb375da6d52d5f1c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a216a3f37a9c034c", "level": "error", "message": {"text": "Dangling fetch: POST /api/progress (src/components/concept/ConceptReader.jsx:54)"}, "properties": {"repobilityId": "09909cbb84dac9f0", "scanner": "scanner-primary", "fingerprint": "a216a3f37a9c034c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1170d710c181eea0", "level": "error", "message": {"text": "Dangling fetch: GET /api/interview-questions (src/app/(admin)/admin/interview-questions/page.jsx:24)"}, "properties": {"repobilityId": "3b7201903f2f755e", "scanner": "scanner-primary", "fingerprint": "1170d710c181eea0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3729c7e772744c32", "level": "error", "message": {"text": "Dangling fetch: POST /api/interview-questions (src/app/(admin)/admin/interview-questions/page.jsx:45)"}, "properties": {"repobilityId": "3d71a0e5cb68cdb1", "scanner": "scanner-primary", "fingerprint": "3729c7e772744c32", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c58e9ec043c02c05", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/interview-questions/${id} (src/app/(admin)/admin/interview-questions/page.jsx:57)"}, "properties": {"repobilityId": "082973747e2959ac", "scanner": "scanner-primary", "fingerprint": "c58e9ec043c02c05", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6317b01a70504b41", "level": "error", "message": {"text": "Dangling fetch: GET /api/concepts?all=1 (src/app/(admin)/admin/concepts/page.jsx:12)"}, "properties": {"repobilityId": "b52b15a5569ae334", "scanner": "scanner-primary", "fingerprint": "6317b01a70504b41", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-40cae3b5394792d8", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/concepts/${id} (src/app/(admin)/admin/concepts/page.jsx:21)"}, "properties": {"repobilityId": "ba778274aeaa9da2", "scanner": "scanner-primary", "fingerprint": "40cae3b5394792d8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6e802077cde158e9", "level": "error", "message": {"text": "Dangling fetch: GET /api/topics?courseId=${c._id} (src/app/(admin)/admin/courses/page.jsx:18)"}, "properties": {"repobilityId": "f3452dbfd9ccfdd1", "scanner": "scanner-primary", "fingerprint": "6e802077cde158e9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-751e82e334d9b603", "level": "error", "message": {"text": "Dangling fetch: POST /api/topics (src/app/(admin)/admin/courses/page.jsx:45)"}, "properties": {"repobilityId": "fef77b182c037f19", "scanner": "scanner-primary", "fingerprint": "751e82e334d9b603", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-015e10b074fd1204", "level": "error", "message": {"text": "Dangling fetch: GET /api/notifications (src/app/(public)/notifications/page.jsx:15)"}, "properties": {"repobilityId": "59756d726681db75", "scanner": "scanner-primary", "fingerprint": "015e10b074fd1204", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2710704a79473619", "level": "error", "message": {"text": "Dangling fetch: POST /api/notifications (src/app/(public)/notifications/page.jsx:20)"}, "properties": {"repobilityId": "a7fc9c4e83434a4a", "scanner": "scanner-primary", "fingerprint": "2710704a79473619", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-13dadd696e4c215f", "level": "error", "message": {"text": "Dangling fetch: GET /api/me/dashboard (src/app/(public)/dashboard/page.jsx:15)"}, "properties": {"repobilityId": "293686a4f02a1da1", "scanner": "scanner-primary", "fingerprint": "13dadd696e4c215f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c9c602ea0bc8b0bb", "level": "error", "message": {"text": "Dangling fetch: GET /api/leaderboard?scope=${scope} (src/app/(public)/leaderboard/page.jsx:14)"}, "properties": {"repobilityId": "3581988406faf248", "scanner": "scanner-primary", "fingerprint": "c9c602ea0bc8b0bb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4c3c8ce8468db248", "level": "error", "message": {"text": "Dangling fetch: GET /api/mock-interview?courseSlug=${slug} (src/app/(public)/mock-interview/[slug]/page.jsx:19)"}, "properties": {"repobilityId": "0fbfef3fd7aed9e2", "scanner": "scanner-primary", "fingerprint": "4c3c8ce8468db248", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4845765f76430a19", "level": "error", "message": {"text": "Dangling fetch: GET /api/resume (src/app/(public)/resume/page.jsx:39)"}, "properties": {"repobilityId": "db17e6d3d18b686f", "scanner": "scanner-primary", "fingerprint": "4845765f76430a19", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6852a2f42f90a359", "level": "error", "message": {"text": "Dangling fetch: PUT /api/resume (src/app/(public)/resume/page.jsx:75)"}, "properties": {"repobilityId": "de5dc636e8252742", "scanner": "scanner-primary", "fingerprint": "6852a2f42f90a359", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b85bc5bf6e653c73", "level": "error", "message": {"text": "Dangling fetch: GET /api/me/dashboard (src/app/(public)/resume/page.jsx:92)"}, "properties": {"repobilityId": "7561649aeae3cb81", "scanner": "scanner-primary", "fingerprint": "b85bc5bf6e653c73", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0996c476b2d18c7d", "level": "error", "message": {"text": "Dangling fetch: GET /api/practice?courseSlug=${slug} (src/app/(public)/practice/[slug]/page.jsx:19)"}, "properties": {"repobilityId": "b77ce0296f4aa110", "scanner": "scanner-primary", "fingerprint": "0996c476b2d18c7d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0a543cb7e188ae46", "level": "error", "message": {"text": "Dangling fetch: GET /api/revise (src/app/(public)/revise/page.jsx:25)"}, "properties": {"repobilityId": "776c85ac4ce9227f", "scanner": "scanner-primary", "fingerprint": "0a543cb7e188ae46", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ff23db5c9f67aae5", "level": "error", "message": {"text": "Dangling fetch: POST /api/revise (src/app/(public)/revise/page.jsx:66)"}, "properties": {"repobilityId": "08d3405da1cf3624", "scanner": "scanner-primary", "fingerprint": "ff23db5c9f67aae5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2a5e9edc4cdb115e", "level": "error", "message": {"text": "Dangling fetch: GET /api/discussions?courseSlug=${slug} (src/app/(public)/courses/[slug]/discuss/page.jsx:20)"}, "properties": {"repobilityId": "ff28dcb1ba8a563e", "scanner": "scanner-primary", "fingerprint": "2a5e9edc4cdb115e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b208c37f6bfc3d84", "level": "error", "message": {"text": "Dangling fetch: POST /api/discussions (src/app/(public)/courses/[slug]/discuss/page.jsx:29)"}, "properties": {"repobilityId": "9b930bbb8ddaabc1", "scanner": "scanner-primary", "fingerprint": "b208c37f6bfc3d84", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4328a33bba1c59f8", "level": "error", "message": {"text": "Dangling fetch: GET /api/discussions/${id} (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:19)"}, "properties": {"repobilityId": "113fd5bed9e6fb48", "scanner": "scanner-primary", "fingerprint": "4328a33bba1c59f8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-899b96f75921a1bb", "level": "error", "message": {"text": "Dangling fetch: POST /api/discussions/${targetId}/vote (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:27)"}, "properties": {"repobilityId": "8004c197a4f24f73", "scanner": "scanner-primary", "fingerprint": "899b96f75921a1bb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-82db0f9662bed2a8", "level": "error", "message": {"text": "Dangling fetch: POST /api/discussions/${id}/reply (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:34)"}, "properties": {"repobilityId": "49befae42db7b173", "scanner": "scanner-primary", "fingerprint": "82db0f9662bed2a8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-698a08b7ce357b02", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/discussions/${targetId} (src/app/(public)/courses/[slug]/discuss/[id]/page.jsx:44)"}, "properties": {"repobilityId": "587bbbf808de2891", "scanner": "scanner-primary", "fingerprint": "698a08b7ce357b02", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "fe39eabc16e91f0c", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "945ef2c1dfdb6bbf", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a61c112b611f4bb", "level": "note", "message": {"text": "Unused endpoint: DELETE /:id"}, "properties": {"repobilityId": "dfae7e70970a73ac", "scanner": "scanner-primary", "fingerprint": "7a61c112b611f4bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-41aa9e92da3f14ad", "level": "note", "message": {"text": "Unused endpoint: GET /users/:id"}, "properties": {"repobilityId": "992dcb6531563bc4", "scanner": "scanner-primary", "fingerprint": "41aa9e92da3f14ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1bca8100a44f7f25", "level": "note", "message": {"text": "Unused endpoint: POST /users"}, "properties": {"repobilityId": "0d654381df7816c3", "scanner": "scanner-primary", "fingerprint": "1bca8100a44f7f25", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca5756175765b49d", "level": "note", "message": {"text": "Unused endpoint: GET /:id"}, "properties": {"repobilityId": "ccfaa1388e844a24", "scanner": "scanner-primary", "fingerprint": "ca5756175765b49d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4e480cf1bc736555", "level": "note", "message": {"text": "Unused endpoint: USE /users"}, "properties": {"repobilityId": "a300be4a57bc63e0", "scanner": "scanner-primary", "fingerprint": "4e480cf1bc736555", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e3ddb7bd27267f3b", "level": "note", "message": {"text": "Unused endpoint: USE /path"}, "properties": {"repobilityId": "9d081485a1dd4f7f", "scanner": "scanner-primary", "fingerprint": "e3ddb7bd27267f3b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0c70359e360d801b", "level": "note", "message": {"text": "Unused endpoint: GET /todos"}, "properties": {"repobilityId": "03b575384b350904", "scanner": "scanner-primary", "fingerprint": "0c70359e360d801b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-31f38cf25278c564", "level": "note", "message": {"text": "Unused endpoint: POST /todos"}, "properties": {"repobilityId": "09c61403eecde2a8", "scanner": "scanner-primary", "fingerprint": "31f38cf25278c564", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1ca3f257179f9b60", "level": "note", "message": {"text": "Unused endpoint: DELETE /todos/:id"}, "properties": {"repobilityId": "c4f0d881c9128965", "scanner": "scanner-primary", "fingerprint": "1ca3f257179f9b60", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}