{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-3aaa4f69a9b011fa", "name": "Possibly dead Python function: footer", "shortDescription": {"text": "Possibly dead Python function: footer"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-183e6b7d97715986", "name": "Possibly dead Python function: section_header", "shortDescription": {"text": "Possibly dead Python function: section_header"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a4a5dcb346d53507", "name": "Stray `console.log` in TS/JS \u2014 scripts/merge_leads_gsheet.ts:225", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/merge_leads_gsheet.ts:225"}, "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-ad4285ff41eed951", "name": "Stray `console.log` in TS/JS \u2014 scripts/prerender.js:63", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/prerender.js:63"}, "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-24870e94bae7c072", "name": "Stray `console.log` in TS/JS \u2014 src/App.tsx:121", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/App.tsx:121"}, "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-d529fc774068c0ed", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/SpecialitePage.tsx:400", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/SpecialitePage.tsx:400"}, "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-0b4a895c401b9cfc", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/Admin.tsx:4560", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/Admin.tsx:4560"}, "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-d440d1b78890e940", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/QuotePage.tsx:364", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/QuotePage.tsx:364"}, "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-8e64ce8585c56d31", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-leads-gsheet-sync.ts:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-leads-gsheet-sync.ts:16"}, "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-5b47269dc126f36a", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-nurture.ts:195", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-nurture.ts:195"}, "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-9605508e5c55a919", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-leads-digest.ts:49", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-leads-digest.ts:49"}, "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-9ba64256a890f694", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/submission-created.ts:51", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/submission-created.ts:51"}, "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-5c0ed42e5dcc0fed", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/notion-sync-cron.ts:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/notion-sync-cron.ts:22"}, "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-5994271cad1865f5", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/unsubscribe.ts:55", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/unsubscribe.ts:55"}, "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-fb463b7cb6ab52f9", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-seo-check.ts:19", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-seo-check.ts:19"}, "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-6b0b8869ec0812a1", "name": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-nps-ask.ts:97", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-nps-ask.ts:97"}, "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-0fbbef33a0f3a98c", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/components/BarChartRace.tsx:181", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/BarChartRace.tsx:181"}, "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-3fdeffbddb5c8e7f", "name": "Insecure pattern 'dangerous_innerhtml' in src/pages/SpecialitePage.tsx:400", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/pages/SpecialitePage.tsx:400"}, "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-8eb896cfc82f3e3f", "name": "Insecure pattern 'exec_used' in src/pages/Admin.tsx:4588", "shortDescription": {"text": "Insecure pattern 'exec_used' in src/pages/Admin.tsx:4588"}, "fullDescription": {"text": "Found a known-risky pattern (exec_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-857b7817ed7eb1fd", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/Admin.tsx:4569", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/Admin.tsx:4569"}, "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-76f8540141004ee2", "name": "Insecure pattern 'local_storage_auth_token' in src/pages/Admin.tsx:412", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in src/pages/Admin.tsx:412"}, "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-0413dced7fb38cb5", "name": "Insecure pattern 'dangerous_innerhtml' in src/pages/QuotePage.tsx:364", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/pages/QuotePage.tsx:364"}, "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-c856d782a221a52e", "name": "Insecure pattern 'cors_wildcard' in netlify/functions/admin-quotes.ts:6", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/admin-quotes.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-15c471eef6efe5ea", "name": "Insecure pattern 'cors_wildcard' in netlify/functions/track-visit.ts:68", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/track-visit.ts:68"}, "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-7bb0aa1b53007d75", "name": "Insecure pattern 'cors_wildcard' in netlify/functions/track-crm-visit.ts:9", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/track-crm-visit.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-d6da61d2f6368a81", "name": "Insecure pattern 'cors_wildcard' in netlify/functions/sign-quote.ts:233", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/sign-quote.ts:233"}, "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-12422f8fefbc32b5", "name": "Insecure pattern 'cors_wildcard' in netlify/functions/send-quote.ts:51", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/send-quote.ts:51"}, "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-ea44d9412381404d", "name": "Insecure pattern 'cors_wildcard' in netlify/functions/get-quote.ts:5", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/get-quote.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-f702496e741b3544", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/tools/devis.html:303", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/tools/devis.html:303"}, "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-e45951a09f58c8e6", "name": "Insecure pattern 'local_storage_auth_token' in public/tools/devis.html:253", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in public/tools/devis.html:253"}, "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-080c6951d2e18c85", "name": "Very large file: src/pages/Admin.tsx (6318 lines)", "shortDescription": {"text": "Very large file: src/pages/Admin.tsx (6318 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-2c3b1a0625f33d1c", "name": "Very large file: src/pages/QuotePage.tsx (1122 lines)", "shortDescription": {"text": "Very large file: src/pages/QuotePage.tsx (1122 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-46fd168d462d1ee9", "name": "Very large file: src/pages/Home.tsx (1471 lines)", "shortDescription": {"text": "Very large file: src/pages/Home.tsx (1471 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": "0 test file(s) for 102 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 20 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 76 placeholder/mock markers across 13 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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, tests. 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-122f91b7f2906dc4", "name": "Agent authority lacks a verifier contract: .claude/settings.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/settings.json"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-fe83e745e25e869e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Booking.tsx:183", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Booking.tsx:183"}, "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-e3669096a1f4f054", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Hiring.tsx:200", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Hiring.tsx:200"}, "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-b98298cc85d7aa59", "name": "Commented-code block (7 lines) in src/pages/Admin.tsx:4559", "shortDescription": {"text": "Commented-code block (7 lines) in src/pages/Admin.tsx:4559"}, "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-06e1e114051c6133", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Admin.tsx:659", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Admin.tsx:659"}, "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-7679de03e8eef187", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/admin-extract-job-title.ts:71", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/admin-extract-job-title.ts:71"}, "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-d4ae14839feefecc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/book-meeting.ts:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/book-meeting.ts:36"}, "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-2233d105e7165d7c", "name": "Commented-code block (5 lines) in netlify/functions/admin-enrich-lead.ts:33", "shortDescription": {"text": "Commented-code block (5 lines) in netlify/functions/admin-enrich-lead.ts:33"}, "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-f5170ab02895d34c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/get-busy-slots.ts:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/get-busy-slots.ts:13"}, "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-8cc56ba7a70b06bc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/daily-tasks-reminder.ts:138", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/daily-tasks-reminder.ts:138"}, "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-fa8974ba38a2bb19", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_notion-sync.ts:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_notion-sync.ts:32"}, "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-78a1301f914bf023", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/scheduled-leads-digest.ts:63", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/scheduled-leads-digest.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-0e169e68e4d05648", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/admin-classify-company.ts:89", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/admin-classify-company.ts:89"}, "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-5cc9737b631ae1fc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/submission-created.ts:152", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/submission-created.ts:152"}, "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-c832c8f66db4bd75", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/sign-quote.ts:400", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/sign-quote.ts:400"}, "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-4d1d9393e65fe89b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_seo-check.ts:47", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_seo-check.ts:47"}, "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-382777e1827d6e1f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/send-quote.ts:197", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/send-quote.ts:197"}, "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-c9b5ab21e7d48b1c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_gsheet.ts:93", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_gsheet.ts:93"}, "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-e6980c3745ab56c0", "name": "Commented-code block (5 lines) in netlify/functions/scheduled-nps-ask.ts:58", "shortDescription": {"text": "Commented-code block (5 lines) in netlify/functions/scheduled-nps-ask.ts:58"}, "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-2219b0804e081d47", "name": "Commented-code block (7 lines) in public/generate_brochure.py:4", "shortDescription": {"text": "Commented-code block (7 lines) in public/generate_brochure.py: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-2def4ca8631eb15e", "name": "Frontend route `/articles/:slug` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/articles/:slug` 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-02c4bdabc0899843", "name": "Frontend route `/consultant-marketing-sante` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/consultant-marketing-sante` 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-7fc4d5ee98e79717", "name": "Frontend route `/specialites/:slug` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/specialites/:slug` 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-f848ef6d018bab63", "name": "Frontend route `/hiring` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/hiring` 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-4e88697794e21822", "name": "Frontend route `/confirmation` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/confirmation` 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-3d47341344301241", "name": "Frontend route `/admin` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/admin` 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-7f600c1f0a7ed9af", "name": "Frontend route `/devis/:company/:id` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/devis/:company/: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-aa5a6fe6c24b7e8e", "name": "Frontend route `/merci-nps` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/merci-nps` 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/25007"}, "properties": {"repository": "clempok/clempo.fr", "repoUrl": "https://github.com/clempok/clempo.fr", "branch": "main"}, "results": [{"ruleId": "scanner-3aaa4f69a9b011fa", "level": "note", "message": {"text": "Possibly dead Python function: footer"}, "properties": {"repobilityId": "9f0be3db8aae782f", "scanner": "scanner-primary", "fingerprint": "3aaa4f69a9b011fa", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/generate_brochure.py:99"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-183e6b7d97715986", "level": "note", "message": {"text": "Possibly dead Python function: section_header"}, "properties": {"repobilityId": "f0e3b3196eab6fad", "scanner": "scanner-primary", "fingerprint": "183e6b7d97715986", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/generate_brochure.py:162"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a4a5dcb346d53507", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/merge_leads_gsheet.ts:225"}, "properties": {"repobilityId": "28484a58450f8bb8", "scanner": "scanner-primary", "fingerprint": "a4a5dcb346d53507", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ad4285ff41eed951", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/prerender.js:63"}, "properties": {"repobilityId": "b33b9ddda35960cb", "scanner": "scanner-primary", "fingerprint": "ad4285ff41eed951", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-24870e94bae7c072", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/App.tsx:121"}, "properties": {"repobilityId": "f3d63003b5dbefbd", "scanner": "scanner-primary", "fingerprint": "24870e94bae7c072", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d529fc774068c0ed", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/SpecialitePage.tsx:400"}, "properties": {"repobilityId": "4e129ae9a498f32c", "scanner": "scanner-primary", "fingerprint": "d529fc774068c0ed", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-0b4a895c401b9cfc", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/Admin.tsx:4560"}, "properties": {"repobilityId": "9f1f10e2cd3347d5", "scanner": "scanner-primary", "fingerprint": "0b4a895c401b9cfc", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-d440d1b78890e940", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/QuotePage.tsx:364"}, "properties": {"repobilityId": "1ed94540e02dd6f0", "scanner": "scanner-primary", "fingerprint": "d440d1b78890e940", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-8e64ce8585c56d31", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-leads-gsheet-sync.ts:16"}, "properties": {"repobilityId": "c338f027f08a4afd", "scanner": "scanner-primary", "fingerprint": "8e64ce8585c56d31", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5b47269dc126f36a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-nurture.ts:195"}, "properties": {"repobilityId": "be96cfdd7e08a227", "scanner": "scanner-primary", "fingerprint": "5b47269dc126f36a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9605508e5c55a919", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-leads-digest.ts:49"}, "properties": {"repobilityId": "c134217fdb0da010", "scanner": "scanner-primary", "fingerprint": "9605508e5c55a919", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9ba64256a890f694", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/submission-created.ts:51"}, "properties": {"repobilityId": "1bc1340cd70dab16", "scanner": "scanner-primary", "fingerprint": "9ba64256a890f694", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5c0ed42e5dcc0fed", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/notion-sync-cron.ts:22"}, "properties": {"repobilityId": "b1933e64e4c97aeb", "scanner": "scanner-primary", "fingerprint": "5c0ed42e5dcc0fed", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5994271cad1865f5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/unsubscribe.ts:55"}, "properties": {"repobilityId": "05e00973f702532b", "scanner": "scanner-primary", "fingerprint": "5994271cad1865f5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fb463b7cb6ab52f9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-seo-check.ts:19"}, "properties": {"repobilityId": "a5fab3a57e198583", "scanner": "scanner-primary", "fingerprint": "fb463b7cb6ab52f9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6b0b8869ec0812a1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 netlify/functions/scheduled-nps-ask.ts:97"}, "properties": {"repobilityId": "7fc8c6d6deb4b61e", "scanner": "scanner-primary", "fingerprint": "6b0b8869ec0812a1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0fbbef33a0f3a98c", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/components/BarChartRace.tsx:181"}, "properties": {"repobilityId": "6add757e2fae3495", "scanner": "scanner-primary", "fingerprint": "0fbbef33a0f3a98c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/BarChartRace.tsx"}, "region": {"startLine": 181}}}]}, {"ruleId": "scanner-3fdeffbddb5c8e7f", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/pages/SpecialitePage.tsx:400"}, "properties": {"repobilityId": "80e7273f90366c05", "scanner": "scanner-primary", "fingerprint": "3fdeffbddb5c8e7f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/SpecialitePage.tsx"}, "region": {"startLine": 400}}}]}, {"ruleId": "scanner-8eb896cfc82f3e3f", "level": "error", "message": {"text": "Insecure pattern 'exec_used' in src/pages/Admin.tsx:4588"}, "properties": {"repobilityId": "aa47317a81f6b88a", "scanner": "scanner-primary", "fingerprint": "8eb896cfc82f3e3f", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "exec_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/Admin.tsx"}, "region": {"startLine": 4588}}}]}, {"ruleId": "scanner-857b7817ed7eb1fd", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/Admin.tsx:4569"}, "properties": {"repobilityId": "1fce563b58b604e5", "scanner": "scanner-primary", "fingerprint": "857b7817ed7eb1fd", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/Admin.tsx"}, "region": {"startLine": 4569}}}]}, {"ruleId": "scanner-76f8540141004ee2", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in src/pages/Admin.tsx:412"}, "properties": {"repobilityId": "5a6aad9fd9b88263", "scanner": "scanner-primary", "fingerprint": "76f8540141004ee2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/Admin.tsx"}, "region": {"startLine": 412}}}]}, {"ruleId": "scanner-0413dced7fb38cb5", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/pages/QuotePage.tsx:364"}, "properties": {"repobilityId": "f05e9e51bb33e874", "scanner": "scanner-primary", "fingerprint": "0413dced7fb38cb5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/QuotePage.tsx"}, "region": {"startLine": 364}}}]}, {"ruleId": "scanner-c856d782a221a52e", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/admin-quotes.ts:6"}, "properties": {"repobilityId": "1621259868fece9f", "scanner": "scanner-primary", "fingerprint": "c856d782a221a52e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "netlify/functions/admin-quotes.ts"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-15c471eef6efe5ea", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/track-visit.ts:68"}, "properties": {"repobilityId": "04e6780ed9e9045c", "scanner": "scanner-primary", "fingerprint": "15c471eef6efe5ea", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "netlify/functions/track-visit.ts"}, "region": {"startLine": 68}}}]}, {"ruleId": "scanner-7bb0aa1b53007d75", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/track-crm-visit.ts:9"}, "properties": {"repobilityId": "95c1d49cf862b6b7", "scanner": "scanner-primary", "fingerprint": "7bb0aa1b53007d75", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "netlify/functions/track-crm-visit.ts"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-d6da61d2f6368a81", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/sign-quote.ts:233"}, "properties": {"repobilityId": "b83b557d98806797", "scanner": "scanner-primary", "fingerprint": "d6da61d2f6368a81", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "netlify/functions/sign-quote.ts"}, "region": {"startLine": 233}}}]}, {"ruleId": "scanner-12422f8fefbc32b5", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/send-quote.ts:51"}, "properties": {"repobilityId": "f72ec2d54a1484f1", "scanner": "scanner-primary", "fingerprint": "12422f8fefbc32b5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "netlify/functions/send-quote.ts"}, "region": {"startLine": 51}}}]}, {"ruleId": "scanner-ea44d9412381404d", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in netlify/functions/get-quote.ts:5"}, "properties": {"repobilityId": "d6e63f46c12c4ab5", "scanner": "scanner-primary", "fingerprint": "ea44d9412381404d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "netlify/functions/get-quote.ts"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-f702496e741b3544", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/tools/devis.html:303"}, "properties": {"repobilityId": "c0742e633997f26a", "scanner": "scanner-primary", "fingerprint": "f702496e741b3544", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/tools/devis.html"}, "region": {"startLine": 303}}}]}, {"ruleId": "scanner-e45951a09f58c8e6", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in public/tools/devis.html:253"}, "properties": {"repobilityId": "4cadc2c2224c0ef9", "scanner": "scanner-primary", "fingerprint": "e45951a09f58c8e6", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/tools/devis.html"}, "region": {"startLine": 253}}}]}, {"ruleId": "scanner-080c6951d2e18c85", "level": "note", "message": {"text": "Very large file: src/pages/Admin.tsx (6318 lines)"}, "properties": {"repobilityId": "94d5febc9f430fe1", "scanner": "scanner-primary", "fingerprint": "080c6951d2e18c85", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-2c3b1a0625f33d1c", "level": "note", "message": {"text": "Very large file: src/pages/QuotePage.tsx (1122 lines)"}, "properties": {"repobilityId": "f4eda031a1d55aec", "scanner": "scanner-primary", "fingerprint": "2c3b1a0625f33d1c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-46fd168d462d1ee9", "level": "note", "message": {"text": "Very large file: src/pages/Home.tsx (1471 lines)"}, "properties": {"repobilityId": "91939324b61238a5", "scanner": "scanner-primary", "fingerprint": "46fd168d462d1ee9", "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": "6212f06f55eb125c", "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": "503eb6c0a75b7519", "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": "b610544b36ec23a1", "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": "9fd22d6b6a1687f0", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "9cad4ee44765106e", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "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": "d8bdb78b436881a8", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-122f91b7f2906dc4", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/settings.json"}, "properties": {"repobilityId": "a2967269048b6a9d", "scanner": "scanner-primary", "fingerprint": "122f91b7f2906dc4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/settings.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fe83e745e25e869e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Booking.tsx:183"}, "properties": {"repobilityId": "f5fdb4394a24242c", "scanner": "scanner-primary", "fingerprint": "fe83e745e25e869e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e3669096a1f4f054", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Hiring.tsx:200"}, "properties": {"repobilityId": "e937a1ffa41bae38", "scanner": "scanner-primary", "fingerprint": "e3669096a1f4f054", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b98298cc85d7aa59", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/pages/Admin.tsx:4559"}, "properties": {"repobilityId": "cbdd2d4bf4c7c268", "scanner": "scanner-primary", "fingerprint": "b98298cc85d7aa59", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-06e1e114051c6133", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/pages/Admin.tsx:659"}, "properties": {"repobilityId": "c0987bbb8a0c02c1", "scanner": "scanner-primary", "fingerprint": "06e1e114051c6133", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7679de03e8eef187", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/admin-extract-job-title.ts:71"}, "properties": {"repobilityId": "9be7612477c1d09e", "scanner": "scanner-primary", "fingerprint": "7679de03e8eef187", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d4ae14839feefecc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/book-meeting.ts:36"}, "properties": {"repobilityId": "c45049101f5b968e", "scanner": "scanner-primary", "fingerprint": "d4ae14839feefecc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2233d105e7165d7c", "level": "none", "message": {"text": "Commented-code block (5 lines) in netlify/functions/admin-enrich-lead.ts:33"}, "properties": {"repobilityId": "7ca9b492b6d2f5da", "scanner": "scanner-primary", "fingerprint": "2233d105e7165d7c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f5170ab02895d34c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/get-busy-slots.ts:13"}, "properties": {"repobilityId": "1ef3d9b5dc7cad59", "scanner": "scanner-primary", "fingerprint": "f5170ab02895d34c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8cc56ba7a70b06bc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/daily-tasks-reminder.ts:138"}, "properties": {"repobilityId": "74c8edc210e8676e", "scanner": "scanner-primary", "fingerprint": "8cc56ba7a70b06bc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fa8974ba38a2bb19", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_notion-sync.ts:32"}, "properties": {"repobilityId": "03c9a5df28f7c752", "scanner": "scanner-primary", "fingerprint": "fa8974ba38a2bb19", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-78a1301f914bf023", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/scheduled-leads-digest.ts:63"}, "properties": {"repobilityId": "1184df9188b9b5bb", "scanner": "scanner-primary", "fingerprint": "78a1301f914bf023", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0e169e68e4d05648", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/admin-classify-company.ts:89"}, "properties": {"repobilityId": "2f2b17b3b827bd98", "scanner": "scanner-primary", "fingerprint": "0e169e68e4d05648", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5cc9737b631ae1fc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/submission-created.ts:152"}, "properties": {"repobilityId": "5ed762baffbfc1bf", "scanner": "scanner-primary", "fingerprint": "5cc9737b631ae1fc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c832c8f66db4bd75", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/sign-quote.ts:400"}, "properties": {"repobilityId": "d951c04b61264c82", "scanner": "scanner-primary", "fingerprint": "c832c8f66db4bd75", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4d1d9393e65fe89b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_seo-check.ts:47"}, "properties": {"repobilityId": "8471363264fbc813", "scanner": "scanner-primary", "fingerprint": "4d1d9393e65fe89b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-382777e1827d6e1f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/send-quote.ts:197"}, "properties": {"repobilityId": "e37cb480e46e3f6d", "scanner": "scanner-primary", "fingerprint": "382777e1827d6e1f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c9b5ab21e7d48b1c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 netlify/functions/_gsheet.ts:93"}, "properties": {"repobilityId": "4ce9da91ba5a0e30", "scanner": "scanner-primary", "fingerprint": "c9b5ab21e7d48b1c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e6980c3745ab56c0", "level": "none", "message": {"text": "Commented-code block (5 lines) in netlify/functions/scheduled-nps-ask.ts:58"}, "properties": {"repobilityId": "627ae88ffba714f2", "scanner": "scanner-primary", "fingerprint": "e6980c3745ab56c0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2219b0804e081d47", "level": "none", "message": {"text": "Commented-code block (7 lines) in public/generate_brochure.py:4"}, "properties": {"repobilityId": "72ce86c43396986e", "scanner": "scanner-primary", "fingerprint": "2219b0804e081d47", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2def4ca8631eb15e", "level": "warning", "message": {"text": "Frontend route `/articles/:slug` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "5495b0a7fccb0755", "scanner": "scanner-primary", "fingerprint": "2def4ca8631eb15e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-02c4bdabc0899843", "level": "warning", "message": {"text": "Frontend route `/consultant-marketing-sante` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "8acd4b13f93b86a3", "scanner": "scanner-primary", "fingerprint": "02c4bdabc0899843", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-7fc4d5ee98e79717", "level": "warning", "message": {"text": "Frontend route `/specialites/:slug` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "d463173ac29b6d92", "scanner": "scanner-primary", "fingerprint": "7fc4d5ee98e79717", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-f848ef6d018bab63", "level": "warning", "message": {"text": "Frontend route `/hiring` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "8bc3003eaf7981e8", "scanner": "scanner-primary", "fingerprint": "f848ef6d018bab63", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-4e88697794e21822", "level": "warning", "message": {"text": "Frontend route `/confirmation` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "7bfc9add54886fe1", "scanner": "scanner-primary", "fingerprint": "4e88697794e21822", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3d47341344301241", "level": "warning", "message": {"text": "Frontend route `/admin` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "3060fc2a800f6a3c", "scanner": "scanner-primary", "fingerprint": "3d47341344301241", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-7f600c1f0a7ed9af", "level": "warning", "message": {"text": "Frontend route `/devis/:company/:id` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "7e198da2f8e85072", "scanner": "scanner-primary", "fingerprint": "7f600c1f0a7ed9af", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-aa5a6fe6c24b7e8e", "level": "warning", "message": {"text": "Frontend route `/merci-nps` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "5b53c69007eb09ac", "scanner": "scanner-primary", "fingerprint": "aa5a6fe6c24b7e8e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}]}]}