{"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": "foundry_assumption_check", "name": "Foundry mined assumption checks: watcharapon7574/rsec6hub", "shortDescription": {"text": "Foundry mined assumption checks: watcharapon7574/rsec6hub"}, "fullDescription": {"text": "Comment chain pattern product: assumption_checks\nRepo: watcharapon7574/rsec6hub\nThread: watcharapon7574/rsec6hub#1\nOutcome: ambiguous_needs_more_evidence\nThread label: thread_has_human_issue_and_fix_context\nSource graph label: source_backed_multi_signal_graph\nReasons: source_graph_has_real_artifacts, source_graph_has_verification_artifacts, repo_has_isolated_helicopter_views, link_quality_weak_supervision, high_risk_human_feedback_label\nChain evidence:\nIssue/PR evidence chain: watcharapon7574/rsec6hub#1\nRepo: watcharapon7574/rsec6hub\nThread label: thread_has_human_issue_and_fix_context\nOutcome: ambiguous_needs_more_evidence\nComment count: 2\nLinked commit count: 2\nLinked CI commit count: 0\nLinked CI labels: {}\nChanged file count: 32\nLabels: {'security_auth_secret': 1, 'deployment_env_gap': 1}\nPolarities: {'bad': 2}\nChanged file labels: {'source_or_other': 4, 'dependency_or_build': 2, 'ui_or_frontend': 13, 'test_or_ci': 4, 'schema_or_data': 9}\nExamples:\n[\n  {\n    \"id\": \"github-feedback-c"}, "properties": {"scanner": "foundry_dataset", "category": "practices", "severity": "medium", "confidence": 0.62, "cwe": "", "owasp": ""}}, {"id": "scanner-bead75b0f9233e05", "name": "No API endpoints detected", "shortDescription": {"text": "No API endpoints detected"}, "fullDescription": {"text": "The scanner did not find FastAPI/Flask/Express/NestJS/GraphQL/gRPC routes. If this repo exposes APIs, the framework may be unsupported."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "info", "confidence": 1.0}}, {"id": "scanner-658877ebaaacf0a8", "name": "Stray `console.log` in TS/JS \u2014 test-railway-stop.js:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 test-railway-stop.js:9"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-681d82b8f9f862c2", "name": "Stray `console.log` in TS/JS \u2014 check-railway-logs.js:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 check-railway-logs.js:9"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3410f1e73a51f2bf", "name": "Stray `console.log` in TS/JS \u2014 scripts/bump-sw-version.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/bump-sw-version.js:13"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5b31a520b75d3688", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/leave-telegram-notify/index.ts:358", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/leave-telegram-notify/index.ts:358"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-922dc14e24ead1e7", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/telegram-otp/index.ts:83", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/telegram-otp/index.ts:83"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-49d9aa2346a86177", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/grammar-check/index.ts:182", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/grammar-check/index.ts:182"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8392ac0baf04d908", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/leave-sign-notify/index.ts:301", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/leave-sign-notify/index.ts:301"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2acdfe51a0e9f6c4", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/verify-otp/index.ts:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/verify-otp/index.ts:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cb549abfa70e7340", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/telegram-notify/index.ts:391", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/telegram-notify/index.ts:391"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-adfb52df14ecbc79", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/railway-api/index.ts:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/railway-api/index.ts:26"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-46fe05e2103680ae", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/line-wrap/index.ts:143", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/line-wrap/index.ts:143"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bca5315273e73fca", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/sign-document/index.ts:31", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/sign-document/index.ts:31"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e5b3f01f9099244a", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/railway-scheduler/index.ts:82", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/railway-scheduler/index.ts:82"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b25b738f86f7b3cf", "name": "Stray `console.log` in TS/JS \u2014 public/sw.js:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 public/sw.js:28"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3d63e085e1e02c20", "name": "TODO/FIXME marker in shipping code \u2014 src/utils/pdfAnnotationUtils.ts:212", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/utils/pdfAnnotationUtils.ts:212"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-879018f12a20adc9", "name": "Stray `console.log` in TS/JS \u2014 src/utils/testRequestQueue.ts:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/utils/testRequestQueue.ts:23"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-87d7bf1d1e4ce1ac", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Payslip/PayslipCard.tsx:33", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Payslip/PayslipCard.tsx:33"}, "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-e90b9b6dad1d21b9", "name": "TODO/FIXME marker in shipping code \u2014 src/components/Auth/TelegramChatIdStep.tsx:47", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/components/Auth/TelegramChatIdStep.tsx:47"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0d3cbf9bc5cac36c", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Dashboard/CalendarWidget.tsx:250", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Dashboard/CalendarWidget.tsx:250"}, "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-2e608c290c010790", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Profile/SessionManagement.tsx:243", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Profile/SessionManagement.tsx:243"}, "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-b9effbdca5383e16", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Register/RegisterTable.tsx:568", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Register/RegisterTable.tsx:568"}, "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-070a2ccdcf7839d2", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:79", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:79"}, "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-d0da5a3ebf0b8c5b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrUploadCard.tsx:117", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrUploadCard.tsx:117"}, "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-e540ddbc5c146ef4", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrGoogleSearchBar.tsx:112", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrGoogleSearchBar.tsx:112"}, "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-fafca291ac333199", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrSearchResultCard.tsx:63", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrSearchResultCard.tsx:63"}, "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-486a101f17391e02", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrDocumentCard.tsx:125", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrDocumentCard.tsx:125"}, "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-fc668078a32119f2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/SavedGroupsList.tsx:181", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/SavedGroupsList.tsx:181"}, "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-f457fc5ac2207165", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/LocationCombobox.tsx:120", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/LocationCombobox.tsx:120"}, "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-0c2251d9fd3dbcfd", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/AssignedTasksList.tsx:392", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/AssignedTasksList.tsx:392"}, "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-839006d5d5d0c8e7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/RejectionCard.tsx:206", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/RejectionCard.tsx:206"}, "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-4701457557a51689", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/DocumentList.tsx:1435", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/DocumentList.tsx:1435"}, "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-e9397913e01250d8", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/MemoList.tsx:1091", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/MemoList.tsx:1091"}, "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-70ee17a9dd1d16f9", "name": "TODO/FIXME marker in shipping code \u2014 src/components/OfficialDocuments/MemoList.tsx:890", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/components/OfficialDocuments/MemoList.tsx:890"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0c761b958aa16a24", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/PDFViewer.tsx:657", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/PDFViewer.tsx:657"}, "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-0977858b24b8c5d7", "name": "Stray `console.log` in TS/JS \u2014 src/components/OfficialDocuments/PDFViewer.tsx:513", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/components/OfficialDocuments/PDFViewer.tsx:513"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9f678d117fad5884", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/OfficialDocuments/PDFViewer.tsx:712", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/OfficialDocuments/PDFViewer.tsx:712"}, "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-0697e6b0d749974e", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/AssignedDocumentsList.tsx:697", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/AssignedDocumentsList.tsx:697"}, "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-590a90b2179e15c0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/DocReceiveList.tsx:1264", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/DocReceiveList.tsx:1264"}, "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-1e3a73d0b6e2c067", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/Accordion.tsx:132", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/Accordion.tsx:132"}, "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-512722ef109138a7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Layout/APIMaintenanceBanner.tsx:263", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Layout/APIMaintenanceBanner.tsx:263"}, "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-25a6c84fb0e1a15f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Layout/TopBar.tsx:112", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Layout/TopBar.tsx:112"}, "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-10e34fc42345302a", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/MemoApproval/MemoApprovalPage.tsx:268", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/MemoApproval/MemoApprovalPage.tsx:268"}, "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-0a2374947d08d45f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Newsfeed/NewsfeedPostCard.tsx:163", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Newsfeed/NewsfeedPostCard.tsx:163"}, "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-598867ce60c6a194", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Newsfeed/NewsfeedReactions.tsx:238", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Newsfeed/NewsfeedReactions.tsx:238"}, "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-e905d80821757466", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/DocumentManage/Step3SignaturePositions.tsx:100", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/DocumentManage/Step3SignaturePositions.tsx:100"}, "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-dfee253459360e6d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/OcrSearchEmbedPage.tsx:137", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/OcrSearchEmbedPage.tsx:137"}, "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-fcd8e355c8162489", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/OcrUploadPage.tsx:171", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/OcrUploadPage.tsx:171"}, "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-43985a238a399db3", "name": "Stray `console.log` in TS/JS \u2014 src/pages/OfficialDocumentsPage.tsx:175", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/OfficialDocumentsPage.tsx:175"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a212fdef583a0d5c", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/Dashboard.tsx:190", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/Dashboard.tsx:190"}, "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-a63e4f81f16d72dd", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/AdminChatsPage.tsx:317", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/AdminChatsPage.tsx:317"}, "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-d2374bdc98328fd2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LeaveRequestsPage.tsx:1150", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LeaveRequestsPage.tsx:1150"}, "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-a92b01594361e27e", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/TelegramAssigneesPage.tsx:220", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/TelegramAssigneesPage.tsx:220"}, "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-0ac446565a717186", "name": "Stray `console.log` in TS/JS \u2014 src/pages/ApproveDocumentPage.tsx:810", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/ApproveDocumentPage.tsx:810"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1b4a4b4c23558a50", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/NewLeaveRequestPage.tsx:489", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/NewLeaveRequestPage.tsx:489"}, "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-f7552d5f232c7693", "name": "TODO/FIXME marker in shipping code \u2014 src/services/leaveService.ts:625", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/services/leaveService.ts:625"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d9036a2b37cf3ef1", "name": "Stray `console.log` in TS/JS \u2014 src/services/leaveService.ts:626", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/services/leaveService.ts:626"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9476b2e166db747f", "name": "TODO/FIXME marker in shipping code \u2014 src/services/approvalWorkflowService.test.ts:291", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/services/approvalWorkflowService.test.ts:291"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-41f721ad1df116df", "name": "TODO/FIXME marker in shipping code \u2014 src/services/officialDocumentService.ts:131", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/services/officialDocumentService.ts:131"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-dda1bac1b22d03a2", "name": "Stray `console.log` in TS/JS \u2014 railway-scheduler/test-railway-api.js:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 railway-scheduler/test-railway-api.js:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ca1ba0c0a8aa0764", "name": "Stray `console.log` in TS/JS \u2014 railway-scheduler/scheduler.js:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 railway-scheduler/scheduler.js:46"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e422d660847d2871", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-telegram-notify/index.ts:21", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-telegram-notify/index.ts:21"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ad6c32c531d60c4b", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/telegram-otp/index.ts:8", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/telegram-otp/index.ts:8"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f43d647b8e62ed8e", "name": "Insecure pattern 'private_key_in_repo' in supabase/functions/ocr-search/index.ts:34", "shortDescription": {"text": "Insecure pattern 'private_key_in_repo' in supabase/functions/ocr-search/index.ts:34"}, "fullDescription": {"text": "Found a known-risky pattern (private_key_in_repo). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-78aab84480ce484e", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/ocr-search/index.ts:6", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/ocr-search/index.ts:6"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3fa175e5fe50431e", "name": "Insecure pattern 'private_key_in_repo' in supabase/functions/grammar-check/index.ts:42", "shortDescription": {"text": "Insecure pattern 'private_key_in_repo' in supabase/functions/grammar-check/index.ts:42"}, "fullDescription": {"text": "Found a known-risky pattern (private_key_in_repo). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-3630ebc0efe99556", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/grammar-check/index.ts:8", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/grammar-check/index.ts:8"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-620a76ed6f736773", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-sign-notify/index.ts:17", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-sign-notify/index.ts:17"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9a7e58c978ef2962", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/verify-otp/index.ts:5", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/verify-otp/index.ts:5"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-063c8784207dcd4d", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-miniapp-auth/index.ts:23", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-miniapp-auth/index.ts:23"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d623677553e896c4", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/telegram-notify/index.ts:8", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/telegram-notify/index.ts:8"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-157f6279842de196", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/get-my-profile/index.ts:5", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/get-my-profile/index.ts:5"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8c77a817734b7798", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/crop-payslip/index.ts:5", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/crop-payslip/index.ts:5"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a8da91e3078418f6", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/railway-api/index.ts:9", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/railway-api/index.ts:9"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1f67ef63bb791ccc", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/get-task-assignees/index.ts:9", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/get-task-assignees/index.ts:9"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7eef70e6a82fbdd1", "name": "Insecure pattern 'private_key_in_repo' in supabase/functions/line-wrap/index.ts:27", "shortDescription": {"text": "Insecure pattern 'private_key_in_repo' in supabase/functions/line-wrap/index.ts:27"}, "fullDescription": {"text": "Found a known-risky pattern (private_key_in_repo). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-93bf1080010943e5", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/line-wrap/index.ts:8", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/line-wrap/index.ts:8"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-043a171799541404", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/health-check/index.ts:12", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/health-check/index.ts:12"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e98288eaa4f5f7b8", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/upload-report-image/index.ts:13", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/upload-report-image/index.ts:13"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cce4a50b4515495f", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/google-calendar/index.ts:6", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/google-calendar/index.ts:6"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-848b35df7a0d636d", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/download-document/index.ts:5", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/download-document/index.ts:5"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-08034dd91f6cd710", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/sign-document/index.ts:7", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/sign-document/index.ts:7"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e3b7085febd0cd92", "name": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:79", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:79"}, "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-d37dcd5c49343635", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/DocumentList.tsx:907", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/DocumentList.tsx:907"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4b858f656eea101b", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/MemoList.tsx:732", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/MemoList.tsx:732"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8cbf796c53a57f41", "name": "Insecure pattern 'dangerous_innerhtml' in src/components/OfficialDocuments/PDFViewer.tsx:712", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/OfficialDocuments/PDFViewer.tsx:712"}, "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-e2f68444991bc040", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/PendingDocumentCard.tsx:595", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/PendingDocumentCard.tsx:595"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3dc48ab23b00f7d2", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/PersonalDocumentList.tsx:605", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/PersonalDocumentList.tsx:605"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1835558685d5776a", "name": "Insecure pattern 'dangerous_innerhtml' in src/components/MemoApproval/MemoApprovalPage.tsx:268", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/MemoApproval/MemoApprovalPage.tsx:268"}, "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-269f247828213891", "name": "Insecure pattern 'local_storage_auth_token' in src/services/sessionService.ts:65", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in src/services/sessionService.ts:65"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-b11381257fad5e1b", "name": "Very large file: src/integrations/supabase/types.ts (3898 lines)", "shortDescription": {"text": "Very large file: src/integrations/supabase/types.ts (3898 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-940a63b02cab4679", "name": "Very large file: src/components/OfficialDocuments/DocumentList.tsx (1524 lines)", "shortDescription": {"text": "Very large file: src/components/OfficialDocuments/DocumentList.tsx (1524 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-94463c4933f06645", "name": "Very large file: src/components/OfficialDocuments/MemoList.tsx (1180 lines)", "shortDescription": {"text": "Very large file: src/components/OfficialDocuments/MemoList.tsx (1180 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-469fb9d42a310926", "name": "Very large file: src/components/OfficialDocuments/PDFViewer.tsx (1337 lines)", "shortDescription": {"text": "Very large file: src/components/OfficialDocuments/PDFViewer.tsx (1337 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e4e9d0084e5fd978", "name": "Very large file: src/components/OfficialDocuments/AssignedDocumentsList.tsx (1163 lines)", "shortDescription": {"text": "Very large file: src/components/OfficialDocuments/AssignedDocumentsList.tsx (1163 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-98736d93eb3c6634", "name": "Very large file: src/components/OfficialDocuments/PendingDocumentCard.tsx (905 lines)", "shortDescription": {"text": "Very large file: src/components/OfficialDocuments/PendingDocumentCard.tsx (905 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-979f6a497ee0e000", "name": "Very large file: src/components/OfficialDocuments/DocReceiveList.tsx (1352 lines)", "shortDescription": {"text": "Very large file: src/components/OfficialDocuments/DocReceiveList.tsx (1352 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8065588491a61297", "name": "Very large file: src/pages/CreateReportMemoPage.tsx (1683 lines)", "shortDescription": {"text": "Very large file: src/pages/CreateReportMemoPage.tsx (1683 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1dcb21d083ec4763", "name": "Very large file: src/pages/CreateMemoPage.tsx (1950 lines)", "shortDescription": {"text": "Very large file: src/pages/CreateMemoPage.tsx (1950 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3bb54e62baf8bf51", "name": "Very large file: src/pages/DocumentManagePage.tsx (1693 lines)", "shortDescription": {"text": "Very large file: src/pages/DocumentManagePage.tsx (1693 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-68690830bbc4e489", "name": "Very large file: src/pages/LeaveRequestsPage.tsx (3488 lines)", "shortDescription": {"text": "Very large file: src/pages/LeaveRequestsPage.tsx (3488 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fed2ae2cc2e58a2b", "name": "Very large file: src/pages/ApproveDocumentPage.tsx (1506 lines)", "shortDescription": {"text": "Very large file: src/pages/ApproveDocumentPage.tsx (1506 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2a938dfcf2cfa44e", "name": "Very large file: src/pages/ManageReportMemoPage.tsx (1475 lines)", "shortDescription": {"text": "Very large file: src/pages/ManageReportMemoPage.tsx (1475 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "30 test file(s) for 363 source file(s) (ratio 0.08). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 334 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 227 placeholder/mock markers across 82 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e1d6bb11aa93adf0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 test-railway-stop.js:75", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 test-railway-stop.js:75"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d50cb8929b29eace", "name": "Commented-code block (5 lines) in supabase/functions/leave-telegram-notify/index.ts:4", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/leave-telegram-notify/index.ts:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-20554304ae178447", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/telegram-otp/index.ts:729", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/telegram-otp/index.ts:729"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-96c24d69eff8bb5b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/ocr-search/index.ts:61", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/ocr-search/index.ts:61"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5b373a545d6863b8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/grammar-check/index.ts:78", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/grammar-check/index.ts:78"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-13d0421e4906a89a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/leave-sign-notify/index.ts:81", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/leave-sign-notify/index.ts:81"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ef4b6599126b0040", "name": "Commented-code block (5 lines) in supabase/functions/telegram-notify/index.ts:343", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/telegram-notify/index.ts:343"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-090b75d8e4cf0c7c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/crop-payslip/index.ts:29", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/crop-payslip/index.ts:29"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1819b89457c21066", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/railway-api/index.ts:69", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/railway-api/index.ts:69"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-976ab98438ee9a89", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/line-wrap/index.ts:63", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/line-wrap/index.ts:63"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e52e04bcfe8587e3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/google-calendar/index.ts:77", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/google-calendar/index.ts:77"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f2aa6a580e339cab", "name": "Legacy-named symbol `add_signature_v2` in supabase/functions/sign-document/index.ts:72", "shortDescription": {"text": "Legacy-named symbol `add_signature_v2` in supabase/functions/sign-document/index.ts:72"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f148b0b697ee5969", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/sign-document/index.ts:50", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/sign-document/index.ts:50"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-06b8dcd1abab8117", "name": "Legacy-named symbol `data_std_admin_add_v2` in src/integrations/supabase/types.ts:3015", "shortDescription": {"text": "Legacy-named symbol `data_std_admin_add_v2` in src/integrations/supabase/types.ts:3015"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8d47b2d3d07d88bd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/pdfAnnotationUtils.ts:86", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/pdfAnnotationUtils.ts:86"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8c10a96bcdb3efb0", "name": "Commented-code block (6 lines) in src/utils/railwayFetch.ts:6", "shortDescription": {"text": "Commented-code block (6 lines) in src/utils/railwayFetch.ts:6"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ba12ad339417689e", "name": "Commented-code block (6 lines) in src/components/Dashboard/StudentAttendanceWidget.tsx:192", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/Dashboard/StudentAttendanceWidget.tsx:192"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3a16ceceac8e88e9", "name": "Commented-code block (5 lines) in src/components/OfficialDocuments/MemoList.tsx:200", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/OfficialDocuments/MemoList.tsx:200"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-1cad8d330325b41f", "name": "Commented-code block (15 lines) in src/components/OfficialDocuments/PDFViewer.tsx:574", "shortDescription": {"text": "Commented-code block (15 lines) in src/components/OfficialDocuments/PDFViewer.tsx:574"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b0ab7116de79d5cf", "name": "Legacy-named symbol `add_signature_v2` in src/pages/PDFDocumentManagePage.tsx:429", "shortDescription": {"text": "Legacy-named symbol `add_signature_v2` in src/pages/PDFDocumentManagePage.tsx:429"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-572e290ccd9ec78b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/PDFDocumentManagePage.tsx:362", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/PDFDocumentManagePage.tsx:362"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7d5b121de94e5efd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateReportMemoPage.tsx:754", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateReportMemoPage.tsx:754"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-36481b2be9d32da9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateMemoPage.tsx:706", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateMemoPage.tsx:706"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e8546d9f42f88587", "name": "Commented-code block (6 lines) in src/pages/OfficialDocumentsPage.tsx:172", "shortDescription": {"text": "Commented-code block (6 lines) in src/pages/OfficialDocumentsPage.tsx:172"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-45a623a0ce02130b", "name": "Legacy-named symbol `add_signature_v2` in src/pages/DocumentManagePage.tsx:1234", "shortDescription": {"text": "Legacy-named symbol `add_signature_v2` in src/pages/DocumentManagePage.tsx:1234"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1a2d938c6385ef6c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/DocumentManagePage.tsx:1186", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/DocumentManagePage.tsx:1186"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-692fa5b51a0e9818", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/ApproveDocumentPage.tsx:596", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/ApproveDocumentPage.tsx:596"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-bad4b0e356bcb459", "name": "Legacy-named symbol `add_signature_v2` in src/pages/ManageReportMemoPage.tsx:1092", "shortDescription": {"text": "Legacy-named symbol `add_signature_v2` in src/pages/ManageReportMemoPage.tsx:1092"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-660ee21ed22dcd75", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateDocReceivePage.tsx:348", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateDocReceivePage.tsx:348"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-872e85446403743e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/PDFReceiveManagePage.tsx:233", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/PDFReceiveManagePage.tsx:233"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-779e55f1a32bf9d0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useGoogleCalendar.ts:42", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useGoogleCalendar.ts:42"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e81116e6be4c087f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/pdfSignatureChainService.ts:25", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/pdfSignatureChainService.ts:25"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-915c082bbf248480", "name": "Commented-code block (7 lines) in src/services/taskAssignmentService.ts:358", "shortDescription": {"text": "Commented-code block (7 lines) in src/services/taskAssignmentService.ts:358"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c82f7f0343cce5d0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/memoService.ts:466", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/memoService.ts:466"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d26c89e70f723f12", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/memoManageAPIcall.ts:46", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/memoManageAPIcall.ts:46"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-f0c626f1b959ef76", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/auth/otp.ts:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/auth/otp.ts:18"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ff040e09dbe77ff3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/auth/signIn.ts:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/auth/signIn.ts:21"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-75602d9fe81c5ec9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/test-railway-api.js:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/test-railway-api.js:35"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-bba6d591996478fe", "name": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/scheduler.js:27", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/scheduler.js:27"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d2606f35e23ecdfd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/railway-mcp-server.js:151", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/railway-mcp-server.js:151"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9f42fb5925bf28fe", "name": "Frontend route `/embed/search` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/embed/search` has no Link/navigate to it \u2014 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-c783d56f85f7328f", "name": "Frontend route `/telegram-assignees/:documentId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/telegram-assignees/:documentId` has no Link/navigate to it \u2014 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-b71f0c1dc82aeced", "name": "Frontend route `/telegram-assignees` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/telegram-assignees` has no Link/navigate to it \u2014 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-ce473e102f66da9b", "name": "Frontend route `/tg/leave/:id` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/tg/leave/:id` has no Link/navigate to it \u2014 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-790a64df598c85cc", "name": "Frontend route `/tg/leave` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/tg/leave` has no Link/navigate to it \u2014 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-2c4185282207354b", "name": "Frontend route `/leave-requests` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/leave-requests` has no Link/navigate to it \u2014 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-0dcad0da8c32cfc5", "name": "Frontend route `/daily-reports` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/daily-reports` has no Link/navigate to it \u2014 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-2ce0297f45f85fe8", "name": "Frontend route `/report-memo/:taskId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/report-memo/:taskId` has no Link/navigate to it \u2014 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-b51420c111297578", "name": "Frontend route `/create-report-memo` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/create-report-memo` has no Link/navigate to it \u2014 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-d717532a9b135eaf", "name": "Frontend route `/manage-report-memo/:memoId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/manage-report-memo/:memoId` has no Link/navigate to it \u2014 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-d6fd69665f3109f3", "name": "Frontend route `/document-manage/:memoId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/document-manage/:memoId` has no Link/navigate to it \u2014 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-75a811335b063926", "name": "Frontend route `/pdf-document-manage/:memoId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/pdf-document-manage/:memoId` has no Link/navigate to it \u2014 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-9d0fe1d02420f8c0", "name": "Frontend route `/pdf-receive-manage/:memoId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/pdf-receive-manage/:memoId` has no Link/navigate to it \u2014 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-30133e443375f420", "name": "Frontend route `/edit-doc-receive/:memoId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/edit-doc-receive/:memoId` has no Link/navigate to it \u2014 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-cce3045d3b77e620", "name": "Frontend route `/approve-document/:memoId` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/approve-document/:memoId` has no Link/navigate to it \u2014 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-613d4f1b7145e006", "name": "Frontend route `/task-assignment` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/task-assignment` has no Link/navigate to it \u2014 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}}]}}, "automationDetails": {"id": "repobility/22553"}, "properties": {"repository": "watcharapon7574/rsec6hub", "repoUrl": "https://github.com/watcharapon7574/rsec6hub", "branch": "main"}, "results": [{"ruleId": "foundry_assumption_check", "level": "warning", "message": {"text": "Foundry mined assumption checks: watcharapon7574/rsec6hub"}, "properties": {"repobilityId": 439855, "scanner": "foundry_dataset", "fingerprint": "7948b9d07b34b149910eda0eda6e81aff3c7fc92c662caa2a2ed07d93f5806f7", "category": "practices", "severity": "medium", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Imported from mined Foundry/Fable5 evidence with real GitHub/source provenance. Review source_id before acting.", "evidence": {"meta": {"kind": "comment_chain_pattern_product", "source": "comment_chain_pattern_miner", "product": "assumption_checks", "synthetic": false, "thread_key": "watcharapon7574/rsec6hub#1", "human_labels": ["dependency_or_build", "deployment_env_gap", "schema_or_data", "security_auth_secret", "source_or_other", "test_or_ci", "ui_or_frontend"], "issue_number": "1", "thread_label": "thread_has_human_issue_and_fix_context", "outcome_label": "ambiguous_needs_more_evidence", "source_backed": true, "max_confidence": 0.708, "repo_full_name": "watcharapon7574/rsec6hub", "training_usage": "weak_supervision", "confidence_tier": "weak_supervision", "source_chain_id": "evidence-chain-issue_chain-ed4b1f9107a7ee6c", "helicopter_views": {"schemas": 2}, "artifact_families": {"ci": 1, "docs": 1, "designs": 3, "schemas": 1}, "source_chain_kind": "issue_chain", "changed_file_count": 32, "source_graph_label": "source_backed_multi_signal_graph", "changed_file_labels": {"test_or_ci": 4, "schema_or_data": 9, "ui_or_frontend": 13, "source_or_other": 4, "dependency_or_build": 2}, "linked_commit_count": 2, "helicopter_view_count": 2, "source_artifact_count": 6, "classification_reasons": ["source_graph_has_real_artifacts", "source_graph_has_verification_artifacts", "repo_has_isolated_helicopter_views", "link_quality_weak_supervision", "high_risk_human_feedback_label"], "linked_ci_commit_count": 0, "verification_artifact_count": 2, "design_schema_api_artifact_count": 4}, "text": "Comment chain pattern product: assumption_checks\nRepo: watcharapon7574/rsec6hub\nThread: watcharapon7574/rsec6hub#1\nOutcome: ambiguous_needs_more_evidence\nThread label: thread_has_human_issue_and_fix_context\nSource graph label: source_backed_multi_signal_graph\nReasons: source_graph_has_real_artifacts, source_graph_has_verification_artifacts, repo_has_isolated_helicopter_views, link_quality_weak_supervision, high_risk_human_feedback_label\nChain evidence:\nIssue/PR evidence chain: watcharapon7574/rsec6hub#1\nRepo: watcharapon7574/rsec6hub\nThread label: thread_has_human_issue_and_fix_context\nOutcome: ambiguous_needs_more_evidence\nComment count: 2\nLinked commit count: 2\nLinked CI commit count: 0\nLinked CI labels: {}\nChanged file count: 32\nLabels: {'security_auth_secret': 1, 'deployment_env_gap': 1}\nPolarities: {'bad': 2}\nChanged file labels: {'source_or_other': 4, 'dependency_or_build': 2, 'ui_or_frontend': 13, 'test_or_ci': 4, 'schema_or_data': 9}\nExamples:\n[\n  {\n    \"id\": \"github-feedback-comment-2d010d894c291abc\",\n    \"kind\": \"pull_request_body\",\n    \"label\": \"security_auth_secret\",\n    \"polarity\": \"bad\",\n    \"url\": \"https://github.com/watcharapon7574/rsec6hub/pull/1\",\n    \"text\": \"GitHub feedback: security_auth_secret\\nPolarity: bad\\nKind: pull_request_body\\nRepo: watcharapon7574/rsec6hub\\nAuthor: watcharapon7574 (User)\\nURL: https://github.com/watcharapon7574/rsec6hub/pull/1\\nTitle: feat(lunch): \u0e2b\u0e19\u0e31\u0e07\u0e2a\u0e37\u0e2d\u0e25\u0e49\u0e32\u0e07\u0e2b\u0e19\u0e35\u0e49\u0e2d\u0e32\u0e2b\u0e32\u0e23\u0e01\u0e25\u0e32\u0e07\u0e27\u0e31\u0e19 + \u0e23\u0e30\u0e1a\u0e1a\u0e01\u0e23\u0e2d\u0e01\u0e22\u0e2d\u0e14\u0e23\u0e32\u0e22\u0e40\u0e14\u0e37\u0e2d\u0e19\\nBody:\\n## \u0e2a\u0e23\u0e38\u0e1b\\n\u0e23\u0e30\u0e1a\u0e1a\u0e2b\u0e19\u0e31\u0e07\u0e2a\u0e37\u0e2d\u0e25\u0e49\u0e32\u0e07\u0e2b\u0e19\u0e35\u0e49\u0e04\u0e48\u0e32\u0e2d\u0e32\u0e2b\u0e32\u0e23\u0e01\u0e25\u0e32\u0e07\u0e27\u0e31\u0e19 + \u0e01\u0e32\u0e23\u0e01\u0e23\u0e2d\u0e01\u0e22\u0e2d\u0e14\u0e23\u0e32\u0e22\u0e40\u0e14\u0e37\u0e2d\u0e19 \u0e04\u0e23\u0e1a end-to-end\\n\\n### \u0e1f\u0e35\u0e40\u0e08\u0e2d\u0e23\u0e4c\\n- **\u0e1f\u0e2d\u0e23\u0e4c\u0e21\u0e01\u0e23\u0e2d\u0e01\u0e22\u0e2d\u0e14** `/lunch-budget` \u2014 \u0e01\u0e23\u0e2d\u0e01 \u0e19\u0e31\u0e01\u0e40\u0e23\u0e35\u0e22\u0e19\u0e17\u0e31\u0e49\u0e07\u0e2b\u0e21\u0e14/\u0e21\u0e32\u0e40\u0e23\u0e35\u0e22\u0e19/\u0e23\u0e32\u0e22\u0e2b\u0e31\u0e27/\u0e08\u0e33\u0e19\u0e27\u0e19\u0e27\u0e31\u0e19 \u0e23\u0e32\u0e22\u0e2b\u0e19\u0e48\u0e27\u0e22/\u0e40\u0e14\u0e37\u0e2d\u0e19 (\u0e08\u0e33\u0e19\u0e27\u0e19\u0e27\u0e31\u0e19 default = \u0e27\u0e31\u0e19\u0e17\u0e33\u0e01\u0e32\u0e23\u0e2b\u0e31\u0e01\u0e27\u0e31\u0e19\u0e2b\u0e22\u0e38\u0e14\u0e23\u0e32\u0e0a\u0e01\u0e32\u0e23 2569)\\n- **\u0e1a\u0e17\u0e1a\u0e32\u0e17 \\\"\u0e1c\u0e39\u0e49\u0e01\u0e33\u0e2b\u0e19\u0e14\u0e22\u0e2d\u0e14\u0e2d\u0e32\u0e2b\u0e32\u0e23\u0e01\u0e25\u0e32\u0e07\u0e27\u0e31\u0e19\\\"** \u0e21\u0e2d\u0e1a\u0e2b\u0e21\u0e32\u0e22\u0e17\u0e35\u0e48 `/admin/roles` (flag `is_lunch_budget_setter`) + \u0e44\u0e17\u0e25\u0e4c\u0e40\u0e02\u0e49\u0e32\u0e16\u0e36\u0e07\u0e1a\u0e19 Dashboard\\n- **\u0e1b\u0e38\u0e48\u0e21 export \u0e2b\u0e19\u0e31\u0e07\u0e2a\u0e37\u0e2d\u0e25\u0e49\u0e32\u0e07\u0e2b\u0e19\u0e35\u0e49 (docx)** \u0e1a\u0e19\u0e01\u0e32\u0e23\u0e4c\u0e14\u0e2d\u0e32\u0e2b\u0e32\u0e23\u0e01\u0e25\u0e32\u0e07\u0e27\u0e31\u0e19 \u2014 \u0e40\u0e2b\u0e47\u0e19\u0e40\u0e09\u0e1e\u0e32\u0e30\u0e2b\u0e31\u0e27\u0e2b\u0e19\u0e49\u0e32\u0e2b\u0e19\u0e48\u0e27\u0e22\u0e1a\u0e23\u0e34\u0e01\u0e32\u0e23 + \u0e08\u0e2d PC\\n  - \u0e1d\u0e31\u0e07\u0e41\u0e17\u0e47\u0e01 docxtemplater \u0e25\u0e07 **template \u0e23\u0e32\u0e0a\u0e01\u0e32\u0e23\u0e08\u0e23\u0e34\u0e07** 5 \u0e2a\u0e48\u0e27\u0e19 (\u0e41\u0e1c\u0e19\u0e40\u0e21\u0e19\u0e39 / \u0e2a\u0e23\u0e38\u0e1b\u0e08\u0e31\u0e14\u0e0b\u0e37\u0e49\u0e2d\u0e23\u0e32\u0e22\u0e27\u0e31\u0e19 / \u0e23\u0e39\u0e1b / \u0e43\u0e1a\u0e2a\u0e33\u0e04\u0e31\u0e0d; \u0e15\u0e31\u0e14\u0e2a\u0e48\u0e27\u0e19 \\\"\u0e15\u0e31\u0e27\u0e2d\u0e22\u0e48\u0e32\u0e07\\\")\\n  - \u0e2a\u0e48\u0e27\u0e19\u0e2a\u0e23\u0e38\u0e1b\u0e08\u0e31\u0e14\u0e0b\u0e37\u0e49\u0e2d: AI (gemini-3.5-flash \u0e1c\u0e48\u0e32\u0e19 gemini-proxy) \u0e40\u0e08\u0e19\u0e27\u0e31\u0e15\u0e16\u0e38\u0e14\u0e34\u0e1a\u0e23\u0e32\u0e22\u0e27\u0e31\u0e19\u0e04\u0e38\u0e21\u0e22\u0e2d\u0e14 = \u0e07\u0e1a/\u0e27\u0e31\u0e19; \u0e27\u0e31\u0e19\u0e44\u0e21\u0e48\u0e21\u0e35\u0e23\u0e32\u0e22\u0e07\u0e32\u0e19 = \u0e41\u0e1c\u0e48\u0e19\u0e40\u0e1b\u0e25\u0e48\u0e32\u0e01\u0e23\u0e2d\u0e01\u0e21\u0e37\u0e2d\\n  - **\u0e14\u0e48\u0e32\u0e19 OTP (Telegram) \u0e01\u0e48\u0e2d\u0e19\u0e40\u0e23\u0e35\u0e22\u0e01 AI** \u0e01\u0e31\u0e19\u0e01\u0e14\u0e21\u0e31\u0e48\u0e27\u0e40\u0e1b\u0e25\u0e37\u0e2d\u0e07\u0e04\u0e48\u0e32 \u2014 verify \u0e42\u0e14\u0e22\u0e44\u0e21\u0e48 re-login\\n- \u0e27\u0e31\u0e19\u0e17\u0e33\u0e01\u0e32\u0e23\u0e04\u0e33\u0e19\u0e27\u0e13\u0e08\u0e32\u0e01\u0e27\u0e31\u0e19\u0e2b\u0e22\u0e38\u0e14\u0e23\u0e32\u0e0a\u0e01\u0e32\u0e23 2569 (`thaiHolidays.ts`, \u0e42\u0e04\u0e23\u0e07 per-year)\\n\\n### \u0e01\u0e32\u0e23\u0e40\u0e1b\u0e25\u0e35\u0e48\u0e22\u0e19\u0e1d\u0e31\u0e48\u0e07 DB/Infra (apply \u0e01\u0e31\u0e1a prod \u0e41\u0e25\u0e49\u0e27\u0e23\u0e30\u0e2b\u0e27\u0e48\u0e32\u0e07\u0e1e\"\n  },\n  {\n    \"id\": \"github-feedback-comment-2576f428af0d8af7\",\n    \"kind\": \"issue_comment\",\n    \"label\": \"deployment_env_gap\",\n    \"polarity\": \"bad\",\n    \"url\": \"https://github.com/watcharapon7574/rsec6hub/pull/1#issuecomment-4715699171\",\n    \"text\": \"GitHub feedback: deployment_env_gap\\nPolarity: bad\\nKind: issue_comment\\nRepo: watcharapon7574/rsec6hub\\nAuthor: vercel[bot] (Bot)\\nURL: https://github.com/watcharapon7574/rsec6hub/pull/1#issuecomment-4715699171\\nTitle: \\nBody:\\n[vc]: #nCCp3rDMWjD5Q49U/vZVJyILYUuXkZfBQxn3WAu1oOQ=:eyJpc01vbm9y\n[truncated by importer]", "source": "foundry_mined_dataset", "repo_url": "https://github.com/watcharapon7574/rsec6hub", "source_id": "comment-chain-pattern-assumption_checks-0cf7fa3b0f55d73d", "synthetic": false, "gold_label": "", "graph_label": "source_backed_multi_signal_graph", "source_path": "/data/distillate/foundry_data/comment_chain_patterns/assumption_checks/shard-0.jsonl", "bundle_label": "", "priority_band": "", "priority_score": 0, "repo_full_name": "watcharapon7574/rsec6hub", "source_dataset": "comment_chain_patterns/assumption_checks", "training_usage": "weak_supervision"}}}, {"ruleId": "scanner-bead75b0f9233e05", "level": "none", "message": {"text": "No API endpoints detected"}, "properties": {"repobilityId": "0f8bb852027c38f8", "scanner": "scanner-primary", "fingerprint": "bead75b0f9233e05", "layer": "api", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-658877ebaaacf0a8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 test-railway-stop.js:9"}, "properties": {"repobilityId": "caec7c2ac177b991", "scanner": "scanner-primary", "fingerprint": "658877ebaaacf0a8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-681d82b8f9f862c2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 check-railway-logs.js:9"}, "properties": {"repobilityId": "9600e62d9ea28f18", "scanner": "scanner-primary", "fingerprint": "681d82b8f9f862c2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3410f1e73a51f2bf", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/bump-sw-version.js:13"}, "properties": {"repobilityId": "699ad9d20c141dcc", "scanner": "scanner-primary", "fingerprint": "3410f1e73a51f2bf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5b31a520b75d3688", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/leave-telegram-notify/index.ts:358"}, "properties": {"repobilityId": "0ff3d95f1bdd434b", "scanner": "scanner-primary", "fingerprint": "5b31a520b75d3688", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-922dc14e24ead1e7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/telegram-otp/index.ts:83"}, "properties": {"repobilityId": "db677eba18ac5e7d", "scanner": "scanner-primary", "fingerprint": "922dc14e24ead1e7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-49d9aa2346a86177", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/grammar-check/index.ts:182"}, "properties": {"repobilityId": "49fe5b3e1bd6ae27", "scanner": "scanner-primary", "fingerprint": "49d9aa2346a86177", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8392ac0baf04d908", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/leave-sign-notify/index.ts:301"}, "properties": {"repobilityId": "8c0b53ac23b50c43", "scanner": "scanner-primary", "fingerprint": "8392ac0baf04d908", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2acdfe51a0e9f6c4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/verify-otp/index.ts:14"}, "properties": {"repobilityId": "48562f37bd6f567e", "scanner": "scanner-primary", "fingerprint": "2acdfe51a0e9f6c4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cb549abfa70e7340", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/telegram-notify/index.ts:391"}, "properties": {"repobilityId": "049ac5d852824815", "scanner": "scanner-primary", "fingerprint": "cb549abfa70e7340", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-adfb52df14ecbc79", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/railway-api/index.ts:26"}, "properties": {"repobilityId": "b7d995ca04a264bc", "scanner": "scanner-primary", "fingerprint": "adfb52df14ecbc79", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-46fe05e2103680ae", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/line-wrap/index.ts:143"}, "properties": {"repobilityId": "609136fb897e91b4", "scanner": "scanner-primary", "fingerprint": "46fe05e2103680ae", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bca5315273e73fca", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/sign-document/index.ts:31"}, "properties": {"repobilityId": "61fb022e1c9fe90e", "scanner": "scanner-primary", "fingerprint": "bca5315273e73fca", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e5b3f01f9099244a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/railway-scheduler/index.ts:82"}, "properties": {"repobilityId": "3d4ffd87aa18ac6f", "scanner": "scanner-primary", "fingerprint": "e5b3f01f9099244a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b25b738f86f7b3cf", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 public/sw.js:28"}, "properties": {"repobilityId": "19ecb22d48da856c", "scanner": "scanner-primary", "fingerprint": "b25b738f86f7b3cf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3d63e085e1e02c20", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/utils/pdfAnnotationUtils.ts:212"}, "properties": {"repobilityId": "3590345479b24f2f", "scanner": "scanner-primary", "fingerprint": "3d63e085e1e02c20", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-879018f12a20adc9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/utils/testRequestQueue.ts:23"}, "properties": {"repobilityId": "1f6b6ed25adbce9d", "scanner": "scanner-primary", "fingerprint": "879018f12a20adc9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-87d7bf1d1e4ce1ac", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Payslip/PayslipCard.tsx:33"}, "properties": {"repobilityId": "ddc9ad05a7372caf", "scanner": "scanner-primary", "fingerprint": "87d7bf1d1e4ce1ac", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e90b9b6dad1d21b9", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/components/Auth/TelegramChatIdStep.tsx:47"}, "properties": {"repobilityId": "fa1735b253675139", "scanner": "scanner-primary", "fingerprint": "e90b9b6dad1d21b9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-0d3cbf9bc5cac36c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Dashboard/CalendarWidget.tsx:250"}, "properties": {"repobilityId": "5f937ca780981700", "scanner": "scanner-primary", "fingerprint": "0d3cbf9bc5cac36c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2e608c290c010790", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Profile/SessionManagement.tsx:243"}, "properties": {"repobilityId": "b489e768a7682620", "scanner": "scanner-primary", "fingerprint": "2e608c290c010790", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b9effbdca5383e16", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Register/RegisterTable.tsx:568"}, "properties": {"repobilityId": "d1a87e4fabab36c3", "scanner": "scanner-primary", "fingerprint": "b9effbdca5383e16", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-070a2ccdcf7839d2", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:79"}, "properties": {"repobilityId": "b8c68f17a4018107", "scanner": "scanner-primary", "fingerprint": "070a2ccdcf7839d2", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-d0da5a3ebf0b8c5b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrUploadCard.tsx:117"}, "properties": {"repobilityId": "364e900765cf5a9d", "scanner": "scanner-primary", "fingerprint": "d0da5a3ebf0b8c5b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e540ddbc5c146ef4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrGoogleSearchBar.tsx:112"}, "properties": {"repobilityId": "6bf9e52e22761536", "scanner": "scanner-primary", "fingerprint": "e540ddbc5c146ef4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fafca291ac333199", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrSearchResultCard.tsx:63"}, "properties": {"repobilityId": "0204c386b4c3a0ed", "scanner": "scanner-primary", "fingerprint": "fafca291ac333199", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-486a101f17391e02", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OCR/OcrDocumentCard.tsx:125"}, "properties": {"repobilityId": "1eed4a94012856b0", "scanner": "scanner-primary", "fingerprint": "486a101f17391e02", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fc668078a32119f2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/SavedGroupsList.tsx:181"}, "properties": {"repobilityId": "d3f25379b40b19de", "scanner": "scanner-primary", "fingerprint": "fc668078a32119f2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f457fc5ac2207165", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/LocationCombobox.tsx:120"}, "properties": {"repobilityId": "3ef20a90330bae8b", "scanner": "scanner-primary", "fingerprint": "f457fc5ac2207165", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0c2251d9fd3dbcfd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/TaskAssignment/AssignedTasksList.tsx:392"}, "properties": {"repobilityId": "756bdf5bed3c7452", "scanner": "scanner-primary", "fingerprint": "0c2251d9fd3dbcfd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-839006d5d5d0c8e7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/RejectionCard.tsx:206"}, "properties": {"repobilityId": "1902a8d4bb683b36", "scanner": "scanner-primary", "fingerprint": "839006d5d5d0c8e7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4701457557a51689", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/DocumentList.tsx:1435"}, "properties": {"repobilityId": "2dd2b030ebc1c050", "scanner": "scanner-primary", "fingerprint": "4701457557a51689", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e9397913e01250d8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/MemoList.tsx:1091"}, "properties": {"repobilityId": "a71c5d1ac7ed1e0a", "scanner": "scanner-primary", "fingerprint": "e9397913e01250d8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-70ee17a9dd1d16f9", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/components/OfficialDocuments/MemoList.tsx:890"}, "properties": {"repobilityId": "0b04291235164dfc", "scanner": "scanner-primary", "fingerprint": "70ee17a9dd1d16f9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-0c761b958aa16a24", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/PDFViewer.tsx:657"}, "properties": {"repobilityId": "9e42b58ab66bb98b", "scanner": "scanner-primary", "fingerprint": "0c761b958aa16a24", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0977858b24b8c5d7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/components/OfficialDocuments/PDFViewer.tsx:513"}, "properties": {"repobilityId": "aab3d23785c7528e", "scanner": "scanner-primary", "fingerprint": "0977858b24b8c5d7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9f678d117fad5884", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/OfficialDocuments/PDFViewer.tsx:712"}, "properties": {"repobilityId": "f0812152508df91a", "scanner": "scanner-primary", "fingerprint": "9f678d117fad5884", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-0697e6b0d749974e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/AssignedDocumentsList.tsx:697"}, "properties": {"repobilityId": "492947479bf29041", "scanner": "scanner-primary", "fingerprint": "0697e6b0d749974e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-590a90b2179e15c0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/DocReceiveList.tsx:1264"}, "properties": {"repobilityId": "c51d1c6620aafa81", "scanner": "scanner-primary", "fingerprint": "590a90b2179e15c0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1e3a73d0b6e2c067", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/OfficialDocuments/Accordion.tsx:132"}, "properties": {"repobilityId": "87ccdcee3291dc0e", "scanner": "scanner-primary", "fingerprint": "1e3a73d0b6e2c067", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-512722ef109138a7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Layout/APIMaintenanceBanner.tsx:263"}, "properties": {"repobilityId": "7450ddd7d73676d5", "scanner": "scanner-primary", "fingerprint": "512722ef109138a7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-25a6c84fb0e1a15f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Layout/TopBar.tsx:112"}, "properties": {"repobilityId": "570c1907421545d2", "scanner": "scanner-primary", "fingerprint": "25a6c84fb0e1a15f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-10e34fc42345302a", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/MemoApproval/MemoApprovalPage.tsx:268"}, "properties": {"repobilityId": "7496ee9c1b48bcbf", "scanner": "scanner-primary", "fingerprint": "10e34fc42345302a", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-0a2374947d08d45f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Newsfeed/NewsfeedPostCard.tsx:163"}, "properties": {"repobilityId": "132dbe98b0a35bed", "scanner": "scanner-primary", "fingerprint": "0a2374947d08d45f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-598867ce60c6a194", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Newsfeed/NewsfeedReactions.tsx:238"}, "properties": {"repobilityId": "390845af519abea2", "scanner": "scanner-primary", "fingerprint": "598867ce60c6a194", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e905d80821757466", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/DocumentManage/Step3SignaturePositions.tsx:100"}, "properties": {"repobilityId": "93a9ecafae238de1", "scanner": "scanner-primary", "fingerprint": "e905d80821757466", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-dfee253459360e6d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/OcrSearchEmbedPage.tsx:137"}, "properties": {"repobilityId": "b8d9dd91bcae49a3", "scanner": "scanner-primary", "fingerprint": "dfee253459360e6d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fcd8e355c8162489", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/OcrUploadPage.tsx:171"}, "properties": {"repobilityId": "93475db874112026", "scanner": "scanner-primary", "fingerprint": "fcd8e355c8162489", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-43985a238a399db3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/OfficialDocumentsPage.tsx:175"}, "properties": {"repobilityId": "17dd136a5104e37a", "scanner": "scanner-primary", "fingerprint": "43985a238a399db3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a212fdef583a0d5c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/Dashboard.tsx:190"}, "properties": {"repobilityId": "ef6dffe971709383", "scanner": "scanner-primary", "fingerprint": "a212fdef583a0d5c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a63e4f81f16d72dd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/AdminChatsPage.tsx:317"}, "properties": {"repobilityId": "98390597b1592102", "scanner": "scanner-primary", "fingerprint": "a63e4f81f16d72dd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d2374bdc98328fd2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/LeaveRequestsPage.tsx:1150"}, "properties": {"repobilityId": "3567c58148d71c04", "scanner": "scanner-primary", "fingerprint": "d2374bdc98328fd2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a92b01594361e27e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/TelegramAssigneesPage.tsx:220"}, "properties": {"repobilityId": "5c830b1d7bfc28f9", "scanner": "scanner-primary", "fingerprint": "a92b01594361e27e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0ac446565a717186", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/pages/ApproveDocumentPage.tsx:810"}, "properties": {"repobilityId": "4a006d685d035b8d", "scanner": "scanner-primary", "fingerprint": "0ac446565a717186", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1b4a4b4c23558a50", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/NewLeaveRequestPage.tsx:489"}, "properties": {"repobilityId": "f0a87cea3a11a422", "scanner": "scanner-primary", "fingerprint": "1b4a4b4c23558a50", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f7552d5f232c7693", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/services/leaveService.ts:625"}, "properties": {"repobilityId": "589fd8abc0a92204", "scanner": "scanner-primary", "fingerprint": "f7552d5f232c7693", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-d9036a2b37cf3ef1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/services/leaveService.ts:626"}, "properties": {"repobilityId": "f84a6a0a53333f8f", "scanner": "scanner-primary", "fingerprint": "d9036a2b37cf3ef1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9476b2e166db747f", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/services/approvalWorkflowService.test.ts:291"}, "properties": {"repobilityId": "fdb89fec036cc402", "scanner": "scanner-primary", "fingerprint": "9476b2e166db747f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-41f721ad1df116df", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/services/officialDocumentService.ts:131"}, "properties": {"repobilityId": "4cc30985ed120a2d", "scanner": "scanner-primary", "fingerprint": "41f721ad1df116df", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-dda1bac1b22d03a2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 railway-scheduler/test-railway-api.js:14"}, "properties": {"repobilityId": "da9af22af1f0d76b", "scanner": "scanner-primary", "fingerprint": "dda1bac1b22d03a2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ca1ba0c0a8aa0764", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 railway-scheduler/scheduler.js:46"}, "properties": {"repobilityId": "e75a735b784c638f", "scanner": "scanner-primary", "fingerprint": "ca1ba0c0a8aa0764", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e422d660847d2871", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-telegram-notify/index.ts:21"}, "properties": {"repobilityId": "c474090768e3b348", "scanner": "scanner-primary", "fingerprint": "e422d660847d2871", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/leave-telegram-notify/index.ts"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-ad6c32c531d60c4b", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/telegram-otp/index.ts:8"}, "properties": {"repobilityId": "cc4feba7dd18e5dd", "scanner": "scanner-primary", "fingerprint": "ad6c32c531d60c4b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/telegram-otp/index.ts"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-f43d647b8e62ed8e", "level": "error", "message": {"text": "Insecure pattern 'private_key_in_repo' in supabase/functions/ocr-search/index.ts:34"}, "properties": {"repobilityId": "932e4c01304077bd", "scanner": "scanner-primary", "fingerprint": "f43d647b8e62ed8e", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["owasp", "private_key_in_repo"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/ocr-search/index.ts"}, "region": {"startLine": 34}}}]}, {"ruleId": "scanner-78aab84480ce484e", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/ocr-search/index.ts:6"}, "properties": {"repobilityId": "7a7195aabaf283e7", "scanner": "scanner-primary", "fingerprint": "78aab84480ce484e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/ocr-search/index.ts"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-3fa175e5fe50431e", "level": "error", "message": {"text": "Insecure pattern 'private_key_in_repo' in supabase/functions/grammar-check/index.ts:42"}, "properties": {"repobilityId": "1452243e69af30c4", "scanner": "scanner-primary", "fingerprint": "3fa175e5fe50431e", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["owasp", "private_key_in_repo"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/grammar-check/index.ts"}, "region": {"startLine": 42}}}]}, {"ruleId": "scanner-3630ebc0efe99556", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/grammar-check/index.ts:8"}, "properties": {"repobilityId": "c68faf903482d0f4", "scanner": "scanner-primary", "fingerprint": "3630ebc0efe99556", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/grammar-check/index.ts"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-620a76ed6f736773", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-sign-notify/index.ts:17"}, "properties": {"repobilityId": "a07e9fc73cf53275", "scanner": "scanner-primary", "fingerprint": "620a76ed6f736773", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/leave-sign-notify/index.ts"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-9a7e58c978ef2962", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/verify-otp/index.ts:5"}, "properties": {"repobilityId": "1c93f7d2243aa2fa", "scanner": "scanner-primary", "fingerprint": "9a7e58c978ef2962", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/verify-otp/index.ts"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-063c8784207dcd4d", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/leave-miniapp-auth/index.ts:23"}, "properties": {"repobilityId": "27a9b0c0c7e95ae7", "scanner": "scanner-primary", "fingerprint": "063c8784207dcd4d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/leave-miniapp-auth/index.ts"}, "region": {"startLine": 23}}}]}, {"ruleId": "scanner-d623677553e896c4", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/telegram-notify/index.ts:8"}, "properties": {"repobilityId": "19be1680e3062b08", "scanner": "scanner-primary", "fingerprint": "d623677553e896c4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/telegram-notify/index.ts"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-157f6279842de196", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/get-my-profile/index.ts:5"}, "properties": {"repobilityId": "478f80a7dfed0e88", "scanner": "scanner-primary", "fingerprint": "157f6279842de196", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/get-my-profile/index.ts"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-8c77a817734b7798", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/crop-payslip/index.ts:5"}, "properties": {"repobilityId": "e3467443a21e0c2d", "scanner": "scanner-primary", "fingerprint": "8c77a817734b7798", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/crop-payslip/index.ts"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-a8da91e3078418f6", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/railway-api/index.ts:9"}, "properties": {"repobilityId": "8a50285745f7e722", "scanner": "scanner-primary", "fingerprint": "a8da91e3078418f6", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/railway-api/index.ts"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-1f67ef63bb791ccc", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/get-task-assignees/index.ts:9"}, "properties": {"repobilityId": "391d926b5109ca30", "scanner": "scanner-primary", "fingerprint": "1f67ef63bb791ccc", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/get-task-assignees/index.ts"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-7eef70e6a82fbdd1", "level": "error", "message": {"text": "Insecure pattern 'private_key_in_repo' in supabase/functions/line-wrap/index.ts:27"}, "properties": {"repobilityId": "50d2d2d6ab437543", "scanner": "scanner-primary", "fingerprint": "7eef70e6a82fbdd1", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["owasp", "private_key_in_repo"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/line-wrap/index.ts"}, "region": {"startLine": 27}}}]}, {"ruleId": "scanner-93bf1080010943e5", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/line-wrap/index.ts:8"}, "properties": {"repobilityId": "4055deb11d9e7db7", "scanner": "scanner-primary", "fingerprint": "93bf1080010943e5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/line-wrap/index.ts"}, "region": {"startLine": 8}}}]}, {"ruleId": "scanner-043a171799541404", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/health-check/index.ts:12"}, "properties": {"repobilityId": "6ab5f8e11bdd10d3", "scanner": "scanner-primary", "fingerprint": "043a171799541404", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/health-check/index.ts"}, "region": {"startLine": 12}}}]}, {"ruleId": "scanner-e98288eaa4f5f7b8", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/upload-report-image/index.ts:13"}, "properties": {"repobilityId": "5a8fde3f933a576f", "scanner": "scanner-primary", "fingerprint": "e98288eaa4f5f7b8", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/upload-report-image/index.ts"}, "region": {"startLine": 13}}}]}, {"ruleId": "scanner-cce4a50b4515495f", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/google-calendar/index.ts:6"}, "properties": {"repobilityId": "2b912d3310748646", "scanner": "scanner-primary", "fingerprint": "cce4a50b4515495f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/google-calendar/index.ts"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-848b35df7a0d636d", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/download-document/index.ts:5"}, "properties": {"repobilityId": "454de996e6395006", "scanner": "scanner-primary", "fingerprint": "848b35df7a0d636d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/download-document/index.ts"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-08034dd91f6cd710", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/sign-document/index.ts:7"}, "properties": {"repobilityId": "874278931529a614", "scanner": "scanner-primary", "fingerprint": "08034dd91f6cd710", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/sign-document/index.ts"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-e3b7085febd0cd92", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:79"}, "properties": {"repobilityId": "33f10636e53b4298", "scanner": "scanner-primary", "fingerprint": "e3b7085febd0cd92", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/ui/chart.tsx"}, "region": {"startLine": 79}}}]}, {"ruleId": "scanner-d37dcd5c49343635", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/DocumentList.tsx:907"}, "properties": {"repobilityId": "019b7da283bea14a", "scanner": "scanner-primary", "fingerprint": "d37dcd5c49343635", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/OfficialDocuments/DocumentList.tsx"}, "region": {"startLine": 907}}}]}, {"ruleId": "scanner-4b858f656eea101b", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/MemoList.tsx:732"}, "properties": {"repobilityId": "e759b21d965acf49", "scanner": "scanner-primary", "fingerprint": "4b858f656eea101b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/OfficialDocuments/MemoList.tsx"}, "region": {"startLine": 732}}}]}, {"ruleId": "scanner-8cbf796c53a57f41", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/OfficialDocuments/PDFViewer.tsx:712"}, "properties": {"repobilityId": "5051706888b26376", "scanner": "scanner-primary", "fingerprint": "8cbf796c53a57f41", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/OfficialDocuments/PDFViewer.tsx"}, "region": {"startLine": 712}}}]}, {"ruleId": "scanner-e2f68444991bc040", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/PendingDocumentCard.tsx:595"}, "properties": {"repobilityId": "dd0a1128ebad517f", "scanner": "scanner-primary", "fingerprint": "e2f68444991bc040", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/OfficialDocuments/PendingDocumentCard.tsx"}, "region": {"startLine": 595}}}]}, {"ruleId": "scanner-3dc48ab23b00f7d2", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/OfficialDocuments/PersonalDocumentList.tsx:605"}, "properties": {"repobilityId": "04fc5e2d09c89527", "scanner": "scanner-primary", "fingerprint": "3dc48ab23b00f7d2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/OfficialDocuments/PersonalDocumentList.tsx"}, "region": {"startLine": 605}}}]}, {"ruleId": "scanner-1835558685d5776a", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/MemoApproval/MemoApprovalPage.tsx:268"}, "properties": {"repobilityId": "e337eb4840a37472", "scanner": "scanner-primary", "fingerprint": "1835558685d5776a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/MemoApproval/MemoApprovalPage.tsx"}, "region": {"startLine": 268}}}]}, {"ruleId": "scanner-269f247828213891", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in src/services/sessionService.ts:65"}, "properties": {"repobilityId": "2c262d93e5ca6450", "scanner": "scanner-primary", "fingerprint": "269f247828213891", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/services/sessionService.ts"}, "region": {"startLine": 65}}}]}, {"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-b11381257fad5e1b", "level": "note", "message": {"text": "Very large file: src/integrations/supabase/types.ts (3898 lines)"}, "properties": {"repobilityId": "ede8ac5264027534", "scanner": "scanner-primary", "fingerprint": "b11381257fad5e1b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-940a63b02cab4679", "level": "note", "message": {"text": "Very large file: src/components/OfficialDocuments/DocumentList.tsx (1524 lines)"}, "properties": {"repobilityId": "f2e8ebbc3d81cef8", "scanner": "scanner-primary", "fingerprint": "940a63b02cab4679", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-94463c4933f06645", "level": "note", "message": {"text": "Very large file: src/components/OfficialDocuments/MemoList.tsx (1180 lines)"}, "properties": {"repobilityId": "20de62eae60d4e24", "scanner": "scanner-primary", "fingerprint": "94463c4933f06645", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-469fb9d42a310926", "level": "note", "message": {"text": "Very large file: src/components/OfficialDocuments/PDFViewer.tsx (1337 lines)"}, "properties": {"repobilityId": "e409fc919067099f", "scanner": "scanner-primary", "fingerprint": "469fb9d42a310926", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-e4e9d0084e5fd978", "level": "note", "message": {"text": "Very large file: src/components/OfficialDocuments/AssignedDocumentsList.tsx (1163 lines)"}, "properties": {"repobilityId": "6b26353d6a17c784", "scanner": "scanner-primary", "fingerprint": "e4e9d0084e5fd978", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-98736d93eb3c6634", "level": "note", "message": {"text": "Very large file: src/components/OfficialDocuments/PendingDocumentCard.tsx (905 lines)"}, "properties": {"repobilityId": "09bd67f108884e4b", "scanner": "scanner-primary", "fingerprint": "98736d93eb3c6634", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-979f6a497ee0e000", "level": "note", "message": {"text": "Very large file: src/components/OfficialDocuments/DocReceiveList.tsx (1352 lines)"}, "properties": {"repobilityId": "8ca5f5bbc094f18a", "scanner": "scanner-primary", "fingerprint": "979f6a497ee0e000", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-8065588491a61297", "level": "note", "message": {"text": "Very large file: src/pages/CreateReportMemoPage.tsx (1683 lines)"}, "properties": {"repobilityId": "d6b4e4bdb75475fd", "scanner": "scanner-primary", "fingerprint": "8065588491a61297", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1dcb21d083ec4763", "level": "note", "message": {"text": "Very large file: src/pages/CreateMemoPage.tsx (1950 lines)"}, "properties": {"repobilityId": "302ce81cc9c47932", "scanner": "scanner-primary", "fingerprint": "1dcb21d083ec4763", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3bb54e62baf8bf51", "level": "note", "message": {"text": "Very large file: src/pages/DocumentManagePage.tsx (1693 lines)"}, "properties": {"repobilityId": "49fe59e5585b35ea", "scanner": "scanner-primary", "fingerprint": "3bb54e62baf8bf51", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-68690830bbc4e489", "level": "note", "message": {"text": "Very large file: src/pages/LeaveRequestsPage.tsx (3488 lines)"}, "properties": {"repobilityId": "11d28b5c383fbfaa", "scanner": "scanner-primary", "fingerprint": "68690830bbc4e489", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-fed2ae2cc2e58a2b", "level": "note", "message": {"text": "Very large file: src/pages/ApproveDocumentPage.tsx (1506 lines)"}, "properties": {"repobilityId": "d911a04e1f015da4", "scanner": "scanner-primary", "fingerprint": "fed2ae2cc2e58a2b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-2a938dfcf2cfa44e", "level": "note", "message": {"text": "Very large file: src/pages/ManageReportMemoPage.tsx (1475 lines)"}, "properties": {"repobilityId": "7ef39346a032aed7", "scanner": "scanner-primary", "fingerprint": "2a938dfcf2cfa44e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "079704ae0c9e3570", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "3c0c508744522cb5", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "cd4b3069de9ae596", "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": "2cce7af2b830ffb4", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "ce7f5ae618b5b133", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "eb779d88a995d2fd", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "6d9c96a530e88c12", "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": "a3a202561ff3b29f", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-e1d6bb11aa93adf0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 test-railway-stop.js:75"}, "properties": {"repobilityId": "72de73058dc096f7", "scanner": "scanner-primary", "fingerprint": "e1d6bb11aa93adf0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d50cb8929b29eace", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/leave-telegram-notify/index.ts:4"}, "properties": {"repobilityId": "2ffde483a785b08e", "scanner": "scanner-primary", "fingerprint": "d50cb8929b29eace", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-20554304ae178447", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/telegram-otp/index.ts:729"}, "properties": {"repobilityId": "7d55abda4280de6c", "scanner": "scanner-primary", "fingerprint": "20554304ae178447", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-96c24d69eff8bb5b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/ocr-search/index.ts:61"}, "properties": {"repobilityId": "fe1dac03b7e82d58", "scanner": "scanner-primary", "fingerprint": "96c24d69eff8bb5b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5b373a545d6863b8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/grammar-check/index.ts:78"}, "properties": {"repobilityId": "0591185b7f815366", "scanner": "scanner-primary", "fingerprint": "5b373a545d6863b8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-13d0421e4906a89a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/leave-sign-notify/index.ts:81"}, "properties": {"repobilityId": "1997655c7e143750", "scanner": "scanner-primary", "fingerprint": "13d0421e4906a89a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ef4b6599126b0040", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/telegram-notify/index.ts:343"}, "properties": {"repobilityId": "8bddbd7cce64ba3c", "scanner": "scanner-primary", "fingerprint": "ef4b6599126b0040", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-090b75d8e4cf0c7c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/crop-payslip/index.ts:29"}, "properties": {"repobilityId": "c715ee6bd1940237", "scanner": "scanner-primary", "fingerprint": "090b75d8e4cf0c7c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1819b89457c21066", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/railway-api/index.ts:69"}, "properties": {"repobilityId": "f521caace0389183", "scanner": "scanner-primary", "fingerprint": "1819b89457c21066", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-976ab98438ee9a89", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/line-wrap/index.ts:63"}, "properties": {"repobilityId": "e2d9664f9ee295a8", "scanner": "scanner-primary", "fingerprint": "976ab98438ee9a89", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e52e04bcfe8587e3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/google-calendar/index.ts:77"}, "properties": {"repobilityId": "01bc3ac9894dd0e3", "scanner": "scanner-primary", "fingerprint": "e52e04bcfe8587e3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f2aa6a580e339cab", "level": "note", "message": {"text": "Legacy-named symbol `add_signature_v2` in supabase/functions/sign-document/index.ts:72"}, "properties": {"repobilityId": "22aefb3fc1e22790", "scanner": "scanner-primary", "fingerprint": "f2aa6a580e339cab", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f148b0b697ee5969", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/sign-document/index.ts:50"}, "properties": {"repobilityId": "b1cb16ca99e25732", "scanner": "scanner-primary", "fingerprint": "f148b0b697ee5969", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-06b8dcd1abab8117", "level": "note", "message": {"text": "Legacy-named symbol `data_std_admin_add_v2` in src/integrations/supabase/types.ts:3015"}, "properties": {"repobilityId": "6430d7918b03bb5a", "scanner": "scanner-primary", "fingerprint": "06b8dcd1abab8117", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-8d47b2d3d07d88bd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/utils/pdfAnnotationUtils.ts:86"}, "properties": {"repobilityId": "9888b7338047c79f", "scanner": "scanner-primary", "fingerprint": "8d47b2d3d07d88bd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8c10a96bcdb3efb0", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/utils/railwayFetch.ts:6"}, "properties": {"repobilityId": "fa23c1d1a203beb0", "scanner": "scanner-primary", "fingerprint": "8c10a96bcdb3efb0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ba12ad339417689e", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/Dashboard/StudentAttendanceWidget.tsx:192"}, "properties": {"repobilityId": "653d162f5f8ec25f", "scanner": "scanner-primary", "fingerprint": "ba12ad339417689e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3a16ceceac8e88e9", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/OfficialDocuments/MemoList.tsx:200"}, "properties": {"repobilityId": "d9b840b3a527216a", "scanner": "scanner-primary", "fingerprint": "3a16ceceac8e88e9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1cad8d330325b41f", "level": "none", "message": {"text": "Commented-code block (15 lines) in src/components/OfficialDocuments/PDFViewer.tsx:574"}, "properties": {"repobilityId": "4d72a16cf2903f85", "scanner": "scanner-primary", "fingerprint": "1cad8d330325b41f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b0ab7116de79d5cf", "level": "note", "message": {"text": "Legacy-named symbol `add_signature_v2` in src/pages/PDFDocumentManagePage.tsx:429"}, "properties": {"repobilityId": "ee598e0708262b6d", "scanner": "scanner-primary", "fingerprint": "b0ab7116de79d5cf", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-572e290ccd9ec78b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/PDFDocumentManagePage.tsx:362"}, "properties": {"repobilityId": "4430c1414963ed3a", "scanner": "scanner-primary", "fingerprint": "572e290ccd9ec78b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7d5b121de94e5efd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateReportMemoPage.tsx:754"}, "properties": {"repobilityId": "bd513af4b0d53f84", "scanner": "scanner-primary", "fingerprint": "7d5b121de94e5efd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-36481b2be9d32da9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateMemoPage.tsx:706"}, "properties": {"repobilityId": "1bb4b68116bcfb0e", "scanner": "scanner-primary", "fingerprint": "36481b2be9d32da9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e8546d9f42f88587", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/pages/OfficialDocumentsPage.tsx:172"}, "properties": {"repobilityId": "ea1dd237f1117132", "scanner": "scanner-primary", "fingerprint": "e8546d9f42f88587", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-45a623a0ce02130b", "level": "note", "message": {"text": "Legacy-named symbol `add_signature_v2` in src/pages/DocumentManagePage.tsx:1234"}, "properties": {"repobilityId": "4cfc6b13196b7fc7", "scanner": "scanner-primary", "fingerprint": "45a623a0ce02130b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1a2d938c6385ef6c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/DocumentManagePage.tsx:1186"}, "properties": {"repobilityId": "efdc6acfecbc65ca", "scanner": "scanner-primary", "fingerprint": "1a2d938c6385ef6c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-692fa5b51a0e9818", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/ApproveDocumentPage.tsx:596"}, "properties": {"repobilityId": "54596d8e7b9f9ecb", "scanner": "scanner-primary", "fingerprint": "692fa5b51a0e9818", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bad4b0e356bcb459", "level": "note", "message": {"text": "Legacy-named symbol `add_signature_v2` in src/pages/ManageReportMemoPage.tsx:1092"}, "properties": {"repobilityId": "e9f1ecd692b56e34", "scanner": "scanner-primary", "fingerprint": "bad4b0e356bcb459", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-660ee21ed22dcd75", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/CreateDocReceivePage.tsx:348"}, "properties": {"repobilityId": "1281f93ed2b71298", "scanner": "scanner-primary", "fingerprint": "660ee21ed22dcd75", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-872e85446403743e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/PDFReceiveManagePage.tsx:233"}, "properties": {"repobilityId": "9ad7adb1e0527cef", "scanner": "scanner-primary", "fingerprint": "872e85446403743e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-779e55f1a32bf9d0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useGoogleCalendar.ts:42"}, "properties": {"repobilityId": "c33907ea77c4474e", "scanner": "scanner-primary", "fingerprint": "779e55f1a32bf9d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e81116e6be4c087f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/pdfSignatureChainService.ts:25"}, "properties": {"repobilityId": "da3ce7957780795e", "scanner": "scanner-primary", "fingerprint": "e81116e6be4c087f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-915c082bbf248480", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/services/taskAssignmentService.ts:358"}, "properties": {"repobilityId": "5cf11d6c7aa9e263", "scanner": "scanner-primary", "fingerprint": "915c082bbf248480", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c82f7f0343cce5d0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/memoService.ts:466"}, "properties": {"repobilityId": "136511ecf8192fdc", "scanner": "scanner-primary", "fingerprint": "c82f7f0343cce5d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d26c89e70f723f12", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/memoManageAPIcall.ts:46"}, "properties": {"repobilityId": "cb557d446ada461d", "scanner": "scanner-primary", "fingerprint": "d26c89e70f723f12", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f0c626f1b959ef76", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/auth/otp.ts:18"}, "properties": {"repobilityId": "2e17749baf1f2309", "scanner": "scanner-primary", "fingerprint": "f0c626f1b959ef76", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ff040e09dbe77ff3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/services/auth/signIn.ts:21"}, "properties": {"repobilityId": "f27870319c4a4c16", "scanner": "scanner-primary", "fingerprint": "ff040e09dbe77ff3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-75602d9fe81c5ec9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/test-railway-api.js:35"}, "properties": {"repobilityId": "ffed4d9dcbfee9bd", "scanner": "scanner-primary", "fingerprint": "75602d9fe81c5ec9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bba6d591996478fe", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/scheduler.js:27"}, "properties": {"repobilityId": "5b957f3535543253", "scanner": "scanner-primary", "fingerprint": "bba6d591996478fe", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d2606f35e23ecdfd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 railway-scheduler/railway-mcp-server.js:151"}, "properties": {"repobilityId": "7bdf5d320a27d844", "scanner": "scanner-primary", "fingerprint": "d2606f35e23ecdfd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9f42fb5925bf28fe", "level": "warning", "message": {"text": "Frontend route `/embed/search` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "ab3c2722df99a7e6", "scanner": "scanner-primary", "fingerprint": "9f42fb5925bf28fe", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c783d56f85f7328f", "level": "warning", "message": {"text": "Frontend route `/telegram-assignees/:documentId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "924811bb303847fc", "scanner": "scanner-primary", "fingerprint": "c783d56f85f7328f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b71f0c1dc82aeced", "level": "warning", "message": {"text": "Frontend route `/telegram-assignees` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "e0e17ab3ede6598a", "scanner": "scanner-primary", "fingerprint": "b71f0c1dc82aeced", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-ce473e102f66da9b", "level": "warning", "message": {"text": "Frontend route `/tg/leave/:id` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "dc7ac5e5e91ab6f0", "scanner": "scanner-primary", "fingerprint": "ce473e102f66da9b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-790a64df598c85cc", "level": "warning", "message": {"text": "Frontend route `/tg/leave` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "caf953def93c1287", "scanner": "scanner-primary", "fingerprint": "790a64df598c85cc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-2c4185282207354b", "level": "warning", "message": {"text": "Frontend route `/leave-requests` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "8cd6a9dc8e017947", "scanner": "scanner-primary", "fingerprint": "2c4185282207354b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-0dcad0da8c32cfc5", "level": "warning", "message": {"text": "Frontend route `/daily-reports` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "2b73e63b448eb8f1", "scanner": "scanner-primary", "fingerprint": "0dcad0da8c32cfc5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-2ce0297f45f85fe8", "level": "warning", "message": {"text": "Frontend route `/report-memo/:taskId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "5f089a22be870790", "scanner": "scanner-primary", "fingerprint": "2ce0297f45f85fe8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b51420c111297578", "level": "warning", "message": {"text": "Frontend route `/create-report-memo` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "6f613e96373b9790", "scanner": "scanner-primary", "fingerprint": "b51420c111297578", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-d717532a9b135eaf", "level": "warning", "message": {"text": "Frontend route `/manage-report-memo/:memoId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "eb41272517765be0", "scanner": "scanner-primary", "fingerprint": "d717532a9b135eaf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-d6fd69665f3109f3", "level": "warning", "message": {"text": "Frontend route `/document-manage/:memoId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "a874d1d32649dce2", "scanner": "scanner-primary", "fingerprint": "d6fd69665f3109f3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-75a811335b063926", "level": "warning", "message": {"text": "Frontend route `/pdf-document-manage/:memoId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "40be8ad883a57bee", "scanner": "scanner-primary", "fingerprint": "75a811335b063926", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9d0fe1d02420f8c0", "level": "warning", "message": {"text": "Frontend route `/pdf-receive-manage/:memoId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "b46650b1c4698c4e", "scanner": "scanner-primary", "fingerprint": "9d0fe1d02420f8c0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-30133e443375f420", "level": "warning", "message": {"text": "Frontend route `/edit-doc-receive/:memoId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "267900de680353db", "scanner": "scanner-primary", "fingerprint": "30133e443375f420", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-cce3045d3b77e620", "level": "warning", "message": {"text": "Frontend route `/approve-document/:memoId` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "86f8f1bae980f533", "scanner": "scanner-primary", "fingerprint": "cce3045d3b77e620", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-613d4f1b7145e006", "level": "warning", "message": {"text": "Frontend route `/task-assignment` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "3161f16cd32afcc5", "scanner": "scanner-primary", "fingerprint": "613d4f1b7145e006", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}]}]}