{"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-e1f21b97b19dde26", "name": "TODO/FIXME marker in shipping code \u2014 frontend/src/i18n/en.js:130", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/i18n/en.js:130"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-04701d7db2458849", "name": "TODO/FIXME marker in shipping code \u2014 frontend/src/i18n/ka.js:128", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/i18n/ka.js:128"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a2ac37387854f7c3", "name": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/team.js:13", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/team.js:13"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-782228be5ef622f5", "name": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/testimonials.js:14", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/testimonials.js:14"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-82914869ba48b26d", "name": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/stories.js:17", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/stories.js:17"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5f0ec0efb1fc3230", "name": "Stray `console.log` in TS/JS \u2014 server/index.js:91", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/index.js:91"}, "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-76e345c8a551e1c3", "name": "Possible secret in frontend/src/i18n/en.js", "shortDescription": {"text": "Possible secret in frontend/src/i18n/en.js"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-9026b08ac96b1a0f", "name": "Possible secret in frontend/src/i18n/ka.js", "shortDescription": {"text": "Possible secret in frontend/src/i18n/ka.js"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-e073f951e96807ef", "name": "Possible secret in server/scripts/diagnose-auth-email.mjs", "shortDescription": {"text": "Possible secret in server/scripts/diagnose-auth-email.mjs"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-834794ceb9c4db90", "name": "Possible secret in server/scripts/live-api-smoke-test.mjs", "shortDescription": {"text": "Possible secret in server/scripts/live-api-smoke-test.mjs"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/setup-node@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "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 94 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 43 placeholder/mock markers across 14 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-390fe14f35d413c0", "name": "Commented-code block (5 lines) in frontend/src/errorReporter.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/errorReporter.js:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e39e209c7908b220", "name": "Commented-code block (7 lines) in frontend/src/api.js:3", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/src/api.js:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-10ff2d2ce0059244", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api.js:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api.js:37"}, "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-a26f7e3e56db7342", "name": "Commented-code block (5 lines) in frontend/src/main.jsx:13", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/main.jsx:13"}, "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-f5f7b8a8aed163ab", "name": "Commented-code block (5 lines) in frontend/src/components/TypewriterPlaceholder.jsx:7", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/TypewriterPlaceholder.jsx:7"}, "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-60f6934d279835c5", "name": "Commented-code block (5 lines) in frontend/src/components/SchoolCard.jsx:4", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/SchoolCard.jsx:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f789305c07fb1fae", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/components/PhotoUpload.jsx:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/components/PhotoUpload.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-fee659f3b4ae0768", "name": "Commented-code block (5 lines) in frontend/src/components/ErrorBoundary.jsx:3", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/components/ErrorBoundary.jsx:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c40cc8a459096a95", "name": "Commented-code block (6 lines) in frontend/src/content/team.js:6", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/src/content/team.js:6"}, "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-2771bd30d5fa654e", "name": "Commented-code block (5 lines) in frontend/src/content/testimonials.js:8", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/src/content/testimonials.js:8"}, "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-a7384877efad3b50", "name": "Commented-code block (10 lines) in frontend/src/content/stories.js:6", "shortDescription": {"text": "Commented-code block (10 lines) in frontend/src/content/stories.js:6"}, "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-cd1926b0ae502217", "name": "Commented-code block (5 lines) in tests/gen-icons.mjs:1", "shortDescription": {"text": "Commented-code block (5 lines) in tests/gen-icons.mjs: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-649d6abe4d74f77b", "name": "Commented-code block (5 lines) in tests/e2e/donate.spec.js:4", "shortDescription": {"text": "Commented-code block (5 lines) in tests/e2e/donate.spec.js:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5d49d636a15ace9c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/api.js:31", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/api.js:31"}, "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-8af713cca7d0abcf", "name": "Commented-code block (10 lines) in server/scripts/nuke-user-data.mjs:3", "shortDescription": {"text": "Commented-code block (10 lines) in server/scripts/nuke-user-data.mjs:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d2d8dd30b49ecf9c", "name": "Commented-code block (5 lines) in server/scripts/diagnose-auth-email.mjs:3", "shortDescription": {"text": "Commented-code block (5 lines) in server/scripts/diagnose-auth-email.mjs:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ec81830bcefcb498", "name": "Commented-code block (6 lines) in server/scripts/live-api-smoke-test.mjs:7", "shortDescription": {"text": "Commented-code block (6 lines) in server/scripts/live-api-smoke-test.mjs:7"}, "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-ef099be78a8335a2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/live-api-smoke-test.mjs:289", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/live-api-smoke-test.mjs:289"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-978dc439a3261478", "name": "Commented-code block (8 lines) in server/scripts/scrub-school-pii.mjs:4", "shortDescription": {"text": "Commented-code block (8 lines) in server/scripts/scrub-school-pii.mjs:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8ab0802008434d3f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/full-flow-test.mjs:39", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/full-flow-test.mjs: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-3a2e4a150cf3bd94", "name": "Commented-code block (8 lines) in server/lib/translit.js:3", "shortDescription": {"text": "Commented-code block (8 lines) in server/lib/translit.js:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7e694e343cee529d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/ratelimit.js:62", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/ratelimit.js:62"}, "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-e89fe823aee311d2", "name": "Commented-code block (5 lines) in server/lib/origins.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in server/lib/origins.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-54ef5469c1b95236", "name": "Commented-code block (6 lines) in server/lib/courier.js:3", "shortDescription": {"text": "Commented-code block (6 lines) in server/lib/courier.js:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7a6347e0a281d869", "name": "Commented-code block (6 lines) in server/routes/auth.js:59", "shortDescription": {"text": "Commented-code block (6 lines) in server/routes/auth.js:59"}, "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-5e1961a8a3a98aad", "name": "Commented-code block (6 lines) in server/db/store.js:313", "shortDescription": {"text": "Commented-code block (6 lines) in server/db/store.js:313"}, "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-d0b17c8c07a7421d", "name": "8 env vars used in code but missing from .env.example", "shortDescription": {"text": "8 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `API_BASE`, `MAILEROO_SMTP_HOST`, `MAILEROO_SMTP_PASS`, `MAILEROO_SMTP_PORT`, `MAILEROO_SMTP_USER`, `VERCEL`, `VITE_SOCIAL_FACEBOOK`, `VITE_SOCIAL_INSTAGRAM`. 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-65fb806b3f1e0f4f", "name": "Frontend route `/:lang/*` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/:lang/*` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f85fcee616bb4d17", "name": "Frontend route `how-it-works` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `how-it-works` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-448bdf4ced86a7a8", "name": "Frontend route `schools` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `schools` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-acce7a2d62429622", "name": "Frontend route `schools/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `schools/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3450a3bfd95ddee9", "name": "Frontend route `volunteer-schools` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `volunteer-schools` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e01f7eb8b7c212b4", "name": "Frontend route `donate/*` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `donate/*` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-70afaceecf10f60e", "name": "Frontend route `dashboard` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `dashboard` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-86fc95d2e3251bc3", "name": "Frontend route `about` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `about` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c0178decfb20f0f9", "name": "Frontend route `stories` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `stories` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1000a7c5a271d7d6", "name": "Frontend route `privacy` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `privacy` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-689a5a04c00025ed", "name": "Frontend route `terms` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `terms` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-63f870c7afb72559", "name": "Frontend route `cookies` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `cookies` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1122f3e6c5b7a2d5", "name": "Frontend route `search` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `search` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-dc49434c6578fbc5", "name": "Frontend route `track/:token` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `track/:token` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a3d6ca3c685a7082", "name": "Frontend route `auth` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `auth` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cc18add6df9c37cd", "name": "Frontend route `auth/forgot` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `auth/forgot` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8d4bc5d383f5bef9", "name": "Frontend route `auth/reset-password` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `auth/reset-password` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-79c3334ecdbead42", "name": "Frontend route `account` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `account` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-0b7973ec34c7762c", "name": "Frontend route `school/manage` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `school/manage` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1b496080be5b7609", "name": "Frontend route `volunteer/manage` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `volunteer/manage` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c5732850aa04a467", "name": "Dangling fetch: GET https://picsum.photos/seed/bookbridge-walk-fixture/600/400.jpg (tests/walkthrough.mjs:35)", "shortDescription": {"text": "Dangling fetch: GET https://picsum.photos/seed/bookbridge-walk-fixture/600/400.jpg (tests/walkthrough.mjs:35)"}, "fullDescription": {"text": "`tests/walkthrough.mjs:35` calls `GET https://picsum.photos/seed/bookbridge-walk-fixture/600/400.jpg` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/picsum.photos/seed/bookbridge-walk-fixture/<p>/400.jpg`\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-76889df7c8e240c5", "name": "Unused endpoint: USE /api/", "shortDescription": {"text": "Unused endpoint: USE /api/"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`server/index.js` declares `USE /api` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6eb452fbfb454d20", "name": "Unused endpoint: USE /api/auth", "shortDescription": {"text": "Unused endpoint: USE /api/auth"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/auth` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-106cf034bc6eda4a", "name": "Unused endpoint: USE /api/schools", "shortDescription": {"text": "Unused endpoint: USE /api/schools"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/schools` 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-552943096e885b7e", "name": "Unused endpoint: USE /api/donations", "shortDescription": {"text": "Unused endpoint: USE /api/donations"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/donations` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f8242ba07247d2f8", "name": "Unused endpoint: USE /api/payments", "shortDescription": {"text": "Unused endpoint: USE /api/payments"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/payments` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-90349b4281d5a6b7", "name": "Unused endpoint: USE /api/volunteer", "shortDescription": {"text": "Unused endpoint: USE /api/volunteer"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/volunteer` 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-d73ccf163920bd14", "name": "Unused endpoint: USE /api/storage", "shortDescription": {"text": "Unused endpoint: USE /api/storage"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/storage` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c3a8b7932f72b92f", "name": "Unused endpoint: USE /api/notifications", "shortDescription": {"text": "Unused endpoint: USE /api/notifications"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/notifications` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d93a530ce10d47d9", "name": "Unused endpoint: USE /api/admin", "shortDescription": {"text": "Unused endpoint: USE /api/admin"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/admin` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b43ff3df14b4bc76", "name": "Unused endpoint: USE /api/admin/schools", "shortDescription": {"text": "Unused endpoint: USE /api/admin/schools"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/admin/schools` 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-1eb0949500951637", "name": "Unused endpoint: USE /api/admin/donations", "shortDescription": {"text": "Unused endpoint: USE /api/admin/donations"}, "fullDescription": {"text": "`server/index.js` declares `USE /api/admin/donations` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`server/routes/schools.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-8456eca76070a1a7", "name": "Unused endpoint: GET /mine", "shortDescription": {"text": "Unused endpoint: GET /mine"}, "fullDescription": {"text": "`server/routes/schools.js` declares `GET /mine` 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": "`server/routes/schools.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-14b70fcb714b5e9d", "name": "Unused endpoint: GET /:id/book-requests", "shortDescription": {"text": "Unused endpoint: GET /:id/book-requests"}, "fullDescription": {"text": "`server/routes/schools.js` declares `GET /:id/book-requests` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0c534eca70d43e58", "name": "Unused endpoint: GET /:id/donations", "shortDescription": {"text": "Unused endpoint: GET /:id/donations"}, "fullDescription": {"text": "`server/routes/schools.js` declares `GET /:id/donations` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`server/routes/schools.js` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8d5b2b188d08ca82", "name": "Unused endpoint: PUT /:id", "shortDescription": {"text": "Unused endpoint: PUT /:id"}, "fullDescription": {"text": "`server/routes/schools.js` declares `PUT /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-09a38d0429b82646", "name": "Unused endpoint: POST /:id/book-requests", "shortDescription": {"text": "Unused endpoint: POST /:id/book-requests"}, "fullDescription": {"text": "`server/routes/schools.js` declares `POST /:id/book-requests` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-81ee8f42c8900dc1", "name": "Unused endpoint: DELETE /:id/book-requests/:reqId", "shortDescription": {"text": "Unused endpoint: DELETE /:id/book-requests/:reqId"}, "fullDescription": {"text": "`server/routes/schools.js` declares `DELETE /:id/book-requests/:reqId` 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-9de4cecd0e235584", "name": "Unused endpoint: GET /pending", "shortDescription": {"text": "Unused endpoint: GET /pending"}, "fullDescription": {"text": "`server/routes/schools.js` declares `GET /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-2c3d1d103b19a7f6", "name": "Unused endpoint: GET /all", "shortDescription": {"text": "Unused endpoint: GET /all"}, "fullDescription": {"text": "`server/routes/schools.js` declares `GET /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-80f81cb58d460be6", "name": "Unused endpoint: POST /:id/approval", "shortDescription": {"text": "Unused endpoint: POST /:id/approval"}, "fullDescription": {"text": "`server/routes/schools.js` declares `POST /:id/approval` 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-055c28eb69e69d27", "name": "Unused endpoint: POST /:id/transfer", "shortDescription": {"text": "Unused endpoint: POST /:id/transfer"}, "fullDescription": {"text": "`server/routes/schools.js` declares `POST /:id/transfer` 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-fd1dc91abf32142d", "name": "Unused endpoint: GET /me", "shortDescription": {"text": "Unused endpoint: GET /me"}, "fullDescription": {"text": "`server/routes/donations.js` declares `GET /me` 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-2081d8e5779aa669", "name": "Unused endpoint: GET /track/:token", "shortDescription": {"text": "Unused endpoint: GET /track/:token"}, "fullDescription": {"text": "`server/routes/donations.js` declares `GET /track/: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-0cb78db4e7bafb1c", "name": "Unused endpoint: POST /:id/cancel", "shortDescription": {"text": "Unused endpoint: POST /:id/cancel"}, "fullDescription": {"text": "`server/routes/donations.js` declares `POST /:id/cancel` 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-a61533c87dae1ef4", "name": "Unused endpoint: POST /:id/confirm-receipt", "shortDescription": {"text": "Unused endpoint: POST /:id/confirm-receipt"}, "fullDescription": {"text": "`server/routes/donations.js` declares `POST /:id/confirm-receipt` 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-09d71208c4545c30", "name": "Unused endpoint: POST /:id/status", "shortDescription": {"text": "Unused endpoint: POST /:id/status"}, "fullDescription": {"text": "`server/routes/donations.js` declares `POST /:id/status` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e9c3026c3b4b507b", "name": "Unused endpoint: GET /content", "shortDescription": {"text": "Unused endpoint: GET /content"}, "fullDescription": {"text": "`server/routes/admin.js` declares `GET /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-cd8dc4599ec52a08", "name": "Unused endpoint: GET /stats", "shortDescription": {"text": "Unused endpoint: GET /stats"}, "fullDescription": {"text": "`server/routes/admin.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-6cef8f603a28977c", "name": "Unused endpoint: PUT /content", "shortDescription": {"text": "Unused endpoint: PUT /content"}, "fullDescription": {"text": "`server/routes/admin.js` declares `PUT /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-8dd484c6bd0e8abd", "name": "Unused endpoint: GET /nearest-volunteer", "shortDescription": {"text": "Unused endpoint: GET /nearest-volunteer"}, "fullDescription": {"text": "`server/routes/admin.js` declares `GET /nearest-volunteer` 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-c924d9b3c26c9d64", "name": "Unused endpoint: GET /export.csv", "shortDescription": {"text": "Unused endpoint: GET /export.csv"}, "fullDescription": {"text": "`server/routes/admin.js` declares `GET /export.csv` 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-554de19801e8fb2d", "name": "Unused endpoint: POST /notify", "shortDescription": {"text": "Unused endpoint: POST /notify"}, "fullDescription": {"text": "`server/routes/admin.js` declares `POST /notify` 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-a2610af46c0d8d52", "name": "Unused endpoint: POST /users/role", "shortDescription": {"text": "Unused endpoint: POST /users/role"}, "fullDescription": {"text": "`server/routes/admin.js` declares `POST /users/role` 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-d16e4fa529c520e9", "name": "Unused endpoint: GET /search", "shortDescription": {"text": "Unused endpoint: GET /search"}, "fullDescription": {"text": "`server/routes/public.js` declares `GET /search` 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-bc4561da7c305448", "name": "Unused endpoint: GET /site-content", "shortDescription": {"text": "Unused endpoint: GET /site-content"}, "fullDescription": {"text": "`server/routes/public.js` declares `GET /site-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-add6dcb6007baef6", "name": "Unused endpoint: GET /leaderboard", "shortDescription": {"text": "Unused endpoint: GET /leaderboard"}, "fullDescription": {"text": "`server/routes/public.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-2a366262a6be358f", "name": "Unused endpoint: GET /activity", "shortDescription": {"text": "Unused endpoint: GET /activity"}, "fullDescription": {"text": "`server/routes/public.js` declares `GET /activity` 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-9a22789f62253c6f", "name": "Unused endpoint: GET /regions", "shortDescription": {"text": "Unused endpoint: GET /regions"}, "fullDescription": {"text": "`server/routes/public.js` declares `GET /regions` 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-06b370824f1756b7", "name": "Unused endpoint: GET /my-schools", "shortDescription": {"text": "Unused endpoint: GET /my-schools"}, "fullDescription": {"text": "`server/routes/volunteer.js` declares `GET /my-schools` 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-1ae64ee69a488efb", "name": "Unused endpoint: GET /incoming/:schoolId", "shortDescription": {"text": "Unused endpoint: GET /incoming/:schoolId"}, "fullDescription": {"text": "`server/routes/volunteer.js` declares `GET /incoming/:schoolId` 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-ce0fd1083f963f71", "name": "Unused endpoint: POST /donations/:id/status", "shortDescription": {"text": "Unused endpoint: POST /donations/:id/status"}, "fullDescription": {"text": "`server/routes/volunteer.js` declares `POST /donations/:id/status` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-304b6f2b403d93f7", "name": "Unused endpoint: POST /register", "shortDescription": {"text": "Unused endpoint: POST /register"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-048e1d8f7ca39177", "name": "Unused endpoint: POST /verify-otp", "shortDescription": {"text": "Unused endpoint: POST /verify-otp"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /verify-otp` 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-64e06d2adbf1f258", "name": "Unused endpoint: POST /resend-otp", "shortDescription": {"text": "Unused endpoint: POST /resend-otp"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /resend-otp` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-99fc36db98c134ce", "name": "Unused endpoint: POST /logout", "shortDescription": {"text": "Unused endpoint: POST /logout"}, "fullDescription": {"text": "`server/routes/auth.js` declares `POST /logout` 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/20973"}, "properties": {"repository": "Teopile/BookBridge", "repoUrl": "https://github.com/Teopile/BookBridge", "branch": "main"}, "results": [{"ruleId": "scanner-e1f21b97b19dde26", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/i18n/en.js:130"}, "properties": {"repobilityId": "b3645f42b73ff44f", "scanner": "scanner-primary", "fingerprint": "e1f21b97b19dde26", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-04701d7db2458849", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/i18n/ka.js:128"}, "properties": {"repobilityId": "e8536ca6a03d2647", "scanner": "scanner-primary", "fingerprint": "04701d7db2458849", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-a2ac37387854f7c3", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/team.js:13"}, "properties": {"repobilityId": "93fc07559b2d0e51", "scanner": "scanner-primary", "fingerprint": "a2ac37387854f7c3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-782228be5ef622f5", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/testimonials.js:14"}, "properties": {"repobilityId": "b648c4a6611ea197", "scanner": "scanner-primary", "fingerprint": "782228be5ef622f5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-82914869ba48b26d", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/src/content/stories.js:17"}, "properties": {"repobilityId": "978f5d8aa003a831", "scanner": "scanner-primary", "fingerprint": "82914869ba48b26d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-5f0ec0efb1fc3230", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/index.js:91"}, "properties": {"repobilityId": "21e6b3de2b3dd856", "scanner": "scanner-primary", "fingerprint": "5f0ec0efb1fc3230", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-76e345c8a551e1c3", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/en.js"}, "properties": {"repobilityId": "68f0b356111f667d", "scanner": "scanner-primary", "fingerprint": "76e345c8a551e1c3", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/en.js"}, "region": {"startLine": 301}}}]}, {"ruleId": "scanner-76e345c8a551e1c3", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/en.js"}, "properties": {"repobilityId": "68f0b356111f667d", "scanner": "scanner-primary", "fingerprint": "76e345c8a551e1c3", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/en.js"}, "region": {"startLine": 302}}}]}, {"ruleId": "scanner-76e345c8a551e1c3", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/en.js"}, "properties": {"repobilityId": "68f0b356111f667d", "scanner": "scanner-primary", "fingerprint": "76e345c8a551e1c3", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/en.js"}, "region": {"startLine": 303}}}]}, {"ruleId": "scanner-76e345c8a551e1c3", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/en.js"}, "properties": {"repobilityId": "68f0b356111f667d", "scanner": "scanner-primary", "fingerprint": "76e345c8a551e1c3", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/en.js"}, "region": {"startLine": 309}}}]}, {"ruleId": "scanner-76e345c8a551e1c3", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/en.js"}, "properties": {"repobilityId": "68f0b356111f667d", "scanner": "scanner-primary", "fingerprint": "76e345c8a551e1c3", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/en.js"}, "region": {"startLine": 321}}}]}, {"ruleId": "scanner-9026b08ac96b1a0f", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/ka.js"}, "properties": {"repobilityId": "c9be6e04c1a953cc", "scanner": "scanner-primary", "fingerprint": "9026b08ac96b1a0f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/ka.js"}, "region": {"startLine": 299}}}]}, {"ruleId": "scanner-9026b08ac96b1a0f", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/ka.js"}, "properties": {"repobilityId": "c9be6e04c1a953cc", "scanner": "scanner-primary", "fingerprint": "9026b08ac96b1a0f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/ka.js"}, "region": {"startLine": 300}}}]}, {"ruleId": "scanner-9026b08ac96b1a0f", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/ka.js"}, "properties": {"repobilityId": "c9be6e04c1a953cc", "scanner": "scanner-primary", "fingerprint": "9026b08ac96b1a0f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/ka.js"}, "region": {"startLine": 301}}}]}, {"ruleId": "scanner-9026b08ac96b1a0f", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/ka.js"}, "properties": {"repobilityId": "c9be6e04c1a953cc", "scanner": "scanner-primary", "fingerprint": "9026b08ac96b1a0f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/ka.js"}, "region": {"startLine": 307}}}]}, {"ruleId": "scanner-9026b08ac96b1a0f", "level": "error", "message": {"text": "Possible secret in frontend/src/i18n/ka.js"}, "properties": {"repobilityId": "c9be6e04c1a953cc", "scanner": "scanner-primary", "fingerprint": "9026b08ac96b1a0f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/i18n/ka.js"}, "region": {"startLine": 319}}}]}, {"ruleId": "scanner-e073f951e96807ef", "level": "error", "message": {"text": "Possible secret in server/scripts/diagnose-auth-email.mjs"}, "properties": {"repobilityId": "850659a6d6596620", "scanner": "scanner-primary", "fingerprint": "e073f951e96807ef", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/scripts/diagnose-auth-email.mjs"}, "region": {"startLine": 45}}}]}, {"ruleId": "scanner-834794ceb9c4db90", "level": "error", "message": {"text": "Possible secret in server/scripts/live-api-smoke-test.mjs"}, "properties": {"repobilityId": "034b5ca91be5262f", "scanner": "scanner-primary", "fingerprint": "834794ceb9c4db90", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/scripts/live-api-smoke-test.mjs"}, "region": {"startLine": 318}}}]}, {"ruleId": "scanner-834794ceb9c4db90", "level": "error", "message": {"text": "Possible secret in server/scripts/live-api-smoke-test.mjs"}, "properties": {"repobilityId": "034b5ca91be5262f", "scanner": "scanner-primary", "fingerprint": "834794ceb9c4db90", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/scripts/live-api-smoke-test.mjs"}, "region": {"startLine": 364}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 56}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 75}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 98}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 118}}}]}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "8acefafe1f872c5b", "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": "ae6b23dc2dc6706f", "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": "5623720afbc9f435", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "d1fc87703612865f", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "ddc5d35980ad3c9a", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "a7772b86e4d307cb", "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": "3c59768ce803de88", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-390fe14f35d413c0", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/errorReporter.js:3"}, "properties": {"repobilityId": "a0e1f1ab87fc3f9d", "scanner": "scanner-primary", "fingerprint": "390fe14f35d413c0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e39e209c7908b220", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/src/api.js:3"}, "properties": {"repobilityId": "c713f7095c01a9a4", "scanner": "scanner-primary", "fingerprint": "e39e209c7908b220", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-10ff2d2ce0059244", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api.js:37"}, "properties": {"repobilityId": "cf745d6a346bddea", "scanner": "scanner-primary", "fingerprint": "10ff2d2ce0059244", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a26f7e3e56db7342", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/main.jsx:13"}, "properties": {"repobilityId": "172738c2fb4f904c", "scanner": "scanner-primary", "fingerprint": "a26f7e3e56db7342", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f5f7b8a8aed163ab", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/TypewriterPlaceholder.jsx:7"}, "properties": {"repobilityId": "0a21b20ff0ddbc24", "scanner": "scanner-primary", "fingerprint": "f5f7b8a8aed163ab", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-60f6934d279835c5", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/SchoolCard.jsx:4"}, "properties": {"repobilityId": "986e8c91446c9bb0", "scanner": "scanner-primary", "fingerprint": "60f6934d279835c5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f789305c07fb1fae", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/components/PhotoUpload.jsx:20"}, "properties": {"repobilityId": "df438dbc043e6a22", "scanner": "scanner-primary", "fingerprint": "f789305c07fb1fae", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fee659f3b4ae0768", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/components/ErrorBoundary.jsx:3"}, "properties": {"repobilityId": "d5d4110a1f84575b", "scanner": "scanner-primary", "fingerprint": "fee659f3b4ae0768", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c40cc8a459096a95", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/src/content/team.js:6"}, "properties": {"repobilityId": "820f928bbd5af861", "scanner": "scanner-primary", "fingerprint": "c40cc8a459096a95", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2771bd30d5fa654e", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/src/content/testimonials.js:8"}, "properties": {"repobilityId": "5f32828b734476f6", "scanner": "scanner-primary", "fingerprint": "2771bd30d5fa654e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a7384877efad3b50", "level": "none", "message": {"text": "Commented-code block (10 lines) in frontend/src/content/stories.js:6"}, "properties": {"repobilityId": "91eab9022c7ac0e8", "scanner": "scanner-primary", "fingerprint": "a7384877efad3b50", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cd1926b0ae502217", "level": "none", "message": {"text": "Commented-code block (5 lines) in tests/gen-icons.mjs:1"}, "properties": {"repobilityId": "f19bebd4192331c9", "scanner": "scanner-primary", "fingerprint": "cd1926b0ae502217", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-649d6abe4d74f77b", "level": "none", "message": {"text": "Commented-code block (5 lines) in tests/e2e/donate.spec.js:4"}, "properties": {"repobilityId": "e8881c61cb4fdb6a", "scanner": "scanner-primary", "fingerprint": "649d6abe4d74f77b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5d49d636a15ace9c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/api.js:31"}, "properties": {"repobilityId": "25bfea9f52bb51ad", "scanner": "scanner-primary", "fingerprint": "5d49d636a15ace9c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8af713cca7d0abcf", "level": "none", "message": {"text": "Commented-code block (10 lines) in server/scripts/nuke-user-data.mjs:3"}, "properties": {"repobilityId": "d16d6d4405a427c3", "scanner": "scanner-primary", "fingerprint": "8af713cca7d0abcf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d2d8dd30b49ecf9c", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/scripts/diagnose-auth-email.mjs:3"}, "properties": {"repobilityId": "6689fd63b72523b8", "scanner": "scanner-primary", "fingerprint": "d2d8dd30b49ecf9c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ec81830bcefcb498", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/scripts/live-api-smoke-test.mjs:7"}, "properties": {"repobilityId": "7b085f9b25b51476", "scanner": "scanner-primary", "fingerprint": "ec81830bcefcb498", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ef099be78a8335a2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/live-api-smoke-test.mjs:289"}, "properties": {"repobilityId": "c66dd0d1352b1a87", "scanner": "scanner-primary", "fingerprint": "ef099be78a8335a2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-978dc439a3261478", "level": "none", "message": {"text": "Commented-code block (8 lines) in server/scripts/scrub-school-pii.mjs:4"}, "properties": {"repobilityId": "5a3a98db8d4ae2dc", "scanner": "scanner-primary", "fingerprint": "978dc439a3261478", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8ab0802008434d3f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/scripts/full-flow-test.mjs:39"}, "properties": {"repobilityId": "9dfaf749c9e6e7a7", "scanner": "scanner-primary", "fingerprint": "8ab0802008434d3f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3a2e4a150cf3bd94", "level": "none", "message": {"text": "Commented-code block (8 lines) in server/lib/translit.js:3"}, "properties": {"repobilityId": "d22a02e19a5e5a7c", "scanner": "scanner-primary", "fingerprint": "3a2e4a150cf3bd94", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7e694e343cee529d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/ratelimit.js:62"}, "properties": {"repobilityId": "a58d2d44f95c330b", "scanner": "scanner-primary", "fingerprint": "7e694e343cee529d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e89fe823aee311d2", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/lib/origins.js:1"}, "properties": {"repobilityId": "c6a6425269da35b0", "scanner": "scanner-primary", "fingerprint": "e89fe823aee311d2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-54ef5469c1b95236", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/lib/courier.js:3"}, "properties": {"repobilityId": "5702ddbf2011c59f", "scanner": "scanner-primary", "fingerprint": "54ef5469c1b95236", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7a6347e0a281d869", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/routes/auth.js:59"}, "properties": {"repobilityId": "0275cc3b8142d02e", "scanner": "scanner-primary", "fingerprint": "7a6347e0a281d869", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5e1961a8a3a98aad", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/db/store.js:313"}, "properties": {"repobilityId": "6dab2d30586ae014", "scanner": "scanner-primary", "fingerprint": "5e1961a8a3a98aad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d0b17c8c07a7421d", "level": "note", "message": {"text": "8 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "17fe720e8247f9df", "scanner": "scanner-primary", "fingerprint": "d0b17c8c07a7421d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-65fb806b3f1e0f4f", "level": "warning", "message": {"text": "Frontend route `/:lang/*` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "563768f8e345105a", "scanner": "scanner-primary", "fingerprint": "65fb806b3f1e0f4f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-f85fcee616bb4d17", "level": "warning", "message": {"text": "Frontend route `how-it-works` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "34195a4fed356559", "scanner": "scanner-primary", "fingerprint": "f85fcee616bb4d17", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-448bdf4ced86a7a8", "level": "warning", "message": {"text": "Frontend route `schools` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "5cd795d265476c79", "scanner": "scanner-primary", "fingerprint": "448bdf4ced86a7a8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-acce7a2d62429622", "level": "warning", "message": {"text": "Frontend route `schools/:id` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "3bda6b2b028a83ab", "scanner": "scanner-primary", "fingerprint": "acce7a2d62429622", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3450a3bfd95ddee9", "level": "warning", "message": {"text": "Frontend route `volunteer-schools` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "eaee0cb48d1a4c0a", "scanner": "scanner-primary", "fingerprint": "3450a3bfd95ddee9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e01f7eb8b7c212b4", "level": "warning", "message": {"text": "Frontend route `donate/*` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "61dc2b1e45a64ebb", "scanner": "scanner-primary", "fingerprint": "e01f7eb8b7c212b4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-70afaceecf10f60e", "level": "warning", "message": {"text": "Frontend route `dashboard` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "2f33234b28aa677b", "scanner": "scanner-primary", "fingerprint": "70afaceecf10f60e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-86fc95d2e3251bc3", "level": "warning", "message": {"text": "Frontend route `about` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "0d949f856861f7de", "scanner": "scanner-primary", "fingerprint": "86fc95d2e3251bc3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c0178decfb20f0f9", "level": "warning", "message": {"text": "Frontend route `stories` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "7dd3595f266593b6", "scanner": "scanner-primary", "fingerprint": "c0178decfb20f0f9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-1000a7c5a271d7d6", "level": "warning", "message": {"text": "Frontend route `privacy` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "09674a7ec6da75d5", "scanner": "scanner-primary", "fingerprint": "1000a7c5a271d7d6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-689a5a04c00025ed", "level": "warning", "message": {"text": "Frontend route `terms` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "2fecd5c7ecefe01a", "scanner": "scanner-primary", "fingerprint": "689a5a04c00025ed", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-63f870c7afb72559", "level": "warning", "message": {"text": "Frontend route `cookies` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "4101a0ca9bc6f0e2", "scanner": "scanner-primary", "fingerprint": "63f870c7afb72559", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-1122f3e6c5b7a2d5", "level": "warning", "message": {"text": "Frontend route `search` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "c385ec74829216f2", "scanner": "scanner-primary", "fingerprint": "1122f3e6c5b7a2d5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-dc49434c6578fbc5", "level": "warning", "message": {"text": "Frontend route `track/:token` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "3a8321e097eeb6a7", "scanner": "scanner-primary", "fingerprint": "dc49434c6578fbc5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a3d6ca3c685a7082", "level": "warning", "message": {"text": "Frontend route `auth` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "16896c298ea31dd5", "scanner": "scanner-primary", "fingerprint": "a3d6ca3c685a7082", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-cc18add6df9c37cd", "level": "warning", "message": {"text": "Frontend route `auth/forgot` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "b701c6a03918bed6", "scanner": "scanner-primary", "fingerprint": "cc18add6df9c37cd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-8d4bc5d383f5bef9", "level": "warning", "message": {"text": "Frontend route `auth/reset-password` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "ca4aaf6e9c5bada0", "scanner": "scanner-primary", "fingerprint": "8d4bc5d383f5bef9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-79c3334ecdbead42", "level": "warning", "message": {"text": "Frontend route `account` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "d43a50eea38da544", "scanner": "scanner-primary", "fingerprint": "79c3334ecdbead42", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-0b7973ec34c7762c", "level": "warning", "message": {"text": "Frontend route `school/manage` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "323945ee5848b7ca", "scanner": "scanner-primary", "fingerprint": "0b7973ec34c7762c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-1b496080be5b7609", "level": "warning", "message": {"text": "Frontend route `volunteer/manage` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "3b30a3d9f19108ab", "scanner": "scanner-primary", "fingerprint": "1b496080be5b7609", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c5732850aa04a467", "level": "error", "message": {"text": "Dangling fetch: GET https://picsum.photos/seed/bookbridge-walk-fixture/600/400.jpg (tests/walkthrough.mjs:35)"}, "properties": {"repobilityId": "ab6bdb817db56369", "scanner": "scanner-primary", "fingerprint": "c5732850aa04a467", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-76889df7c8e240c5", "level": "note", "message": {"text": "Unused endpoint: USE /api/"}, "properties": {"repobilityId": "74d8debbe65a14b4", "scanner": "scanner-primary", "fingerprint": "76889df7c8e240c5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "8428537b70eeca77", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6eb452fbfb454d20", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth"}, "properties": {"repobilityId": "998ca44ee62afef2", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-106cf034bc6eda4a", "level": "note", "message": {"text": "Unused endpoint: USE /api/schools"}, "properties": {"repobilityId": "f9e8e52c9e312d16", "scanner": "scanner-primary", "fingerprint": "106cf034bc6eda4a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-552943096e885b7e", "level": "note", "message": {"text": "Unused endpoint: USE /api/donations"}, "properties": {"repobilityId": "56f0f2116c337e70", "scanner": "scanner-primary", "fingerprint": "552943096e885b7e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f8242ba07247d2f8", "level": "note", "message": {"text": "Unused endpoint: USE /api/payments"}, "properties": {"repobilityId": "76678847d211e443", "scanner": "scanner-primary", "fingerprint": "f8242ba07247d2f8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-90349b4281d5a6b7", "level": "note", "message": {"text": "Unused endpoint: USE /api/volunteer"}, "properties": {"repobilityId": "23fb34dd8e156455", "scanner": "scanner-primary", "fingerprint": "90349b4281d5a6b7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d73ccf163920bd14", "level": "note", "message": {"text": "Unused endpoint: USE /api/storage"}, "properties": {"repobilityId": "f23082ca3aa5b8f4", "scanner": "scanner-primary", "fingerprint": "d73ccf163920bd14", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c3a8b7932f72b92f", "level": "note", "message": {"text": "Unused endpoint: USE /api/notifications"}, "properties": {"repobilityId": "57760fcfbe4e46ed", "scanner": "scanner-primary", "fingerprint": "c3a8b7932f72b92f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d93a530ce10d47d9", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin"}, "properties": {"repobilityId": "b0385d6f41c67e22", "scanner": "scanner-primary", "fingerprint": "d93a530ce10d47d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b43ff3df14b4bc76", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/schools"}, "properties": {"repobilityId": "e10b69dc7b63048c", "scanner": "scanner-primary", "fingerprint": "b43ff3df14b4bc76", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1eb0949500951637", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/donations"}, "properties": {"repobilityId": "8ff9043ebafab78f", "scanner": "scanner-primary", "fingerprint": "1eb0949500951637", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "f1e1e774b39a0f82", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8456eca76070a1a7", "level": "note", "message": {"text": "Unused endpoint: GET /mine"}, "properties": {"repobilityId": "f30290a554b37530", "scanner": "scanner-primary", "fingerprint": "8456eca76070a1a7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca5756175765b49d", "level": "note", "message": {"text": "Unused endpoint: GET /:id"}, "properties": {"repobilityId": "5a9086ae376901b8", "scanner": "scanner-primary", "fingerprint": "ca5756175765b49d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-14b70fcb714b5e9d", "level": "note", "message": {"text": "Unused endpoint: GET /:id/book-requests"}, "properties": {"repobilityId": "15527075b7d1cedc", "scanner": "scanner-primary", "fingerprint": "14b70fcb714b5e9d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0c534eca70d43e58", "level": "note", "message": {"text": "Unused endpoint: GET /:id/donations"}, "properties": {"repobilityId": "ecf28fbcffe0a4e6", "scanner": "scanner-primary", "fingerprint": "0c534eca70d43e58", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "a92a201b6f6c0d36", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8d5b2b188d08ca82", "level": "note", "message": {"text": "Unused endpoint: PUT /:id"}, "properties": {"repobilityId": "ba38bada03766399", "scanner": "scanner-primary", "fingerprint": "8d5b2b188d08ca82", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-09a38d0429b82646", "level": "note", "message": {"text": "Unused endpoint: POST /:id/book-requests"}, "properties": {"repobilityId": "9bfef5301c74b40e", "scanner": "scanner-primary", "fingerprint": "09a38d0429b82646", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-81ee8f42c8900dc1", "level": "note", "message": {"text": "Unused endpoint: DELETE /:id/book-requests/:reqId"}, "properties": {"repobilityId": "2df366a90a102559", "scanner": "scanner-primary", "fingerprint": "81ee8f42c8900dc1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9de4cecd0e235584", "level": "note", "message": {"text": "Unused endpoint: GET /pending"}, "properties": {"repobilityId": "2ab12c23558485a6", "scanner": "scanner-primary", "fingerprint": "9de4cecd0e235584", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2c3d1d103b19a7f6", "level": "note", "message": {"text": "Unused endpoint: GET /all"}, "properties": {"repobilityId": "401d81bcb0d264f8", "scanner": "scanner-primary", "fingerprint": "2c3d1d103b19a7f6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-80f81cb58d460be6", "level": "note", "message": {"text": "Unused endpoint: POST /:id/approval"}, "properties": {"repobilityId": "aa45783544c4fde9", "scanner": "scanner-primary", "fingerprint": "80f81cb58d460be6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-055c28eb69e69d27", "level": "note", "message": {"text": "Unused endpoint: POST /:id/transfer"}, "properties": {"repobilityId": "c276bf59546568e8", "scanner": "scanner-primary", "fingerprint": "055c28eb69e69d27", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd1dc91abf32142d", "level": "note", "message": {"text": "Unused endpoint: GET /me"}, "properties": {"repobilityId": "b356789d3d22eb19", "scanner": "scanner-primary", "fingerprint": "fd1dc91abf32142d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2081d8e5779aa669", "level": "note", "message": {"text": "Unused endpoint: GET /track/:token"}, "properties": {"repobilityId": "590a47991912e93d", "scanner": "scanner-primary", "fingerprint": "2081d8e5779aa669", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0cb78db4e7bafb1c", "level": "note", "message": {"text": "Unused endpoint: POST /:id/cancel"}, "properties": {"repobilityId": "6cf18b136ed4399e", "scanner": "scanner-primary", "fingerprint": "0cb78db4e7bafb1c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a61533c87dae1ef4", "level": "note", "message": {"text": "Unused endpoint: POST /:id/confirm-receipt"}, "properties": {"repobilityId": "c4612143352167e8", "scanner": "scanner-primary", "fingerprint": "a61533c87dae1ef4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-09d71208c4545c30", "level": "note", "message": {"text": "Unused endpoint: POST /:id/status"}, "properties": {"repobilityId": "02923a3b45069498", "scanner": "scanner-primary", "fingerprint": "09d71208c4545c30", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e9c3026c3b4b507b", "level": "note", "message": {"text": "Unused endpoint: GET /content"}, "properties": {"repobilityId": "764b71c8862b79f9", "scanner": "scanner-primary", "fingerprint": "e9c3026c3b4b507b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd8dc4599ec52a08", "level": "note", "message": {"text": "Unused endpoint: GET /stats"}, "properties": {"repobilityId": "09d15506a887c7ad", "scanner": "scanner-primary", "fingerprint": "cd8dc4599ec52a08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6cef8f603a28977c", "level": "note", "message": {"text": "Unused endpoint: PUT /content"}, "properties": {"repobilityId": "bcfe326ee1934498", "scanner": "scanner-primary", "fingerprint": "6cef8f603a28977c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8dd484c6bd0e8abd", "level": "note", "message": {"text": "Unused endpoint: GET /nearest-volunteer"}, "properties": {"repobilityId": "b0f44a97fbeaef7d", "scanner": "scanner-primary", "fingerprint": "8dd484c6bd0e8abd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c924d9b3c26c9d64", "level": "note", "message": {"text": "Unused endpoint: GET /export.csv"}, "properties": {"repobilityId": "3b3aa35f94d8a1d8", "scanner": "scanner-primary", "fingerprint": "c924d9b3c26c9d64", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-554de19801e8fb2d", "level": "note", "message": {"text": "Unused endpoint: POST /notify"}, "properties": {"repobilityId": "c1b43d90f33eb67e", "scanner": "scanner-primary", "fingerprint": "554de19801e8fb2d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a2610af46c0d8d52", "level": "note", "message": {"text": "Unused endpoint: POST /users/role"}, "properties": {"repobilityId": "3926d474fb3bdf25", "scanner": "scanner-primary", "fingerprint": "a2610af46c0d8d52", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d16e4fa529c520e9", "level": "note", "message": {"text": "Unused endpoint: GET /search"}, "properties": {"repobilityId": "4daf10b9ba803ec0", "scanner": "scanner-primary", "fingerprint": "d16e4fa529c520e9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bc4561da7c305448", "level": "note", "message": {"text": "Unused endpoint: GET /site-content"}, "properties": {"repobilityId": "c22d4fd3c0e4393c", "scanner": "scanner-primary", "fingerprint": "bc4561da7c305448", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-add6dcb6007baef6", "level": "note", "message": {"text": "Unused endpoint: GET /leaderboard"}, "properties": {"repobilityId": "12fa26e5807623fe", "scanner": "scanner-primary", "fingerprint": "add6dcb6007baef6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2a366262a6be358f", "level": "note", "message": {"text": "Unused endpoint: GET /activity"}, "properties": {"repobilityId": "28ac9a873ac900c1", "scanner": "scanner-primary", "fingerprint": "2a366262a6be358f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9a22789f62253c6f", "level": "note", "message": {"text": "Unused endpoint: GET /regions"}, "properties": {"repobilityId": "73dae1428205bd26", "scanner": "scanner-primary", "fingerprint": "9a22789f62253c6f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-06b370824f1756b7", "level": "note", "message": {"text": "Unused endpoint: GET /my-schools"}, "properties": {"repobilityId": "380616e7bfd51519", "scanner": "scanner-primary", "fingerprint": "06b370824f1756b7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1ae64ee69a488efb", "level": "note", "message": {"text": "Unused endpoint: GET /incoming/:schoolId"}, "properties": {"repobilityId": "74b4e1d31f0a1011", "scanner": "scanner-primary", "fingerprint": "1ae64ee69a488efb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ce0fd1083f963f71", "level": "note", "message": {"text": "Unused endpoint: POST /donations/:id/status"}, "properties": {"repobilityId": "81acbca3a01d8236", "scanner": "scanner-primary", "fingerprint": "ce0fd1083f963f71", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-304b6f2b403d93f7", "level": "note", "message": {"text": "Unused endpoint: POST /register"}, "properties": {"repobilityId": "99d0a92f288848c3", "scanner": "scanner-primary", "fingerprint": "304b6f2b403d93f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-048e1d8f7ca39177", "level": "note", "message": {"text": "Unused endpoint: POST /verify-otp"}, "properties": {"repobilityId": "0c342f83bbd4e869", "scanner": "scanner-primary", "fingerprint": "048e1d8f7ca39177", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-64e06d2adbf1f258", "level": "note", "message": {"text": "Unused endpoint: POST /resend-otp"}, "properties": {"repobilityId": "0bb33bd8e45895e1", "scanner": "scanner-primary", "fingerprint": "64e06d2adbf1f258", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "2689f0f5e061c9d0", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99fc36db98c134ce", "level": "note", "message": {"text": "Unused endpoint: POST /logout"}, "properties": {"repobilityId": "146fdbc715b6210a", "scanner": "scanner-primary", "fingerprint": "99fc36db98c134ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}