{"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-0f34b23f28f190f9", "name": "Possibly dead Python function: require_auth", "shortDescription": {"text": "Possibly dead Python function: require_auth"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-68a79f882547fc64", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/AdminLayout.tsx:192", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/AdminLayout.tsx:192"}, "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-734e00f4dfa15d82", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/EditorPage.tsx:390", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/EditorPage.tsx:390"}, "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-49b7ae40112883f6", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/KnowledgeBasePage.tsx:154", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/KnowledgeBasePage.tsx:154"}, "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-a6c93c74e4d68017", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/UserManagement.tsx:167", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/UserManagement.tsx:167"}, "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-0d4d8e9eac7192b3", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/public/FaqPage.tsx:82", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/public/FaqPage.tsx:82"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9c0cc9b416ae41d6", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/public/ContentDetailPage.tsx:105", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/public/ContentDetailPage.tsx:105"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-835eae4c7f17a2f8", "name": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-de3c1f217d72a063", "name": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-60427b03771411b6", "name": "Dockerfile runs as root: frontend/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: frontend/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a7f39cdd5fa21931", "name": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b048d166901fd868", "name": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1f66ad88286ca30a", "name": "Dockerfile runs as root: backend/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: backend/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-714c31ca9f474ae6", "name": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0e28b7db66baa460", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/public/FaqPage.tsx:82", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/public/FaqPage.tsx:82"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-495e914ed7a93d05", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/public/ContentDetailPage.tsx:105", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/public/ContentDetailPage.tsx:105"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 38 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 32 placeholder/mock markers across 11 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-d0b17c8c07a7421d", "name": "8 env vars used in code but missing from .env.example", "shortDescription": {"text": "8 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BACKEND_URL`, `CORS_ORIGINS`, `DATABASE_URL`, `FRONTEND_DIST`, `SECRET_KEY`, `SECRET_KEY_FILE`, `SUPABASE_ANON_KEY`, `SUPABASE_URL`. 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-be46ea126aa5d8dc", "name": "Near-duplicate function bodies in 3 places", "shortDescription": {"text": "Near-duplicate function bodies in 3 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nbackend/app/routers/admin.py:delete_item, backend/app/routers/admin.py:publish_item, backend/app/routers/admin.py:unpublish_item\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-31b463c34131fe1e", "name": "Frontend route `/blogs/:slug` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `/blogs/:slug` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b75bdf063872651d", "name": "Frontend route `/news/:slug` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `/news/:slug` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-fac3d854725f096a", "name": "Frontend route `media` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `media` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-138b7acf73bcd1d5", "name": "Frontend route `knowledge` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `knowledge` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-17bacb17f6efb788", "name": "Frontend route `settings` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7de8955b97a52b86", "name": "Frontend route `:module` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `:module` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1f1ea3187ffea46a", "name": "Frontend route `:module/drafts` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `:module/drafts` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d92ced6584c66047", "name": "Frontend route `:module/published` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `:module/published` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-db81d3af488b3dc1", "name": "Frontend route `:module/scheduled` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `:module/scheduled` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9318c9c8f29d855e", "name": "Frontend route `:module/new` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `:module/new` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-adac4a7776b1e889", "name": "Frontend route `:module/:id/edit` has no Link/navigate to it \u2014 frontend/src/App.tsx", "shortDescription": {"text": "Frontend route `:module/:id/edit` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ad234891feb079a1", "name": "FastAPI POST `upload_document` without auth dependency \u2014 backend/app/routers/knowledge.py:54", "shortDescription": {"text": "FastAPI POST `upload_document` without auth dependency \u2014 backend/app/routers/knowledge.py:54"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b67bf2a1cdeb6f7e", "name": "FastAPI POST `reanalyze_document` without auth dependency \u2014 backend/app/routers/knowledge.py:93", "shortDescription": {"text": "FastAPI POST `reanalyze_document` without auth dependency \u2014 backend/app/routers/knowledge.py:93"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-de93eac00df3e20e", "name": "FastAPI DELETE `delete_document` without auth dependency \u2014 backend/app/routers/knowledge.py:109", "shortDescription": {"text": "FastAPI DELETE `delete_document` without auth dependency \u2014 backend/app/routers/knowledge.py:109"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-775da09099c41590", "name": "FastAPI POST `create_item` without auth dependency \u2014 backend/app/routers/admin.py:106", "shortDescription": {"text": "FastAPI POST `create_item` without auth dependency \u2014 backend/app/routers/admin.py:106"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0a839dee5e963db7", "name": "FastAPI PUT `update_item` without auth dependency \u2014 backend/app/routers/admin.py:141", "shortDescription": {"text": "FastAPI PUT `update_item` without auth dependency \u2014 backend/app/routers/admin.py:141"}, "fullDescription": {"text": "`@router.put` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0f7b86dd59fdc7d1", "name": "FastAPI DELETE `delete_item` without auth dependency \u2014 backend/app/routers/admin.py:164", "shortDescription": {"text": "FastAPI DELETE `delete_item` without auth dependency \u2014 backend/app/routers/admin.py:164"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-08442b1670edde7d", "name": "FastAPI POST `publish_item` without auth dependency \u2014 backend/app/routers/admin.py:175", "shortDescription": {"text": "FastAPI POST `publish_item` without auth dependency \u2014 backend/app/routers/admin.py:175"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a30aafa90196ad61", "name": "FastAPI POST `unpublish_item` without auth dependency \u2014 backend/app/routers/admin.py:190", "shortDescription": {"text": "FastAPI POST `unpublish_item` without auth dependency \u2014 backend/app/routers/admin.py:190"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ce416ebd8c75750a", "name": "FastAPI POST `schedule_item` without auth dependency \u2014 backend/app/routers/admin.py:204", "shortDescription": {"text": "FastAPI POST `schedule_item` without auth dependency \u2014 backend/app/routers/admin.py:204"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fd1b92c6628a0714", "name": "FastAPI POST `duplicate_item` without auth dependency \u2014 backend/app/routers/admin.py:219", "shortDescription": {"text": "FastAPI POST `duplicate_item` without auth dependency \u2014 backend/app/routers/admin.py:219"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-24479f5b08ed3c10", "name": "FastAPI POST `generate` without auth dependency \u2014 backend/app/routers/ai.py:115", "shortDescription": {"text": "FastAPI POST `generate` without auth dependency \u2014 backend/app/routers/ai.py:115"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a170037e7223f926", "name": "FastAPI POST `upload_file` without auth dependency \u2014 backend/app/routers/uploads.py:15", "shortDescription": {"text": "FastAPI POST `upload_file` without auth dependency \u2014 backend/app/routers/uploads.py:15"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6899617926c07bc8", "name": "FastAPI PUT `update_profile` without auth dependency \u2014 backend/app/routers/settings.py:43", "shortDescription": {"text": "FastAPI PUT `update_profile` without auth dependency \u2014 backend/app/routers/settings.py:43"}, "fullDescription": {"text": "`@router.put` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-353466d8828ccf92", "name": "FastAPI POST `create_user` without auth dependency \u2014 backend/app/routers/settings.py:114", "shortDescription": {"text": "FastAPI POST `create_user` without auth dependency \u2014 backend/app/routers/settings.py:114"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-dd4abc6cde023c42", "name": "FastAPI PUT `update_user` without auth dependency \u2014 backend/app/routers/settings.py:126", "shortDescription": {"text": "FastAPI PUT `update_user` without auth dependency \u2014 backend/app/routers/settings.py:126"}, "fullDescription": {"text": "`@router.put` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-330d9a2e533e1836", "name": "FastAPI DELETE `delete_user` without auth dependency \u2014 backend/app/routers/settings.py:146", "shortDescription": {"text": "FastAPI DELETE `delete_user` without auth dependency \u2014 backend/app/routers/settings.py:146"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d0ebd0c07488388a", "name": "FastAPI DELETE `delete_media` without auth dependency \u2014 backend/app/routers/media.py:79", "shortDescription": {"text": "FastAPI DELETE `delete_media` without auth dependency \u2014 backend/app/routers/media.py:79"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6c70f486f1a98699", "name": "Dangling fetch: POST /api/auth/login (frontend/src/lib/api.ts:205)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/login (frontend/src/lib/api.ts:205)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:205` 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-8f6ffb76495255fd", "name": "Dangling fetch: GET /api/auth/me (frontend/src/lib/api.ts:209)", "shortDescription": {"text": "Dangling fetch: GET /api/auth/me (frontend/src/lib/api.ts:209)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:209` calls `GET /api/auth/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: `/auth/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-9e06e06f57cafd9f", "name": "Dangling fetch: GET /api/admin/${module}?${qs} (frontend/src/lib/api.ts:219)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/${module}?${qs} (frontend/src/lib/api.ts:219)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:219` calls `GET /api/admin/${module}?${qs}` 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/<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-b3b2eee3420bb6db", "name": "Dangling fetch: GET /api/admin/${module}/stats (frontend/src/lib/api.ts:221)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/${module}/stats (frontend/src/lib/api.ts:221)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:221` calls `GET /api/admin/${module}/stats` 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/<p>/stats`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-759c22ca91972cbd", "name": "Dangling fetch: GET /api/admin/stats (frontend/src/lib/api.ts:222)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/stats (frontend/src/lib/api.ts:222)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:222` calls `GET /api/admin/stats` 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/stats`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0305fd17583ec2ed", "name": "Dangling fetch: GET /api/admin/${module}/${id} (frontend/src/lib/api.ts:223)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/${module}/${id} (frontend/src/lib/api.ts:223)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:223` calls `GET /api/admin/${module}/${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: `/admin/<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-f0dbbf2b8ff409b4", "name": "Dangling fetch: POST /api/admin/${module} (frontend/src/lib/api.ts:225)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/${module} (frontend/src/lib/api.ts:225)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:225` calls `POST /api/admin/${module}` 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/<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-6f86165486f3d612", "name": "Dangling fetch: PUT /api/admin/${module}/${id} (frontend/src/lib/api.ts:227)", "shortDescription": {"text": "Dangling fetch: PUT /api/admin/${module}/${id} (frontend/src/lib/api.ts:227)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:227` calls `PUT /api/admin/${module}/${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: `/admin/<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-c03a912aaf24fc3e", "name": "Dangling fetch: DELETE /api/admin/${module}/${id} (frontend/src/lib/api.ts:229)", "shortDescription": {"text": "Dangling fetch: DELETE /api/admin/${module}/${id} (frontend/src/lib/api.ts:229)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:229` calls `DELETE /api/admin/${module}/${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: `/admin/<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-1a5a0d418478cfc7", "name": "Dangling fetch: POST /api/admin/${module}/${id}/publish (frontend/src/lib/api.ts:231)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/publish (frontend/src/lib/api.ts:231)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:231` calls `POST /api/admin/${module}/${id}/publish` 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/<p>/<p>/publish`\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-9f207ba86a5fb7fe", "name": "Dangling fetch: POST /api/admin/${module}/${id}/unpublish (frontend/src/lib/api.ts:233)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/unpublish (frontend/src/lib/api.ts:233)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:233` calls `POST /api/admin/${module}/${id}/unpublish` 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/<p>/<p>/unpublish`\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-2c5c8bb5d9253daa", "name": "Dangling fetch: POST /api/admin/${module}/${id}/schedule (frontend/src/lib/api.ts:235)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/schedule (frontend/src/lib/api.ts:235)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:235` calls `POST /api/admin/${module}/${id}/schedule` 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/<p>/<p>/schedule`\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-113aea2d96966ada", "name": "Dangling fetch: POST /api/admin/${module}/${id}/duplicate (frontend/src/lib/api.ts:240)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/duplicate (frontend/src/lib/api.ts:240)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:240` calls `POST /api/admin/${module}/${id}/duplicate` 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/<p>/<p>/duplicate`\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-180aab69324063e7", "name": "Dangling fetch: GET /api/admin/media?${qs} (frontend/src/lib/api.ts:264)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/media?${qs} (frontend/src/lib/api.ts:264)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:264` calls `GET /api/admin/media?${qs}` 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/media`\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-5238a2496ddd78de", "name": "Dangling fetch: DELETE /api/admin/media/${encodeURIComponent(name)} (frontend/src/lib/api.ts:267)", "shortDescription": {"text": "Dangling fetch: DELETE /api/admin/media/${encodeURIComponent(name)} (frontend/src/lib/api.ts:267)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:267` calls `DELETE /api/admin/media/${encodeURIComponent(name)}` 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/media/<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-66d6f82ec792ebc8", "name": "Dangling fetch: GET /api/admin/settings/profile (frontend/src/lib/api.ts:271)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/settings/profile (frontend/src/lib/api.ts:271)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:271` calls `GET /api/admin/settings/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: `/admin/settings/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-4eb96adee894ef2f", "name": "Dangling fetch: PUT /api/admin/settings/profile (frontend/src/lib/api.ts:273)", "shortDescription": {"text": "Dangling fetch: PUT /api/admin/settings/profile (frontend/src/lib/api.ts:273)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:273` calls `PUT /api/admin/settings/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: `/admin/settings/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-a22f92d53d2e9618", "name": "Dangling fetch: GET /api/admin/settings/users (frontend/src/lib/api.ts:274)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/settings/users (frontend/src/lib/api.ts:274)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:274` calls `GET /api/admin/settings/users` 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/settings/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-c3f645a1c900a12b", "name": "Dangling fetch: POST /api/admin/settings/users (frontend/src/lib/api.ts:276)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/settings/users (frontend/src/lib/api.ts:276)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:276` calls `POST /api/admin/settings/users` 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/settings/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-59c955c9cc9b595f", "name": "Dangling fetch: PUT /api/admin/settings/users/${id} (frontend/src/lib/api.ts:278)", "shortDescription": {"text": "Dangling fetch: PUT /api/admin/settings/users/${id} (frontend/src/lib/api.ts:278)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:278` calls `PUT /api/admin/settings/users/${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: `/admin/settings/users/<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-e9b4ad8e8878dc00", "name": "Dangling fetch: DELETE /api/admin/settings/users/${id} (frontend/src/lib/api.ts:280)", "shortDescription": {"text": "Dangling fetch: DELETE /api/admin/settings/users/${id} (frontend/src/lib/api.ts:280)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:280` calls `DELETE /api/admin/settings/users/${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: `/admin/settings/users/<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-78744caa68e8fcb7", "name": "Dangling fetch: POST /api/ai/generate (frontend/src/lib/api.ts:301)", "shortDescription": {"text": "Dangling fetch: POST /api/ai/generate (frontend/src/lib/api.ts:301)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:301` calls `POST /api/ai/generate` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/ai/generate`\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-e2e5c4e1d6ca0052", "name": "Dangling fetch: GET /api/admin/knowledge (frontend/src/lib/api.ts:314)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/knowledge (frontend/src/lib/api.ts:314)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:314` calls `GET /api/admin/knowledge` 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/knowledge`\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-9877a15909925026", "name": "Dangling fetch: GET /api/admin/knowledge/${id} (frontend/src/lib/api.ts:315)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/knowledge/${id} (frontend/src/lib/api.ts:315)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:315` calls `GET /api/admin/knowledge/${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: `/admin/knowledge/<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-5d32fb5a2588b912", "name": "Dangling fetch: POST /api/admin/knowledge (frontend/src/lib/api.ts:319)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/knowledge (frontend/src/lib/api.ts:319)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:319` calls `POST /api/admin/knowledge` 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/knowledge`\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-9a848bf424624d60", "name": "Dangling fetch: POST /api/admin/knowledge/${id}/reanalyze (frontend/src/lib/api.ts:322)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/knowledge/${id}/reanalyze (frontend/src/lib/api.ts:322)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:322` calls `POST /api/admin/knowledge/${id}/reanalyze` 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/knowledge/<p>/reanalyze`\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-30a38cc8a3e7a393", "name": "Dangling fetch: DELETE /api/admin/knowledge/${id} (frontend/src/lib/api.ts:323)", "shortDescription": {"text": "Dangling fetch: DELETE /api/admin/knowledge/${id} (frontend/src/lib/api.ts:323)"}, "fullDescription": {"text": "`frontend/src/lib/api.ts:323` calls `DELETE /api/admin/knowledge/${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: `/admin/knowledge/<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-4756b4c4da7d2088", "name": "Unused endpoint: GET /api/health", "shortDescription": {"text": "Unused endpoint: GET /api/health"}, "fullDescription": {"text": "`backend/app/main.py` declares `GET /api/health` 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": "`backend/app/routers/knowledge.py` 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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`backend/app/routers/knowledge.py` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-14ca9451df2c5dcc", "name": "Unused endpoint: GET /{doc_id}", "shortDescription": {"text": "Unused endpoint: GET /{doc_id}"}, "fullDescription": {"text": "`backend/app/routers/knowledge.py` declares `GET /{doc_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-d44c8014dccb3dfe", "name": "Unused endpoint: POST /{doc_id}/reanalyze", "shortDescription": {"text": "Unused endpoint: POST /{doc_id}/reanalyze"}, "fullDescription": {"text": "`backend/app/routers/knowledge.py` declares `POST /{doc_id}/reanalyze` 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-e96576fde6078449", "name": "Unused endpoint: DELETE /{doc_id}", "shortDescription": {"text": "Unused endpoint: DELETE /{doc_id}"}, "fullDescription": {"text": "`backend/app/routers/knowledge.py` declares `DELETE /{doc_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": "`backend/app/routers/auth.py` 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-fd1dc91abf32142d", "name": "Unused endpoint: GET /me", "shortDescription": {"text": "Unused endpoint: GET /me"}, "fullDescription": {"text": "`backend/app/routers/auth.py` declares `GET /me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9374ee49bcfb4df1", "name": "Unused endpoint: GET /{module}", "shortDescription": {"text": "Unused endpoint: GET /{module}"}, "fullDescription": {"text": "`backend/app/routers/public.py` declares `GET /{module}` 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-c1b6ac24269451bc", "name": "Unused endpoint: GET /resources/{item_id}/download", "shortDescription": {"text": "Unused endpoint: GET /resources/{item_id}/download"}, "fullDescription": {"text": "`backend/app/routers/public.py` declares `GET /resources/{item_id}/download` 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": "`backend/app/routers/admin.py` 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-6724ec101bfc8d1c", "name": "Unused endpoint: GET /{module}/stats", "shortDescription": {"text": "Unused endpoint: GET /{module}/stats"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `GET /{module}/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-c68b9937118c740b", "name": "Unused endpoint: POST /{module}", "shortDescription": {"text": "Unused endpoint: POST /{module}"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `POST /{module}` 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-bad369a46673aecc", "name": "Unused endpoint: GET /{module}/{item_id}", "shortDescription": {"text": "Unused endpoint: GET /{module}/{item_id}"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `GET /{module}/{item_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-548ac29848a68435", "name": "Unused endpoint: PUT /{module}/{item_id}", "shortDescription": {"text": "Unused endpoint: PUT /{module}/{item_id}"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `PUT /{module}/{item_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-5a7ee4b25b442fa4", "name": "Unused endpoint: DELETE /{module}/{item_id}", "shortDescription": {"text": "Unused endpoint: DELETE /{module}/{item_id}"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `DELETE /{module}/{item_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-62dcfb1ed34a2f74", "name": "Unused endpoint: POST /{module}/{item_id}/publish", "shortDescription": {"text": "Unused endpoint: POST /{module}/{item_id}/publish"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `POST /{module}/{item_id}/publish` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2c7954c2724edf38", "name": "Unused endpoint: POST /{module}/{item_id}/unpublish", "shortDescription": {"text": "Unused endpoint: POST /{module}/{item_id}/unpublish"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `POST /{module}/{item_id}/unpublish` 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-3dba6f37e17e7fe6", "name": "Unused endpoint: POST /{module}/{item_id}/schedule", "shortDescription": {"text": "Unused endpoint: POST /{module}/{item_id}/schedule"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `POST /{module}/{item_id}/schedule` 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-611922f26606c396", "name": "Unused endpoint: POST /{module}/{item_id}/duplicate", "shortDescription": {"text": "Unused endpoint: POST /{module}/{item_id}/duplicate"}, "fullDescription": {"text": "`backend/app/routers/admin.py` declares `POST /{module}/{item_id}/duplicate` 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-970eb92d6ec2bfaa", "name": "Unused endpoint: POST /generate", "shortDescription": {"text": "Unused endpoint: POST /generate"}, "fullDescription": {"text": "`backend/app/routers/ai.py` declares `POST /generate` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2595b39638e5c045", "name": "Unused endpoint: GET /profile", "shortDescription": {"text": "Unused endpoint: GET /profile"}, "fullDescription": {"text": "`backend/app/routers/settings.py` declares `GET /profile` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-911492554a68d0c1", "name": "Unused endpoint: PUT /profile", "shortDescription": {"text": "Unused endpoint: PUT /profile"}, "fullDescription": {"text": "`backend/app/routers/settings.py` declares `PUT /profile` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-841e50bf821e4158", "name": "Unused endpoint: GET /users", "shortDescription": {"text": "Unused endpoint: GET /users"}, "fullDescription": {"text": "`backend/app/routers/settings.py` 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-1bca8100a44f7f25", "name": "Unused endpoint: POST /users", "shortDescription": {"text": "Unused endpoint: POST /users"}, "fullDescription": {"text": "`backend/app/routers/settings.py` declares `POST /users` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d07acca647618197", "name": "Unused endpoint: PUT /users/{user_id}", "shortDescription": {"text": "Unused endpoint: PUT /users/{user_id}"}, "fullDescription": {"text": "`backend/app/routers/settings.py` declares `PUT /users/{user_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-fecd99fa2d3d6078", "name": "Unused endpoint: DELETE /users/{user_id}", "shortDescription": {"text": "Unused endpoint: DELETE /users/{user_id}"}, "fullDescription": {"text": "`backend/app/routers/settings.py` declares `DELETE /users/{user_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-c562c83979dce866", "name": "Unused endpoint: DELETE /{name}", "shortDescription": {"text": "Unused endpoint: DELETE /{name}"}, "fullDescription": {"text": "`backend/app/routers/media.py` declares `DELETE /{name}` 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/20811"}, "properties": {"repository": "tanjirkhan3229-cmyk/ForgeCMS", "repoUrl": "https://github.com/tanjirkhan3229-cmyk/ForgeCMS", "branch": "main"}, "results": [{"ruleId": "scanner-0f34b23f28f190f9", "level": "note", "message": {"text": "Possibly dead Python function: require_auth"}, "properties": {"repobilityId": "d7855475dea79341", "scanner": "scanner-primary", "fingerprint": "0f34b23f28f190f9", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/auth.py:83"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-68a79f882547fc64", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/AdminLayout.tsx:192"}, "properties": {"repobilityId": "b1da2e3f481a0c76", "scanner": "scanner-primary", "fingerprint": "68a79f882547fc64", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-734e00f4dfa15d82", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/EditorPage.tsx:390"}, "properties": {"repobilityId": "35e012ca3b52802f", "scanner": "scanner-primary", "fingerprint": "734e00f4dfa15d82", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-49b7ae40112883f6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/KnowledgeBasePage.tsx:154"}, "properties": {"repobilityId": "dbbfadd3be907f36", "scanner": "scanner-primary", "fingerprint": "49b7ae40112883f6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a6c93c74e4d68017", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/admin/UserManagement.tsx:167"}, "properties": {"repobilityId": "6aaf70508889f1eb", "scanner": "scanner-primary", "fingerprint": "a6c93c74e4d68017", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0d4d8e9eac7192b3", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/public/FaqPage.tsx:82"}, "properties": {"repobilityId": "a7a158de4f0c071b", "scanner": "scanner-primary", "fingerprint": "0d4d8e9eac7192b3", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-9c0cc9b416ae41d6", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/src/pages/public/ContentDetailPage.tsx:105"}, "properties": {"repobilityId": "52e179106b73cc2b", "scanner": "scanner-primary", "fingerprint": "9c0cc9b416ae41d6", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-835eae4c7f17a2f8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "82612d959b5b5310", "scanner": "scanner-primary", "fingerprint": "835eae4c7f17a2f8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-de3c1f217d72a063", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "properties": {"repobilityId": "d8d309e75a226340", "scanner": "scanner-primary", "fingerprint": "de3c1f217d72a063", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-60427b03771411b6", "level": "warning", "message": {"text": "Dockerfile runs as root: frontend/Dockerfile"}, "properties": {"repobilityId": "735c01d8531dfd2c", "scanner": "scanner-primary", "fingerprint": "60427b03771411b6", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-a7f39cdd5fa21931", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "cab9982a12e27589", "scanner": "scanner-primary", "fingerprint": "a7f39cdd5fa21931", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-b048d166901fd868", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine"}, "properties": {"repobilityId": "ac3286d5a4e1d099", "scanner": "scanner-primary", "fingerprint": "b048d166901fd868", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-1f66ad88286ca30a", "level": "warning", "message": {"text": "Dockerfile runs as root: backend/Dockerfile"}, "properties": {"repobilityId": "7afd2b0e8a8c9eeb", "scanner": "scanner-primary", "fingerprint": "1f66ad88286ca30a", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-714c31ca9f474ae6", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "properties": {"repobilityId": "f790b9f0ff986b2a", "scanner": "scanner-primary", "fingerprint": "714c31ca9f474ae6", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-0e28b7db66baa460", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/public/FaqPage.tsx:82"}, "properties": {"repobilityId": "9460e15f5ceaa6ee", "scanner": "scanner-primary", "fingerprint": "0e28b7db66baa460", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/pages/public/FaqPage.tsx"}, "region": {"startLine": 82}}}]}, {"ruleId": "scanner-495e914ed7a93d05", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/src/pages/public/ContentDetailPage.tsx:105"}, "properties": {"repobilityId": "ff5c76b41fb18dc8", "scanner": "scanner-primary", "fingerprint": "495e914ed7a93d05", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/pages/public/ContentDetailPage.tsx"}, "region": {"startLine": 105}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"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-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": "d7936dde8b2ed98f", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "4e6eefeafffadc4c", "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": "5880fd1d1e814633", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "914d2b7439b44060", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "df5a41fca2cc0dab", "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": "ef4012db4edeb903", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-d0b17c8c07a7421d", "level": "note", "message": {"text": "8 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "17fe720e8247f9df", "scanner": "scanner-primary", "fingerprint": "d0b17c8c07a7421d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "e2b30b6d03381e15", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-31b463c34131fe1e", "level": "warning", "message": {"text": "Frontend route `/blogs/:slug` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "7f6d8ecb5ad36972", "scanner": "scanner-primary", "fingerprint": "31b463c34131fe1e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b75bdf063872651d", "level": "warning", "message": {"text": "Frontend route `/news/:slug` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "dde7db0bffe5bc21", "scanner": "scanner-primary", "fingerprint": "b75bdf063872651d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-fac3d854725f096a", "level": "warning", "message": {"text": "Frontend route `media` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "8350837a6527a2c2", "scanner": "scanner-primary", "fingerprint": "fac3d854725f096a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-138b7acf73bcd1d5", "level": "warning", "message": {"text": "Frontend route `knowledge` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "8b3ff5df46e9561a", "scanner": "scanner-primary", "fingerprint": "138b7acf73bcd1d5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-17bacb17f6efb788", "level": "warning", "message": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "7a6f6cf42324831f", "scanner": "scanner-primary", "fingerprint": "17bacb17f6efb788", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-7de8955b97a52b86", "level": "warning", "message": {"text": "Frontend route `:module` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "6d51997376aa385c", "scanner": "scanner-primary", "fingerprint": "7de8955b97a52b86", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-1f1ea3187ffea46a", "level": "warning", "message": {"text": "Frontend route `:module/drafts` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "1a55d6f691706ac0", "scanner": "scanner-primary", "fingerprint": "1f1ea3187ffea46a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-d92ced6584c66047", "level": "warning", "message": {"text": "Frontend route `:module/published` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "34ac1e477d0228de", "scanner": "scanner-primary", "fingerprint": "d92ced6584c66047", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-db81d3af488b3dc1", "level": "warning", "message": {"text": "Frontend route `:module/scheduled` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "2eb77c26a57c1ff4", "scanner": "scanner-primary", "fingerprint": "db81d3af488b3dc1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9318c9c8f29d855e", "level": "warning", "message": {"text": "Frontend route `:module/new` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "d40ee82e449692f1", "scanner": "scanner-primary", "fingerprint": "9318c9c8f29d855e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-adac4a7776b1e889", "level": "warning", "message": {"text": "Frontend route `:module/:id/edit` has no Link/navigate to it \u2014 frontend/src/App.tsx"}, "properties": {"repobilityId": "afce345594f15db9", "scanner": "scanner-primary", "fingerprint": "adac4a7776b1e889", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-ad234891feb079a1", "level": "error", "message": {"text": "FastAPI POST `upload_document` without auth dependency \u2014 backend/app/routers/knowledge.py:54"}, "properties": {"repobilityId": "57b61c981438b9b1", "scanner": "scanner-primary", "fingerprint": "ad234891feb079a1", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/knowledge.py"}, "region": {"startLine": 54}}}]}, {"ruleId": "scanner-b67bf2a1cdeb6f7e", "level": "error", "message": {"text": "FastAPI POST `reanalyze_document` without auth dependency \u2014 backend/app/routers/knowledge.py:93"}, "properties": {"repobilityId": "168e01199051d09d", "scanner": "scanner-primary", "fingerprint": "b67bf2a1cdeb6f7e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/knowledge.py"}, "region": {"startLine": 93}}}]}, {"ruleId": "scanner-de93eac00df3e20e", "level": "error", "message": {"text": "FastAPI DELETE `delete_document` without auth dependency \u2014 backend/app/routers/knowledge.py:109"}, "properties": {"repobilityId": "e21b79f6fe33b8f8", "scanner": "scanner-primary", "fingerprint": "de93eac00df3e20e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/knowledge.py"}, "region": {"startLine": 109}}}]}, {"ruleId": "scanner-775da09099c41590", "level": "error", "message": {"text": "FastAPI POST `create_item` without auth dependency \u2014 backend/app/routers/admin.py:106"}, "properties": {"repobilityId": "47bf9184373ca48c", "scanner": "scanner-primary", "fingerprint": "775da09099c41590", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/admin.py"}, "region": {"startLine": 106}}}]}, {"ruleId": "scanner-0a839dee5e963db7", "level": "error", "message": {"text": "FastAPI PUT `update_item` without auth dependency \u2014 backend/app/routers/admin.py:141"}, "properties": {"repobilityId": "3ed6b530112e4ea4", "scanner": "scanner-primary", "fingerprint": "0a839dee5e963db7", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/admin.py"}, "region": {"startLine": 141}}}]}, {"ruleId": "scanner-0f7b86dd59fdc7d1", "level": "error", "message": {"text": "FastAPI DELETE `delete_item` without auth dependency \u2014 backend/app/routers/admin.py:164"}, "properties": {"repobilityId": "a4696eddf55273e8", "scanner": "scanner-primary", "fingerprint": "0f7b86dd59fdc7d1", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/admin.py"}, "region": {"startLine": 164}}}]}, {"ruleId": "scanner-08442b1670edde7d", "level": "error", "message": {"text": "FastAPI POST `publish_item` without auth dependency \u2014 backend/app/routers/admin.py:175"}, "properties": {"repobilityId": "d4f2914b797a74ba", "scanner": "scanner-primary", "fingerprint": "08442b1670edde7d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/admin.py"}, "region": {"startLine": 175}}}]}, {"ruleId": "scanner-a30aafa90196ad61", "level": "error", "message": {"text": "FastAPI POST `unpublish_item` without auth dependency \u2014 backend/app/routers/admin.py:190"}, "properties": {"repobilityId": "8fb05b8f748087db", "scanner": "scanner-primary", "fingerprint": "a30aafa90196ad61", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/admin.py"}, "region": {"startLine": 190}}}]}, {"ruleId": "scanner-ce416ebd8c75750a", "level": "error", "message": {"text": "FastAPI POST `schedule_item` without auth dependency \u2014 backend/app/routers/admin.py:204"}, "properties": {"repobilityId": "4e4f87819de08e6f", "scanner": "scanner-primary", "fingerprint": "ce416ebd8c75750a", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/admin.py"}, "region": {"startLine": 204}}}]}, {"ruleId": "scanner-fd1b92c6628a0714", "level": "error", "message": {"text": "FastAPI POST `duplicate_item` without auth dependency \u2014 backend/app/routers/admin.py:219"}, "properties": {"repobilityId": "43cdc73536cb08d6", "scanner": "scanner-primary", "fingerprint": "fd1b92c6628a0714", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/admin.py"}, "region": {"startLine": 219}}}]}, {"ruleId": "scanner-24479f5b08ed3c10", "level": "error", "message": {"text": "FastAPI POST `generate` without auth dependency \u2014 backend/app/routers/ai.py:115"}, "properties": {"repobilityId": "01bb1a67c5fc660f", "scanner": "scanner-primary", "fingerprint": "24479f5b08ed3c10", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/ai.py"}, "region": {"startLine": 115}}}]}, {"ruleId": "scanner-a170037e7223f926", "level": "error", "message": {"text": "FastAPI POST `upload_file` without auth dependency \u2014 backend/app/routers/uploads.py:15"}, "properties": {"repobilityId": "e55c11d22d889be5", "scanner": "scanner-primary", "fingerprint": "a170037e7223f926", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/uploads.py"}, "region": {"startLine": 15}}}]}, {"ruleId": "scanner-6899617926c07bc8", "level": "error", "message": {"text": "FastAPI PUT `update_profile` without auth dependency \u2014 backend/app/routers/settings.py:43"}, "properties": {"repobilityId": "29b43aab93f9daa1", "scanner": "scanner-primary", "fingerprint": "6899617926c07bc8", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/settings.py"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-353466d8828ccf92", "level": "error", "message": {"text": "FastAPI POST `create_user` without auth dependency \u2014 backend/app/routers/settings.py:114"}, "properties": {"repobilityId": "608965c3745440fb", "scanner": "scanner-primary", "fingerprint": "353466d8828ccf92", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/settings.py"}, "region": {"startLine": 114}}}]}, {"ruleId": "scanner-dd4abc6cde023c42", "level": "error", "message": {"text": "FastAPI PUT `update_user` without auth dependency \u2014 backend/app/routers/settings.py:126"}, "properties": {"repobilityId": "03ef3cb6b5edeb84", "scanner": "scanner-primary", "fingerprint": "dd4abc6cde023c42", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/settings.py"}, "region": {"startLine": 126}}}]}, {"ruleId": "scanner-330d9a2e533e1836", "level": "error", "message": {"text": "FastAPI DELETE `delete_user` without auth dependency \u2014 backend/app/routers/settings.py:146"}, "properties": {"repobilityId": "ec8e142c878fcb12", "scanner": "scanner-primary", "fingerprint": "330d9a2e533e1836", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/settings.py"}, "region": {"startLine": 146}}}]}, {"ruleId": "scanner-d0ebd0c07488388a", "level": "error", "message": {"text": "FastAPI DELETE `delete_media` without auth dependency \u2014 backend/app/routers/media.py:79"}, "properties": {"repobilityId": "de429d543acfff97", "scanner": "scanner-primary", "fingerprint": "d0ebd0c07488388a", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routers/media.py"}, "region": {"startLine": 79}}}]}, {"ruleId": "scanner-6c70f486f1a98699", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/login (frontend/src/lib/api.ts:205)"}, "properties": {"repobilityId": "592d9819ac067692", "scanner": "scanner-primary", "fingerprint": "6c70f486f1a98699", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-8f6ffb76495255fd", "level": "error", "message": {"text": "Dangling fetch: GET /api/auth/me (frontend/src/lib/api.ts:209)"}, "properties": {"repobilityId": "e056843a07c8c0bd", "scanner": "scanner-primary", "fingerprint": "8f6ffb76495255fd", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9e06e06f57cafd9f", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/${module}?${qs} (frontend/src/lib/api.ts:219)"}, "properties": {"repobilityId": "82b1fa8577063d57", "scanner": "scanner-primary", "fingerprint": "9e06e06f57cafd9f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b3b2eee3420bb6db", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/${module}/stats (frontend/src/lib/api.ts:221)"}, "properties": {"repobilityId": "852d98e190fbf563", "scanner": "scanner-primary", "fingerprint": "b3b2eee3420bb6db", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-759c22ca91972cbd", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/stats (frontend/src/lib/api.ts:222)"}, "properties": {"repobilityId": "75485b8f887b8412", "scanner": "scanner-primary", "fingerprint": "759c22ca91972cbd", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-0305fd17583ec2ed", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/${module}/${id} (frontend/src/lib/api.ts:223)"}, "properties": {"repobilityId": "cbb3d86ffcad9c4c", "scanner": "scanner-primary", "fingerprint": "0305fd17583ec2ed", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f0dbbf2b8ff409b4", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/${module} (frontend/src/lib/api.ts:225)"}, "properties": {"repobilityId": "f55ba9c41d0edf6d", "scanner": "scanner-primary", "fingerprint": "f0dbbf2b8ff409b4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-6f86165486f3d612", "level": "error", "message": {"text": "Dangling fetch: PUT /api/admin/${module}/${id} (frontend/src/lib/api.ts:227)"}, "properties": {"repobilityId": "145dda0f84135347", "scanner": "scanner-primary", "fingerprint": "6f86165486f3d612", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c03a912aaf24fc3e", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/admin/${module}/${id} (frontend/src/lib/api.ts:229)"}, "properties": {"repobilityId": "8f6000a932f46c3d", "scanner": "scanner-primary", "fingerprint": "c03a912aaf24fc3e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-1a5a0d418478cfc7", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/publish (frontend/src/lib/api.ts:231)"}, "properties": {"repobilityId": "d7c89979ff6c94ee", "scanner": "scanner-primary", "fingerprint": "1a5a0d418478cfc7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9f207ba86a5fb7fe", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/unpublish (frontend/src/lib/api.ts:233)"}, "properties": {"repobilityId": "9d72442cec173564", "scanner": "scanner-primary", "fingerprint": "9f207ba86a5fb7fe", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2c5c8bb5d9253daa", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/schedule (frontend/src/lib/api.ts:235)"}, "properties": {"repobilityId": "de7c92df002c07a7", "scanner": "scanner-primary", "fingerprint": "2c5c8bb5d9253daa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-113aea2d96966ada", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/${module}/${id}/duplicate (frontend/src/lib/api.ts:240)"}, "properties": {"repobilityId": "adf40113a67772d7", "scanner": "scanner-primary", "fingerprint": "113aea2d96966ada", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-180aab69324063e7", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/media?${qs} (frontend/src/lib/api.ts:264)"}, "properties": {"repobilityId": "d214f1131393376a", "scanner": "scanner-primary", "fingerprint": "180aab69324063e7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5238a2496ddd78de", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/admin/media/${encodeURIComponent(name)} (frontend/src/lib/api.ts:267)"}, "properties": {"repobilityId": "7e97016621992166", "scanner": "scanner-primary", "fingerprint": "5238a2496ddd78de", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-66d6f82ec792ebc8", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/settings/profile (frontend/src/lib/api.ts:271)"}, "properties": {"repobilityId": "f8ac62a5a38bca3d", "scanner": "scanner-primary", "fingerprint": "66d6f82ec792ebc8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-4eb96adee894ef2f", "level": "error", "message": {"text": "Dangling fetch: PUT /api/admin/settings/profile (frontend/src/lib/api.ts:273)"}, "properties": {"repobilityId": "6a7fd6743b15817a", "scanner": "scanner-primary", "fingerprint": "4eb96adee894ef2f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a22f92d53d2e9618", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/settings/users (frontend/src/lib/api.ts:274)"}, "properties": {"repobilityId": "9805c17d8d847156", "scanner": "scanner-primary", "fingerprint": "a22f92d53d2e9618", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c3f645a1c900a12b", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/settings/users (frontend/src/lib/api.ts:276)"}, "properties": {"repobilityId": "01a1490c7a017672", "scanner": "scanner-primary", "fingerprint": "c3f645a1c900a12b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-59c955c9cc9b595f", "level": "error", "message": {"text": "Dangling fetch: PUT /api/admin/settings/users/${id} (frontend/src/lib/api.ts:278)"}, "properties": {"repobilityId": "36bf2ea4b2254c34", "scanner": "scanner-primary", "fingerprint": "59c955c9cc9b595f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-e9b4ad8e8878dc00", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/admin/settings/users/${id} (frontend/src/lib/api.ts:280)"}, "properties": {"repobilityId": "15a591fd99a773a1", "scanner": "scanner-primary", "fingerprint": "e9b4ad8e8878dc00", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-78744caa68e8fcb7", "level": "error", "message": {"text": "Dangling fetch: POST /api/ai/generate (frontend/src/lib/api.ts:301)"}, "properties": {"repobilityId": "ed829f9a3986bb42", "scanner": "scanner-primary", "fingerprint": "78744caa68e8fcb7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-e2e5c4e1d6ca0052", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/knowledge (frontend/src/lib/api.ts:314)"}, "properties": {"repobilityId": "9a1967d51c191a18", "scanner": "scanner-primary", "fingerprint": "e2e5c4e1d6ca0052", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9877a15909925026", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/knowledge/${id} (frontend/src/lib/api.ts:315)"}, "properties": {"repobilityId": "710793134e11a2bd", "scanner": "scanner-primary", "fingerprint": "9877a15909925026", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5d32fb5a2588b912", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/knowledge (frontend/src/lib/api.ts:319)"}, "properties": {"repobilityId": "a7fd4364d9ed0973", "scanner": "scanner-primary", "fingerprint": "5d32fb5a2588b912", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9a848bf424624d60", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/knowledge/${id}/reanalyze (frontend/src/lib/api.ts:322)"}, "properties": {"repobilityId": "013b735e6dd42f7c", "scanner": "scanner-primary", "fingerprint": "9a848bf424624d60", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-30a38cc8a3e7a393", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/admin/knowledge/${id} (frontend/src/lib/api.ts:323)"}, "properties": {"repobilityId": "6aab09969b9cf485", "scanner": "scanner-primary", "fingerprint": "30a38cc8a3e7a393", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-4756b4c4da7d2088", "level": "note", "message": {"text": "Unused endpoint: GET /api/health"}, "properties": {"repobilityId": "414de3a0f9ad89dd", "scanner": "scanner-primary", "fingerprint": "4756b4c4da7d2088", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "05e4738b080c4147", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "4181fbe2cba6c3c2", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-14ca9451df2c5dcc", "level": "note", "message": {"text": "Unused endpoint: GET /{doc_id}"}, "properties": {"repobilityId": "d1474caf35ca2d7e", "scanner": "scanner-primary", "fingerprint": "14ca9451df2c5dcc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d44c8014dccb3dfe", "level": "note", "message": {"text": "Unused endpoint: POST /{doc_id}/reanalyze"}, "properties": {"repobilityId": "70f6ec80c4a5db5f", "scanner": "scanner-primary", "fingerprint": "d44c8014dccb3dfe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e96576fde6078449", "level": "note", "message": {"text": "Unused endpoint: DELETE /{doc_id}"}, "properties": {"repobilityId": "05c2cdd348273454", "scanner": "scanner-primary", "fingerprint": "e96576fde6078449", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "4f445a0b56cc60f5", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd1dc91abf32142d", "level": "note", "message": {"text": "Unused endpoint: GET /me"}, "properties": {"repobilityId": "d59abcc5b893707a", "scanner": "scanner-primary", "fingerprint": "fd1dc91abf32142d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9374ee49bcfb4df1", "level": "note", "message": {"text": "Unused endpoint: GET /{module}"}, "properties": {"repobilityId": "53b204943309a36b", "scanner": "scanner-primary", "fingerprint": "9374ee49bcfb4df1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c1b6ac24269451bc", "level": "note", "message": {"text": "Unused endpoint: GET /resources/{item_id}/download"}, "properties": {"repobilityId": "464a50dfd10c92f3", "scanner": "scanner-primary", "fingerprint": "c1b6ac24269451bc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd8dc4599ec52a08", "level": "note", "message": {"text": "Unused endpoint: GET /stats"}, "properties": {"repobilityId": "9ae4c770acf18979", "scanner": "scanner-primary", "fingerprint": "cd8dc4599ec52a08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6724ec101bfc8d1c", "level": "note", "message": {"text": "Unused endpoint: GET /{module}/stats"}, "properties": {"repobilityId": "8314d400e3e9250f", "scanner": "scanner-primary", "fingerprint": "6724ec101bfc8d1c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c68b9937118c740b", "level": "note", "message": {"text": "Unused endpoint: POST /{module}"}, "properties": {"repobilityId": "ca0675e10e05fb36", "scanner": "scanner-primary", "fingerprint": "c68b9937118c740b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bad369a46673aecc", "level": "note", "message": {"text": "Unused endpoint: GET /{module}/{item_id}"}, "properties": {"repobilityId": "7a5fe2da6316c4b2", "scanner": "scanner-primary", "fingerprint": "bad369a46673aecc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-548ac29848a68435", "level": "note", "message": {"text": "Unused endpoint: PUT /{module}/{item_id}"}, "properties": {"repobilityId": "7b416a5eb3a687b8", "scanner": "scanner-primary", "fingerprint": "548ac29848a68435", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5a7ee4b25b442fa4", "level": "note", "message": {"text": "Unused endpoint: DELETE /{module}/{item_id}"}, "properties": {"repobilityId": "ccc4804a3523ba62", "scanner": "scanner-primary", "fingerprint": "5a7ee4b25b442fa4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-62dcfb1ed34a2f74", "level": "note", "message": {"text": "Unused endpoint: POST /{module}/{item_id}/publish"}, "properties": {"repobilityId": "e411a27b1c239b5f", "scanner": "scanner-primary", "fingerprint": "62dcfb1ed34a2f74", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2c7954c2724edf38", "level": "note", "message": {"text": "Unused endpoint: POST /{module}/{item_id}/unpublish"}, "properties": {"repobilityId": "20bb1952d6d678f7", "scanner": "scanner-primary", "fingerprint": "2c7954c2724edf38", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3dba6f37e17e7fe6", "level": "note", "message": {"text": "Unused endpoint: POST /{module}/{item_id}/schedule"}, "properties": {"repobilityId": "4c353470b40c4a58", "scanner": "scanner-primary", "fingerprint": "3dba6f37e17e7fe6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-611922f26606c396", "level": "note", "message": {"text": "Unused endpoint: POST /{module}/{item_id}/duplicate"}, "properties": {"repobilityId": "986540195e212eff", "scanner": "scanner-primary", "fingerprint": "611922f26606c396", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-970eb92d6ec2bfaa", "level": "note", "message": {"text": "Unused endpoint: POST /generate"}, "properties": {"repobilityId": "fe37c3e8099bdefa", "scanner": "scanner-primary", "fingerprint": "970eb92d6ec2bfaa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2595b39638e5c045", "level": "note", "message": {"text": "Unused endpoint: GET /profile"}, "properties": {"repobilityId": "89ad6cc172756033", "scanner": "scanner-primary", "fingerprint": "2595b39638e5c045", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-911492554a68d0c1", "level": "note", "message": {"text": "Unused endpoint: PUT /profile"}, "properties": {"repobilityId": "25c0574d7a0430d4", "scanner": "scanner-primary", "fingerprint": "911492554a68d0c1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-841e50bf821e4158", "level": "note", "message": {"text": "Unused endpoint: GET /users"}, "properties": {"repobilityId": "7f624387d7ec0c8b", "scanner": "scanner-primary", "fingerprint": "841e50bf821e4158", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1bca8100a44f7f25", "level": "note", "message": {"text": "Unused endpoint: POST /users"}, "properties": {"repobilityId": "c49e65cd0e861755", "scanner": "scanner-primary", "fingerprint": "1bca8100a44f7f25", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d07acca647618197", "level": "note", "message": {"text": "Unused endpoint: PUT /users/{user_id}"}, "properties": {"repobilityId": "63d7d5ad674c75dc", "scanner": "scanner-primary", "fingerprint": "d07acca647618197", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fecd99fa2d3d6078", "level": "note", "message": {"text": "Unused endpoint: DELETE /users/{user_id}"}, "properties": {"repobilityId": "48c5c3bfc7dd8c92", "scanner": "scanner-primary", "fingerprint": "fecd99fa2d3d6078", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c562c83979dce866", "level": "note", "message": {"text": "Unused endpoint: DELETE /{name}"}, "properties": {"repobilityId": "fa434e360e049b37", "scanner": "scanner-primary", "fingerprint": "c562c83979dce866", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}