{"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-5c0dc5b7fb221f40", "name": "Stray `console.log` in TS/JS \u2014 prisma/seed.js:6", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 prisma/seed.js:6"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4f2aef919efea69e", "name": "Possible secret in .env.example", "shortDescription": {"text": "Possible secret in .env.example"}, "fullDescription": {"text": "Detected pattern matching private_key. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-cb639d9a10a47b23", "name": "package.json defines install-time lifecycle scripts", "shortDescription": {"text": "package.json defines install-time lifecycle scripts"}, "fullDescription": {"text": "preinstall/install/postinstall/prepare scripts execute during dependency installation. Review them carefully for network calls, obfuscation, shell execution, or credential access."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "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 46 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-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "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 6 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-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, operator-readme. 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-98c81f0e9133918e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/controllers/socialController.js:158", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/controllers/socialController.js:158"}, "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-af022f937dd5b7fd", "name": "9 env vars used in code but missing from .env.example", "shortDescription": {"text": "9 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ANTHROPIC_API_KEY`, `JAAS_APP_ID`, `JAAS_KID`, `JAAS_PRIVATE_KEY`, `SMTP_HOST`, `SMTP_PASS`, `SMTP_PORT`, `SMTP_USER` + 1 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b22d2dcf2495f345", "name": "Dangling fetch: GET https://www.googleapis.com/youtube/v3/videos?part=contentDetails,statistics&id=${videoIds}&key=${api", "shortDescription": {"text": "Dangling fetch: GET https://www.googleapis.com/youtube/v3/videos?part=contentDetails,statistics&id=${videoIds}&key=${apiKey} (src/controllers/socialController.js:166)"}, "fullDescription": {"text": "`src/controllers/socialController.js:166` calls `GET https://www.googleapis.com/youtube/v3/videos?part=contentDetails,statistics&id=${videoIds}&key=${apiKey}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/www.googleapis.com/youtube/v3/videos`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`src/app.js` declares `USE /api` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`src/app.js` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bc043602ec3592ed", "name": "Unused endpoint: GET /my", "shortDescription": {"text": "Unused endpoint: GET /my"}, "fullDescription": {"text": "`src/routes/courses.js` declares `GET /my` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`src/routes/courses.js` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ca5756175765b49d", "name": "Unused endpoint: GET /:id", "shortDescription": {"text": "Unused endpoint: GET /:id"}, "fullDescription": {"text": "`src/routes/courses.js` declares `GET /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5fbc954f63526821", "name": "Unused endpoint: PATCH /:id", "shortDescription": {"text": "Unused endpoint: PATCH /:id"}, "fullDescription": {"text": "`src/routes/courses.js` declares `PATCH /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a61c112b611f4bb", "name": "Unused endpoint: DELETE /:id", "shortDescription": {"text": "Unused endpoint: DELETE /:id"}, "fullDescription": {"text": "`src/routes/courses.js` declares `DELETE /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6d589fc537557405", "name": "Unused endpoint: PATCH /:id/publish", "shortDescription": {"text": "Unused endpoint: PATCH /:id/publish"}, "fullDescription": {"text": "`src/routes/courses.js` declares `PATCH /:id/publish` 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-9e0b6ca1a4ecbba7", "name": "Unused endpoint: POST /broadcast", "shortDescription": {"text": "Unused endpoint: POST /broadcast"}, "fullDescription": {"text": "`src/routes/notifications.js` declares `POST /broadcast` 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-ed4d2d73b6897c8d", "name": "Unused endpoint: PATCH /read-all", "shortDescription": {"text": "Unused endpoint: PATCH /read-all"}, "fullDescription": {"text": "`src/routes/notifications.js` declares `PATCH /read-all` 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-afd4ed162f8ab9b0", "name": "Unused endpoint: PATCH /:id/read", "shortDescription": {"text": "Unused endpoint: PATCH /:id/read"}, "fullDescription": {"text": "`src/routes/notifications.js` declares `PATCH /:id/read` 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-7aea7456f76f9b8e", "name": "Unused endpoint: PATCH /reorder", "shortDescription": {"text": "Unused endpoint: PATCH /reorder"}, "fullDescription": {"text": "`src/routes/modules.js` declares `PATCH /reorder` 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-b28d92215a503990", "name": "Unused endpoint: USE /auth", "shortDescription": {"text": "Unused endpoint: USE /auth"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /auth` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4e480cf1bc736555", "name": "Unused endpoint: USE /users", "shortDescription": {"text": "Unused endpoint: USE /users"}, "fullDescription": {"text": "`src/routes/index.js` 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-f02a079c69b52f2d", "name": "Unused endpoint: USE /", "shortDescription": {"text": "Unused endpoint: USE /"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /` 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-f7eed8de652b86a4", "name": "Unused endpoint: USE /:moduleId/content", "shortDescription": {"text": "Unused endpoint: USE /:moduleId/content"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /:moduleId/content` 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-107fb4d56cbe302f", "name": "Unused endpoint: USE /:courseId/modules", "shortDescription": {"text": "Unused endpoint: USE /:courseId/modules"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /:courseId/modules` 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-2d9bcae7114be942", "name": "Unused endpoint: USE /:courseId/discussions", "shortDescription": {"text": "Unused endpoint: USE /:courseId/discussions"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /:courseId/discussions` 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-478d0f96b515c75d", "name": "Unused endpoint: GET /:courseId/submissions", "shortDescription": {"text": "Unused endpoint: GET /:courseId/submissions"}, "fullDescription": {"text": "`src/routes/index.js` declares `GET /:courseId/submissions` 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-41a6decebab87874", "name": "Unused endpoint: GET /:courseId/certificate", "shortDescription": {"text": "Unused endpoint: GET /:courseId/certificate"}, "fullDescription": {"text": "`src/routes/index.js` declares `GET /:courseId/certificate` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ff82f0a571c2b89", "name": "Unused endpoint: USE /courses", "shortDescription": {"text": "Unused endpoint: USE /courses"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /courses` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-22370d5c39724022", "name": "Unused endpoint: USE /modules", "shortDescription": {"text": "Unused endpoint: USE /modules"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /modules` 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-04933cc9b372ebe5", "name": "Unused endpoint: USE /content", "shortDescription": {"text": "Unused endpoint: USE /content"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /content` 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-40ce0f936555536b", "name": "Unused endpoint: USE /discussions", "shortDescription": {"text": "Unused endpoint: USE /discussions"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /discussions` 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-d2303d50a0a26bd4", "name": "Unused endpoint: USE /certificates", "shortDescription": {"text": "Unused endpoint: USE /certificates"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /certificates` 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-6bdcbf2073dfa768", "name": "Unused endpoint: USE /ai", "shortDescription": {"text": "Unused endpoint: USE /ai"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /ai` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c4a96a956e9d486b", "name": "Unused endpoint: USE /social", "shortDescription": {"text": "Unused endpoint: USE /social"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /social` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d80629752210b855", "name": "Unused endpoint: USE /notifications", "shortDescription": {"text": "Unused endpoint: USE /notifications"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /notifications` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f77b94cd9f2ffcd7", "name": "Unused endpoint: USE /live-sessions", "shortDescription": {"text": "Unused endpoint: USE /live-sessions"}, "fullDescription": {"text": "`src/routes/index.js` declares `USE /live-sessions` 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-a005497d5a71980f", "name": "Unused endpoint: POST /:id/complete", "shortDescription": {"text": "Unused endpoint: POST /:id/complete"}, "fullDescription": {"text": "`src/routes/content.js` declares `POST /:id/complete` 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-8fff0f5d7443c19d", "name": "Unused endpoint: GET /:id/completion", "shortDescription": {"text": "Unused endpoint: GET /:id/completion"}, "fullDescription": {"text": "`src/routes/content.js` declares `GET /:id/completion` 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-a41ca042843f09c2", "name": "Unused endpoint: POST /:id/quiz", "shortDescription": {"text": "Unused endpoint: POST /:id/quiz"}, "fullDescription": {"text": "`src/routes/content.js` declares `POST /:id/quiz` 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-bfdae9d9dc20b1c6", "name": "Unused endpoint: GET /:id/quiz/attempts", "shortDescription": {"text": "Unused endpoint: GET /:id/quiz/attempts"}, "fullDescription": {"text": "`src/routes/content.js` declares `GET /:id/quiz/attempts` 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-28c7e366d4549d97", "name": "Unused endpoint: POST /:id/submit", "shortDescription": {"text": "Unused endpoint: POST /:id/submit"}, "fullDescription": {"text": "`src/routes/content.js` declares `POST /:id/submit` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-563901264b8f371d", "name": "Unused endpoint: GET /:id/submission", "shortDescription": {"text": "Unused endpoint: GET /:id/submission"}, "fullDescription": {"text": "`src/routes/content.js` declares `GET /:id/submission` 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-e6f782e1b6946f7a", "name": "Unused endpoint: PATCH /:id/submission/:submissionId/grade", "shortDescription": {"text": "Unused endpoint: PATCH /:id/submission/:submissionId/grade"}, "fullDescription": {"text": "`src/routes/content.js` declares `PATCH /:id/submission/:submissionId/grade` 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-cff8da5fbc19c76d", "name": "Unused endpoint: POST /chat", "shortDescription": {"text": "Unused endpoint: POST /chat"}, "fullDescription": {"text": "`src/routes/ai.js` declares `POST /chat` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-284b542f5aeb1d78", "name": "Unused endpoint: POST /youtube-suggest", "shortDescription": {"text": "Unused endpoint: POST /youtube-suggest"}, "fullDescription": {"text": "`src/routes/ai.js` declares `POST /youtube-suggest` 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-291047209eee153c", "name": "Unused endpoint: POST /courses/:courseId/enroll", "shortDescription": {"text": "Unused endpoint: POST /courses/:courseId/enroll"}, "fullDescription": {"text": "`src/routes/enrollments.js` declares `POST /courses/:courseId/enroll` 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-2901b075f8a856cc", "name": "Unused endpoint: DELETE /courses/:courseId/enroll", "shortDescription": {"text": "Unused endpoint: DELETE /courses/:courseId/enroll"}, "fullDescription": {"text": "`src/routes/enrollments.js` declares `DELETE /courses/:courseId/enroll` 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-3af7da8686b131cb", "name": "Unused endpoint: GET /enrollments/my", "shortDescription": {"text": "Unused endpoint: GET /enrollments/my"}, "fullDescription": {"text": "`src/routes/enrollments.js` declares `GET /enrollments/my` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3352c8db165fa06a", "name": "Unused endpoint: PATCH /enrollments/:id/progress", "shortDescription": {"text": "Unused endpoint: PATCH /enrollments/:id/progress"}, "fullDescription": {"text": "`src/routes/enrollments.js` declares `PATCH /enrollments/:id/progress` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9e07914e1e4f77cc", "name": "Unused endpoint: GET /courses/:courseId/students", "shortDescription": {"text": "Unused endpoint: GET /courses/:courseId/students"}, "fullDescription": {"text": "`src/routes/enrollments.js` declares `GET /courses/:courseId/students` 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-6979ffe2fe114529", "name": "Unused endpoint: GET /enrollments/pending", "shortDescription": {"text": "Unused endpoint: GET /enrollments/pending"}, "fullDescription": {"text": "`src/routes/enrollments.js` declares `GET /enrollments/pending` 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-f753ec6ab50a6b51", "name": "Unused endpoint: PATCH /enrollments/:id/approve", "shortDescription": {"text": "Unused endpoint: PATCH /enrollments/:id/approve"}, "fullDescription": {"text": "`src/routes/enrollments.js` declares `PATCH /enrollments/:id/approve` 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-59a1cc885f47e39f", "name": "Unused endpoint: PATCH /profile", "shortDescription": {"text": "Unused endpoint: PATCH /profile"}, "fullDescription": {"text": "`src/routes/users.js` declares `PATCH /profile` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d8e1c3dca07fe5ac", "name": "Unused endpoint: PATCH /push-token", "shortDescription": {"text": "Unused endpoint: PATCH /push-token"}, "fullDescription": {"text": "`src/routes/users.js` declares `PATCH /push-token` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-add6dcb6007baef6", "name": "Unused endpoint: GET /leaderboard", "shortDescription": {"text": "Unused endpoint: GET /leaderboard"}, "fullDescription": {"text": "`src/routes/users.js` declares `GET /leaderboard` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cd8dc4599ec52a08", "name": "Unused endpoint: GET /stats", "shortDescription": {"text": "Unused endpoint: GET /stats"}, "fullDescription": {"text": "`src/routes/users.js` declares `GET /stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-13365baaf9115e3c", "name": "Unused endpoint: POST /lecturers", "shortDescription": {"text": "Unused endpoint: POST /lecturers"}, "fullDescription": {"text": "`src/routes/users.js` declares `POST /lecturers` 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/24926"}, "properties": {"repository": "chinedumsunday/mathaino-backend", "repoUrl": "https://github.com/chinedumsunday/mathaino-backend", "branch": "main"}, "results": [{"ruleId": "scanner-5c0dc5b7fb221f40", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 prisma/seed.js:6"}, "properties": {"repobilityId": "811c4f12ca772b62", "scanner": "scanner-primary", "fingerprint": "5c0dc5b7fb221f40", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4f2aef919efea69e", "level": "error", "message": {"text": "Possible secret in .env.example"}, "properties": {"repobilityId": "b588b005ce958593", "scanner": "scanner-primary", "fingerprint": "4f2aef919efea69e", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".env.example"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-cb639d9a10a47b23", "level": "note", "message": {"text": "package.json defines install-time lifecycle scripts"}, "properties": {"repobilityId": "edeab51902066991", "scanner": "scanner-primary", "fingerprint": "cb639d9a10a47b23", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "npm", "install-scripts"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"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": "86ae2fbf3e17550a", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "9876eb561a96a837", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "76fe81347e3e6415", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "aa611348dbe98d60", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-98c81f0e9133918e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/controllers/socialController.js:158"}, "properties": {"repobilityId": "28f0d4829e291687", "scanner": "scanner-primary", "fingerprint": "98c81f0e9133918e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-af022f937dd5b7fd", "level": "note", "message": {"text": "9 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "5597384795dea7a4", "scanner": "scanner-primary", "fingerprint": "af022f937dd5b7fd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-b22d2dcf2495f345", "level": "error", "message": {"text": "Dangling fetch: GET https://www.googleapis.com/youtube/v3/videos?part=contentDetails,statistics&id=${videoIds}&key=${apiKey} (src/controllers/socialController.js:166)"}, "properties": {"repobilityId": "08198cc07b0413a8", "scanner": "scanner-primary", "fingerprint": "b22d2dcf2495f345", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "d2f9a4b74450c0bc", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "c86c4fc6f4d12863", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bc043602ec3592ed", "level": "note", "message": {"text": "Unused endpoint: GET /my"}, "properties": {"repobilityId": "e97c8e257dd28382", "scanner": "scanner-primary", "fingerprint": "bc043602ec3592ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "8c1f473fa372f93f", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca5756175765b49d", "level": "note", "message": {"text": "Unused endpoint: GET /:id"}, "properties": {"repobilityId": "537ba77f60789c26", "scanner": "scanner-primary", "fingerprint": "ca5756175765b49d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5fbc954f63526821", "level": "note", "message": {"text": "Unused endpoint: PATCH /:id"}, "properties": {"repobilityId": "37d56c3b03912747", "scanner": "scanner-primary", "fingerprint": "5fbc954f63526821", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a61c112b611f4bb", "level": "note", "message": {"text": "Unused endpoint: DELETE /:id"}, "properties": {"repobilityId": "647747ee6e6c1461", "scanner": "scanner-primary", "fingerprint": "7a61c112b611f4bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6d589fc537557405", "level": "note", "message": {"text": "Unused endpoint: PATCH /:id/publish"}, "properties": {"repobilityId": "e51fcb860e1d1e36", "scanner": "scanner-primary", "fingerprint": "6d589fc537557405", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9e0b6ca1a4ecbba7", "level": "note", "message": {"text": "Unused endpoint: POST /broadcast"}, "properties": {"repobilityId": "5323f6cdb7b4b59e", "scanner": "scanner-primary", "fingerprint": "9e0b6ca1a4ecbba7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ed4d2d73b6897c8d", "level": "note", "message": {"text": "Unused endpoint: PATCH /read-all"}, "properties": {"repobilityId": "de7a487b8c3f03ee", "scanner": "scanner-primary", "fingerprint": "ed4d2d73b6897c8d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-afd4ed162f8ab9b0", "level": "note", "message": {"text": "Unused endpoint: PATCH /:id/read"}, "properties": {"repobilityId": "e9e6a421de415489", "scanner": "scanner-primary", "fingerprint": "afd4ed162f8ab9b0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7aea7456f76f9b8e", "level": "note", "message": {"text": "Unused endpoint: PATCH /reorder"}, "properties": {"repobilityId": "a8049a0bcc583a15", "scanner": "scanner-primary", "fingerprint": "7aea7456f76f9b8e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b28d92215a503990", "level": "note", "message": {"text": "Unused endpoint: USE /auth"}, "properties": {"repobilityId": "1108faee9df7e8c5", "scanner": "scanner-primary", "fingerprint": "b28d92215a503990", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4e480cf1bc736555", "level": "note", "message": {"text": "Unused endpoint: USE /users"}, "properties": {"repobilityId": "b1779e41e5525767", "scanner": "scanner-primary", "fingerprint": "4e480cf1bc736555", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f02a079c69b52f2d", "level": "note", "message": {"text": "Unused endpoint: USE /"}, "properties": {"repobilityId": "8ee90517c156aaf6", "scanner": "scanner-primary", "fingerprint": "f02a079c69b52f2d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f7eed8de652b86a4", "level": "note", "message": {"text": "Unused endpoint: USE /:moduleId/content"}, "properties": {"repobilityId": "0373cecaf620ab70", "scanner": "scanner-primary", "fingerprint": "f7eed8de652b86a4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-107fb4d56cbe302f", "level": "note", "message": {"text": "Unused endpoint: USE /:courseId/modules"}, "properties": {"repobilityId": "8ab2219cf085a74a", "scanner": "scanner-primary", "fingerprint": "107fb4d56cbe302f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2d9bcae7114be942", "level": "note", "message": {"text": "Unused endpoint: USE /:courseId/discussions"}, "properties": {"repobilityId": "b9673f42a9762d7d", "scanner": "scanner-primary", "fingerprint": "2d9bcae7114be942", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-478d0f96b515c75d", "level": "note", "message": {"text": "Unused endpoint: GET /:courseId/submissions"}, "properties": {"repobilityId": "901c7ff46df11d68", "scanner": "scanner-primary", "fingerprint": "478d0f96b515c75d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-41a6decebab87874", "level": "note", "message": {"text": "Unused endpoint: GET /:courseId/certificate"}, "properties": {"repobilityId": "181a7d410705d5f4", "scanner": "scanner-primary", "fingerprint": "41a6decebab87874", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3ff82f0a571c2b89", "level": "note", "message": {"text": "Unused endpoint: USE /courses"}, "properties": {"repobilityId": "bd20fdd9823784d0", "scanner": "scanner-primary", "fingerprint": "3ff82f0a571c2b89", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-22370d5c39724022", "level": "note", "message": {"text": "Unused endpoint: USE /modules"}, "properties": {"repobilityId": "d1e313e8c4ce8433", "scanner": "scanner-primary", "fingerprint": "22370d5c39724022", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-04933cc9b372ebe5", "level": "note", "message": {"text": "Unused endpoint: USE /content"}, "properties": {"repobilityId": "af0148ce1972b998", "scanner": "scanner-primary", "fingerprint": "04933cc9b372ebe5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-40ce0f936555536b", "level": "note", "message": {"text": "Unused endpoint: USE /discussions"}, "properties": {"repobilityId": "ed62f29ee5000b7b", "scanner": "scanner-primary", "fingerprint": "40ce0f936555536b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d2303d50a0a26bd4", "level": "note", "message": {"text": "Unused endpoint: USE /certificates"}, "properties": {"repobilityId": "da5ac9589d2893d8", "scanner": "scanner-primary", "fingerprint": "d2303d50a0a26bd4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6bdcbf2073dfa768", "level": "note", "message": {"text": "Unused endpoint: USE /ai"}, "properties": {"repobilityId": "c337f53ecbd79e74", "scanner": "scanner-primary", "fingerprint": "6bdcbf2073dfa768", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c4a96a956e9d486b", "level": "note", "message": {"text": "Unused endpoint: USE /social"}, "properties": {"repobilityId": "03341aa49b8466c8", "scanner": "scanner-primary", "fingerprint": "c4a96a956e9d486b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d80629752210b855", "level": "note", "message": {"text": "Unused endpoint: USE /notifications"}, "properties": {"repobilityId": "52a2ee44ac5bec1f", "scanner": "scanner-primary", "fingerprint": "d80629752210b855", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f77b94cd9f2ffcd7", "level": "note", "message": {"text": "Unused endpoint: USE /live-sessions"}, "properties": {"repobilityId": "14de3239d6789d27", "scanner": "scanner-primary", "fingerprint": "f77b94cd9f2ffcd7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a005497d5a71980f", "level": "note", "message": {"text": "Unused endpoint: POST /:id/complete"}, "properties": {"repobilityId": "6d525f8118e9ac3f", "scanner": "scanner-primary", "fingerprint": "a005497d5a71980f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8fff0f5d7443c19d", "level": "note", "message": {"text": "Unused endpoint: GET /:id/completion"}, "properties": {"repobilityId": "0d8eaaa66d2eece4", "scanner": "scanner-primary", "fingerprint": "8fff0f5d7443c19d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a41ca042843f09c2", "level": "note", "message": {"text": "Unused endpoint: POST /:id/quiz"}, "properties": {"repobilityId": "69ce2170ddff4637", "scanner": "scanner-primary", "fingerprint": "a41ca042843f09c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bfdae9d9dc20b1c6", "level": "note", "message": {"text": "Unused endpoint: GET /:id/quiz/attempts"}, "properties": {"repobilityId": "c5839092f83de477", "scanner": "scanner-primary", "fingerprint": "bfdae9d9dc20b1c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-28c7e366d4549d97", "level": "note", "message": {"text": "Unused endpoint: POST /:id/submit"}, "properties": {"repobilityId": "66ac23fa79b81539", "scanner": "scanner-primary", "fingerprint": "28c7e366d4549d97", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-563901264b8f371d", "level": "note", "message": {"text": "Unused endpoint: GET /:id/submission"}, "properties": {"repobilityId": "544dbc2e872de211", "scanner": "scanner-primary", "fingerprint": "563901264b8f371d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e6f782e1b6946f7a", "level": "note", "message": {"text": "Unused endpoint: PATCH /:id/submission/:submissionId/grade"}, "properties": {"repobilityId": "39324a9efc89fe77", "scanner": "scanner-primary", "fingerprint": "e6f782e1b6946f7a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cff8da5fbc19c76d", "level": "note", "message": {"text": "Unused endpoint: POST /chat"}, "properties": {"repobilityId": "471edfee50fa7794", "scanner": "scanner-primary", "fingerprint": "cff8da5fbc19c76d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-284b542f5aeb1d78", "level": "note", "message": {"text": "Unused endpoint: POST /youtube-suggest"}, "properties": {"repobilityId": "63b1cc2ead66459a", "scanner": "scanner-primary", "fingerprint": "284b542f5aeb1d78", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-291047209eee153c", "level": "note", "message": {"text": "Unused endpoint: POST /courses/:courseId/enroll"}, "properties": {"repobilityId": "b577cba704e35cf5", "scanner": "scanner-primary", "fingerprint": "291047209eee153c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2901b075f8a856cc", "level": "note", "message": {"text": "Unused endpoint: DELETE /courses/:courseId/enroll"}, "properties": {"repobilityId": "0d9960a7bd8998a1", "scanner": "scanner-primary", "fingerprint": "2901b075f8a856cc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3af7da8686b131cb", "level": "note", "message": {"text": "Unused endpoint: GET /enrollments/my"}, "properties": {"repobilityId": "d08ce8ec62c204a1", "scanner": "scanner-primary", "fingerprint": "3af7da8686b131cb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3352c8db165fa06a", "level": "note", "message": {"text": "Unused endpoint: PATCH /enrollments/:id/progress"}, "properties": {"repobilityId": "b9258769d9ea9e98", "scanner": "scanner-primary", "fingerprint": "3352c8db165fa06a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9e07914e1e4f77cc", "level": "note", "message": {"text": "Unused endpoint: GET /courses/:courseId/students"}, "properties": {"repobilityId": "dacfc2bc6b560aa2", "scanner": "scanner-primary", "fingerprint": "9e07914e1e4f77cc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6979ffe2fe114529", "level": "note", "message": {"text": "Unused endpoint: GET /enrollments/pending"}, "properties": {"repobilityId": "8628254c47f1c52d", "scanner": "scanner-primary", "fingerprint": "6979ffe2fe114529", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f753ec6ab50a6b51", "level": "note", "message": {"text": "Unused endpoint: PATCH /enrollments/:id/approve"}, "properties": {"repobilityId": "7385e21e90338fa6", "scanner": "scanner-primary", "fingerprint": "f753ec6ab50a6b51", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-59a1cc885f47e39f", "level": "note", "message": {"text": "Unused endpoint: PATCH /profile"}, "properties": {"repobilityId": "724a5cb58c3e48f2", "scanner": "scanner-primary", "fingerprint": "59a1cc885f47e39f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d8e1c3dca07fe5ac", "level": "note", "message": {"text": "Unused endpoint: PATCH /push-token"}, "properties": {"repobilityId": "5eb3fab5b7e94582", "scanner": "scanner-primary", "fingerprint": "d8e1c3dca07fe5ac", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-add6dcb6007baef6", "level": "note", "message": {"text": "Unused endpoint: GET /leaderboard"}, "properties": {"repobilityId": "2e93cb8d3c17849b", "scanner": "scanner-primary", "fingerprint": "add6dcb6007baef6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd8dc4599ec52a08", "level": "note", "message": {"text": "Unused endpoint: GET /stats"}, "properties": {"repobilityId": "de23cee41b41b611", "scanner": "scanner-primary", "fingerprint": "cd8dc4599ec52a08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-13365baaf9115e3c", "level": "note", "message": {"text": "Unused endpoint: POST /lecturers"}, "properties": {"repobilityId": "5ddb2bdb9b239431", "scanner": "scanner-primary", "fingerprint": "13365baaf9115e3c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}