{"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-8508887edabcf6f6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/v2/V2App.jsx:36", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/v2/V2App.jsx:36"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ba3d5bc04a5d37ea", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/Sidebar.jsx:71", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/Sidebar.jsx:71"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-916da634f39fd624", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/Header.jsx:179", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/Header.jsx:179"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b85579f2ab78dae0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/feature/PaymentCard.jsx:29", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feature/PaymentCard.jsx:29"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0814bfac68a857aa", "name": "Icon-only button without accessible name \u2014 src/components/feature/PromotionBanner.jsx:30", "shortDescription": {"text": "Icon-only button without accessible name \u2014 src/components/feature/PromotionBanner.jsx:30"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-db051697197a5753", "name": "Icon-only button without accessible name \u2014 src/components/feature/PaywallModal.jsx:66", "shortDescription": {"text": "Icon-only button without accessible name \u2014 src/components/feature/PaywallModal.jsx:66"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1d9f4891cc92f57e", "name": "TODO/FIXME marker in shipping code \u2014 src/components/feature/PaywallModal.jsx:44", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/components/feature/PaywallModal.jsx:44"}, "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-8c9b893e2f1b374f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/feature/CostSummaryCard.jsx:93", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feature/CostSummaryCard.jsx:93"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d9e33c79fba7ac2d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/EntityDetailV3.jsx:412", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/EntityDetailV3.jsx:412"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e25a268ece56a1a0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/DashboardV3.jsx:339", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/DashboardV3.jsx:339"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-762bb1e74ec4c2c2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/SemesterDetailPage_V3.jsx:293", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/SemesterDetailPage_V3.jsx:293"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-43e7a661aa7447f2", "name": "TODO/FIXME marker in shipping code \u2014 src/pages/ParentDashboardView.jsx:30", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/pages/ParentDashboardView.jsx:30"}, "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-c80e7640057af3f5", "name": "Stray `console.log` in TS/JS \u2014 src/pages/ParentDashboardView.jsx:31", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/ParentDashboardView.jsx:31"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-66d16e15ade0ab6a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LoansView.jsx:333", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LoansView.jsx:333"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-52f510c39405d6e2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ProfileV2.jsx:103", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ProfileV2.jsx:103"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-906ca15958b9ccdf", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/SettingsView.jsx:81", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/SettingsView.jsx:81"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c13e82ede8d158d3", "name": "TODO/FIXME marker in shipping code \u2014 src/pages/ParentOnboardingView.jsx:38", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/pages/ParentOnboardingView.jsx:38"}, "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-534ae3a1a9daf3e9", "name": "Stray `console.log` in TS/JS \u2014 src/pages/ParentOnboardingView.jsx:39", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/ParentOnboardingView.jsx:39"}, "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-7ccda01b9680437d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/AdminDashboardPage.jsx:298", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/AdminDashboardPage.jsx:298"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4807a8a837c2f31e", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/AdminUserDetailPage.jsx:81", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/AdminUserDetailPage.jsx:81"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5a32ac60613087ac", "name": "Runtime dotenv file present in repo: .env.production", "shortDescription": {"text": "Runtime dotenv file present in repo: .env.production"}, "fullDescription": {"text": "`.env.production` looks like a runtime dotenv file. It contains secret-looking assignments for VITE_FIREBASE_API_KEY. Move real values to a secret manager and keep only `.env.example` style templates in source control."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-a1e8567de59b8732", "name": "Insecure pattern 'cors_wildcard' in server/index.cjs:37", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in server/index.cjs:37"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d92952f57fc6097f", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/v2/V2Landing.jsx:108", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/v2/V2Landing.jsx:108"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2bafca2d40d212c2", "name": "Insecure pattern 'local_storage_auth_token' in src/contexts/AdminContext.jsx:53", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in src/contexts/AdminContext.jsx:53"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-de68609752d19967", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/lib/firebase.js:96", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/lib/firebase.js:96"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cc5bacfcb0d4f857", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/LandingPage.jsx:68", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/LandingPage.jsx:68"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b48e07e6ce1706e8", "name": "Very large file: src/v2/V2App.jsx (2973 lines)", "shortDescription": {"text": "Very large file: src/v2/V2App.jsx (2973 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "12 test file(s) for 212 source file(s) (ratio 0.06). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 77 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 218 placeholder/mock markers across 53 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ecb0d2c55ed6875d", "name": "Agent authority lacks a verifier contract: .claude/settings.local.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/settings.local.json"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2cf5acf6b573bf45", "name": "Legacy-named symbol `cc_v2` in src/main.jsx:12", "shortDescription": {"text": "Legacy-named symbol `cc_v2` in src/main.jsx:12"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6fb2f551f5197e22", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/v2/Leeboon.jsx:60", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/v2/Leeboon.jsx:60"}, "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-2123fd6ac752b963", "name": "Commented-code block (5 lines) in src/constants/education.js:471", "shortDescription": {"text": "Commented-code block (5 lines) in src/constants/education.js:471"}, "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-c4c17e9fb3adf206", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/contexts/AdminContext.jsx:60", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/contexts/AdminContext.jsx:60"}, "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-c3480f50e5bf9230", "name": "Commented-code block (9 lines) in src/contexts/AppContext.jsx:127", "shortDescription": {"text": "Commented-code block (9 lines) in src/contexts/AppContext.jsx:127"}, "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-361114ceacb39040", "name": "Commented-code block (8 lines) in src/contexts/UniversalSemesterContext.jsx:11", "shortDescription": {"text": "Commented-code block (8 lines) in src/contexts/UniversalSemesterContext.jsx:11"}, "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-e2c087a3f1c899c5", "name": "Commented-code block (5 lines) in src/lib/firebase.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/firebase.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-eedc63bab94370c8", "name": "Legacy-named symbol `leboon_brain_v1` in src/lib/leboonBrain.js:9", "shortDescription": {"text": "Legacy-named symbol `leboon_brain_v1` in src/lib/leboonBrain.js:9"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5d8e2fec87226767", "name": "Commented-code block (5 lines) in src/lib/installmentEngine.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/installmentEngine.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-fa3d36c176e595cc", "name": "Commented-code block (6 lines) in src/pages/LandingPage.jsx:56", "shortDescription": {"text": "Commented-code block (6 lines) in src/pages/LandingPage.jsx:56"}, "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-5228608b5adebe34", "name": "Commented-code block (5 lines) in src/hooks/useUnifiedTotals.js:172", "shortDescription": {"text": "Commented-code block (5 lines) in src/hooks/useUnifiedTotals.js:172"}, "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-7c8b918e1fee9558", "name": "20 env vars used in code but missing from .env.example", "shortDescription": {"text": "20 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_JWT_SECRET`, `ADMIN_PASSWORD`, `ADMIN_PASSWORD_HASH`, `ADMIN_USERNAME`, `ANTHROPIC_API_KEY`, `ASSISTANT_MODEL`, `ASSISTANT_RATE_MAX`, `ASSISTANT_RATE_WINDOW_MS` + 12 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bc02052490c6442d", "name": "Dangling fetch: POST /api/auth/send-otp (src/api.js:35)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/send-otp (src/api.js:35)"}, "fullDescription": {"text": "`src/api.js:35` calls `POST /api/auth/send-otp` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/send-otp`\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-078d89a20a763aec", "name": "Dangling fetch: POST /api/auth/verify-otp (src/api.js:42)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/verify-otp (src/api.js:42)"}, "fullDescription": {"text": "`src/api.js:42` calls `POST /api/auth/verify-otp` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/verify-otp`\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-f4303fa0cc48ea4e", "name": "Dangling fetch: POST /api/auth/google (src/api.js:51)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/google (src/api.js:51)"}, "fullDescription": {"text": "`src/api.js:51` calls `POST /api/auth/google` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/google`\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-9de5e4954a9e88be", "name": "Dangling fetch: POST /api/auth/register (src/api.js:60)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/register (src/api.js:60)"}, "fullDescription": {"text": "`src/api.js:60` calls `POST /api/auth/register` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/register`\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-3084ed31a6eeaf44", "name": "Dangling fetch: POST /api/auth/login (src/api.js:67)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/login (src/api.js:67)"}, "fullDescription": {"text": "`src/api.js:67` calls `POST /api/auth/login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/login`\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-31ab0fe338e642f4", "name": "Dangling fetch: GET /api/auth/user/${id} (src/api.js:74)", "shortDescription": {"text": "Dangling fetch: GET /api/auth/user/${id} (src/api.js:74)"}, "fullDescription": {"text": "`src/api.js:74` calls `GET /api/auth/user/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/user/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-32d3cf8f80f0f3b9", "name": "Dangling fetch: PUT /api/auth/profile/${id} (src/api.js:78)", "shortDescription": {"text": "Dangling fetch: PUT /api/auth/profile/${id} (src/api.js:78)"}, "fullDescription": {"text": "`src/api.js:78` calls `PUT /api/auth/profile/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/profile/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8839ee9e484fca54", "name": "Dangling fetch: GET /api/expenses/${userId} (src/api.js:87)", "shortDescription": {"text": "Dangling fetch: GET /api/expenses/${userId} (src/api.js:87)"}, "fullDescription": {"text": "`src/api.js:87` calls `GET /api/expenses/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-73e2005e2f15e399", "name": "Dangling fetch: POST /api/expenses (src/api.js:91)", "shortDescription": {"text": "Dangling fetch: POST /api/expenses (src/api.js:91)"}, "fullDescription": {"text": "`src/api.js:91` calls `POST /api/expenses` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-b4c375e72fa8f5f9", "name": "Dangling fetch: PUT /api/expenses/${id} (src/api.js:98)", "shortDescription": {"text": "Dangling fetch: PUT /api/expenses/${id} (src/api.js:98)"}, "fullDescription": {"text": "`src/api.js:98` calls `PUT /api/expenses/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ee01fc16b1ce60b1", "name": "Dangling fetch: DELETE /api/expenses/${id} (src/api.js:105)", "shortDescription": {"text": "Dangling fetch: DELETE /api/expenses/${id} (src/api.js:105)"}, "fullDescription": {"text": "`src/api.js:105` calls `DELETE /api/expenses/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-72b4a33d87b3a35e", "name": "Dangling fetch: GET /api/semesters/${userId} (src/api.js:113)", "shortDescription": {"text": "Dangling fetch: GET /api/semesters/${userId} (src/api.js:113)"}, "fullDescription": {"text": "`src/api.js:113` calls `GET /api/semesters/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semesters/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b13a6e9d1ebee9ff", "name": "Dangling fetch: POST /api/semesters (src/api.js:117)", "shortDescription": {"text": "Dangling fetch: POST /api/semesters (src/api.js:117)"}, "fullDescription": {"text": "`src/api.js:117` calls `POST /api/semesters` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semesters`\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-e6d243d79142f43e", "name": "Dangling fetch: PUT /api/semesters/${id} (src/api.js:124)", "shortDescription": {"text": "Dangling fetch: PUT /api/semesters/${id} (src/api.js:124)"}, "fullDescription": {"text": "`src/api.js:124` calls `PUT /api/semesters/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semesters/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2ce1caab0b1153b6", "name": "Dangling fetch: DELETE /api/semesters/${id} (src/api.js:131)", "shortDescription": {"text": "Dangling fetch: DELETE /api/semesters/${id} (src/api.js:131)"}, "fullDescription": {"text": "`src/api.js:131` calls `DELETE /api/semesters/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semesters/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8bed5e4023d557fd", "name": "Dangling fetch: GET /api/loans/${userId} (src/api.js:139)", "shortDescription": {"text": "Dangling fetch: GET /api/loans/${userId} (src/api.js:139)"}, "fullDescription": {"text": "`src/api.js:139` calls `GET /api/loans/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/loans/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-86d992b7f18b6234", "name": "Dangling fetch: POST /api/loans (src/api.js:143)", "shortDescription": {"text": "Dangling fetch: POST /api/loans (src/api.js:143)"}, "fullDescription": {"text": "`src/api.js:143` calls `POST /api/loans` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/loans`\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-7a8081b54a274439", "name": "Dangling fetch: PUT /api/loans/${id} (src/api.js:150)", "shortDescription": {"text": "Dangling fetch: PUT /api/loans/${id} (src/api.js:150)"}, "fullDescription": {"text": "`src/api.js:150` calls `PUT /api/loans/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/loans/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d2172fdf5509ab24", "name": "Dangling fetch: PUT /api/loans/${id}/payment (src/api.js:157)", "shortDescription": {"text": "Dangling fetch: PUT /api/loans/${id}/payment (src/api.js:157)"}, "fullDescription": {"text": "`src/api.js:157` calls `PUT /api/loans/${id}/payment` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/loans/<p>/payment`\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-7f70797066fd9de2", "name": "Dangling fetch: DELETE /api/loans/${id} (src/api.js:164)", "shortDescription": {"text": "Dangling fetch: DELETE /api/loans/${id} (src/api.js:164)"}, "fullDescription": {"text": "`src/api.js:164` calls `DELETE /api/loans/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/loans/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2cd5d8129c26c846", "name": "Dangling fetch: GET /api/settings/${userId} (src/api.js:172)", "shortDescription": {"text": "Dangling fetch: GET /api/settings/${userId} (src/api.js:172)"}, "fullDescription": {"text": "`src/api.js:172` calls `GET /api/settings/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/settings/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-98052313fbbcb2c4", "name": "Dangling fetch: PUT /api/settings/${userId} (src/api.js:176)", "shortDescription": {"text": "Dangling fetch: PUT /api/settings/${userId} (src/api.js:176)"}, "fullDescription": {"text": "`src/api.js:176` calls `PUT /api/settings/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/settings/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ed5a5017d20eac0a", "name": "Dangling fetch: GET /api/v2data/${userId} (src/api.js:185)", "shortDescription": {"text": "Dangling fetch: GET /api/v2data/${userId} (src/api.js:185)"}, "fullDescription": {"text": "`src/api.js:185` calls `GET /api/v2data/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/v2data/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9c41341624ec1d14", "name": "Dangling fetch: PUT /api/v2data/${userId} (src/api.js:189)", "shortDescription": {"text": "Dangling fetch: PUT /api/v2data/${userId} (src/api.js:189)"}, "fullDescription": {"text": "`src/api.js:189` calls `PUT /api/v2data/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/v2data/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a4d447f14b18d292", "name": "Dangling fetch: GET /api/feed/profile/me (src/api.js:198)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/profile/me (src/api.js:198)"}, "fullDescription": {"text": "`src/api.js:198` calls `GET /api/feed/profile/me` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/profile/me`\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-06b3e8a98043e626", "name": "Dangling fetch: POST /api/feed/profile (src/api.js:202)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/profile (src/api.js:202)"}, "fullDescription": {"text": "`src/api.js:202` calls `POST /api/feed/profile` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/profile`\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-56b9beee36050598", "name": "Dangling fetch: POST /api/feed/posts (src/api.js:213)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/posts (src/api.js:213)"}, "fullDescription": {"text": "`src/api.js:213` calls `POST /api/feed/posts` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts`\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-d393c2feceb8d81b", "name": "Dangling fetch: POST /api/feed/posts/${id}/like (src/api.js:219)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/posts/${id}/like (src/api.js:219)"}, "fullDescription": {"text": "`src/api.js:219` calls `POST /api/feed/posts/${id}/like` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>/like`\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-fae51ca93c9b2aa5", "name": "Dangling fetch: DELETE /api/feed/posts/${id}/like (src/api.js:220)", "shortDescription": {"text": "Dangling fetch: DELETE /api/feed/posts/${id}/like (src/api.js:220)"}, "fullDescription": {"text": "`src/api.js:220` calls `DELETE /api/feed/posts/${id}/like` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>/like`\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-2df8e934f641a49e", "name": "Dangling fetch: GET /api/feed/posts/${id}/comments (src/api.js:221)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/posts/${id}/comments (src/api.js:221)"}, "fullDescription": {"text": "`src/api.js:221` calls `GET /api/feed/posts/${id}/comments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>/comments`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-16d852009506fe90", "name": "Dangling fetch: POST /api/feed/posts/${id}/comments (src/api.js:222)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/posts/${id}/comments (src/api.js:222)"}, "fullDescription": {"text": "`src/api.js:222` calls `POST /api/feed/posts/${id}/comments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>/comments`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f1db8ef59be928f0", "name": "Dangling fetch: POST /api/feed/follow/${encodeURIComponent(handle)} (src/api.js:223)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/follow/${encodeURIComponent(handle)} (src/api.js:223)"}, "fullDescription": {"text": "`src/api.js:223` calls `POST /api/feed/follow/${encodeURIComponent(handle)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/follow/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ca7d84b223077b19", "name": "Dangling fetch: DELETE /api/feed/follow/${encodeURIComponent(handle)} (src/api.js:224)", "shortDescription": {"text": "Dangling fetch: DELETE /api/feed/follow/${encodeURIComponent(handle)} (src/api.js:224)"}, "fullDescription": {"text": "`src/api.js:224` calls `DELETE /api/feed/follow/${encodeURIComponent(handle)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/follow/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-93733dbe39173f47", "name": "Dangling fetch: GET /api/feed/users?q=${encodeURIComponent(q)} (src/api.js:225)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/users?q=${encodeURIComponent(q)} (src/api.js:225)"}, "fullDescription": {"text": "`src/api.js:225` calls `GET /api/feed/users?q=${encodeURIComponent(q)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/users`\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-a48ac516b1024b67", "name": "Dangling fetch: GET /api/feed/profile/u/${encodeURIComponent(handle)} (src/api.js:226)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/profile/u/${encodeURIComponent(handle)} (src/api.js:226)"}, "fullDescription": {"text": "`src/api.js:226` calls `GET /api/feed/profile/u/${encodeURIComponent(handle)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/profile/u/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2ec0bacc4f1bc8e9", "name": "Dangling fetch: GET /api/feed/profile/u/${encodeURIComponent(handle)}/posts (src/api.js:227)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/profile/u/${encodeURIComponent(handle)}/posts (src/api.js:227)"}, "fullDescription": {"text": "`src/api.js:227` calls `GET /api/feed/profile/u/${encodeURIComponent(handle)}/posts` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/profile/u/<p>/posts`\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-3869878f05085e5c", "name": "Dangling fetch: POST /api/feed/upload (src/api.js:228)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/upload (src/api.js:228)"}, "fullDescription": {"text": "`src/api.js:228` calls `POST /api/feed/upload` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/upload`\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-f66746a006caaae3", "name": "Dangling fetch: POST /api/feed/report (src/api.js:229)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/report (src/api.js:229)"}, "fullDescription": {"text": "`src/api.js:229` calls `POST /api/feed/report` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/report`\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-ccbd2b0899199515", "name": "Dangling fetch: GET /api/feed/dm (src/api.js:232)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/dm (src/api.js:232)"}, "fullDescription": {"text": "`src/api.js:232` calls `GET /api/feed/dm` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/dm`\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-f5232a31b13c0c4e", "name": "Dangling fetch: GET /api/feed/notes (src/api.js:238)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/notes (src/api.js:238)"}, "fullDescription": {"text": "`src/api.js:238` calls `GET /api/feed/notes` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/notes`\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-2ed440b8c0ad78b1", "name": "Dangling fetch: POST /api/feed/notes (src/api.js:239)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/notes (src/api.js:239)"}, "fullDescription": {"text": "`src/api.js:239` calls `POST /api/feed/notes` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/notes`\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-df40d825e0d205cf", "name": "Dangling fetch: GET /api/feed/stories (src/api.js:242)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/stories (src/api.js:242)"}, "fullDescription": {"text": "`src/api.js:242` calls `GET /api/feed/stories` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/stories`\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-682642f29c47f8fa", "name": "Dangling fetch: POST /api/feed/stories (src/api.js:243)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/stories (src/api.js:243)"}, "fullDescription": {"text": "`src/api.js:243` calls `POST /api/feed/stories` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/stories`\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-ccf575677731fe13", "name": "Dangling fetch: DELETE /api/feed/stories/${encodeURIComponent(id)} (src/api.js:244)", "shortDescription": {"text": "Dangling fetch: DELETE /api/feed/stories/${encodeURIComponent(id)} (src/api.js:244)"}, "fullDescription": {"text": "`src/api.js:244` calls `DELETE /api/feed/stories/${encodeURIComponent(id)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/stories/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-24d816c24dc46470", "name": "Dangling fetch: GET /api/feed/notifications (src/api.js:247)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/notifications (src/api.js:247)"}, "fullDescription": {"text": "`src/api.js:247` calls `GET /api/feed/notifications` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/notifications`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-19df42dd1604ee6d", "name": "Dangling fetch: POST /api/feed/notifications/read (src/api.js:248)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/notifications/read (src/api.js:248)"}, "fullDescription": {"text": "`src/api.js:248` calls `POST /api/feed/notifications/read` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/notifications/read`\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-03f852413c427013", "name": "Dangling fetch: GET /api/feed/posts/${encodeURIComponent(id)} (src/api.js:252)", "shortDescription": {"text": "Dangling fetch: GET /api/feed/posts/${encodeURIComponent(id)} (src/api.js:252)"}, "fullDescription": {"text": "`src/api.js:252` calls `GET /api/feed/posts/${encodeURIComponent(id)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f7b1e9d6413206a2", "name": "Dangling fetch: POST /api/feed/profile (src/api.js:255)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/profile (src/api.js:255)"}, "fullDescription": {"text": "`src/api.js:255` calls `POST /api/feed/profile` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/profile`\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-b0f936cac36fd5d9", "name": "Dangling fetch: DELETE /api/feed/posts/${id} (src/api.js:256)", "shortDescription": {"text": "Dangling fetch: DELETE /api/feed/posts/${id} (src/api.js:256)"}, "fullDescription": {"text": "`src/api.js:256` calls `DELETE /api/feed/posts/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-833f27f81e2ead7a", "name": "Dangling fetch: POST /api/feed/posts/${encodeURIComponent(id)}/pin (src/api.js:257)", "shortDescription": {"text": "Dangling fetch: POST /api/feed/posts/${encodeURIComponent(id)}/pin (src/api.js:257)"}, "fullDescription": {"text": "`src/api.js:257` calls `POST /api/feed/posts/${encodeURIComponent(id)}/pin` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>/pin`\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-f837a24c2132ef81", "name": "Dangling fetch: DELETE /api/feed/posts/${postId}/comments/${commentId} (src/api.js:258)", "shortDescription": {"text": "Dangling fetch: DELETE /api/feed/posts/${postId}/comments/${commentId} (src/api.js:258)"}, "fullDescription": {"text": "`src/api.js:258` calls `DELETE /api/feed/posts/${postId}/comments/${commentId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/feed/posts/<p>/comments/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d8862fe650de1f70", "name": "Dangling fetch: GET /api/education-fees/${userId} (src/api.js:263)", "shortDescription": {"text": "Dangling fetch: GET /api/education-fees/${userId} (src/api.js:263)"}, "fullDescription": {"text": "`src/api.js:263` calls `GET /api/education-fees/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/education-fees/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c5b712d962c79744", "name": "Dangling fetch: POST /api/education-fees/sync (src/api.js:267)", "shortDescription": {"text": "Dangling fetch: POST /api/education-fees/sync (src/api.js:267)"}, "fullDescription": {"text": "`src/api.js:267` calls `POST /api/education-fees/sync` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/education-fees/sync`\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-f9bf7c7d2cc42f2d", "name": "Dangling fetch: GET /api/housing/${userId} (src/api.js:276)", "shortDescription": {"text": "Dangling fetch: GET /api/housing/${userId} (src/api.js:276)"}, "fullDescription": {"text": "`src/api.js:276` calls `GET /api/housing/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/housing/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a036ea0fd5d2baa0", "name": "Dangling fetch: POST /api/housing (src/api.js:280)", "shortDescription": {"text": "Dangling fetch: POST /api/housing (src/api.js:280)"}, "fullDescription": {"text": "`src/api.js:280` calls `POST /api/housing` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/housing`\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-6c43beb9c7f20194", "name": "Dangling fetch: PUT /api/housing/${id} (src/api.js:287)", "shortDescription": {"text": "Dangling fetch: PUT /api/housing/${id} (src/api.js:287)"}, "fullDescription": {"text": "`src/api.js:287` calls `PUT /api/housing/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/housing/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-cf55c3162c781a1c", "name": "Dangling fetch: DELETE /api/housing/${id} (src/api.js:294)", "shortDescription": {"text": "Dangling fetch: DELETE /api/housing/${id} (src/api.js:294)"}, "fullDescription": {"text": "`src/api.js:294` calls `DELETE /api/housing/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/housing/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9eba4f4677784734", "name": "Dangling fetch: GET /api/coaching/${userId} (src/api.js:300)", "shortDescription": {"text": "Dangling fetch: GET /api/coaching/${userId} (src/api.js:300)"}, "fullDescription": {"text": "`src/api.js:300` calls `GET /api/coaching/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/coaching/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a52addb27466efdb", "name": "Dangling fetch: POST /api/coaching (src/api.js:304)", "shortDescription": {"text": "Dangling fetch: POST /api/coaching (src/api.js:304)"}, "fullDescription": {"text": "`src/api.js:304` calls `POST /api/coaching` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/coaching`\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-13baa0bf024a0fc0", "name": "Dangling fetch: PUT /api/coaching/${id} (src/api.js:308)", "shortDescription": {"text": "Dangling fetch: PUT /api/coaching/${id} (src/api.js:308)"}, "fullDescription": {"text": "`src/api.js:308` calls `PUT /api/coaching/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/coaching/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4ee04f32099a0656", "name": "Dangling fetch: DELETE /api/coaching/${id} (src/api.js:312)", "shortDescription": {"text": "Dangling fetch: DELETE /api/coaching/${id} (src/api.js:312)"}, "fullDescription": {"text": "`src/api.js:312` calls `DELETE /api/coaching/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/coaching/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b56795f70d41570a", "name": "Dangling fetch: PATCH /api/coaching/${id}/payment (src/api.js:316)", "shortDescription": {"text": "Dangling fetch: PATCH /api/coaching/${id}/payment (src/api.js:316)"}, "fullDescription": {"text": "`src/api.js:316` calls `PATCH /api/coaching/${id}/payment` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/coaching/<p>/payment`\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-2bdcb0f27111226c", "name": "Dangling fetch: GET /api/batches/${userId} (src/api.js:322)", "shortDescription": {"text": "Dangling fetch: GET /api/batches/${userId} (src/api.js:322)"}, "fullDescription": {"text": "`src/api.js:322` calls `GET /api/batches/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/batches/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f16f53f3cee8f5f4", "name": "Dangling fetch: POST /api/batches (src/api.js:326)", "shortDescription": {"text": "Dangling fetch: POST /api/batches (src/api.js:326)"}, "fullDescription": {"text": "`src/api.js:326` calls `POST /api/batches` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/batches`\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-439fc5e6c641d98e", "name": "Dangling fetch: PUT /api/batches/${id} (src/api.js:330)", "shortDescription": {"text": "Dangling fetch: PUT /api/batches/${id} (src/api.js:330)"}, "fullDescription": {"text": "`src/api.js:330` calls `PUT /api/batches/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/batches/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-bbcad70971b0c6fc", "name": "Dangling fetch: DELETE /api/batches/${id} (src/api.js:334)", "shortDescription": {"text": "Dangling fetch: DELETE /api/batches/${id} (src/api.js:334)"}, "fullDescription": {"text": "`src/api.js:334` calls `DELETE /api/batches/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/batches/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-3316268be5b9f172", "name": "Dangling fetch: GET /api/tutors/${userId} (src/api.js:340)", "shortDescription": {"text": "Dangling fetch: GET /api/tutors/${userId} (src/api.js:340)"}, "fullDescription": {"text": "`src/api.js:340` calls `GET /api/tutors/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tutors/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-efaa7441dc06286c", "name": "Dangling fetch: POST /api/tutors (src/api.js:344)", "shortDescription": {"text": "Dangling fetch: POST /api/tutors (src/api.js:344)"}, "fullDescription": {"text": "`src/api.js:344` calls `POST /api/tutors` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tutors`\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-691ec7ea1a6d4c05", "name": "Dangling fetch: PUT /api/tutors/${id} (src/api.js:348)", "shortDescription": {"text": "Dangling fetch: PUT /api/tutors/${id} (src/api.js:348)"}, "fullDescription": {"text": "`src/api.js:348` calls `PUT /api/tutors/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tutors/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-777669803807056b", "name": "Dangling fetch: DELETE /api/tutors/${id} (src/api.js:352)", "shortDescription": {"text": "Dangling fetch: DELETE /api/tutors/${id} (src/api.js:352)"}, "fullDescription": {"text": "`src/api.js:352` calls `DELETE /api/tutors/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tutors/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-700a54ee92fbed97", "name": "Dangling fetch: GET /api/clubs/${userId} (src/api.js:358)", "shortDescription": {"text": "Dangling fetch: GET /api/clubs/${userId} (src/api.js:358)"}, "fullDescription": {"text": "`src/api.js:358` calls `GET /api/clubs/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/clubs/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-26d88298a89c135f", "name": "Dangling fetch: POST /api/clubs (src/api.js:362)", "shortDescription": {"text": "Dangling fetch: POST /api/clubs (src/api.js:362)"}, "fullDescription": {"text": "`src/api.js:362` calls `POST /api/clubs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/clubs`\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-9de3308d1ad54cf6", "name": "Dangling fetch: PUT /api/clubs/${id} (src/api.js:366)", "shortDescription": {"text": "Dangling fetch: PUT /api/clubs/${id} (src/api.js:366)"}, "fullDescription": {"text": "`src/api.js:366` calls `PUT /api/clubs/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/clubs/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-001c047fa240ec4b", "name": "Dangling fetch: DELETE /api/clubs/${id} (src/api.js:370)", "shortDescription": {"text": "Dangling fetch: DELETE /api/clubs/${id} (src/api.js:370)"}, "fullDescription": {"text": "`src/api.js:370` calls `DELETE /api/clubs/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/clubs/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-51976ffb239af3ef", "name": "Dangling fetch: GET /api/events/${userId} (src/api.js:376)", "shortDescription": {"text": "Dangling fetch: GET /api/events/${userId} (src/api.js:376)"}, "fullDescription": {"text": "`src/api.js:376` calls `GET /api/events/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/events/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-28cd0dd981489e53", "name": "Dangling fetch: POST /api/events (src/api.js:380)", "shortDescription": {"text": "Dangling fetch: POST /api/events (src/api.js:380)"}, "fullDescription": {"text": "`src/api.js:380` calls `POST /api/events` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/events`\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-2f5b940de72a75dc", "name": "Dangling fetch: PUT /api/events/${id} (src/api.js:384)", "shortDescription": {"text": "Dangling fetch: PUT /api/events/${id} (src/api.js:384)"}, "fullDescription": {"text": "`src/api.js:384` calls `PUT /api/events/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/events/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-3a95a6ed335a66f8", "name": "Dangling fetch: DELETE /api/events/${id} (src/api.js:388)", "shortDescription": {"text": "Dangling fetch: DELETE /api/events/${id} (src/api.js:388)"}, "fullDescription": {"text": "`src/api.js:388` calls `DELETE /api/events/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/events/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-279278cb1cd051f6", "name": "Dangling fetch: GET /api/uniforms/${userId} (src/api.js:394)", "shortDescription": {"text": "Dangling fetch: GET /api/uniforms/${userId} (src/api.js:394)"}, "fullDescription": {"text": "`src/api.js:394` calls `GET /api/uniforms/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/uniforms/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e0f27dbb51b878ef", "name": "Dangling fetch: POST /api/uniforms (src/api.js:398)", "shortDescription": {"text": "Dangling fetch: POST /api/uniforms (src/api.js:398)"}, "fullDescription": {"text": "`src/api.js:398` calls `POST /api/uniforms` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/uniforms`\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-04555ca54279d7d5", "name": "Dangling fetch: PUT /api/uniforms/${id} (src/api.js:402)", "shortDescription": {"text": "Dangling fetch: PUT /api/uniforms/${id} (src/api.js:402)"}, "fullDescription": {"text": "`src/api.js:402` calls `PUT /api/uniforms/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/uniforms/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5363dbf864eba0e6", "name": "Dangling fetch: DELETE /api/uniforms/${id} (src/api.js:406)", "shortDescription": {"text": "Dangling fetch: DELETE /api/uniforms/${id} (src/api.js:406)"}, "fullDescription": {"text": "`src/api.js:406` calls `DELETE /api/uniforms/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/uniforms/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-aa427357d49705e4", "name": "Dangling fetch: POST /api/admin/redeem (src/api.js:412)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/redeem (src/api.js:412)"}, "fullDescription": {"text": "`src/api.js:412` calls `POST /api/admin/redeem` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/admin/redeem`\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-60beab192534663a", "name": "Dangling fetch: GET /api/entities/${userId} (src/api.js:421)", "shortDescription": {"text": "Dangling fetch: GET /api/entities/${userId} (src/api.js:421)"}, "fullDescription": {"text": "`src/api.js:421` calls `GET /api/entities/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/entities/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-05796193d2426221", "name": "Dangling fetch: POST /api/entities/${userId} (src/api.js:425)", "shortDescription": {"text": "Dangling fetch: POST /api/entities/${userId} (src/api.js:425)"}, "fullDescription": {"text": "`src/api.js:425` calls `POST /api/entities/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/entities/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-615da81436a2999d", "name": "Dangling fetch: PUT /api/entities/${userId}/${id} (src/api.js:432)", "shortDescription": {"text": "Dangling fetch: PUT /api/entities/${userId}/${id} (src/api.js:432)"}, "fullDescription": {"text": "`src/api.js:432` calls `PUT /api/entities/${userId}/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/entities/<p>/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-aadd755d1eaba367", "name": "Dangling fetch: GET /api/trackers/${userId} (src/api.js:445)", "shortDescription": {"text": "Dangling fetch: GET /api/trackers/${userId} (src/api.js:445)"}, "fullDescription": {"text": "`src/api.js:445` calls `GET /api/trackers/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/trackers/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f313964c7e25abc6", "name": "Dangling fetch: GET /api/trackers/${userId}/entity/${entityId} (src/api.js:449)", "shortDescription": {"text": "Dangling fetch: GET /api/trackers/${userId}/entity/${entityId} (src/api.js:449)"}, "fullDescription": {"text": "`src/api.js:449` calls `GET /api/trackers/${userId}/entity/${entityId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/trackers/<p>/entity/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8c43c4d3b5b21525", "name": "Dangling fetch: POST /api/trackers/${userId} (src/api.js:453)", "shortDescription": {"text": "Dangling fetch: POST /api/trackers/${userId} (src/api.js:453)"}, "fullDescription": {"text": "`src/api.js:453` calls `POST /api/trackers/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/trackers/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-3592f4402da6ee69", "name": "Dangling fetch: PUT /api/trackers/${userId}/${id} (src/api.js:460)", "shortDescription": {"text": "Dangling fetch: PUT /api/trackers/${userId}/${id} (src/api.js:460)"}, "fullDescription": {"text": "`src/api.js:460` calls `PUT /api/trackers/${userId}/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/trackers/<p>/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-375e85577c8fb36e", "name": "Dangling fetch: GET /api/obligations/${userId} (src/api.js:469)", "shortDescription": {"text": "Dangling fetch: GET /api/obligations/${userId} (src/api.js:469)"}, "fullDescription": {"text": "`src/api.js:469` calls `GET /api/obligations/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/obligations/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-81ffcac226946a55", "name": "Dangling fetch: GET /api/obligations/${userId}/upcoming (src/api.js:473)", "shortDescription": {"text": "Dangling fetch: GET /api/obligations/${userId}/upcoming (src/api.js:473)"}, "fullDescription": {"text": "`src/api.js:473` calls `GET /api/obligations/${userId}/upcoming` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/obligations/<p>/upcoming`\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-ed5dc0feecb98ec6", "name": "Dangling fetch: POST /api/obligations/${userId} (src/api.js:477)", "shortDescription": {"text": "Dangling fetch: POST /api/obligations/${userId} (src/api.js:477)"}, "fullDescription": {"text": "`src/api.js:477` calls `POST /api/obligations/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/obligations/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c69afdac629c19c1", "name": "Dangling fetch: PUT /api/obligations/${userId}/${id} (src/api.js:484)", "shortDescription": {"text": "Dangling fetch: PUT /api/obligations/${userId}/${id} (src/api.js:484)"}, "fullDescription": {"text": "`src/api.js:484` calls `PUT /api/obligations/${userId}/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/obligations/<p>/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4e0092200c1defc1", "name": "Dangling fetch: PATCH /api/obligations/${userId}/${id}/waiver (src/api.js:491)", "shortDescription": {"text": "Dangling fetch: PATCH /api/obligations/${userId}/${id}/waiver (src/api.js:491)"}, "fullDescription": {"text": "`src/api.js:491` calls `PATCH /api/obligations/${userId}/${id}/waiver` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/obligations/<p>/<p>/waiver`\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-a258b7d2b299614d", "name": "Dangling fetch: PATCH /api/obligations/${userId}/${id}/skip (src/api.js:498)", "shortDescription": {"text": "Dangling fetch: PATCH /api/obligations/${userId}/${id}/skip (src/api.js:498)"}, "fullDescription": {"text": "`src/api.js:498` calls `PATCH /api/obligations/${userId}/${id}/skip` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/obligations/<p>/<p>/skip`\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-98bdfb1497dddf47", "name": "Dangling fetch: GET /api/ledger/${userId}/summary (src/api.js:516)", "shortDescription": {"text": "Dangling fetch: GET /api/ledger/${userId}/summary (src/api.js:516)"}, "fullDescription": {"text": "`src/api.js:516` calls `GET /api/ledger/${userId}/summary` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/ledger/<p>/summary`\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-aef7fed11ff1fe69", "name": "Dangling fetch: POST /api/ledger/${userId} (src/api.js:520)", "shortDescription": {"text": "Dangling fetch: POST /api/ledger/${userId} (src/api.js:520)"}, "fullDescription": {"text": "`src/api.js:520` calls `POST /api/ledger/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/ledger/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8027fc6b1c7add53", "name": "Dangling fetch: PATCH /api/ledger/${userId}/${id}/void (src/api.js:527)", "shortDescription": {"text": "Dangling fetch: PATCH /api/ledger/${userId}/${id}/void (src/api.js:527)"}, "fullDescription": {"text": "`src/api.js:527` calls `PATCH /api/ledger/${userId}/${id}/void` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/ledger/<p>/<p>/void`\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-3a0410543d0949a5", "name": "Dangling fetch: GET /api/allocations/${userId}/entry/${entryId} (src/api.js:536)", "shortDescription": {"text": "Dangling fetch: GET /api/allocations/${userId}/entry/${entryId} (src/api.js:536)"}, "fullDescription": {"text": "`src/api.js:536` calls `GET /api/allocations/${userId}/entry/${entryId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/allocations/<p>/entry/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6fa8d17a54b641aa", "name": "Dangling fetch: POST /api/allocations/${userId} (src/api.js:540)", "shortDescription": {"text": "Dangling fetch: POST /api/allocations/${userId} (src/api.js:540)"}, "fullDescription": {"text": "`src/api.js:540` calls `POST /api/allocations/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/allocations/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-61a948f0497079c4", "name": "Dangling fetch: POST /api/semester-engine?userId=${userId} (src/api.js:549)", "shortDescription": {"text": "Dangling fetch: POST /api/semester-engine?userId=${userId} (src/api.js:549)"}, "fullDescription": {"text": "`src/api.js:549` calls `POST /api/semester-engine?userId=${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semester-engine`\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-812816e3071e1415", "name": "Dangling fetch: GET /api/semester-engine/${trackerId}/summary (src/api.js:556)", "shortDescription": {"text": "Dangling fetch: GET /api/semester-engine/${trackerId}/summary (src/api.js:556)"}, "fullDescription": {"text": "`src/api.js:556` calls `GET /api/semester-engine/${trackerId}/summary` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semester-engine/<p>/summary`\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-bda01573670302b4", "name": "Dangling fetch: GET /api/semester-engine/entity/${entityId} (src/api.js:560)", "shortDescription": {"text": "Dangling fetch: GET /api/semester-engine/entity/${entityId} (src/api.js:560)"}, "fullDescription": {"text": "`src/api.js:560` calls `GET /api/semester-engine/entity/${entityId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semester-engine/entity/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2bc09c87dd15a5b2", "name": "Dangling fetch: POST /api/semester-engine/${trackerId}/fee-items?userId=${userId} (src/api.js:564)", "shortDescription": {"text": "Dangling fetch: POST /api/semester-engine/${trackerId}/fee-items?userId=${userId} (src/api.js:564)"}, "fullDescription": {"text": "`src/api.js:564` calls `POST /api/semester-engine/${trackerId}/fee-items?userId=${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semester-engine/<p>/fee-items`\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-fd7a2b026ecab1b2", "name": "Dangling fetch: POST /api/semester-engine/${trackerId}/adjustments?userId=${userId} (src/api.js:571)", "shortDescription": {"text": "Dangling fetch: POST /api/semester-engine/${trackerId}/adjustments?userId=${userId} (src/api.js:571)"}, "fullDescription": {"text": "`src/api.js:571` calls `POST /api/semester-engine/${trackerId}/adjustments?userId=${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semester-engine/<p>/adjustments`\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-12778b6c4887a726", "name": "Dangling fetch: POST /api/semester-engine/${trackerId}/waivers?userId=${userId} (src/api.js:578)", "shortDescription": {"text": "Dangling fetch: POST /api/semester-engine/${trackerId}/waivers?userId=${userId} (src/api.js:578)"}, "fullDescription": {"text": "`src/api.js:578` calls `POST /api/semester-engine/${trackerId}/waivers?userId=${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/semester-engine/<p>/waivers`\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-f501ed85d776ce1c", "name": "Dangling fetch: GET /api/reports/${userId}/summary (src/api.js:587)", "shortDescription": {"text": "Dangling fetch: GET /api/reports/${userId}/summary (src/api.js:587)"}, "fullDescription": {"text": "`src/api.js:587` calls `GET /api/reports/${userId}/summary` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/reports/<p>/summary`\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-d93665ead88eafc7", "name": "Dangling fetch: GET /api/reports/${userId}/waiver-saved (src/api.js:591)", "shortDescription": {"text": "Dangling fetch: GET /api/reports/${userId}/waiver-saved (src/api.js:591)"}, "fullDescription": {"text": "`src/api.js:591` calls `GET /api/reports/${userId}/waiver-saved` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/reports/<p>/waiver-saved`\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-a4b106e70bd7609f", "name": "Dangling fetch: GET /api/circles/${userId} (src/api.js:604)", "shortDescription": {"text": "Dangling fetch: GET /api/circles/${userId} (src/api.js:604)"}, "fullDescription": {"text": "`src/api.js:604` calls `GET /api/circles/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/circles/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9744950c33556b67", "name": "Dangling fetch: POST /api/circles/${userId} (src/api.js:608)", "shortDescription": {"text": "Dangling fetch: POST /api/circles/${userId} (src/api.js:608)"}, "fullDescription": {"text": "`src/api.js:608` calls `POST /api/circles/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/circles/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6c4dfd43a69e2dd2", "name": "Dangling fetch: PATCH /api/circles/${userId}/${circleId}/status (src/api.js:612)", "shortDescription": {"text": "Dangling fetch: PATCH /api/circles/${userId}/${circleId}/status (src/api.js:612)"}, "fullDescription": {"text": "`src/api.js:612` calls `PATCH /api/circles/${userId}/${circleId}/status` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/circles/<p>/<p>/status`\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-ec2565067c5e35af", "name": "Dangling fetch: PATCH /api/circles/${userId}/${circleId}/permission (src/api.js:616)", "shortDescription": {"text": "Dangling fetch: PATCH /api/circles/${userId}/${circleId}/permission (src/api.js:616)"}, "fullDescription": {"text": "`src/api.js:616` calls `PATCH /api/circles/${userId}/${circleId}/permission` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/circles/<p>/<p>/permission`\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-47d80ea2562b6cb0", "name": "Dangling fetch: GET /api/recurring/${userId} (src/api.js:622)", "shortDescription": {"text": "Dangling fetch: GET /api/recurring/${userId} (src/api.js:622)"}, "fullDescription": {"text": "`src/api.js:622` calls `GET /api/recurring/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/recurring/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7667ed85da6792a7", "name": "Dangling fetch: POST /api/recurring/${userId} (src/api.js:626)", "shortDescription": {"text": "Dangling fetch: POST /api/recurring/${userId} (src/api.js:626)"}, "fullDescription": {"text": "`src/api.js:626` calls `POST /api/recurring/${userId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/recurring/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a9afaa4306a6779e", "name": "Dangling fetch: GET /api/recurring/${userId}/${scheduleId}/slots (src/api.js:630)", "shortDescription": {"text": "Dangling fetch: GET /api/recurring/${userId}/${scheduleId}/slots (src/api.js:630)"}, "fullDescription": {"text": "`src/api.js:630` calls `GET /api/recurring/${userId}/${scheduleId}/slots` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/recurring/<p>/<p>/slots`\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-2b3edd1b502de092", "name": "Dangling fetch: POST /api/recurring/${userId}/slots/${slotId}/pay (src/api.js:634)", "shortDescription": {"text": "Dangling fetch: POST /api/recurring/${userId}/slots/${slotId}/pay (src/api.js:634)"}, "fullDescription": {"text": "`src/api.js:634` calls `POST /api/recurring/${userId}/slots/${slotId}/pay` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/recurring/<p>/slots/<p>/pay`\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-175b76d9a6d799d2", "name": "Dangling fetch: POST /api/recurring/${userId}/slots/${slotId}/unpay (src/api.js:638)", "shortDescription": {"text": "Dangling fetch: POST /api/recurring/${userId}/slots/${slotId}/unpay (src/api.js:638)"}, "fullDescription": {"text": "`src/api.js:638` calls `POST /api/recurring/${userId}/slots/${slotId}/unpay` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/recurring/<p>/slots/<p>/unpay`\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-60f18a863877fd5f", "name": "Dangling fetch: POST /api/recurring/${userId}/${scheduleId}/advance (src/api.js:642)", "shortDescription": {"text": "Dangling fetch: POST /api/recurring/${userId}/${scheduleId}/advance (src/api.js:642)"}, "fullDescription": {"text": "`src/api.js:642` calls `POST /api/recurring/${userId}/${scheduleId}/advance` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/recurring/<p>/<p>/advance`\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-9c729615a16a035f", "name": "Dangling fetch: POST /api/assistant (src/api.js:648)", "shortDescription": {"text": "Dangling fetch: POST /api/assistant (src/api.js:648)"}, "fullDescription": {"text": "`src/api.js:648` calls `POST /api/assistant` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/assistant`\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-e9a4d2ef089c3019", "name": "Dangling fetch: POST /api/assistant/agent (src/api.js:656)", "shortDescription": {"text": "Dangling fetch: POST /api/assistant/agent (src/api.js:656)"}, "fullDescription": {"text": "`src/api.js:656` calls `POST /api/assistant/agent` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/assistant/agent`\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-29bbe229d2e5536b", "name": "Dangling fetch: GET /api/closure/${userId}/closures (src/api.js:665)", "shortDescription": {"text": "Dangling fetch: GET /api/closure/${userId}/closures (src/api.js:665)"}, "fullDescription": {"text": "`src/api.js:665` calls `GET /api/closure/${userId}/closures` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/closure/<p>/closures`\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-5f75589aac25cc27", "name": "Dangling fetch: POST /api/closure/${userId}/semester/${trackerId}/close (src/api.js:669)", "shortDescription": {"text": "Dangling fetch: POST /api/closure/${userId}/semester/${trackerId}/close (src/api.js:669)"}, "fullDescription": {"text": "`src/api.js:669` calls `POST /api/closure/${userId}/semester/${trackerId}/close` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/closure/<p>/semester/<p>/close`\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-ab78aeadcc3ac657", "name": "Dangling fetch: POST /api/closure/${userId}/closures/${closureId}/settle (src/api.js:673)", "shortDescription": {"text": "Dangling fetch: POST /api/closure/${userId}/closures/${closureId}/settle (src/api.js:673)"}, "fullDescription": {"text": "`src/api.js:673` calls `POST /api/closure/${userId}/closures/${closureId}/settle` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/closure/<p>/closures/<p>/settle`\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-6f6088e43d0f026a", "name": "Dangling fetch: POST /api/assistant/agent (src/v2/Leeboon.jsx:60)", "shortDescription": {"text": "Dangling fetch: POST /api/assistant/agent (src/v2/Leeboon.jsx:60)"}, "fullDescription": {"text": "`src/v2/Leeboon.jsx:60` calls `POST /api/assistant/agent` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/assistant/agent`\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-72b98ad24dd8d2f1", "name": "Dangling fetch: POST /api/admin/login (src/contexts/AdminContext.jsx:41)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/login (src/contexts/AdminContext.jsx:41)"}, "fullDescription": {"text": "`src/contexts/AdminContext.jsx:41` calls `POST /api/admin/login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/login`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`server/index.cjs` 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.cjs` 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-5c42734d4d670873", "name": "Unused endpoint: USE /api/expenses", "shortDescription": {"text": "Unused endpoint: USE /api/expenses"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/expenses` 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-26dfef6db57a40a8", "name": "Unused endpoint: USE /api/semesters", "shortDescription": {"text": "Unused endpoint: USE /api/semesters"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/semesters` 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-955c408a2a1e6755", "name": "Unused endpoint: USE /api/loans", "shortDescription": {"text": "Unused endpoint: USE /api/loans"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/loans` 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-8ca4664c9cda1cd6", "name": "Unused endpoint: USE /api/settings", "shortDescription": {"text": "Unused endpoint: USE /api/settings"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/settings` 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.cjs` 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-0e76e800612b093e", "name": "Unused endpoint: USE /api/coaching", "shortDescription": {"text": "Unused endpoint: USE /api/coaching"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/coaching` 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-b4667df8d1d98198", "name": "Unused endpoint: USE /api/batches", "shortDescription": {"text": "Unused endpoint: USE /api/batches"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/batches` 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-c1222051eaa8fce0", "name": "Unused endpoint: USE /api/tutors", "shortDescription": {"text": "Unused endpoint: USE /api/tutors"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/tutors` 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-e48cfbc31746e539", "name": "Unused endpoint: USE /api/clubs", "shortDescription": {"text": "Unused endpoint: USE /api/clubs"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/clubs` 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-ec00984b27c88c15", "name": "Unused endpoint: USE /api/events", "shortDescription": {"text": "Unused endpoint: USE /api/events"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/events` 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-3b87660ce2200e31", "name": "Unused endpoint: USE /api/uniforms", "shortDescription": {"text": "Unused endpoint: USE /api/uniforms"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/uniforms` 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-4e3afff781526ae6", "name": "Unused endpoint: USE /api/education-fees", "shortDescription": {"text": "Unused endpoint: USE /api/education-fees"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/education-fees` 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-0fb5ff52a88bc1c7", "name": "Unused endpoint: USE /api/housing", "shortDescription": {"text": "Unused endpoint: USE /api/housing"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/housing` 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-e6dbffcc362c2929", "name": "Unused endpoint: USE /api/entities", "shortDescription": {"text": "Unused endpoint: USE /api/entities"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/entities` 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-5458262cc1466f1c", "name": "Unused endpoint: USE /api/trackers", "shortDescription": {"text": "Unused endpoint: USE /api/trackers"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/trackers` 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-25dd4e9d78a047ee", "name": "Unused endpoint: USE /api/obligations", "shortDescription": {"text": "Unused endpoint: USE /api/obligations"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/obligations` 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-7ef3ca47ec14a78f", "name": "Unused endpoint: USE /api/ledger", "shortDescription": {"text": "Unused endpoint: USE /api/ledger"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/ledger` 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-97d8dc901e9aa6b6", "name": "Unused endpoint: USE /api/allocations", "shortDescription": {"text": "Unused endpoint: USE /api/allocations"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/allocations` 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-594ba67a2438ff11", "name": "Unused endpoint: USE /api/semester-engine", "shortDescription": {"text": "Unused endpoint: USE /api/semester-engine"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/semester-engine` 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-001a1436225296b6", "name": "Unused endpoint: USE /api/institutions", "shortDescription": {"text": "Unused endpoint: USE /api/institutions"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/institutions` 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-4d25aedc90a887a6", "name": "Unused endpoint: USE /api/recurring", "shortDescription": {"text": "Unused endpoint: USE /api/recurring"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/recurring` 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-2a06e6d401449b82", "name": "Unused endpoint: USE /api/reports", "shortDescription": {"text": "Unused endpoint: USE /api/reports"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/reports` 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-84b52f40f216d5dc", "name": "Unused endpoint: USE /api/closure", "shortDescription": {"text": "Unused endpoint: USE /api/closure"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/closure` 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-74653654fc29fc2a", "name": "Unused endpoint: USE /api/circles", "shortDescription": {"text": "Unused endpoint: USE /api/circles"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/circles` 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-135c732484f1341a", "name": "Unused endpoint: USE /api/assistant", "shortDescription": {"text": "Unused endpoint: USE /api/assistant"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/assistant` 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-5f8e1141d1782a8c", "name": "Unused endpoint: USE /api/v2data", "shortDescription": {"text": "Unused endpoint: USE /api/v2data"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/v2data` 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-d95f6b6be4decff8", "name": "Unused endpoint: USE /api/feed", "shortDescription": {"text": "Unused endpoint: USE /api/feed"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /api/feed` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1bc898b3b7565990", "name": "Unused endpoint: USE /uploads", "shortDescription": {"text": "Unused endpoint: USE /uploads"}, "fullDescription": {"text": "`server/index.cjs` declares `USE /uploads` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fb902fa8f06593cb", "name": "Unused endpoint: GET /:userId", "shortDescription": {"text": "Unused endpoint: GET /:userId"}, "fullDescription": {"text": "`server/routes/semesters.cjs` declares `GET /:userId` 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/semesters.cjs` 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/semesters.cjs` declares `PUT /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a61c112b611f4bb", "name": "Unused endpoint: DELETE /:id", "shortDescription": {"text": "Unused endpoint: DELETE /:id"}, "fullDescription": {"text": "`server/routes/semesters.cjs` declares `DELETE /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-27fb1188f31ce958", "name": "Unused endpoint: POST /:userId/semester/:trackerId/close", "shortDescription": {"text": "Unused endpoint: POST /:userId/semester/:trackerId/close"}, "fullDescription": {"text": "`server/routes/closure.cjs` declares `POST /:userId/semester/:trackerId/close` 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-d299d7a89487b487", "name": "Unused endpoint: GET /:userId/closures", "shortDescription": {"text": "Unused endpoint: GET /:userId/closures"}, "fullDescription": {"text": "`server/routes/closure.cjs` declares `GET /:userId/closures` 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-f1fb2e06d957ccb8", "name": "Unused endpoint: POST /:userId/closures/:id/settle", "shortDescription": {"text": "Unused endpoint: POST /:userId/closures/:id/settle"}, "fullDescription": {"text": "`server/routes/closure.cjs` declares `POST /:userId/closures/:id/settle` 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-4c8499022f17a673", "name": "Unused endpoint: GET /:userId/:id", "shortDescription": {"text": "Unused endpoint: GET /:userId/:id"}, "fullDescription": {"text": "`server/routes/entities.cjs` declares `GET /:userId/: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-745d0349641ea3c7", "name": "Unused endpoint: POST /:userId", "shortDescription": {"text": "Unused endpoint: POST /:userId"}, "fullDescription": {"text": "`server/routes/entities.cjs` declares `POST /:userId` 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-91ba31a29cd2dcc0", "name": "Unused endpoint: PUT /:userId/:id", "shortDescription": {"text": "Unused endpoint: PUT /:userId/:id"}, "fullDescription": {"text": "`server/routes/entities.cjs` declares `PUT /:userId/: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-d3ae624de6c5aeb3", "name": "Unused endpoint: DELETE /:userId/:id", "shortDescription": {"text": "Unused endpoint: DELETE /:userId/:id"}, "fullDescription": {"text": "`server/routes/entities.cjs` declares `DELETE /:userId/: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-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`server/routes/admin.cjs` 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-d504b80adc9409ec", "name": "Unused endpoint: GET /dashboard", "shortDescription": {"text": "Unused endpoint: GET /dashboard"}, "fullDescription": {"text": "`server/routes/admin.cjs` declares `GET /dashboard` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-841e50bf821e4158", "name": "Unused endpoint: GET /users", "shortDescription": {"text": "Unused endpoint: GET /users"}, "fullDescription": {"text": "`server/routes/admin.cjs` declares `GET /users` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9da256c72d46eb8c", "name": "Unused endpoint: GET /users/:id/full", "shortDescription": {"text": "Unused endpoint: GET /users/:id/full"}, "fullDescription": {"text": "`server/routes/admin.cjs` declares `GET /users/:id/full` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-41aa9e92da3f14ad", "name": "Unused endpoint: GET /users/:id", "shortDescription": {"text": "Unused endpoint: GET /users/:id"}, "fullDescription": {"text": "`server/routes/admin.cjs` declares `GET /users/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-67d3c865c237279a", "name": "Unused endpoint: GET /analytics/signups", "shortDescription": {"text": "Unused endpoint: GET /analytics/signups"}, "fullDescription": {"text": "`server/routes/admin.cjs` declares `GET /analytics/signups` 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-11d4c129e1a6e7ef", "name": "Unused endpoint: GET /analytics/education-levels", "shortDescription": {"text": "Unused endpoint: GET /analytics/education-levels"}, "fullDescription": {"text": "`server/routes/admin.cjs` declares `GET /analytics/education-levels` 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.cjs` 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-0015e9c38df18e0d", "name": "Unused endpoint: GET /promos", "shortDescription": {"text": "Unused endpoint: GET /promos"}, "fullDescription": {"text": "`server/routes/admin.cjs` declares `GET /promos` 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/20819"}, "properties": {"repository": "tanvirazamtaif/classcost", "repoUrl": "https://github.com/tanvirazamtaif/classcost", "branch": "main"}, "results": [{"ruleId": "scanner-8508887edabcf6f6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/v2/V2App.jsx:36"}, "properties": {"repobilityId": "6a11d8e784d0e0c3", "scanner": "scanner-primary", "fingerprint": "8508887edabcf6f6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ba3d5bc04a5d37ea", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/Sidebar.jsx:71"}, "properties": {"repobilityId": "86cc1d7e19f26a28", "scanner": "scanner-primary", "fingerprint": "ba3d5bc04a5d37ea", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-916da634f39fd624", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/layout/Header.jsx:179"}, "properties": {"repobilityId": "f6845e2bb1b92bd5", "scanner": "scanner-primary", "fingerprint": "916da634f39fd624", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b85579f2ab78dae0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feature/PaymentCard.jsx:29"}, "properties": {"repobilityId": "d666e8ec8afe3bfe", "scanner": "scanner-primary", "fingerprint": "b85579f2ab78dae0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0814bfac68a857aa", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 src/components/feature/PromotionBanner.jsx:30"}, "properties": {"repobilityId": "f34f9791fb5ec51c", "scanner": "scanner-primary", "fingerprint": "0814bfac68a857aa", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-db051697197a5753", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 src/components/feature/PaywallModal.jsx:66"}, "properties": {"repobilityId": "88a5bfc43f04f5bb", "scanner": "scanner-primary", "fingerprint": "db051697197a5753", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-1d9f4891cc92f57e", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/components/feature/PaywallModal.jsx:44"}, "properties": {"repobilityId": "5939c682e7a25665", "scanner": "scanner-primary", "fingerprint": "1d9f4891cc92f57e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-8c9b893e2f1b374f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/feature/CostSummaryCard.jsx:93"}, "properties": {"repobilityId": "015948909fcd67c7", "scanner": "scanner-primary", "fingerprint": "8c9b893e2f1b374f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d9e33c79fba7ac2d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/EntityDetailV3.jsx:412"}, "properties": {"repobilityId": "2509e81329904cec", "scanner": "scanner-primary", "fingerprint": "d9e33c79fba7ac2d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e25a268ece56a1a0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/DashboardV3.jsx:339"}, "properties": {"repobilityId": "f125f8c7d9a37700", "scanner": "scanner-primary", "fingerprint": "e25a268ece56a1a0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-762bb1e74ec4c2c2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/SemesterDetailPage_V3.jsx:293"}, "properties": {"repobilityId": "ecb17b19f07e1376", "scanner": "scanner-primary", "fingerprint": "762bb1e74ec4c2c2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-43e7a661aa7447f2", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/pages/ParentDashboardView.jsx:30"}, "properties": {"repobilityId": "10ad2ec4a3038299", "scanner": "scanner-primary", "fingerprint": "43e7a661aa7447f2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-c80e7640057af3f5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/ParentDashboardView.jsx:31"}, "properties": {"repobilityId": "8c754e7389b9aae0", "scanner": "scanner-primary", "fingerprint": "c80e7640057af3f5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-66d16e15ade0ab6a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LoansView.jsx:333"}, "properties": {"repobilityId": "a8e64593aac87d92", "scanner": "scanner-primary", "fingerprint": "66d16e15ade0ab6a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-52f510c39405d6e2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/ProfileV2.jsx:103"}, "properties": {"repobilityId": "1d611898f9ee64b6", "scanner": "scanner-primary", "fingerprint": "52f510c39405d6e2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-906ca15958b9ccdf", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/SettingsView.jsx:81"}, "properties": {"repobilityId": "6004b578464c7029", "scanner": "scanner-primary", "fingerprint": "906ca15958b9ccdf", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c13e82ede8d158d3", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/pages/ParentOnboardingView.jsx:38"}, "properties": {"repobilityId": "816e420e6cb76bc7", "scanner": "scanner-primary", "fingerprint": "c13e82ede8d158d3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-534ae3a1a9daf3e9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/ParentOnboardingView.jsx:39"}, "properties": {"repobilityId": "5e2b0e9b499f6e2c", "scanner": "scanner-primary", "fingerprint": "534ae3a1a9daf3e9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7ccda01b9680437d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/AdminDashboardPage.jsx:298"}, "properties": {"repobilityId": "2cede55188e8655e", "scanner": "scanner-primary", "fingerprint": "7ccda01b9680437d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4807a8a837c2f31e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/AdminUserDetailPage.jsx:81"}, "properties": {"repobilityId": "ce82725ba02d6ac9", "scanner": "scanner-primary", "fingerprint": "4807a8a837c2f31e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5a32ac60613087ac", "level": "error", "message": {"text": "Runtime dotenv file present in repo: .env.production"}, "properties": {"repobilityId": "da3016501941bee3", "scanner": "scanner-primary", "fingerprint": "5a32ac60613087ac", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets", "config", "env-file", "runtime-env", "env_file_with_secret"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".env.production"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a1e8567de59b8732", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in server/index.cjs:37"}, "properties": {"repobilityId": "fde349a4adf85eee", "scanner": "scanner-primary", "fingerprint": "a1e8567de59b8732", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server/index.cjs"}, "region": {"startLine": 37}}}]}, {"ruleId": "scanner-d92952f57fc6097f", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/v2/V2Landing.jsx:108"}, "properties": {"repobilityId": "d1cca9b04886b45b", "scanner": "scanner-primary", "fingerprint": "d92952f57fc6097f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/v2/V2Landing.jsx"}, "region": {"startLine": 108}}}]}, {"ruleId": "scanner-2bafca2d40d212c2", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in src/contexts/AdminContext.jsx:53"}, "properties": {"repobilityId": "f990a95ee7b0eeb5", "scanner": "scanner-primary", "fingerprint": "2bafca2d40d212c2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/contexts/AdminContext.jsx"}, "region": {"startLine": 53}}}]}, {"ruleId": "scanner-de68609752d19967", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/lib/firebase.js:96"}, "properties": {"repobilityId": "7bfa4e25984fe6e7", "scanner": "scanner-primary", "fingerprint": "de68609752d19967", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/lib/firebase.js"}, "region": {"startLine": 96}}}]}, {"ruleId": "scanner-cc5bacfcb0d4f857", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/LandingPage.jsx:68"}, "properties": {"repobilityId": "784aa906f78ddc12", "scanner": "scanner-primary", "fingerprint": "cc5bacfcb0d4f857", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/LandingPage.jsx"}, "region": {"startLine": 68}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-b48e07e6ce1706e8", "level": "note", "message": {"text": "Very large file: src/v2/V2App.jsx (2973 lines)"}, "properties": {"repobilityId": "720b697ddc12b86b", "scanner": "scanner-primary", "fingerprint": "b48e07e6ce1706e8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "350d651d3463aa08", "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": "eb30c5ab0f1f22ce", "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": "e33a16c3299b1eea", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "62c5cc950b42af80", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "d7d99153f9a5960a", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "5030c2d511c08b9b", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "b0df6459d083b6dd", "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": "f3dd350c84084f09", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-ecb0d2c55ed6875d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/settings.local.json"}, "properties": {"repobilityId": "d8bae33a6d517bf0", "scanner": "scanner-primary", "fingerprint": "ecb0d2c55ed6875d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/settings.local.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2cf5acf6b573bf45", "level": "note", "message": {"text": "Legacy-named symbol `cc_v2` in src/main.jsx:12"}, "properties": {"repobilityId": "25916243d360bab8", "scanner": "scanner-primary", "fingerprint": "2cf5acf6b573bf45", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-6fb2f551f5197e22", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/v2/Leeboon.jsx:60"}, "properties": {"repobilityId": "f4f11dca15abcc37", "scanner": "scanner-primary", "fingerprint": "6fb2f551f5197e22", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2123fd6ac752b963", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/constants/education.js:471"}, "properties": {"repobilityId": "735c8e9b194a1db5", "scanner": "scanner-primary", "fingerprint": "2123fd6ac752b963", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c4c17e9fb3adf206", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/contexts/AdminContext.jsx:60"}, "properties": {"repobilityId": "204adeeb7ebab5ba", "scanner": "scanner-primary", "fingerprint": "c4c17e9fb3adf206", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c3480f50e5bf9230", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/contexts/AppContext.jsx:127"}, "properties": {"repobilityId": "9624ca3d2eeafb4f", "scanner": "scanner-primary", "fingerprint": "c3480f50e5bf9230", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-361114ceacb39040", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/contexts/UniversalSemesterContext.jsx:11"}, "properties": {"repobilityId": "cdd16bd2e1c03fc6", "scanner": "scanner-primary", "fingerprint": "361114ceacb39040", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e2c087a3f1c899c5", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/firebase.js:3"}, "properties": {"repobilityId": "05f354435d57cb65", "scanner": "scanner-primary", "fingerprint": "e2c087a3f1c899c5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-eedc63bab94370c8", "level": "note", "message": {"text": "Legacy-named symbol `leboon_brain_v1` in src/lib/leboonBrain.js:9"}, "properties": {"repobilityId": "8f95bcdb12831315", "scanner": "scanner-primary", "fingerprint": "eedc63bab94370c8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-5d8e2fec87226767", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/installmentEngine.js:1"}, "properties": {"repobilityId": "62df9a3fe7f2dfa6", "scanner": "scanner-primary", "fingerprint": "5d8e2fec87226767", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fa3d36c176e595cc", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/pages/LandingPage.jsx:56"}, "properties": {"repobilityId": "0bf8d848ad9936f7", "scanner": "scanner-primary", "fingerprint": "fa3d36c176e595cc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5228608b5adebe34", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/hooks/useUnifiedTotals.js:172"}, "properties": {"repobilityId": "d7fbcd59ecb1b34c", "scanner": "scanner-primary", "fingerprint": "5228608b5adebe34", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7c8b918e1fee9558", "level": "note", "message": {"text": "20 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "bd1f6d44917e8105", "scanner": "scanner-primary", "fingerprint": "7c8b918e1fee9558", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-bc02052490c6442d", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/send-otp (src/api.js:35)"}, "properties": {"repobilityId": "60c5d5d9ddd493bb", "scanner": "scanner-primary", "fingerprint": "bc02052490c6442d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-078d89a20a763aec", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/verify-otp (src/api.js:42)"}, "properties": {"repobilityId": "d1e93832fcbd3b00", "scanner": "scanner-primary", "fingerprint": "078d89a20a763aec", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f4303fa0cc48ea4e", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/google (src/api.js:51)"}, "properties": {"repobilityId": "84f35d6328754acd", "scanner": "scanner-primary", "fingerprint": "f4303fa0cc48ea4e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9de5e4954a9e88be", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/register (src/api.js:60)"}, "properties": {"repobilityId": "33592a1cde3079e8", "scanner": "scanner-primary", "fingerprint": "9de5e4954a9e88be", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3084ed31a6eeaf44", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/login (src/api.js:67)"}, "properties": {"repobilityId": "3b54048f84d2fb48", "scanner": "scanner-primary", "fingerprint": "3084ed31a6eeaf44", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-31ab0fe338e642f4", "level": "error", "message": {"text": "Dangling fetch: GET /api/auth/user/${id} (src/api.js:74)"}, "properties": {"repobilityId": "a9874543373b6ded", "scanner": "scanner-primary", "fingerprint": "31ab0fe338e642f4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-32d3cf8f80f0f3b9", "level": "error", "message": {"text": "Dangling fetch: PUT /api/auth/profile/${id} (src/api.js:78)"}, "properties": {"repobilityId": "596974e4988ef4a6", "scanner": "scanner-primary", "fingerprint": "32d3cf8f80f0f3b9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-8839ee9e484fca54", "level": "error", "message": {"text": "Dangling fetch: GET /api/expenses/${userId} (src/api.js:87)"}, "properties": {"repobilityId": "e4f1b24a91039b0e", "scanner": "scanner-primary", "fingerprint": "8839ee9e484fca54", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-73e2005e2f15e399", "level": "error", "message": {"text": "Dangling fetch: POST /api/expenses (src/api.js:91)"}, "properties": {"repobilityId": "616df887f2ab793b", "scanner": "scanner-primary", "fingerprint": "73e2005e2f15e399", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b4c375e72fa8f5f9", "level": "error", "message": {"text": "Dangling fetch: PUT /api/expenses/${id} (src/api.js:98)"}, "properties": {"repobilityId": "afc027e41692390b", "scanner": "scanner-primary", "fingerprint": "b4c375e72fa8f5f9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ee01fc16b1ce60b1", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/expenses/${id} (src/api.js:105)"}, "properties": {"repobilityId": "0bd7b0d8991fb693", "scanner": "scanner-primary", "fingerprint": "ee01fc16b1ce60b1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-72b4a33d87b3a35e", "level": "error", "message": {"text": "Dangling fetch: GET /api/semesters/${userId} (src/api.js:113)"}, "properties": {"repobilityId": "ed8072fe643d928a", "scanner": "scanner-primary", "fingerprint": "72b4a33d87b3a35e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b13a6e9d1ebee9ff", "level": "error", "message": {"text": "Dangling fetch: POST /api/semesters (src/api.js:117)"}, "properties": {"repobilityId": "4d4f49c230060bdd", "scanner": "scanner-primary", "fingerprint": "b13a6e9d1ebee9ff", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-e6d243d79142f43e", "level": "error", "message": {"text": "Dangling fetch: PUT /api/semesters/${id} (src/api.js:124)"}, "properties": {"repobilityId": "53eb7422a1d69a83", "scanner": "scanner-primary", "fingerprint": "e6d243d79142f43e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2ce1caab0b1153b6", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/semesters/${id} (src/api.js:131)"}, "properties": {"repobilityId": "4c035da2fc4fb845", "scanner": "scanner-primary", "fingerprint": "2ce1caab0b1153b6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-8bed5e4023d557fd", "level": "error", "message": {"text": "Dangling fetch: GET /api/loans/${userId} (src/api.js:139)"}, "properties": {"repobilityId": "91d132cb63b748e9", "scanner": "scanner-primary", "fingerprint": "8bed5e4023d557fd", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-86d992b7f18b6234", "level": "error", "message": {"text": "Dangling fetch: POST /api/loans (src/api.js:143)"}, "properties": {"repobilityId": "a63f9696a6cca49d", "scanner": "scanner-primary", "fingerprint": "86d992b7f18b6234", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-7a8081b54a274439", "level": "error", "message": {"text": "Dangling fetch: PUT /api/loans/${id} (src/api.js:150)"}, "properties": {"repobilityId": "7aabfdbad6df3047", "scanner": "scanner-primary", "fingerprint": "7a8081b54a274439", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d2172fdf5509ab24", "level": "error", "message": {"text": "Dangling fetch: PUT /api/loans/${id}/payment (src/api.js:157)"}, "properties": {"repobilityId": "f7bb9ca1cba45409", "scanner": "scanner-primary", "fingerprint": "d2172fdf5509ab24", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-7f70797066fd9de2", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/loans/${id} (src/api.js:164)"}, "properties": {"repobilityId": "663a050a7e412759", "scanner": "scanner-primary", "fingerprint": "7f70797066fd9de2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2cd5d8129c26c846", "level": "error", "message": {"text": "Dangling fetch: GET /api/settings/${userId} (src/api.js:172)"}, "properties": {"repobilityId": "87396b4e47ea6456", "scanner": "scanner-primary", "fingerprint": "2cd5d8129c26c846", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-98052313fbbcb2c4", "level": "error", "message": {"text": "Dangling fetch: PUT /api/settings/${userId} (src/api.js:176)"}, "properties": {"repobilityId": "8b767622b9fc3466", "scanner": "scanner-primary", "fingerprint": "98052313fbbcb2c4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ed5a5017d20eac0a", "level": "error", "message": {"text": "Dangling fetch: GET /api/v2data/${userId} (src/api.js:185)"}, "properties": {"repobilityId": "d6fd80ed2f27f664", "scanner": "scanner-primary", "fingerprint": "ed5a5017d20eac0a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9c41341624ec1d14", "level": "error", "message": {"text": "Dangling fetch: PUT /api/v2data/${userId} (src/api.js:189)"}, "properties": {"repobilityId": "feb679c3ef645636", "scanner": "scanner-primary", "fingerprint": "9c41341624ec1d14", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a4d447f14b18d292", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/profile/me (src/api.js:198)"}, "properties": {"repobilityId": "92c09439ce71ba03", "scanner": "scanner-primary", "fingerprint": "a4d447f14b18d292", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-06b3e8a98043e626", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/profile (src/api.js:202)"}, "properties": {"repobilityId": "0665ee6fa4c8600e", "scanner": "scanner-primary", "fingerprint": "06b3e8a98043e626", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-56b9beee36050598", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/posts (src/api.js:213)"}, "properties": {"repobilityId": "a7b5a7672a945788", "scanner": "scanner-primary", "fingerprint": "56b9beee36050598", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d393c2feceb8d81b", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/posts/${id}/like (src/api.js:219)"}, "properties": {"repobilityId": "961bb4e2c2c0c372", "scanner": "scanner-primary", "fingerprint": "d393c2feceb8d81b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-fae51ca93c9b2aa5", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/feed/posts/${id}/like (src/api.js:220)"}, "properties": {"repobilityId": "36a3912b435ade91", "scanner": "scanner-primary", "fingerprint": "fae51ca93c9b2aa5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2df8e934f641a49e", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/posts/${id}/comments (src/api.js:221)"}, "properties": {"repobilityId": "6380dc05a804ff7c", "scanner": "scanner-primary", "fingerprint": "2df8e934f641a49e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-16d852009506fe90", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/posts/${id}/comments (src/api.js:222)"}, "properties": {"repobilityId": "1ff8205ff99982cd", "scanner": "scanner-primary", "fingerprint": "16d852009506fe90", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f1db8ef59be928f0", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/follow/${encodeURIComponent(handle)} (src/api.js:223)"}, "properties": {"repobilityId": "66164aa028a91103", "scanner": "scanner-primary", "fingerprint": "f1db8ef59be928f0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ca7d84b223077b19", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/feed/follow/${encodeURIComponent(handle)} (src/api.js:224)"}, "properties": {"repobilityId": "4c16315841518c7f", "scanner": "scanner-primary", "fingerprint": "ca7d84b223077b19", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-93733dbe39173f47", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/users?q=${encodeURIComponent(q)} (src/api.js:225)"}, "properties": {"repobilityId": "27e9ab4c40ee09ec", "scanner": "scanner-primary", "fingerprint": "93733dbe39173f47", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a48ac516b1024b67", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/profile/u/${encodeURIComponent(handle)} (src/api.js:226)"}, "properties": {"repobilityId": "94a1579064490fbd", "scanner": "scanner-primary", "fingerprint": "a48ac516b1024b67", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2ec0bacc4f1bc8e9", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/profile/u/${encodeURIComponent(handle)}/posts (src/api.js:227)"}, "properties": {"repobilityId": "b71e0ca9293e1c88", "scanner": "scanner-primary", "fingerprint": "2ec0bacc4f1bc8e9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3869878f05085e5c", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/upload (src/api.js:228)"}, "properties": {"repobilityId": "2156a102f189c8c6", "scanner": "scanner-primary", "fingerprint": "3869878f05085e5c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f66746a006caaae3", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/report (src/api.js:229)"}, "properties": {"repobilityId": "fbcabdb823b5a66d", "scanner": "scanner-primary", "fingerprint": "f66746a006caaae3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ccbd2b0899199515", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/dm (src/api.js:232)"}, "properties": {"repobilityId": "2fc190e58310a9bf", "scanner": "scanner-primary", "fingerprint": "ccbd2b0899199515", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f5232a31b13c0c4e", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/notes (src/api.js:238)"}, "properties": {"repobilityId": "691043f57558f2cf", "scanner": "scanner-primary", "fingerprint": "f5232a31b13c0c4e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2ed440b8c0ad78b1", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/notes (src/api.js:239)"}, "properties": {"repobilityId": "63f0a1d79c6dab08", "scanner": "scanner-primary", "fingerprint": "2ed440b8c0ad78b1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-df40d825e0d205cf", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/stories (src/api.js:242)"}, "properties": {"repobilityId": "e828fe3fb0a6d122", "scanner": "scanner-primary", "fingerprint": "df40d825e0d205cf", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-682642f29c47f8fa", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/stories (src/api.js:243)"}, "properties": {"repobilityId": "6eb5b2c8ccc878ca", "scanner": "scanner-primary", "fingerprint": "682642f29c47f8fa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ccf575677731fe13", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/feed/stories/${encodeURIComponent(id)} (src/api.js:244)"}, "properties": {"repobilityId": "3a76097c19aae257", "scanner": "scanner-primary", "fingerprint": "ccf575677731fe13", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-24d816c24dc46470", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/notifications (src/api.js:247)"}, "properties": {"repobilityId": "1375609ffd8ac3e5", "scanner": "scanner-primary", "fingerprint": "24d816c24dc46470", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-19df42dd1604ee6d", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/notifications/read (src/api.js:248)"}, "properties": {"repobilityId": "f098a2ddbae6afa2", "scanner": "scanner-primary", "fingerprint": "19df42dd1604ee6d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-03f852413c427013", "level": "error", "message": {"text": "Dangling fetch: GET /api/feed/posts/${encodeURIComponent(id)} (src/api.js:252)"}, "properties": {"repobilityId": "a0a36165dbd89ca0", "scanner": "scanner-primary", "fingerprint": "03f852413c427013", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f7b1e9d6413206a2", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/profile (src/api.js:255)"}, "properties": {"repobilityId": "daf929cc68278c09", "scanner": "scanner-primary", "fingerprint": "f7b1e9d6413206a2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b0f936cac36fd5d9", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/feed/posts/${id} (src/api.js:256)"}, "properties": {"repobilityId": "f0398ae7a98b22ec", "scanner": "scanner-primary", "fingerprint": "b0f936cac36fd5d9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-833f27f81e2ead7a", "level": "error", "message": {"text": "Dangling fetch: POST /api/feed/posts/${encodeURIComponent(id)}/pin (src/api.js:257)"}, "properties": {"repobilityId": "f13521816e5f8e31", "scanner": "scanner-primary", "fingerprint": "833f27f81e2ead7a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f837a24c2132ef81", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/feed/posts/${postId}/comments/${commentId} (src/api.js:258)"}, "properties": {"repobilityId": "e27c52e61875f3f9", "scanner": "scanner-primary", "fingerprint": "f837a24c2132ef81", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d8862fe650de1f70", "level": "error", "message": {"text": "Dangling fetch: GET /api/education-fees/${userId} (src/api.js:263)"}, "properties": {"repobilityId": "692d319b6c837f10", "scanner": "scanner-primary", "fingerprint": "d8862fe650de1f70", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c5b712d962c79744", "level": "error", "message": {"text": "Dangling fetch: POST /api/education-fees/sync (src/api.js:267)"}, "properties": {"repobilityId": "d07ff3e5777b9d6a", "scanner": "scanner-primary", "fingerprint": "c5b712d962c79744", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f9bf7c7d2cc42f2d", "level": "error", "message": {"text": "Dangling fetch: GET /api/housing/${userId} (src/api.js:276)"}, "properties": {"repobilityId": "3a1072cfa16e2846", "scanner": "scanner-primary", "fingerprint": "f9bf7c7d2cc42f2d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a036ea0fd5d2baa0", "level": "error", "message": {"text": "Dangling fetch: POST /api/housing (src/api.js:280)"}, "properties": {"repobilityId": "1f6fd1f37b2fe31a", "scanner": "scanner-primary", "fingerprint": "a036ea0fd5d2baa0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-6c43beb9c7f20194", "level": "error", "message": {"text": "Dangling fetch: PUT /api/housing/${id} (src/api.js:287)"}, "properties": {"repobilityId": "95d208fbc17a0132", "scanner": "scanner-primary", "fingerprint": "6c43beb9c7f20194", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-cf55c3162c781a1c", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/housing/${id} (src/api.js:294)"}, "properties": {"repobilityId": "66c3e39094f001c7", "scanner": "scanner-primary", "fingerprint": "cf55c3162c781a1c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9eba4f4677784734", "level": "error", "message": {"text": "Dangling fetch: GET /api/coaching/${userId} (src/api.js:300)"}, "properties": {"repobilityId": "936649209dfa7cf0", "scanner": "scanner-primary", "fingerprint": "9eba4f4677784734", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a52addb27466efdb", "level": "error", "message": {"text": "Dangling fetch: POST /api/coaching (src/api.js:304)"}, "properties": {"repobilityId": "6685f951a68dd09d", "scanner": "scanner-primary", "fingerprint": "a52addb27466efdb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-13baa0bf024a0fc0", "level": "error", "message": {"text": "Dangling fetch: PUT /api/coaching/${id} (src/api.js:308)"}, "properties": {"repobilityId": "b19bfac96acf5837", "scanner": "scanner-primary", "fingerprint": "13baa0bf024a0fc0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-4ee04f32099a0656", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/coaching/${id} (src/api.js:312)"}, "properties": {"repobilityId": "e8b4bc062a0192f7", "scanner": "scanner-primary", "fingerprint": "4ee04f32099a0656", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b56795f70d41570a", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/coaching/${id}/payment (src/api.js:316)"}, "properties": {"repobilityId": "3c9fdc228dbb4b53", "scanner": "scanner-primary", "fingerprint": "b56795f70d41570a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2bdcb0f27111226c", "level": "error", "message": {"text": "Dangling fetch: GET /api/batches/${userId} (src/api.js:322)"}, "properties": {"repobilityId": "4f1090ffea698cc5", "scanner": "scanner-primary", "fingerprint": "2bdcb0f27111226c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f16f53f3cee8f5f4", "level": "error", "message": {"text": "Dangling fetch: POST /api/batches (src/api.js:326)"}, "properties": {"repobilityId": "57cc756fcc142cf4", "scanner": "scanner-primary", "fingerprint": "f16f53f3cee8f5f4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-439fc5e6c641d98e", "level": "error", "message": {"text": "Dangling fetch: PUT /api/batches/${id} (src/api.js:330)"}, "properties": {"repobilityId": "2182ff5ca02bba49", "scanner": "scanner-primary", "fingerprint": "439fc5e6c641d98e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-bbcad70971b0c6fc", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/batches/${id} (src/api.js:334)"}, "properties": {"repobilityId": "c39d36e9e23d1077", "scanner": "scanner-primary", "fingerprint": "bbcad70971b0c6fc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3316268be5b9f172", "level": "error", "message": {"text": "Dangling fetch: GET /api/tutors/${userId} (src/api.js:340)"}, "properties": {"repobilityId": "17b74f1489120e4b", "scanner": "scanner-primary", "fingerprint": "3316268be5b9f172", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-efaa7441dc06286c", "level": "error", "message": {"text": "Dangling fetch: POST /api/tutors (src/api.js:344)"}, "properties": {"repobilityId": "c293d94dc16509dd", "scanner": "scanner-primary", "fingerprint": "efaa7441dc06286c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-691ec7ea1a6d4c05", "level": "error", "message": {"text": "Dangling fetch: PUT /api/tutors/${id} (src/api.js:348)"}, "properties": {"repobilityId": "8d9d6fbb05bef7e9", "scanner": "scanner-primary", "fingerprint": "691ec7ea1a6d4c05", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-777669803807056b", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/tutors/${id} (src/api.js:352)"}, "properties": {"repobilityId": "e40953c0a7d6d284", "scanner": "scanner-primary", "fingerprint": "777669803807056b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-700a54ee92fbed97", "level": "error", "message": {"text": "Dangling fetch: GET /api/clubs/${userId} (src/api.js:358)"}, "properties": {"repobilityId": "f78520b094e7d86f", "scanner": "scanner-primary", "fingerprint": "700a54ee92fbed97", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-26d88298a89c135f", "level": "error", "message": {"text": "Dangling fetch: POST /api/clubs (src/api.js:362)"}, "properties": {"repobilityId": "c521ce0a840cf239", "scanner": "scanner-primary", "fingerprint": "26d88298a89c135f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9de3308d1ad54cf6", "level": "error", "message": {"text": "Dangling fetch: PUT /api/clubs/${id} (src/api.js:366)"}, "properties": {"repobilityId": "1898a6cb5987bb74", "scanner": "scanner-primary", "fingerprint": "9de3308d1ad54cf6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-001c047fa240ec4b", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/clubs/${id} (src/api.js:370)"}, "properties": {"repobilityId": "fa557bd07f51a5b4", "scanner": "scanner-primary", "fingerprint": "001c047fa240ec4b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-51976ffb239af3ef", "level": "error", "message": {"text": "Dangling fetch: GET /api/events/${userId} (src/api.js:376)"}, "properties": {"repobilityId": "269f8860ddbe2b47", "scanner": "scanner-primary", "fingerprint": "51976ffb239af3ef", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-28cd0dd981489e53", "level": "error", "message": {"text": "Dangling fetch: POST /api/events (src/api.js:380)"}, "properties": {"repobilityId": "78b2574d2eeaf6f1", "scanner": "scanner-primary", "fingerprint": "28cd0dd981489e53", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2f5b940de72a75dc", "level": "error", "message": {"text": "Dangling fetch: PUT /api/events/${id} (src/api.js:384)"}, "properties": {"repobilityId": "a786cf0e9bfce6a5", "scanner": "scanner-primary", "fingerprint": "2f5b940de72a75dc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3a95a6ed335a66f8", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/events/${id} (src/api.js:388)"}, "properties": {"repobilityId": "29e8b133245f6cad", "scanner": "scanner-primary", "fingerprint": "3a95a6ed335a66f8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-279278cb1cd051f6", "level": "error", "message": {"text": "Dangling fetch: GET /api/uniforms/${userId} (src/api.js:394)"}, "properties": {"repobilityId": "236c74c4fa6c1fee", "scanner": "scanner-primary", "fingerprint": "279278cb1cd051f6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-e0f27dbb51b878ef", "level": "error", "message": {"text": "Dangling fetch: POST /api/uniforms (src/api.js:398)"}, "properties": {"repobilityId": "1db91406e1c04653", "scanner": "scanner-primary", "fingerprint": "e0f27dbb51b878ef", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-04555ca54279d7d5", "level": "error", "message": {"text": "Dangling fetch: PUT /api/uniforms/${id} (src/api.js:402)"}, "properties": {"repobilityId": "9bb7f508127c0ad7", "scanner": "scanner-primary", "fingerprint": "04555ca54279d7d5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5363dbf864eba0e6", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/uniforms/${id} (src/api.js:406)"}, "properties": {"repobilityId": "ac5525bc75201f3e", "scanner": "scanner-primary", "fingerprint": "5363dbf864eba0e6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-aa427357d49705e4", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/redeem (src/api.js:412)"}, "properties": {"repobilityId": "df105c59b367bcbe", "scanner": "scanner-primary", "fingerprint": "aa427357d49705e4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-60beab192534663a", "level": "error", "message": {"text": "Dangling fetch: GET /api/entities/${userId} (src/api.js:421)"}, "properties": {"repobilityId": "9d653ac90efb7657", "scanner": "scanner-primary", "fingerprint": "60beab192534663a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-05796193d2426221", "level": "error", "message": {"text": "Dangling fetch: POST /api/entities/${userId} (src/api.js:425)"}, "properties": {"repobilityId": "a829df64baf449e6", "scanner": "scanner-primary", "fingerprint": "05796193d2426221", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-615da81436a2999d", "level": "error", "message": {"text": "Dangling fetch: PUT /api/entities/${userId}/${id} (src/api.js:432)"}, "properties": {"repobilityId": "ad32865488a93fe5", "scanner": "scanner-primary", "fingerprint": "615da81436a2999d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-aadd755d1eaba367", "level": "error", "message": {"text": "Dangling fetch: GET /api/trackers/${userId} (src/api.js:445)"}, "properties": {"repobilityId": "0a5158596b935b4a", "scanner": "scanner-primary", "fingerprint": "aadd755d1eaba367", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f313964c7e25abc6", "level": "error", "message": {"text": "Dangling fetch: GET /api/trackers/${userId}/entity/${entityId} (src/api.js:449)"}, "properties": {"repobilityId": "102dfaced4637636", "scanner": "scanner-primary", "fingerprint": "f313964c7e25abc6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-8c43c4d3b5b21525", "level": "error", "message": {"text": "Dangling fetch: POST /api/trackers/${userId} (src/api.js:453)"}, "properties": {"repobilityId": "dff5c31fe81df21d", "scanner": "scanner-primary", "fingerprint": "8c43c4d3b5b21525", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3592f4402da6ee69", "level": "error", "message": {"text": "Dangling fetch: PUT /api/trackers/${userId}/${id} (src/api.js:460)"}, "properties": {"repobilityId": "f8cdbbf87d9fc953", "scanner": "scanner-primary", "fingerprint": "3592f4402da6ee69", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-375e85577c8fb36e", "level": "error", "message": {"text": "Dangling fetch: GET /api/obligations/${userId} (src/api.js:469)"}, "properties": {"repobilityId": "8c7b16e78e8d9062", "scanner": "scanner-primary", "fingerprint": "375e85577c8fb36e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-81ffcac226946a55", "level": "error", "message": {"text": "Dangling fetch: GET /api/obligations/${userId}/upcoming (src/api.js:473)"}, "properties": {"repobilityId": "e3b08c59a434a427", "scanner": "scanner-primary", "fingerprint": "81ffcac226946a55", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ed5dc0feecb98ec6", "level": "error", "message": {"text": "Dangling fetch: POST /api/obligations/${userId} (src/api.js:477)"}, "properties": {"repobilityId": "1126e6d5a0b16770", "scanner": "scanner-primary", "fingerprint": "ed5dc0feecb98ec6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c69afdac629c19c1", "level": "error", "message": {"text": "Dangling fetch: PUT /api/obligations/${userId}/${id} (src/api.js:484)"}, "properties": {"repobilityId": "30faa59987a6cadc", "scanner": "scanner-primary", "fingerprint": "c69afdac629c19c1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-4e0092200c1defc1", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/obligations/${userId}/${id}/waiver (src/api.js:491)"}, "properties": {"repobilityId": "ff8f2934a8c76519", "scanner": "scanner-primary", "fingerprint": "4e0092200c1defc1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a258b7d2b299614d", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/obligations/${userId}/${id}/skip (src/api.js:498)"}, "properties": {"repobilityId": "50a75a58273077e4", "scanner": "scanner-primary", "fingerprint": "a258b7d2b299614d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-98bdfb1497dddf47", "level": "error", "message": {"text": "Dangling fetch: GET /api/ledger/${userId}/summary (src/api.js:516)"}, "properties": {"repobilityId": "ca8f4e71d1619e5a", "scanner": "scanner-primary", "fingerprint": "98bdfb1497dddf47", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-aef7fed11ff1fe69", "level": "error", "message": {"text": "Dangling fetch: POST /api/ledger/${userId} (src/api.js:520)"}, "properties": {"repobilityId": "9c636797244adcd5", "scanner": "scanner-primary", "fingerprint": "aef7fed11ff1fe69", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-8027fc6b1c7add53", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/ledger/${userId}/${id}/void (src/api.js:527)"}, "properties": {"repobilityId": "8efef767dbe6e34e", "scanner": "scanner-primary", "fingerprint": "8027fc6b1c7add53", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3a0410543d0949a5", "level": "error", "message": {"text": "Dangling fetch: GET /api/allocations/${userId}/entry/${entryId} (src/api.js:536)"}, "properties": {"repobilityId": "395cedba25f259e5", "scanner": "scanner-primary", "fingerprint": "3a0410543d0949a5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-6fa8d17a54b641aa", "level": "error", "message": {"text": "Dangling fetch: POST /api/allocations/${userId} (src/api.js:540)"}, "properties": {"repobilityId": "7c59ca0392f5d364", "scanner": "scanner-primary", "fingerprint": "6fa8d17a54b641aa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-61a948f0497079c4", "level": "error", "message": {"text": "Dangling fetch: POST /api/semester-engine?userId=${userId} (src/api.js:549)"}, "properties": {"repobilityId": "f149e7bd4217f8d3", "scanner": "scanner-primary", "fingerprint": "61a948f0497079c4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-812816e3071e1415", "level": "error", "message": {"text": "Dangling fetch: GET /api/semester-engine/${trackerId}/summary (src/api.js:556)"}, "properties": {"repobilityId": "1d386e6915bbc07f", "scanner": "scanner-primary", "fingerprint": "812816e3071e1415", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-bda01573670302b4", "level": "error", "message": {"text": "Dangling fetch: GET /api/semester-engine/entity/${entityId} (src/api.js:560)"}, "properties": {"repobilityId": "2568bf04b27e6821", "scanner": "scanner-primary", "fingerprint": "bda01573670302b4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2bc09c87dd15a5b2", "level": "error", "message": {"text": "Dangling fetch: POST /api/semester-engine/${trackerId}/fee-items?userId=${userId} (src/api.js:564)"}, "properties": {"repobilityId": "d268916ae4ac07c1", "scanner": "scanner-primary", "fingerprint": "2bc09c87dd15a5b2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-fd7a2b026ecab1b2", "level": "error", "message": {"text": "Dangling fetch: POST /api/semester-engine/${trackerId}/adjustments?userId=${userId} (src/api.js:571)"}, "properties": {"repobilityId": "05763236a7829073", "scanner": "scanner-primary", "fingerprint": "fd7a2b026ecab1b2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-12778b6c4887a726", "level": "error", "message": {"text": "Dangling fetch: POST /api/semester-engine/${trackerId}/waivers?userId=${userId} (src/api.js:578)"}, "properties": {"repobilityId": "fc35799cd4d736b9", "scanner": "scanner-primary", "fingerprint": "12778b6c4887a726", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f501ed85d776ce1c", "level": "error", "message": {"text": "Dangling fetch: GET /api/reports/${userId}/summary (src/api.js:587)"}, "properties": {"repobilityId": "2eed4d6759854b8a", "scanner": "scanner-primary", "fingerprint": "f501ed85d776ce1c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d93665ead88eafc7", "level": "error", "message": {"text": "Dangling fetch: GET /api/reports/${userId}/waiver-saved (src/api.js:591)"}, "properties": {"repobilityId": "7920d0d52e60f6c0", "scanner": "scanner-primary", "fingerprint": "d93665ead88eafc7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a4b106e70bd7609f", "level": "error", "message": {"text": "Dangling fetch: GET /api/circles/${userId} (src/api.js:604)"}, "properties": {"repobilityId": "4e14ba3ad5669d10", "scanner": "scanner-primary", "fingerprint": "a4b106e70bd7609f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9744950c33556b67", "level": "error", "message": {"text": "Dangling fetch: POST /api/circles/${userId} (src/api.js:608)"}, "properties": {"repobilityId": "1ef030da12cbfe42", "scanner": "scanner-primary", "fingerprint": "9744950c33556b67", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-6c4dfd43a69e2dd2", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/circles/${userId}/${circleId}/status (src/api.js:612)"}, "properties": {"repobilityId": "b6d2a21069ea2d29", "scanner": "scanner-primary", "fingerprint": "6c4dfd43a69e2dd2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ec2565067c5e35af", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/circles/${userId}/${circleId}/permission (src/api.js:616)"}, "properties": {"repobilityId": "29d82d80d059b0c5", "scanner": "scanner-primary", "fingerprint": "ec2565067c5e35af", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-47d80ea2562b6cb0", "level": "error", "message": {"text": "Dangling fetch: GET /api/recurring/${userId} (src/api.js:622)"}, "properties": {"repobilityId": "1cac76631dc73a5d", "scanner": "scanner-primary", "fingerprint": "47d80ea2562b6cb0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-7667ed85da6792a7", "level": "error", "message": {"text": "Dangling fetch: POST /api/recurring/${userId} (src/api.js:626)"}, "properties": {"repobilityId": "1575e8c2bd6a72d2", "scanner": "scanner-primary", "fingerprint": "7667ed85da6792a7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a9afaa4306a6779e", "level": "error", "message": {"text": "Dangling fetch: GET /api/recurring/${userId}/${scheduleId}/slots (src/api.js:630)"}, "properties": {"repobilityId": "619c2524554f82ed", "scanner": "scanner-primary", "fingerprint": "a9afaa4306a6779e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2b3edd1b502de092", "level": "error", "message": {"text": "Dangling fetch: POST /api/recurring/${userId}/slots/${slotId}/pay (src/api.js:634)"}, "properties": {"repobilityId": "bd49dac1e6e86736", "scanner": "scanner-primary", "fingerprint": "2b3edd1b502de092", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-175b76d9a6d799d2", "level": "error", "message": {"text": "Dangling fetch: POST /api/recurring/${userId}/slots/${slotId}/unpay (src/api.js:638)"}, "properties": {"repobilityId": "f290d9be2f0d7c7a", "scanner": "scanner-primary", "fingerprint": "175b76d9a6d799d2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-60f18a863877fd5f", "level": "error", "message": {"text": "Dangling fetch: POST /api/recurring/${userId}/${scheduleId}/advance (src/api.js:642)"}, "properties": {"repobilityId": "b19b8c8442c692b7", "scanner": "scanner-primary", "fingerprint": "60f18a863877fd5f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9c729615a16a035f", "level": "error", "message": {"text": "Dangling fetch: POST /api/assistant (src/api.js:648)"}, "properties": {"repobilityId": "a141e0fb987c9090", "scanner": "scanner-primary", "fingerprint": "9c729615a16a035f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-e9a4d2ef089c3019", "level": "error", "message": {"text": "Dangling fetch: POST /api/assistant/agent (src/api.js:656)"}, "properties": {"repobilityId": "6cffaafe1f859deb", "scanner": "scanner-primary", "fingerprint": "e9a4d2ef089c3019", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-29bbe229d2e5536b", "level": "error", "message": {"text": "Dangling fetch: GET /api/closure/${userId}/closures (src/api.js:665)"}, "properties": {"repobilityId": "d63a3a7c2057b075", "scanner": "scanner-primary", "fingerprint": "29bbe229d2e5536b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5f75589aac25cc27", "level": "error", "message": {"text": "Dangling fetch: POST /api/closure/${userId}/semester/${trackerId}/close (src/api.js:669)"}, "properties": {"repobilityId": "f0457030ee2220bb", "scanner": "scanner-primary", "fingerprint": "5f75589aac25cc27", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ab78aeadcc3ac657", "level": "error", "message": {"text": "Dangling fetch: POST /api/closure/${userId}/closures/${closureId}/settle (src/api.js:673)"}, "properties": {"repobilityId": "624444eda7ef5378", "scanner": "scanner-primary", "fingerprint": "ab78aeadcc3ac657", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-6f6088e43d0f026a", "level": "error", "message": {"text": "Dangling fetch: POST /api/assistant/agent (src/v2/Leeboon.jsx:60)"}, "properties": {"repobilityId": "8e9a9ebb1f0ac6b1", "scanner": "scanner-primary", "fingerprint": "6f6088e43d0f026a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-72b98ad24dd8d2f1", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/login (src/contexts/AdminContext.jsx:41)"}, "properties": {"repobilityId": "1fce42e5562e04b7", "scanner": "scanner-primary", "fingerprint": "72b98ad24dd8d2f1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "3ae1d16dc2becaaa", "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": "c03469cf92f3bcf0", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5c42734d4d670873", "level": "note", "message": {"text": "Unused endpoint: USE /api/expenses"}, "properties": {"repobilityId": "c316fd84c2c8082e", "scanner": "scanner-primary", "fingerprint": "5c42734d4d670873", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-26dfef6db57a40a8", "level": "note", "message": {"text": "Unused endpoint: USE /api/semesters"}, "properties": {"repobilityId": "e464a38cfc5215cd", "scanner": "scanner-primary", "fingerprint": "26dfef6db57a40a8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-955c408a2a1e6755", "level": "note", "message": {"text": "Unused endpoint: USE /api/loans"}, "properties": {"repobilityId": "e4c3ead6434561b7", "scanner": "scanner-primary", "fingerprint": "955c408a2a1e6755", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8ca4664c9cda1cd6", "level": "note", "message": {"text": "Unused endpoint: USE /api/settings"}, "properties": {"repobilityId": "71b62e9f67873683", "scanner": "scanner-primary", "fingerprint": "8ca4664c9cda1cd6", "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": "2e38daf40e65e220", "scanner": "scanner-primary", "fingerprint": "d93a530ce10d47d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0e76e800612b093e", "level": "note", "message": {"text": "Unused endpoint: USE /api/coaching"}, "properties": {"repobilityId": "eb6358cb3b3d6205", "scanner": "scanner-primary", "fingerprint": "0e76e800612b093e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b4667df8d1d98198", "level": "note", "message": {"text": "Unused endpoint: USE /api/batches"}, "properties": {"repobilityId": "d8d1362c4756fb6b", "scanner": "scanner-primary", "fingerprint": "b4667df8d1d98198", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c1222051eaa8fce0", "level": "note", "message": {"text": "Unused endpoint: USE /api/tutors"}, "properties": {"repobilityId": "2604f0a7a122d322", "scanner": "scanner-primary", "fingerprint": "c1222051eaa8fce0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e48cfbc31746e539", "level": "note", "message": {"text": "Unused endpoint: USE /api/clubs"}, "properties": {"repobilityId": "21837dbd8917ad48", "scanner": "scanner-primary", "fingerprint": "e48cfbc31746e539", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ec00984b27c88c15", "level": "note", "message": {"text": "Unused endpoint: USE /api/events"}, "properties": {"repobilityId": "bb7a2c43c1ddbd14", "scanner": "scanner-primary", "fingerprint": "ec00984b27c88c15", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b87660ce2200e31", "level": "note", "message": {"text": "Unused endpoint: USE /api/uniforms"}, "properties": {"repobilityId": "cc5c69b5feceed65", "scanner": "scanner-primary", "fingerprint": "3b87660ce2200e31", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4e3afff781526ae6", "level": "note", "message": {"text": "Unused endpoint: USE /api/education-fees"}, "properties": {"repobilityId": "cca9afcf8e921f8a", "scanner": "scanner-primary", "fingerprint": "4e3afff781526ae6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0fb5ff52a88bc1c7", "level": "note", "message": {"text": "Unused endpoint: USE /api/housing"}, "properties": {"repobilityId": "2aff324bdad3e121", "scanner": "scanner-primary", "fingerprint": "0fb5ff52a88bc1c7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e6dbffcc362c2929", "level": "note", "message": {"text": "Unused endpoint: USE /api/entities"}, "properties": {"repobilityId": "1f8a097982356d97", "scanner": "scanner-primary", "fingerprint": "e6dbffcc362c2929", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5458262cc1466f1c", "level": "note", "message": {"text": "Unused endpoint: USE /api/trackers"}, "properties": {"repobilityId": "3a51c2fbae0f9f67", "scanner": "scanner-primary", "fingerprint": "5458262cc1466f1c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-25dd4e9d78a047ee", "level": "note", "message": {"text": "Unused endpoint: USE /api/obligations"}, "properties": {"repobilityId": "7ac36b226174250e", "scanner": "scanner-primary", "fingerprint": "25dd4e9d78a047ee", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7ef3ca47ec14a78f", "level": "note", "message": {"text": "Unused endpoint: USE /api/ledger"}, "properties": {"repobilityId": "40aaf163307db670", "scanner": "scanner-primary", "fingerprint": "7ef3ca47ec14a78f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-97d8dc901e9aa6b6", "level": "note", "message": {"text": "Unused endpoint: USE /api/allocations"}, "properties": {"repobilityId": "0527d846061b9eeb", "scanner": "scanner-primary", "fingerprint": "97d8dc901e9aa6b6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-594ba67a2438ff11", "level": "note", "message": {"text": "Unused endpoint: USE /api/semester-engine"}, "properties": {"repobilityId": "75183ccb3e7e6a8b", "scanner": "scanner-primary", "fingerprint": "594ba67a2438ff11", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-001a1436225296b6", "level": "note", "message": {"text": "Unused endpoint: USE /api/institutions"}, "properties": {"repobilityId": "0edff65e93b8a395", "scanner": "scanner-primary", "fingerprint": "001a1436225296b6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4d25aedc90a887a6", "level": "note", "message": {"text": "Unused endpoint: USE /api/recurring"}, "properties": {"repobilityId": "0721e9fe3a4fba39", "scanner": "scanner-primary", "fingerprint": "4d25aedc90a887a6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2a06e6d401449b82", "level": "note", "message": {"text": "Unused endpoint: USE /api/reports"}, "properties": {"repobilityId": "d48bf310a8a6084a", "scanner": "scanner-primary", "fingerprint": "2a06e6d401449b82", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-84b52f40f216d5dc", "level": "note", "message": {"text": "Unused endpoint: USE /api/closure"}, "properties": {"repobilityId": "729c4bb8bd5eb5ba", "scanner": "scanner-primary", "fingerprint": "84b52f40f216d5dc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-74653654fc29fc2a", "level": "note", "message": {"text": "Unused endpoint: USE /api/circles"}, "properties": {"repobilityId": "ec873f876f4d72ee", "scanner": "scanner-primary", "fingerprint": "74653654fc29fc2a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-135c732484f1341a", "level": "note", "message": {"text": "Unused endpoint: USE /api/assistant"}, "properties": {"repobilityId": "e8ebedf4e12ef467", "scanner": "scanner-primary", "fingerprint": "135c732484f1341a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5f8e1141d1782a8c", "level": "note", "message": {"text": "Unused endpoint: USE /api/v2data"}, "properties": {"repobilityId": "8ab3829938b0d1ea", "scanner": "scanner-primary", "fingerprint": "5f8e1141d1782a8c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d95f6b6be4decff8", "level": "note", "message": {"text": "Unused endpoint: USE /api/feed"}, "properties": {"repobilityId": "16ff1db77bd0b2f7", "scanner": "scanner-primary", "fingerprint": "d95f6b6be4decff8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1bc898b3b7565990", "level": "note", "message": {"text": "Unused endpoint: USE /uploads"}, "properties": {"repobilityId": "0f1f9ddd7d130ac5", "scanner": "scanner-primary", "fingerprint": "1bc898b3b7565990", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fb902fa8f06593cb", "level": "note", "message": {"text": "Unused endpoint: GET /:userId"}, "properties": {"repobilityId": "af2d77945679c0a0", "scanner": "scanner-primary", "fingerprint": "fb902fa8f06593cb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "8e40888ac6f12991", "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": "bba6dde5e38458d8", "scanner": "scanner-primary", "fingerprint": "8d5b2b188d08ca82", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a61c112b611f4bb", "level": "note", "message": {"text": "Unused endpoint: DELETE /:id"}, "properties": {"repobilityId": "8b36c508863bd8cf", "scanner": "scanner-primary", "fingerprint": "7a61c112b611f4bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-27fb1188f31ce958", "level": "note", "message": {"text": "Unused endpoint: POST /:userId/semester/:trackerId/close"}, "properties": {"repobilityId": "7316033068f3cee5", "scanner": "scanner-primary", "fingerprint": "27fb1188f31ce958", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d299d7a89487b487", "level": "note", "message": {"text": "Unused endpoint: GET /:userId/closures"}, "properties": {"repobilityId": "27bec9ef9ac9f4b9", "scanner": "scanner-primary", "fingerprint": "d299d7a89487b487", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f1fb2e06d957ccb8", "level": "note", "message": {"text": "Unused endpoint: POST /:userId/closures/:id/settle"}, "properties": {"repobilityId": "9ff97d31802bfad6", "scanner": "scanner-primary", "fingerprint": "f1fb2e06d957ccb8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4c8499022f17a673", "level": "note", "message": {"text": "Unused endpoint: GET /:userId/:id"}, "properties": {"repobilityId": "5cfce102bc0e45a8", "scanner": "scanner-primary", "fingerprint": "4c8499022f17a673", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-745d0349641ea3c7", "level": "note", "message": {"text": "Unused endpoint: POST /:userId"}, "properties": {"repobilityId": "1c21110fa446299e", "scanner": "scanner-primary", "fingerprint": "745d0349641ea3c7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-91ba31a29cd2dcc0", "level": "note", "message": {"text": "Unused endpoint: PUT /:userId/:id"}, "properties": {"repobilityId": "6a46dd837d909995", "scanner": "scanner-primary", "fingerprint": "91ba31a29cd2dcc0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d3ae624de6c5aeb3", "level": "note", "message": {"text": "Unused endpoint: DELETE /:userId/:id"}, "properties": {"repobilityId": "4b7cdd73dadd917a", "scanner": "scanner-primary", "fingerprint": "d3ae624de6c5aeb3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "d31d55a45bb3fbe7", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d504b80adc9409ec", "level": "note", "message": {"text": "Unused endpoint: GET /dashboard"}, "properties": {"repobilityId": "3f1b1de7caef1138", "scanner": "scanner-primary", "fingerprint": "d504b80adc9409ec", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-841e50bf821e4158", "level": "note", "message": {"text": "Unused endpoint: GET /users"}, "properties": {"repobilityId": "fdbbf4905ad47343", "scanner": "scanner-primary", "fingerprint": "841e50bf821e4158", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9da256c72d46eb8c", "level": "note", "message": {"text": "Unused endpoint: GET /users/:id/full"}, "properties": {"repobilityId": "e066d785647e55a0", "scanner": "scanner-primary", "fingerprint": "9da256c72d46eb8c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-41aa9e92da3f14ad", "level": "note", "message": {"text": "Unused endpoint: GET /users/:id"}, "properties": {"repobilityId": "43c3ad8fb6f59cb2", "scanner": "scanner-primary", "fingerprint": "41aa9e92da3f14ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-67d3c865c237279a", "level": "note", "message": {"text": "Unused endpoint: GET /analytics/signups"}, "properties": {"repobilityId": "5aed4169e6dd745c", "scanner": "scanner-primary", "fingerprint": "67d3c865c237279a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-11d4c129e1a6e7ef", "level": "note", "message": {"text": "Unused endpoint: GET /analytics/education-levels"}, "properties": {"repobilityId": "4a7779bac0c5d691", "scanner": "scanner-primary", "fingerprint": "11d4c129e1a6e7ef", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd8dc4599ec52a08", "level": "note", "message": {"text": "Unused endpoint: GET /stats"}, "properties": {"repobilityId": "29f7c36dd1ade7d8", "scanner": "scanner-primary", "fingerprint": "cd8dc4599ec52a08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0015e9c38df18e0d", "level": "note", "message": {"text": "Unused endpoint: GET /promos"}, "properties": {"repobilityId": "d24d9b62d886254e", "scanner": "scanner-primary", "fingerprint": "0015e9c38df18e0d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}