{"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-51712277891d07e7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/SearchDialog.tsx:140", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SearchDialog.tsx:140"}, "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-3c563fe196cd9a7f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/admin/AdminLayout.tsx:76", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/admin/AdminLayout.tsx:76"}, "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-b209c77e83b119fd", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:70", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:70"}, "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-81694a40e4f56b91", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/ProductsList.tsx:86", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/ProductsList.tsx:86"}, "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-bc60bd3e453ab264", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/PromoCodesAdmin.tsx:130", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/PromoCodesAdmin.tsx:130"}, "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-b89875b90c7a86e4", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/admin/CampaignEdit.tsx:203", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/admin/CampaignEdit.tsx:203"}, "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-214d5494216ef81a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/StoresAdmin.tsx:107", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/StoresAdmin.tsx:107"}, "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-f15d8b29c4c5d3df", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/Dashboard.tsx:231", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/Dashboard.tsx:231"}, "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-7679e027db64f673", "name": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/SupportAdmin.tsx:211", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/SupportAdmin.tsx:211"}, "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-653bbaa5f9b6d7d9", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/verify-turnstile/index.ts:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/verify-turnstile/index.ts:17"}, "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-4dd75737ec0492d1", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/handle-email-unsubscribe/index.ts:127", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/handle-email-unsubscribe/index.ts:127"}, "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-6bd0cf23ccae28dd", "name": "TODO/FIXME marker in shipping code \u2014 supabase/functions/claim-promo-code/index.ts:26", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 supabase/functions/claim-promo-code/index.ts:26"}, "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-6da49d94d6557897", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/claim-promo-code/index.ts:60", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/claim-promo-code/index.ts:60"}, "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-b697419ac6c63a74", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/handle-email-suppression/index.ts:127", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/handle-email-suppression/index.ts:127"}, "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-ca909249847c87aa", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/send-transactional-email/index.ts:158", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/send-transactional-email/index.ts:158"}, "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-c1db9b0925863e96", "name": "Stray `console.log` in TS/JS \u2014 supabase/functions/auth-email-hook/index.ts:256", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/auth-email-hook/index.ts:256"}, "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-93d0283845aa2c2d", "name": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:70", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:70"}, "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-9ebb1e9d01e130f2", "name": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/Intro.tsx:185", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/Intro.tsx:185"}, "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-f4a76cbbe2940343", "name": "Insecure pattern 'dangerous_innerhtml' in src/pages/admin/CampaignEdit.tsx:203", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/pages/admin/CampaignEdit.tsx:203"}, "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-e2bc0003a7fd12e4", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/verify-turnstile/index.ts:3", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/verify-turnstile/index.ts:3"}, "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-9e6d2b4ca7a29dc7", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/handle-email-unsubscribe/index.ts:4", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/handle-email-unsubscribe/index.ts:4"}, "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-35214426f55ddbc4", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/preview-transactional-email/index.ts:6", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/preview-transactional-email/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-c92f9da654140e44", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/check-email/index.ts:9", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/check-email/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-46583fc398e080f0", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/support-chat/index.ts:14", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/support-chat/index.ts:14"}, "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-473ae69bd0465286", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/claim-promo-code/index.ts:10", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/claim-promo-code/index.ts:10"}, "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-d2d15ff9a206a2ca", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/admin-banners/index.ts:19", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/admin-banners/index.ts:19"}, "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-c3d62ceffcf3ca03", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/send-transactional-email/index.ts:19", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/send-transactional-email/index.ts:19"}, "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-a26a4a88f9df8c05", "name": "Insecure pattern 'cors_wildcard' in supabase/functions/auth-email-hook/index.ts:14", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/auth-email-hook/index.ts:14"}, "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-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "3 test file(s) for 156 source file(s) (ratio 0.02). 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-01f96f71d9907a8c", "name": "README lacks setup or run instructions", "shortDescription": {"text": "README lacks setup or run instructions"}, "fullDescription": {"text": "A README exists, but it does not contain common install/setup/run markers. This matches a frequent generated-code pattern: UI is present, operational handoff is thin."}, "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 16 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 39 placeholder/mock markers across 21 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, operator-readme. 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-1821cca556522de9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-sitemap.mjs:39", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-sitemap.mjs:39"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-108e8f92830f9b1b", "name": "Commented-code block (5 lines) in src/hooks/useBanner.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/hooks/useBanner.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d96abcabd8f0c8ce", "name": "Commented-code block (5 lines) in src/components/HeroBanner.tsx:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/HeroBanner.tsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-525eabeab87c4544", "name": "Commented-code block (6 lines) in src/components/HeroPromoCtas.tsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in src/components/HeroPromoCtas.tsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d77e714370d3f96f", "name": "Commented-code block (8 lines) in src/components/admin/BannerPreview.tsx:1", "shortDescription": {"text": "Commented-code block (8 lines) in src/components/admin/BannerPreview.tsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-40fa28c42127f5eb", "name": "Commented-code block (5 lines) in src/pages/admin/BannersAdmin.tsx:108", "shortDescription": {"text": "Commented-code block (5 lines) in src/pages/admin/BannersAdmin.tsx:108"}, "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-b0205de4805f5f38", "name": "Commented-code block (5 lines) in src/lib/banner-positions.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/banner-positions.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-75a25b2424260b6b", "name": "Commented-code block (5 lines) in src/lib/supabase-errors.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/supabase-errors.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-73aac12dd3002696", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/verify-turnstile/index.ts:46", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/verify-turnstile/index.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-89f45a0241099e49", "name": "Commented-code block (6 lines) in supabase/functions/support-chat/index.ts:1", "shortDescription": {"text": "Commented-code block (6 lines) in supabase/functions/support-chat/index.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d1cbfbf006184c81", "name": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/support-chat/index.ts:315", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/support-chat/index.ts:315"}, "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-3cd9fb674ba18502", "name": "Commented-code block (9 lines) in supabase/functions/admin-banners/index.ts:1", "shortDescription": {"text": "Commented-code block (9 lines) in supabase/functions/admin-banners/index.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f81d9f5d342567c8", "name": "Commented-code block (5 lines) in supabase/functions/auth-email-hook/index.ts:88", "shortDescription": {"text": "Commented-code block (5 lines) in supabase/functions/auth-email-hook/index.ts:88"}, "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-fa3c89281556e3ae", "name": "Frontend route `/intro` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/intro` 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-25fca67d0f9b70cc", "name": "Frontend route `/product/:slug` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/product/: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-38c9fafb18d6a82a", "name": "Frontend route `/page/:slug` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/page/: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-7f1bec1fd65c0879", "name": "Frontend route `/reset-password` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/reset-password` 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-486847178fee241c", "name": "Frontend route `/unsubscribe` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/unsubscribe` 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-975a614958d1ecb5", "name": "Frontend route `/email-unsubscribe` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/email-unsubscribe` 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-16077d4894c4b0cb", "name": "Frontend route `/promo-claim` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/promo-claim` 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-aef59d59c8df891f", "name": "Frontend route `/admin/products/:id` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/admin/products/: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-72a063650c995bee", "name": "Frontend route `/admin/campaigns/:id` has no Link/navigate to it \u2014 src/App.tsx", "shortDescription": {"text": "Frontend route `/admin/campaigns/: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}}]}}, "automationDetails": {"id": "repobility/24054"}, "properties": {"repository": "alekseyklepikov11-netizen/dsom-beauty-catalog", "repoUrl": "https://github.com/alekseyklepikov11-netizen/dsom-beauty-catalog", "branch": "main"}, "results": [{"ruleId": "scanner-51712277891d07e7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/SearchDialog.tsx:140"}, "properties": {"repobilityId": "2ff4fb314807000d", "scanner": "scanner-primary", "fingerprint": "51712277891d07e7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3c563fe196cd9a7f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/admin/AdminLayout.tsx:76"}, "properties": {"repobilityId": "57146b130cbbd3b5", "scanner": "scanner-primary", "fingerprint": "3c563fe196cd9a7f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b209c77e83b119fd", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/ui/chart.tsx:70"}, "properties": {"repobilityId": "b8c68f17a4018107", "scanner": "scanner-primary", "fingerprint": "b209c77e83b119fd", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-81694a40e4f56b91", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/ProductsList.tsx:86"}, "properties": {"repobilityId": "069f1f33026833a1", "scanner": "scanner-primary", "fingerprint": "81694a40e4f56b91", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bc60bd3e453ab264", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/PromoCodesAdmin.tsx:130"}, "properties": {"repobilityId": "2c5ce58e748e31a7", "scanner": "scanner-primary", "fingerprint": "bc60bd3e453ab264", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b89875b90c7a86e4", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/pages/admin/CampaignEdit.tsx:203"}, "properties": {"repobilityId": "4722fc992389ed80", "scanner": "scanner-primary", "fingerprint": "b89875b90c7a86e4", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-214d5494216ef81a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/StoresAdmin.tsx:107"}, "properties": {"repobilityId": "70a94a35696bf193", "scanner": "scanner-primary", "fingerprint": "214d5494216ef81a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f15d8b29c4c5d3df", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/Dashboard.tsx:231"}, "properties": {"repobilityId": "5042987516ab7ad8", "scanner": "scanner-primary", "fingerprint": "f15d8b29c4c5d3df", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7679e027db64f673", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/pages/admin/SupportAdmin.tsx:211"}, "properties": {"repobilityId": "9a2bf48ccc5d3320", "scanner": "scanner-primary", "fingerprint": "7679e027db64f673", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-653bbaa5f9b6d7d9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/verify-turnstile/index.ts:17"}, "properties": {"repobilityId": "2f56cc67d039fcc4", "scanner": "scanner-primary", "fingerprint": "653bbaa5f9b6d7d9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4dd75737ec0492d1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/handle-email-unsubscribe/index.ts:127"}, "properties": {"repobilityId": "45530992d13fa60b", "scanner": "scanner-primary", "fingerprint": "4dd75737ec0492d1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6bd0cf23ccae28dd", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 supabase/functions/claim-promo-code/index.ts:26"}, "properties": {"repobilityId": "e47069da6b23fdc7", "scanner": "scanner-primary", "fingerprint": "6bd0cf23ccae28dd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-6da49d94d6557897", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/claim-promo-code/index.ts:60"}, "properties": {"repobilityId": "6b796b533c0edbbd", "scanner": "scanner-primary", "fingerprint": "6da49d94d6557897", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b697419ac6c63a74", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/handle-email-suppression/index.ts:127"}, "properties": {"repobilityId": "9260c7332e80dcf9", "scanner": "scanner-primary", "fingerprint": "b697419ac6c63a74", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ca909249847c87aa", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/send-transactional-email/index.ts:158"}, "properties": {"repobilityId": "2b3048268d61359e", "scanner": "scanner-primary", "fingerprint": "ca909249847c87aa", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c1db9b0925863e96", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 supabase/functions/auth-email-hook/index.ts:256"}, "properties": {"repobilityId": "febfb37bd73a7c9a", "scanner": "scanner-primary", "fingerprint": "c1db9b0925863e96", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-93d0283845aa2c2d", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/ui/chart.tsx:70"}, "properties": {"repobilityId": "33f10636e53b4298", "scanner": "scanner-primary", "fingerprint": "93d0283845aa2c2d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/ui/chart.tsx"}, "region": {"startLine": 70}}}]}, {"ruleId": "scanner-9ebb1e9d01e130f2", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in src/pages/Intro.tsx:185"}, "properties": {"repobilityId": "2b4acaee3efa55e0", "scanner": "scanner-primary", "fingerprint": "9ebb1e9d01e130f2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/Intro.tsx"}, "region": {"startLine": 185}}}]}, {"ruleId": "scanner-f4a76cbbe2940343", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/pages/admin/CampaignEdit.tsx:203"}, "properties": {"repobilityId": "07f595f21e85acbb", "scanner": "scanner-primary", "fingerprint": "f4a76cbbe2940343", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/pages/admin/CampaignEdit.tsx"}, "region": {"startLine": 203}}}]}, {"ruleId": "scanner-e2bc0003a7fd12e4", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/verify-turnstile/index.ts:3"}, "properties": {"repobilityId": "5cf962c8c4500923", "scanner": "scanner-primary", "fingerprint": "e2bc0003a7fd12e4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/verify-turnstile/index.ts"}, "region": {"startLine": 3}}}]}, {"ruleId": "scanner-9e6d2b4ca7a29dc7", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/handle-email-unsubscribe/index.ts:4"}, "properties": {"repobilityId": "534d2c4ace105ec3", "scanner": "scanner-primary", "fingerprint": "9e6d2b4ca7a29dc7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/handle-email-unsubscribe/index.ts"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-35214426f55ddbc4", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/preview-transactional-email/index.ts:6"}, "properties": {"repobilityId": "731e8f231a6831c8", "scanner": "scanner-primary", "fingerprint": "35214426f55ddbc4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/preview-transactional-email/index.ts"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-c92f9da654140e44", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/check-email/index.ts:9"}, "properties": {"repobilityId": "b0f467ef7511c51f", "scanner": "scanner-primary", "fingerprint": "c92f9da654140e44", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/check-email/index.ts"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-46583fc398e080f0", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/support-chat/index.ts:14"}, "properties": {"repobilityId": "80609263d7b86710", "scanner": "scanner-primary", "fingerprint": "46583fc398e080f0", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/support-chat/index.ts"}, "region": {"startLine": 14}}}]}, {"ruleId": "scanner-473ae69bd0465286", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/claim-promo-code/index.ts:10"}, "properties": {"repobilityId": "5d94c1cc83e0fccf", "scanner": "scanner-primary", "fingerprint": "473ae69bd0465286", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/claim-promo-code/index.ts"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-d2d15ff9a206a2ca", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/admin-banners/index.ts:19"}, "properties": {"repobilityId": "0bc154c9a93f1c3f", "scanner": "scanner-primary", "fingerprint": "d2d15ff9a206a2ca", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/admin-banners/index.ts"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-c3d62ceffcf3ca03", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/send-transactional-email/index.ts:19"}, "properties": {"repobilityId": "f4d3b084c2b63b06", "scanner": "scanner-primary", "fingerprint": "c3d62ceffcf3ca03", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/send-transactional-email/index.ts"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-a26a4a88f9df8c05", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in supabase/functions/auth-email-hook/index.ts:14"}, "properties": {"repobilityId": "249fc31148305b77", "scanner": "scanner-primary", "fingerprint": "a26a4a88f9df8c05", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "supabase/functions/auth-email-hook/index.ts"}, "region": {"startLine": 14}}}]}, {"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": "0aace05b4e0ca2e0", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-01f96f71d9907a8c", "level": "note", "message": {"text": "README lacks setup or run instructions"}, "properties": {"repobilityId": "2620577dc68ec293", "scanner": "scanner-primary", "fingerprint": "01f96f71d9907a8c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "4c352117881a1a8e", "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": "e263e13105089430", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "2ece204748c2ae3c", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "42bc2fec4c0f6d85", "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": "f7d38e2381e9ebb5", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-1821cca556522de9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-sitemap.mjs:39"}, "properties": {"repobilityId": "d551747c58b101fe", "scanner": "scanner-primary", "fingerprint": "1821cca556522de9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-108e8f92830f9b1b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/hooks/useBanner.ts:1"}, "properties": {"repobilityId": "806ece35edc80850", "scanner": "scanner-primary", "fingerprint": "108e8f92830f9b1b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d96abcabd8f0c8ce", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/HeroBanner.tsx:1"}, "properties": {"repobilityId": "0601bc61206ade83", "scanner": "scanner-primary", "fingerprint": "d96abcabd8f0c8ce", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-525eabeab87c4544", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/components/HeroPromoCtas.tsx:1"}, "properties": {"repobilityId": "27b0951e3ace09c8", "scanner": "scanner-primary", "fingerprint": "525eabeab87c4544", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d77e714370d3f96f", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/components/admin/BannerPreview.tsx:1"}, "properties": {"repobilityId": "a633c579ce947ceb", "scanner": "scanner-primary", "fingerprint": "d77e714370d3f96f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-40fa28c42127f5eb", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/pages/admin/BannersAdmin.tsx:108"}, "properties": {"repobilityId": "b9dbae751c3071ba", "scanner": "scanner-primary", "fingerprint": "40fa28c42127f5eb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b0205de4805f5f38", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/banner-positions.ts:1"}, "properties": {"repobilityId": "49c8dc399e8197f1", "scanner": "scanner-primary", "fingerprint": "b0205de4805f5f38", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-75a25b2424260b6b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/supabase-errors.ts:1"}, "properties": {"repobilityId": "ab5eebcf352fbba6", "scanner": "scanner-primary", "fingerprint": "75a25b2424260b6b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-73aac12dd3002696", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/verify-turnstile/index.ts:46"}, "properties": {"repobilityId": "0a4913deab172922", "scanner": "scanner-primary", "fingerprint": "73aac12dd3002696", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-89f45a0241099e49", "level": "none", "message": {"text": "Commented-code block (6 lines) in supabase/functions/support-chat/index.ts:1"}, "properties": {"repobilityId": "7d4341771a2e74e3", "scanner": "scanner-primary", "fingerprint": "89f45a0241099e49", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d1cbfbf006184c81", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 supabase/functions/support-chat/index.ts:315"}, "properties": {"repobilityId": "103cd0fab4d14a42", "scanner": "scanner-primary", "fingerprint": "d1cbfbf006184c81", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3cd9fb674ba18502", "level": "none", "message": {"text": "Commented-code block (9 lines) in supabase/functions/admin-banners/index.ts:1"}, "properties": {"repobilityId": "6aa4b06b9de67d10", "scanner": "scanner-primary", "fingerprint": "3cd9fb674ba18502", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f81d9f5d342567c8", "level": "none", "message": {"text": "Commented-code block (5 lines) in supabase/functions/auth-email-hook/index.ts:88"}, "properties": {"repobilityId": "9bf2ae3173b42bd5", "scanner": "scanner-primary", "fingerprint": "f81d9f5d342567c8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fa3c89281556e3ae", "level": "warning", "message": {"text": "Frontend route `/intro` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "c9a056a75e0c23a5", "scanner": "scanner-primary", "fingerprint": "fa3c89281556e3ae", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-25fca67d0f9b70cc", "level": "warning", "message": {"text": "Frontend route `/product/:slug` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "be7c2828e2dd01e8", "scanner": "scanner-primary", "fingerprint": "25fca67d0f9b70cc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-38c9fafb18d6a82a", "level": "warning", "message": {"text": "Frontend route `/page/:slug` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "324349ed40820a42", "scanner": "scanner-primary", "fingerprint": "38c9fafb18d6a82a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-7f1bec1fd65c0879", "level": "warning", "message": {"text": "Frontend route `/reset-password` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "934747c714145754", "scanner": "scanner-primary", "fingerprint": "7f1bec1fd65c0879", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-486847178fee241c", "level": "warning", "message": {"text": "Frontend route `/unsubscribe` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "8926fa7d12313a80", "scanner": "scanner-primary", "fingerprint": "486847178fee241c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-975a614958d1ecb5", "level": "warning", "message": {"text": "Frontend route `/email-unsubscribe` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "cd694de639f9b27c", "scanner": "scanner-primary", "fingerprint": "975a614958d1ecb5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-16077d4894c4b0cb", "level": "warning", "message": {"text": "Frontend route `/promo-claim` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "f11670211c6d2bd5", "scanner": "scanner-primary", "fingerprint": "16077d4894c4b0cb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-aef59d59c8df891f", "level": "warning", "message": {"text": "Frontend route `/admin/products/:id` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "f5ec4e3976b27594", "scanner": "scanner-primary", "fingerprint": "aef59d59c8df891f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-72a063650c995bee", "level": "warning", "message": {"text": "Frontend route `/admin/campaigns/:id` has no Link/navigate to it \u2014 src/App.tsx"}, "properties": {"repobilityId": "e2e52165f4cb6e43", "scanner": "scanner-primary", "fingerprint": "72a063650c995bee", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}]}]}