{"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-cc9a4323a7dcd6d2", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/DashboardLayout.tsx:243", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/DashboardLayout.tsx:243"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6eac27f0ae630081", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/SEOFooter.tsx:156", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/SEOFooter.tsx:156"}, "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-7ac91878b37b4f08", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/LeadScoreBadge.tsx:170", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/LeadScoreBadge.tsx:170"}, "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-fd54759add2cc305", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/EmailVerificationBadge.tsx:122", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/EmailVerificationBadge.tsx:122"}, "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-92f28d55a595968e", "name": "Stray `console.log` in TS/JS \u2014 client/src/components/Analytics.tsx:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 client/src/components/Analytics.tsx: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-992778b41539817d", "name": "Stray `console.log` in TS/JS \u2014 client/src/components/PWAPrompt.tsx:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 client/src/components/PWAPrompt.tsx: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-a7b3db9745e9c497", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ui/chart.tsx:81", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ui/chart.tsx:81"}, "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-784333a1e99c71cc", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/WidgetComponents.tsx:441", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/WidgetComponents.tsx:441"}, "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-5a169b983fa32605", "name": "TODO/FIXME marker in shipping code \u2014 client/src/pages/Contact.tsx:23", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 client/src/pages/Contact.tsx:23"}, "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-0017b9dfaabed9d9", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Webhooks.tsx:496", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Webhooks.tsx:496"}, "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-28314740d0e477c0", "name": "Stray `console.log` in TS/JS \u2014 client/src/pages/Docs.tsx:134", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 client/src/pages/Docs.tsx:134"}, "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-6e35229700d27b06", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/ActivityLog.tsx:299", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/ActivityLog.tsx:299"}, "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-2e6376d8694880de", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Leads.tsx:336", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Leads.tsx:336"}, "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-4f25008c55c74f1b", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Inbox.tsx:292", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Inbox.tsx:292"}, "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-f4a58cb50ea28277", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Templates.tsx:558", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Templates.tsx:558"}, "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-37446b0354111e2f", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Search.tsx:901", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Search.tsx:901"}, "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-cbdd2551c2855954", "name": "Stray `console.log` in TS/JS \u2014 client/src/pages/ComponentShowcase.tsx:197", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 client/src/pages/ComponentShowcase.tsx:197"}, "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-8779a216eb4e349d", "name": "Stray `console.log` in TS/JS \u2014 server/inboundWebhook.ts:86", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/inboundWebhook.ts:86"}, "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-12483002697ea50b", "name": "Stray `console.log` in TS/JS \u2014 server/emailQueueProcessor.ts:38", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/emailQueueProcessor.ts:38"}, "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-2bea101eab56b8fe", "name": "Stray `console.log` in TS/JS \u2014 server/emailService.ts:25", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/emailService.ts:25"}, "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-e8628c8b63e20224", "name": "Stray `console.log` in TS/JS \u2014 server/sendgridWebhook.ts:98", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/sendgridWebhook.ts:98"}, "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-dec4fa179c9d66b0", "name": "TODO/FIXME marker in shipping code \u2014 server/db.ts:836", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 server/db.ts:836"}, "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-5f6873feaad566a6", "name": "Stray `console.log` in TS/JS \u2014 server/db.ts:58", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/db.ts:58"}, "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-8e61da0074ec82f6", "name": "TODO/FIXME marker in shipping code \u2014 server/queueDb.ts:194", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 server/queueDb.ts:194"}, "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-81143abe4cfee528", "name": "Stray `console.log` in TS/JS \u2014 server/queueDb.ts:185", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/queueDb.ts:185"}, "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-456c1a097cfa14d7", "name": "Stray `console.log` in TS/JS \u2014 server/stripeWebhook.ts:57", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/stripeWebhook.ts:57"}, "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-f620f13f6c81081a", "name": "Stray `console.log` in TS/JS \u2014 server/smartRules/webhooks.ts:160", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/webhooks.ts:160"}, "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-4503f792171660c3", "name": "Stray `console.log` in TS/JS \u2014 server/smartRules/index.ts:66", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/index.ts:66"}, "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-fe2c442da9b67e44", "name": "Stray `console.log` in TS/JS \u2014 server/smartRules/replyClassifier.ts:366", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/replyClassifier.ts:366"}, "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-3b25248e20cf7667", "name": "Stray `console.log` in TS/JS \u2014 server/smartRules/cronJobs.ts:122", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/cronJobs.ts:122"}, "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-f2282fd6f7becd1d", "name": "Stray `console.log` in TS/JS \u2014 server/smartRules/trackingPixel.ts:73", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/trackingPixel.ts:73"}, "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-db850e266536d17e", "name": "Stray `console.log` in TS/JS \u2014 server/smartRules/scheduledJobs.ts:71", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/scheduledJobs.ts:71"}, "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-3be10556ad3d95c0", "name": "Stray `console.log` in TS/JS \u2014 server/_core/authRoutes.ts:453", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/authRoutes.ts:453"}, "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-82cb869af5e2a40d", "name": "Stray `console.log` in TS/JS \u2014 server/_core/voiceTranscription.ts:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/voiceTranscription.ts:14"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d3029fb270b4c822", "name": "TODO/FIXME marker in shipping code \u2014 server/_core/securityLogger.ts:60", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 server/_core/securityLogger.ts:60"}, "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-90a0331193d4e64a", "name": "Stray `console.log` in TS/JS \u2014 server/_core/securityLogger.ts:57", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/securityLogger.ts:57"}, "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-281faf4ba24ccc00", "name": "Stray `console.log` in TS/JS \u2014 server/_core/index.ts:239", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/index.ts:239"}, "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-dd07cf6e89f8c05b", "name": "Stray `console.log` in TS/JS \u2014 server/_core/sentry.ts:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/sentry.ts:12"}, "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-879465613515fe51", "name": "Stray `console.log` in TS/JS \u2014 server/_core/sdk.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/sdk.ts:33"}, "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-0798f492e8031937", "name": "Stray `console.log` in TS/JS \u2014 server/services/enrichmentScheduler.ts:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/services/enrichmentScheduler.ts:18"}, "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-98437c22d40c0960", "name": "Stray `console.log` in TS/JS \u2014 server/services/autoEnrichment.ts:285", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/services/autoEnrichment.ts:285"}, "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-06eae2bb05866ac0", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/SEOFooter.tsx:156", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/SEOFooter.tsx:156"}, "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-8df37d9232a59094", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ui/chart.tsx:81", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ui/chart.tsx:81"}, "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-fa722f1a90e94098", "name": "Possible secret in e2e/helpers/auth.ts", "shortDescription": {"text": "Possible secret in e2e/helpers/auth.ts"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-52ee086655d1e2c4", "name": "Very large file: client/src/pages/Admin.tsx (1960 lines)", "shortDescription": {"text": "Very large file: client/src/pages/Admin.tsx (1960 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-cfb82aa1f8415f5d", "name": "Very large file: client/src/pages/ComponentShowcase.tsx (1437 lines)", "shortDescription": {"text": "Very large file: client/src/pages/ComponentShowcase.tsx (1437 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-441f2bc5265298c3", "name": "Very large file: server/db.ts (3587 lines)", "shortDescription": {"text": "Very large file: server/db.ts (3587 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": "21 test file(s) for 239 source file(s) (ratio 0.09). 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 118 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 170 placeholder/mock markers across 48 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-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-dff01cc06aacf241", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/main.tsx:71", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/main.tsx: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-085d69eec1bbd3e5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/components/NotificationCenter.tsx:93", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/components/NotificationCenter.tsx: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-2132bec73868a640", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/components/admin/BrregTab.tsx:151", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/components/admin/BrregTab.tsx:151"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9a2920fd3f11b33d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/trpc.ts:16", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/trpc.ts:16"}, "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-204773d28ea8134a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/pages/Account.tsx:143", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/pages/Account.tsx:143"}, "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-874b69b67b47344b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/pages/Admin.tsx:227", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/pages/Admin.tsx:227"}, "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-6503e30fad639faf", "name": "Legacy-named symbol `daysOld` in client/src/pages/AutoEnrichment.tsx:322", "shortDescription": {"text": "Legacy-named symbol `daysOld` in client/src/pages/AutoEnrichment.tsx:322"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cc6d696821e5b241", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/_core/hooks/useAuth.ts:57", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/_core/hooks/useAuth.ts:57"}, "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-8d021be04ff81900", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/storage.ts:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/storage.ts:37"}, "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-6b1cf84e731fd12a", "name": "Legacy-named symbol `daysOld` in server/routers.ts:640", "shortDescription": {"text": "Legacy-named symbol `daysOld` in server/routers.ts:640"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d2b60431a36ac5b5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/db.ts:3147", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/db.ts:3147"}, "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-eabe2a263301353e", "name": "Commented-code block (5 lines) in server/_core/authRoutes.ts:447", "shortDescription": {"text": "Commented-code block (5 lines) in server/_core/authRoutes.ts:447"}, "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-63388381d87440f1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/dataApi.ts:31", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/dataApi.ts:31"}, "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-bbc7ef99c13a4303", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/imageGeneration.ts:53", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/imageGeneration.ts:53"}, "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-c895968505b611b0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/map.ts:74", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/map.ts:74"}, "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-e780f51f06116fad", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/llm.ts:315", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/llm.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-79cc994daf5a76fc", "name": "Legacy-named symbol `daysOld` in server/services/autoEnrichment.ts:246", "shortDescription": {"text": "Legacy-named symbol `daysOld` in server/services/autoEnrichment.ts:246"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-63a20ded0d387c3b", "name": "Legacy-named symbol `yearsOld` in server/services/leadScoring.ts:155", "shortDescription": {"text": "Legacy-named symbol `yearsOld` in server/services/leadScoring.ts:155"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7c8b918e1fee9558", "name": "20 env vars used in code but missing from .env.example", "shortDescription": {"text": "20 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `APP_URL`, `CI`, `DB_HOST`, `DB_NAME`, `DB_PASS`, `DB_PORT`, `DB_USER`, `DEV` + 12 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e39d2465c8ac0021", "name": "Frontend route `/settings` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/settings` has no Link/navigate to it \u2014 client/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-c28d7a5e777e7469", "name": "Frontend route `/enrichment` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/enrichment` has no Link/navigate to it \u2014 client/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-cc64026b376e3823", "name": "Frontend route `/profile` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/profile` has no Link/navigate to it \u2014 client/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-a408988be4d3e13e", "name": "Frontend route `/bedrifter/:city` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/bedrifter/:city` has no Link/navigate to it \u2014 client/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-76efdac98b04e2b0", "name": "Frontend route `/bransjer/:industry` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/bransjer/:industry` has no Link/navigate to it \u2014 client/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-dc03034258464ee9", "name": "Frontend route `/404` has no Link/navigate to it \u2014 client/src/main.tsx", "shortDescription": {"text": "Frontend route `/404` has no Link/navigate to it \u2014 client/src/main.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-2916b84088050996", "name": "Frontend route `/sentry-test` has no Link/navigate to it \u2014 client/src/App.tsx", "shortDescription": {"text": "Frontend route `/sentry-test` has no Link/navigate to it \u2014 client/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-21ac124bf742c244", "name": "Dangling fetch: GET /api/trpc/brreg.search?${queryParams} (client/src/components/admin/BrregTab.tsx:151)", "shortDescription": {"text": "Dangling fetch: GET /api/trpc/brreg.search?${queryParams} (client/src/components/admin/BrregTab.tsx:151)"}, "fullDescription": {"text": "`client/src/components/admin/BrregTab.tsx:151` calls `GET /api/trpc/brreg.search?${queryParams}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/brreg.search`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-1a814a1ee7c22511", "name": "Dangling fetch: GET /api/trpc/brreg.enrichCompany?${queryParams} (client/src/components/admin/BrregTab.tsx:180)", "shortDescription": {"text": "Dangling fetch: GET /api/trpc/brreg.enrichCompany?${queryParams} (client/src/components/admin/BrregTab.tsx:180)"}, "fullDescription": {"text": "`client/src/components/admin/BrregTab.tsx:180` calls `GET /api/trpc/brreg.enrichCompany?${queryParams}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/brreg.enrichcompany`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-94f12786d79ba982", "name": "Dangling fetch: POST /api/trpc/brreg.importFromSearch (client/src/components/admin/BrregTab.tsx:202)", "shortDescription": {"text": "Dangling fetch: POST /api/trpc/brreg.importFromSearch (client/src/components/admin/BrregTab.tsx:202)"}, "fullDescription": {"text": "`client/src/components/admin/BrregTab.tsx:202` calls `POST /api/trpc/brreg.importFromSearch` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/brreg.importfromsearch`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b9bf8705cc5123f3", "name": "Dangling fetch: POST /api/trpc/brreg.bulkSync (client/src/components/admin/BrregTab.tsx:236)", "shortDescription": {"text": "Dangling fetch: POST /api/trpc/brreg.bulkSync (client/src/components/admin/BrregTab.tsx:236)"}, "fullDescription": {"text": "`client/src/components/admin/BrregTab.tsx:236` calls `POST /api/trpc/brreg.bulkSync` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/brreg.bulksync`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c101e086f33dae60", "name": "Dangling fetch: GET /api/stripe/subscription (client/src/pages/Account.tsx:136)", "shortDescription": {"text": "Dangling fetch: GET /api/stripe/subscription (client/src/pages/Account.tsx:136)"}, "fullDescription": {"text": "`client/src/pages/Account.tsx:136` calls `GET /api/stripe/subscription` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/stripe/subscription`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8cd99c1aebeab1db", "name": "Dangling fetch: GET /api/user/usage (client/src/pages/Account.tsx:143)", "shortDescription": {"text": "Dangling fetch: GET /api/user/usage (client/src/pages/Account.tsx:143)"}, "fullDescription": {"text": "`client/src/pages/Account.tsx:143` calls `GET /api/user/usage` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/user/usage`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a39ebf5161c5036a", "name": "Dangling fetch: GET /api/stripe/invoices (client/src/pages/Account.tsx:150)", "shortDescription": {"text": "Dangling fetch: GET /api/stripe/invoices (client/src/pages/Account.tsx:150)"}, "fullDescription": {"text": "`client/src/pages/Account.tsx:150` calls `GET /api/stripe/invoices` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/stripe/invoices`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6aac9dc725aab28b", "name": "Dangling fetch: POST /api/stripe/create-checkout-session (client/src/pages/Account.tsx:216)", "shortDescription": {"text": "Dangling fetch: POST /api/stripe/create-checkout-session (client/src/pages/Account.tsx:216)"}, "fullDescription": {"text": "`client/src/pages/Account.tsx:216` calls `POST /api/stripe/create-checkout-session` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/stripe/create-checkout-session`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e7720cad9013cffb", "name": "Dangling fetch: POST /api/stripe/create-portal-session (client/src/pages/Account.tsx:234)", "shortDescription": {"text": "Dangling fetch: POST /api/stripe/create-portal-session (client/src/pages/Account.tsx:234)"}, "fullDescription": {"text": "`client/src/pages/Account.tsx:234` calls `POST /api/stripe/create-portal-session` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/stripe/create-portal-session`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-6c4d94618f53874f", "name": "Dangling fetch: POST /api/stripe/cancel-subscription (client/src/pages/Account.tsx:251)", "shortDescription": {"text": "Dangling fetch: POST /api/stripe/cancel-subscription (client/src/pages/Account.tsx:251)"}, "fullDescription": {"text": "`client/src/pages/Account.tsx:251` calls `POST /api/stripe/cancel-subscription` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/stripe/cancel-subscription`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-90166beda392edf2", "name": "Dangling fetch: POST /api/trpc/deliverability.check?batch=1 (client/src/pages/Admin.tsx:159)", "shortDescription": {"text": "Dangling fetch: POST /api/trpc/deliverability.check?batch=1 (client/src/pages/Admin.tsx:159)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:159` calls `POST /api/trpc/deliverability.check?batch=1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/deliverability.check`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c6b980a726a167e1", "name": "Dangling fetch: POST /api/trpc/brreg.syncNow?batch=1 (client/src/pages/Admin.tsx:179)", "shortDescription": {"text": "Dangling fetch: POST /api/trpc/brreg.syncNow?batch=1 (client/src/pages/Admin.tsx:179)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:179` calls `POST /api/trpc/brreg.syncNow?batch=1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/brreg.syncnow`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c878b2d7fb02c17e", "name": "Dangling fetch: GET /api/trpc/emailFinder.getStats (client/src/pages/Admin.tsx:206)", "shortDescription": {"text": "Dangling fetch: GET /api/trpc/emailFinder.getStats (client/src/pages/Admin.tsx:206)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:206` calls `GET /api/trpc/emailFinder.getStats` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/emailfinder.getstats`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-342bb3a961a94eb4", "name": "Dangling fetch: GET /api/trpc/emailFinder.getCompaniesWithoutEmail?${params} (client/src/pages/Admin.tsx:227)", "shortDescription": {"text": "Dangling fetch: GET /api/trpc/emailFinder.getCompaniesWithoutEmail?${params} (client/src/pages/Admin.tsx:227)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:227` calls `GET /api/trpc/emailFinder.getCompaniesWithoutEmail?${params}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/emailfinder.getcompanieswithoutemail`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0c81a511b66b357f", "name": "Dangling fetch: POST /api/trpc/emailFinder.findEmail (client/src/pages/Admin.tsx:249)", "shortDescription": {"text": "Dangling fetch: POST /api/trpc/emailFinder.findEmail (client/src/pages/Admin.tsx:249)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:249` calls `POST /api/trpc/emailFinder.findEmail` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/emailfinder.findemail`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0d8d95aad3eda9b3", "name": "Dangling fetch: POST /api/trpc/emailFinder.autoEnrich (client/src/pages/Admin.tsx:291)", "shortDescription": {"text": "Dangling fetch: POST /api/trpc/emailFinder.autoEnrich (client/src/pages/Admin.tsx:291)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:291` calls `POST /api/trpc/emailFinder.autoEnrich` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/emailfinder.autoenrich`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b96b990ecc780464", "name": "Dangling fetch: PUT /api/admin/users/${changePlanDialog.user.id}/plan (client/src/pages/Admin.tsx:697)", "shortDescription": {"text": "Dangling fetch: PUT /api/admin/users/${changePlanDialog.user.id}/plan (client/src/pages/Admin.tsx:697)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:697` calls `PUT /api/admin/users/${changePlanDialog.user.id}/plan` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users/<p>/plan`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7a66d86bfa7ccd09", "name": "Dangling fetch: PUT /api/admin/users/${userId}/status (client/src/pages/Admin.tsx:724)", "shortDescription": {"text": "Dangling fetch: PUT /api/admin/users/${userId}/status (client/src/pages/Admin.tsx:724)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:724` calls `PUT /api/admin/users/${userId}/status` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users/<p>/status`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-95a795b53baa5ecb", "name": "Dangling fetch: POST /api/admin/send-email (client/src/pages/Admin.tsx:770)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/send-email (client/src/pages/Admin.tsx:770)"}, "fullDescription": {"text": "`client/src/pages/Admin.tsx:770` calls `POST /api/admin/send-email` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/send-email`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-99660024137acfec", "name": "Dangling fetch: POST /api/trpc/test.throwError (client/src/pages/SentryTest.tsx:34)", "shortDescription": {"text": "Dangling fetch: POST /api/trpc/test.throwError (client/src/pages/SentryTest.tsx:34)"}, "fullDescription": {"text": "`client/src/pages/SentryTest.tsx:34` calls `POST /api/trpc/test.throwError` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trpc/test.throwerror`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c0e752a701f4b587", "name": "Dangling fetch: POST /track/unsubscribe/${trackingId} (server/trackingRoutes.ts:203)", "shortDescription": {"text": "Dangling fetch: POST /track/unsubscribe/${trackingId} (server/trackingRoutes.ts:203)"}, "fullDescription": {"text": "`server/trackingRoutes.ts:203` calls `POST /track/unsubscribe/${trackingId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/track/unsubscribe/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-630c69c3a996de23", "name": "Unused endpoint: GET /open/:trackingId", "shortDescription": {"text": "Unused endpoint: GET /open/:trackingId"}, "fullDescription": {"text": "`server/trackingRoutes.ts` declares `GET /open/:trackingId` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-27201e63f000ecd6", "name": "Unused endpoint: GET /click/:trackingId/:encodedUrl", "shortDescription": {"text": "Unused endpoint: GET /click/:trackingId/:encodedUrl"}, "fullDescription": {"text": "`server/trackingRoutes.ts` declares `GET /click/:trackingId/:encodedUrl` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ec93fa94f90c819e", "name": "Unused endpoint: GET /unsubscribe/:trackingId", "shortDescription": {"text": "Unused endpoint: GET /unsubscribe/:trackingId"}, "fullDescription": {"text": "`server/trackingRoutes.ts` declares `GET /unsubscribe/:trackingId` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d8221a55f379cf0b", "name": "Unused endpoint: POST /unsubscribe/:trackingId", "shortDescription": {"text": "Unused endpoint: POST /unsubscribe/:trackingId"}, "fullDescription": {"text": "`server/trackingRoutes.ts` declares `POST /unsubscribe/:trackingId` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`server/smartRules/webhooks.ts` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`server/smartRules/webhooks.ts` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8d5b2b188d08ca82", "name": "Unused endpoint: PUT /:id", "shortDescription": {"text": "Unused endpoint: PUT /:id"}, "fullDescription": {"text": "`server/smartRules/webhooks.ts` declares `PUT /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a61c112b611f4bb", "name": "Unused endpoint: DELETE /:id", "shortDescription": {"text": "Unused endpoint: DELETE /:id"}, "fullDescription": {"text": "`server/smartRules/webhooks.ts` declares `DELETE /:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-09b1d89ab53d3a78", "name": "Unused endpoint: POST /:id/test", "shortDescription": {"text": "Unused endpoint: POST /:id/test"}, "fullDescription": {"text": "`server/smartRules/webhooks.ts` declares `POST /:id/test` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0b4068952b446c50", "name": "Unused endpoint: GET /:id/logs", "shortDescription": {"text": "Unused endpoint: GET /:id/logs"}, "fullDescription": {"text": "`server/smartRules/webhooks.ts` declares `GET /:id/logs` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-43269e4e79c2e69e", "name": "Unused endpoint: GET /events", "shortDescription": {"text": "Unused endpoint: GET /events"}, "fullDescription": {"text": "`server/smartRules/webhooks.ts` declares `GET /events` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7c9c5f425f411f5c", "name": "Unused endpoint: GET /open/:trackingId.gif", "shortDescription": {"text": "Unused endpoint: GET /open/:trackingId.gif"}, "fullDescription": {"text": "`server/smartRules/trackingPixel.ts` declares `GET /open/:trackingId.gif` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2f8ef5e95259d18f", "name": "Unused endpoint: GET /click/:trackingId/:linkId", "shortDescription": {"text": "Unused endpoint: GET /click/:trackingId/:linkId"}, "fullDescription": {"text": "`server/smartRules/trackingPixel.ts` declares `GET /click/:trackingId/:linkId` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8a16fda24126d178", "name": "Unused endpoint: POST /api/auth/logout-all", "shortDescription": {"text": "Unused endpoint: POST /api/auth/logout-all"}, "fullDescription": {"text": "`server/_core/authRoutes.ts` declares `POST /api/auth/logout-all` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-76f7964d6c782e43", "name": "Unused endpoint: POST /api/stripe/webhook", "shortDescription": {"text": "Unused endpoint: POST /api/stripe/webhook"}, "fullDescription": {"text": "`server/_core/index.ts` declares `POST /api/stripe/webhook` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aa9e6eee88be93f1", "name": "Unused endpoint: POST /api/sendgrid/inbound", "shortDescription": {"text": "Unused endpoint: POST /api/sendgrid/inbound"}, "fullDescription": {"text": "`server/_core/index.ts` declares `POST /api/sendgrid/inbound` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8bf2f7ca3faa1f1b", "name": "Unused endpoint: USE /api/auth/login", "shortDescription": {"text": "Unused endpoint: USE /api/auth/login"}, "fullDescription": {"text": "`server/_core/index.ts` declares `USE /api/auth/login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-def16861a13564b0", "name": "Unused endpoint: USE /api/auth/register", "shortDescription": {"text": "Unused endpoint: USE /api/auth/register"}, "fullDescription": {"text": "`server/_core/index.ts` declares `USE /api/auth/register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0bfca63377edb533", "name": "Unused endpoint: USE /api/auth/forgot-password", "shortDescription": {"text": "Unused endpoint: USE /api/auth/forgot-password"}, "fullDescription": {"text": "`server/_core/index.ts` declares `USE /api/auth/forgot-password` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6eb452fbfb454d20", "name": "Unused endpoint: USE /api/auth", "shortDescription": {"text": "Unused endpoint: USE /api/auth"}, "fullDescription": {"text": "`server/_core/index.ts` declares `USE /api/auth` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-abbc1e2493e46ef1", "name": "Unused endpoint: USE /api/track", "shortDescription": {"text": "Unused endpoint: USE /api/track"}, "fullDescription": {"text": "`server/_core/index.ts` declares `USE /api/track` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-360c6c99547c3232", "name": "Unused endpoint: POST /api/sendgrid/webhook", "shortDescription": {"text": "Unused endpoint: POST /api/sendgrid/webhook"}, "fullDescription": {"text": "`server/_core/index.ts` declares `POST /api/sendgrid/webhook` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ac1c4924f32c1d79", "name": "Unused endpoint: USE /api/trpc", "shortDescription": {"text": "Unused endpoint: USE /api/trpc"}, "fullDescription": {"text": "`server/_core/index.ts` declares `USE /api/trpc` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-acbaaa9e533b33f5", "name": "Unused endpoint: GET /api/oauth/callback", "shortDescription": {"text": "Unused endpoint: GET /api/oauth/callback"}, "fullDescription": {"text": "`server/_core/oauth.ts` declares `GET /api/oauth/callback` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3c8bb190c50a9df5", "name": "Unused endpoint: GET /api/admin/companies/stats", "shortDescription": {"text": "Unused endpoint: GET /api/admin/companies/stats"}, "fullDescription": {"text": "`server/_core/adminRoutes.ts` declares `GET /api/admin/companies/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/20799"}, "properties": {"repository": "Tamerb86/norsk-lead-ai", "repoUrl": "https://github.com/Tamerb86/norsk-lead-ai", "branch": "main"}, "results": [{"ruleId": "scanner-cc9a4323a7dcd6d2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/DashboardLayout.tsx:243"}, "properties": {"repobilityId": "f6824b43e2afadd4", "scanner": "scanner-primary", "fingerprint": "cc9a4323a7dcd6d2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6eac27f0ae630081", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/SEOFooter.tsx:156"}, "properties": {"repobilityId": "f96411593fa1ae1d", "scanner": "scanner-primary", "fingerprint": "6eac27f0ae630081", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-7ac91878b37b4f08", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/LeadScoreBadge.tsx:170"}, "properties": {"repobilityId": "f414ffac8cf99fd6", "scanner": "scanner-primary", "fingerprint": "7ac91878b37b4f08", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fd54759add2cc305", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/EmailVerificationBadge.tsx:122"}, "properties": {"repobilityId": "389366d31f46d1ba", "scanner": "scanner-primary", "fingerprint": "fd54759add2cc305", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-92f28d55a595968e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 client/src/components/Analytics.tsx:22"}, "properties": {"repobilityId": "469a3190f40d170c", "scanner": "scanner-primary", "fingerprint": "92f28d55a595968e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-992778b41539817d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 client/src/components/PWAPrompt.tsx:16"}, "properties": {"repobilityId": "bd89f0dafdd4af35", "scanner": "scanner-primary", "fingerprint": "992778b41539817d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a7b3db9745e9c497", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ui/chart.tsx:81"}, "properties": {"repobilityId": "1c3a04e593515dbe", "scanner": "scanner-primary", "fingerprint": "a7b3db9745e9c497", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-784333a1e99c71cc", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/WidgetComponents.tsx:441"}, "properties": {"repobilityId": "a6eb1bdcb5606b6c", "scanner": "scanner-primary", "fingerprint": "784333a1e99c71cc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5a169b983fa32605", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 client/src/pages/Contact.tsx:23"}, "properties": {"repobilityId": "402a6dd099f6301c", "scanner": "scanner-primary", "fingerprint": "5a169b983fa32605", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-0017b9dfaabed9d9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Webhooks.tsx:496"}, "properties": {"repobilityId": "37e25dcbbdcd43f8", "scanner": "scanner-primary", "fingerprint": "0017b9dfaabed9d9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-28314740d0e477c0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 client/src/pages/Docs.tsx:134"}, "properties": {"repobilityId": "298922f2cada2a0c", "scanner": "scanner-primary", "fingerprint": "28314740d0e477c0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6e35229700d27b06", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/ActivityLog.tsx:299"}, "properties": {"repobilityId": "64a479eca7284cf3", "scanner": "scanner-primary", "fingerprint": "6e35229700d27b06", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2e6376d8694880de", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Leads.tsx:336"}, "properties": {"repobilityId": "cb791030b3b43e86", "scanner": "scanner-primary", "fingerprint": "2e6376d8694880de", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4f25008c55c74f1b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Inbox.tsx:292"}, "properties": {"repobilityId": "d7009406a862bf86", "scanner": "scanner-primary", "fingerprint": "4f25008c55c74f1b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f4a58cb50ea28277", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Templates.tsx:558"}, "properties": {"repobilityId": "8e1e3e1941eeeec0", "scanner": "scanner-primary", "fingerprint": "f4a58cb50ea28277", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-37446b0354111e2f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/Search.tsx:901"}, "properties": {"repobilityId": "6f713e904f16b0de", "scanner": "scanner-primary", "fingerprint": "37446b0354111e2f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cbdd2551c2855954", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 client/src/pages/ComponentShowcase.tsx:197"}, "properties": {"repobilityId": "625b517500d9096d", "scanner": "scanner-primary", "fingerprint": "cbdd2551c2855954", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8779a216eb4e349d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/inboundWebhook.ts:86"}, "properties": {"repobilityId": "4aab8685cea4b9c9", "scanner": "scanner-primary", "fingerprint": "8779a216eb4e349d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-12483002697ea50b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/emailQueueProcessor.ts:38"}, "properties": {"repobilityId": "d3078495e97c08c1", "scanner": "scanner-primary", "fingerprint": "12483002697ea50b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2bea101eab56b8fe", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/emailService.ts:25"}, "properties": {"repobilityId": "7e7fc7e1a5e72a04", "scanner": "scanner-primary", "fingerprint": "2bea101eab56b8fe", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e8628c8b63e20224", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/sendgridWebhook.ts:98"}, "properties": {"repobilityId": "41b9eacb0697d472", "scanner": "scanner-primary", "fingerprint": "e8628c8b63e20224", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-dec4fa179c9d66b0", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 server/db.ts:836"}, "properties": {"repobilityId": "ba88ddc99b541321", "scanner": "scanner-primary", "fingerprint": "dec4fa179c9d66b0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-5f6873feaad566a6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/db.ts:58"}, "properties": {"repobilityId": "d6b4a075df42d670", "scanner": "scanner-primary", "fingerprint": "5f6873feaad566a6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8e61da0074ec82f6", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 server/queueDb.ts:194"}, "properties": {"repobilityId": "4f96505c44e0407e", "scanner": "scanner-primary", "fingerprint": "8e61da0074ec82f6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-81143abe4cfee528", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/queueDb.ts:185"}, "properties": {"repobilityId": "19228ddd256b5455", "scanner": "scanner-primary", "fingerprint": "81143abe4cfee528", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-456c1a097cfa14d7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/stripeWebhook.ts:57"}, "properties": {"repobilityId": "aab7908fe682c042", "scanner": "scanner-primary", "fingerprint": "456c1a097cfa14d7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f620f13f6c81081a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/webhooks.ts:160"}, "properties": {"repobilityId": "0d5360cb2ed9ad69", "scanner": "scanner-primary", "fingerprint": "f620f13f6c81081a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4503f792171660c3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/index.ts:66"}, "properties": {"repobilityId": "45c653e1c9fb1710", "scanner": "scanner-primary", "fingerprint": "4503f792171660c3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fe2c442da9b67e44", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/replyClassifier.ts:366"}, "properties": {"repobilityId": "44c36434688c16f9", "scanner": "scanner-primary", "fingerprint": "fe2c442da9b67e44", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3b25248e20cf7667", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/cronJobs.ts:122"}, "properties": {"repobilityId": "485b35a7c990f46b", "scanner": "scanner-primary", "fingerprint": "3b25248e20cf7667", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f2282fd6f7becd1d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/trackingPixel.ts:73"}, "properties": {"repobilityId": "5c8a810ca4d51f9f", "scanner": "scanner-primary", "fingerprint": "f2282fd6f7becd1d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-db850e266536d17e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/smartRules/scheduledJobs.ts:71"}, "properties": {"repobilityId": "8f3c27b8653ac628", "scanner": "scanner-primary", "fingerprint": "db850e266536d17e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3be10556ad3d95c0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/authRoutes.ts:453"}, "properties": {"repobilityId": "24fcf3159939fe1b", "scanner": "scanner-primary", "fingerprint": "3be10556ad3d95c0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-82cb869af5e2a40d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/voiceTranscription.ts:14"}, "properties": {"repobilityId": "b01c83469f71cf51", "scanner": "scanner-primary", "fingerprint": "82cb869af5e2a40d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d3029fb270b4c822", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 server/_core/securityLogger.ts:60"}, "properties": {"repobilityId": "419df1c62e70b90c", "scanner": "scanner-primary", "fingerprint": "d3029fb270b4c822", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-90a0331193d4e64a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/securityLogger.ts:57"}, "properties": {"repobilityId": "115cfabeaee27fbd", "scanner": "scanner-primary", "fingerprint": "90a0331193d4e64a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-281faf4ba24ccc00", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/index.ts:239"}, "properties": {"repobilityId": "222c2b877d341bd4", "scanner": "scanner-primary", "fingerprint": "281faf4ba24ccc00", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-dd07cf6e89f8c05b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/sentry.ts:12"}, "properties": {"repobilityId": "0b1c0b61048f7b6b", "scanner": "scanner-primary", "fingerprint": "dd07cf6e89f8c05b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-879465613515fe51", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/_core/sdk.ts:33"}, "properties": {"repobilityId": "e4e38532158319c4", "scanner": "scanner-primary", "fingerprint": "879465613515fe51", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0798f492e8031937", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/services/enrichmentScheduler.ts:18"}, "properties": {"repobilityId": "6c69bfcc1fda7e42", "scanner": "scanner-primary", "fingerprint": "0798f492e8031937", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-98437c22d40c0960", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/services/autoEnrichment.ts:285"}, "properties": {"repobilityId": "e69f751a0d7038fe", "scanner": "scanner-primary", "fingerprint": "98437c22d40c0960", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-06eae2bb05866ac0", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/SEOFooter.tsx:156"}, "properties": {"repobilityId": "58669f8fd1540542", "scanner": "scanner-primary", "fingerprint": "06eae2bb05866ac0", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/SEOFooter.tsx"}, "region": {"startLine": 156}}}]}, {"ruleId": "scanner-8df37d9232a59094", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ui/chart.tsx:81"}, "properties": {"repobilityId": "298aaf10501f50f1", "scanner": "scanner-primary", "fingerprint": "8df37d9232a59094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/ui/chart.tsx"}, "region": {"startLine": 81}}}]}, {"ruleId": "scanner-fa722f1a90e94098", "level": "error", "message": {"text": "Possible secret in e2e/helpers/auth.ts"}, "properties": {"repobilityId": "10353351341b1da7", "scanner": "scanner-primary", "fingerprint": "fa722f1a90e94098", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "e2e/helpers/auth.ts"}, "region": {"startLine": 13}}}]}, {"ruleId": "scanner-52ee086655d1e2c4", "level": "note", "message": {"text": "Very large file: client/src/pages/Admin.tsx (1960 lines)"}, "properties": {"repobilityId": "e50f426e904e8def", "scanner": "scanner-primary", "fingerprint": "52ee086655d1e2c4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-cfb82aa1f8415f5d", "level": "note", "message": {"text": "Very large file: client/src/pages/ComponentShowcase.tsx (1437 lines)"}, "properties": {"repobilityId": "96a173a0d62b652e", "scanner": "scanner-primary", "fingerprint": "cfb82aa1f8415f5d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-441f2bc5265298c3", "level": "note", "message": {"text": "Very large file: server/db.ts (3587 lines)"}, "properties": {"repobilityId": "044454e4c1fd13d8", "scanner": "scanner-primary", "fingerprint": "441f2bc5265298c3", "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": "dcbdab16c5374a3c", "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": "105fdccb6bf892f7", "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": "d2ad7af523537cf8", "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": "486dee8fb41d758d", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "aac998e1c318e797", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "ee6c4c627007a636", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-dff01cc06aacf241", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/main.tsx:71"}, "properties": {"repobilityId": "f27e231ed643b6e9", "scanner": "scanner-primary", "fingerprint": "dff01cc06aacf241", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-085d69eec1bbd3e5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/components/NotificationCenter.tsx:93"}, "properties": {"repobilityId": "0021d9c80fd56126", "scanner": "scanner-primary", "fingerprint": "085d69eec1bbd3e5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2132bec73868a640", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/components/admin/BrregTab.tsx:151"}, "properties": {"repobilityId": "74f5bea67aeec7fe", "scanner": "scanner-primary", "fingerprint": "2132bec73868a640", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9a2920fd3f11b33d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/trpc.ts:16"}, "properties": {"repobilityId": "62aa7d274c2911af", "scanner": "scanner-primary", "fingerprint": "9a2920fd3f11b33d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-204773d28ea8134a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/pages/Account.tsx:143"}, "properties": {"repobilityId": "df895003cee2e336", "scanner": "scanner-primary", "fingerprint": "204773d28ea8134a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-874b69b67b47344b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/pages/Admin.tsx:227"}, "properties": {"repobilityId": "0cab82145dee922c", "scanner": "scanner-primary", "fingerprint": "874b69b67b47344b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6503e30fad639faf", "level": "note", "message": {"text": "Legacy-named symbol `daysOld` in client/src/pages/AutoEnrichment.tsx:322"}, "properties": {"repobilityId": "b12ed253ba17675c", "scanner": "scanner-primary", "fingerprint": "6503e30fad639faf", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-cc6d696821e5b241", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/_core/hooks/useAuth.ts:57"}, "properties": {"repobilityId": "09c8ec26d78eb095", "scanner": "scanner-primary", "fingerprint": "cc6d696821e5b241", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8d021be04ff81900", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/storage.ts:37"}, "properties": {"repobilityId": "7c15970f9996fb19", "scanner": "scanner-primary", "fingerprint": "8d021be04ff81900", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6b1cf84e731fd12a", "level": "note", "message": {"text": "Legacy-named symbol `daysOld` in server/routers.ts:640"}, "properties": {"repobilityId": "7739ff4185565c7e", "scanner": "scanner-primary", "fingerprint": "6b1cf84e731fd12a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-d2b60431a36ac5b5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/db.ts:3147"}, "properties": {"repobilityId": "704e654c8570f447", "scanner": "scanner-primary", "fingerprint": "d2b60431a36ac5b5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-eabe2a263301353e", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/_core/authRoutes.ts:447"}, "properties": {"repobilityId": "c5208fd3d69f3679", "scanner": "scanner-primary", "fingerprint": "eabe2a263301353e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-63388381d87440f1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/dataApi.ts:31"}, "properties": {"repobilityId": "59c8d55833bbf770", "scanner": "scanner-primary", "fingerprint": "63388381d87440f1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bbc7ef99c13a4303", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/imageGeneration.ts:53"}, "properties": {"repobilityId": "fabacf3af88234d0", "scanner": "scanner-primary", "fingerprint": "bbc7ef99c13a4303", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c895968505b611b0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/map.ts:74"}, "properties": {"repobilityId": "3f801d7d4a46ad95", "scanner": "scanner-primary", "fingerprint": "c895968505b611b0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e780f51f06116fad", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/_core/llm.ts:315"}, "properties": {"repobilityId": "bef0d3a8885c928e", "scanner": "scanner-primary", "fingerprint": "e780f51f06116fad", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-79cc994daf5a76fc", "level": "note", "message": {"text": "Legacy-named symbol `daysOld` in server/services/autoEnrichment.ts:246"}, "properties": {"repobilityId": "3e7795948562af4f", "scanner": "scanner-primary", "fingerprint": "79cc994daf5a76fc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-63a20ded0d387c3b", "level": "note", "message": {"text": "Legacy-named symbol `yearsOld` in server/services/leadScoring.ts:155"}, "properties": {"repobilityId": "012fadc28a7ad38b", "scanner": "scanner-primary", "fingerprint": "63a20ded0d387c3b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-7c8b918e1fee9558", "level": "note", "message": {"text": "20 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "bd1f6d44917e8105", "scanner": "scanner-primary", "fingerprint": "7c8b918e1fee9558", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-e39d2465c8ac0021", "level": "warning", "message": {"text": "Frontend route `/settings` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "94ac17d3e8808875", "scanner": "scanner-primary", "fingerprint": "e39d2465c8ac0021", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c28d7a5e777e7469", "level": "warning", "message": {"text": "Frontend route `/enrichment` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "4ad0614b9c976aaa", "scanner": "scanner-primary", "fingerprint": "c28d7a5e777e7469", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-cc64026b376e3823", "level": "warning", "message": {"text": "Frontend route `/profile` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "133a9d1bb86c91ba", "scanner": "scanner-primary", "fingerprint": "cc64026b376e3823", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a408988be4d3e13e", "level": "warning", "message": {"text": "Frontend route `/bedrifter/:city` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "115d75e94b86131c", "scanner": "scanner-primary", "fingerprint": "a408988be4d3e13e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-76efdac98b04e2b0", "level": "warning", "message": {"text": "Frontend route `/bransjer/:industry` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "704c17e32497ca28", "scanner": "scanner-primary", "fingerprint": "76efdac98b04e2b0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-dc03034258464ee9", "level": "warning", "message": {"text": "Frontend route `/404` has no Link/navigate to it \u2014 client/src/main.tsx"}, "properties": {"repobilityId": "334bcbe64a6e0876", "scanner": "scanner-primary", "fingerprint": "dc03034258464ee9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-2916b84088050996", "level": "warning", "message": {"text": "Frontend route `/sentry-test` has no Link/navigate to it \u2014 client/src/App.tsx"}, "properties": {"repobilityId": "6d3d66b60f6e7493", "scanner": "scanner-primary", "fingerprint": "2916b84088050996", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-21ac124bf742c244", "level": "error", "message": {"text": "Dangling fetch: GET /api/trpc/brreg.search?${queryParams} (client/src/components/admin/BrregTab.tsx:151)"}, "properties": {"repobilityId": "6d6f3951ef3de620", "scanner": "scanner-primary", "fingerprint": "21ac124bf742c244", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1a814a1ee7c22511", "level": "error", "message": {"text": "Dangling fetch: GET /api/trpc/brreg.enrichCompany?${queryParams} (client/src/components/admin/BrregTab.tsx:180)"}, "properties": {"repobilityId": "9b00a6ed0d05f9a7", "scanner": "scanner-primary", "fingerprint": "1a814a1ee7c22511", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-94f12786d79ba982", "level": "error", "message": {"text": "Dangling fetch: POST /api/trpc/brreg.importFromSearch (client/src/components/admin/BrregTab.tsx:202)"}, "properties": {"repobilityId": "77678ab2293b544a", "scanner": "scanner-primary", "fingerprint": "94f12786d79ba982", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b9bf8705cc5123f3", "level": "error", "message": {"text": "Dangling fetch: POST /api/trpc/brreg.bulkSync (client/src/components/admin/BrregTab.tsx:236)"}, "properties": {"repobilityId": "6bd0bf96d8f01fc4", "scanner": "scanner-primary", "fingerprint": "b9bf8705cc5123f3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c101e086f33dae60", "level": "error", "message": {"text": "Dangling fetch: GET /api/stripe/subscription (client/src/pages/Account.tsx:136)"}, "properties": {"repobilityId": "29294a09ee22ff9c", "scanner": "scanner-primary", "fingerprint": "c101e086f33dae60", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8cd99c1aebeab1db", "level": "error", "message": {"text": "Dangling fetch: GET /api/user/usage (client/src/pages/Account.tsx:143)"}, "properties": {"repobilityId": "857483c4a578d290", "scanner": "scanner-primary", "fingerprint": "8cd99c1aebeab1db", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a39ebf5161c5036a", "level": "error", "message": {"text": "Dangling fetch: GET /api/stripe/invoices (client/src/pages/Account.tsx:150)"}, "properties": {"repobilityId": "be81b652bf286c15", "scanner": "scanner-primary", "fingerprint": "a39ebf5161c5036a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6aac9dc725aab28b", "level": "error", "message": {"text": "Dangling fetch: POST /api/stripe/create-checkout-session (client/src/pages/Account.tsx:216)"}, "properties": {"repobilityId": "e56ccd66d7221074", "scanner": "scanner-primary", "fingerprint": "6aac9dc725aab28b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e7720cad9013cffb", "level": "error", "message": {"text": "Dangling fetch: POST /api/stripe/create-portal-session (client/src/pages/Account.tsx:234)"}, "properties": {"repobilityId": "a9b6f21bfc9ba47b", "scanner": "scanner-primary", "fingerprint": "e7720cad9013cffb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6c4d94618f53874f", "level": "error", "message": {"text": "Dangling fetch: POST /api/stripe/cancel-subscription (client/src/pages/Account.tsx:251)"}, "properties": {"repobilityId": "156aae9cc2be2639", "scanner": "scanner-primary", "fingerprint": "6c4d94618f53874f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-90166beda392edf2", "level": "error", "message": {"text": "Dangling fetch: POST /api/trpc/deliverability.check?batch=1 (client/src/pages/Admin.tsx:159)"}, "properties": {"repobilityId": "7119caf52361149f", "scanner": "scanner-primary", "fingerprint": "90166beda392edf2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c6b980a726a167e1", "level": "error", "message": {"text": "Dangling fetch: POST /api/trpc/brreg.syncNow?batch=1 (client/src/pages/Admin.tsx:179)"}, "properties": {"repobilityId": "2af3dd29508c3e4b", "scanner": "scanner-primary", "fingerprint": "c6b980a726a167e1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c878b2d7fb02c17e", "level": "error", "message": {"text": "Dangling fetch: GET /api/trpc/emailFinder.getStats (client/src/pages/Admin.tsx:206)"}, "properties": {"repobilityId": "28790a8e9213df11", "scanner": "scanner-primary", "fingerprint": "c878b2d7fb02c17e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-342bb3a961a94eb4", "level": "error", "message": {"text": "Dangling fetch: GET /api/trpc/emailFinder.getCompaniesWithoutEmail?${params} (client/src/pages/Admin.tsx:227)"}, "properties": {"repobilityId": "0a421df327ac3a46", "scanner": "scanner-primary", "fingerprint": "342bb3a961a94eb4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0c81a511b66b357f", "level": "error", "message": {"text": "Dangling fetch: POST /api/trpc/emailFinder.findEmail (client/src/pages/Admin.tsx:249)"}, "properties": {"repobilityId": "551092cdc90f2fca", "scanner": "scanner-primary", "fingerprint": "0c81a511b66b357f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0d8d95aad3eda9b3", "level": "error", "message": {"text": "Dangling fetch: POST /api/trpc/emailFinder.autoEnrich (client/src/pages/Admin.tsx:291)"}, "properties": {"repobilityId": "b37cdd1d39d9801f", "scanner": "scanner-primary", "fingerprint": "0d8d95aad3eda9b3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b96b990ecc780464", "level": "error", "message": {"text": "Dangling fetch: PUT /api/admin/users/${changePlanDialog.user.id}/plan (client/src/pages/Admin.tsx:697)"}, "properties": {"repobilityId": "ddb02a3c20bfaf2f", "scanner": "scanner-primary", "fingerprint": "b96b990ecc780464", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7a66d86bfa7ccd09", "level": "error", "message": {"text": "Dangling fetch: PUT /api/admin/users/${userId}/status (client/src/pages/Admin.tsx:724)"}, "properties": {"repobilityId": "45fc7df1a9e9f7bc", "scanner": "scanner-primary", "fingerprint": "7a66d86bfa7ccd09", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-95a795b53baa5ecb", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/send-email (client/src/pages/Admin.tsx:770)"}, "properties": {"repobilityId": "f4da2350dfff5b7f", "scanner": "scanner-primary", "fingerprint": "95a795b53baa5ecb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-99660024137acfec", "level": "error", "message": {"text": "Dangling fetch: POST /api/trpc/test.throwError (client/src/pages/SentryTest.tsx:34)"}, "properties": {"repobilityId": "f00e70d3d3acacdd", "scanner": "scanner-primary", "fingerprint": "99660024137acfec", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c0e752a701f4b587", "level": "error", "message": {"text": "Dangling fetch: POST /track/unsubscribe/${trackingId} (server/trackingRoutes.ts:203)"}, "properties": {"repobilityId": "b3d87aede69a956b", "scanner": "scanner-primary", "fingerprint": "c0e752a701f4b587", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-630c69c3a996de23", "level": "note", "message": {"text": "Unused endpoint: GET /open/:trackingId"}, "properties": {"repobilityId": "74cf90fedfeb5fb1", "scanner": "scanner-primary", "fingerprint": "630c69c3a996de23", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-27201e63f000ecd6", "level": "note", "message": {"text": "Unused endpoint: GET /click/:trackingId/:encodedUrl"}, "properties": {"repobilityId": "554e485c3eff9bf9", "scanner": "scanner-primary", "fingerprint": "27201e63f000ecd6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ec93fa94f90c819e", "level": "note", "message": {"text": "Unused endpoint: GET /unsubscribe/:trackingId"}, "properties": {"repobilityId": "959faa501d5f3a0b", "scanner": "scanner-primary", "fingerprint": "ec93fa94f90c819e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d8221a55f379cf0b", "level": "note", "message": {"text": "Unused endpoint: POST /unsubscribe/:trackingId"}, "properties": {"repobilityId": "bc854d57ff45381d", "scanner": "scanner-primary", "fingerprint": "d8221a55f379cf0b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "74845ae6b69660e7", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "6bc8f59f4b9191f4", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8d5b2b188d08ca82", "level": "note", "message": {"text": "Unused endpoint: PUT /:id"}, "properties": {"repobilityId": "1ed3deb559cb4c99", "scanner": "scanner-primary", "fingerprint": "8d5b2b188d08ca82", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a61c112b611f4bb", "level": "note", "message": {"text": "Unused endpoint: DELETE /:id"}, "properties": {"repobilityId": "662d1852871a25a2", "scanner": "scanner-primary", "fingerprint": "7a61c112b611f4bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-09b1d89ab53d3a78", "level": "note", "message": {"text": "Unused endpoint: POST /:id/test"}, "properties": {"repobilityId": "b12e6eb06b0c2008", "scanner": "scanner-primary", "fingerprint": "09b1d89ab53d3a78", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0b4068952b446c50", "level": "note", "message": {"text": "Unused endpoint: GET /:id/logs"}, "properties": {"repobilityId": "4a56094a4d84a9e8", "scanner": "scanner-primary", "fingerprint": "0b4068952b446c50", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-43269e4e79c2e69e", "level": "note", "message": {"text": "Unused endpoint: GET /events"}, "properties": {"repobilityId": "4ed809e987f6743f", "scanner": "scanner-primary", "fingerprint": "43269e4e79c2e69e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c9c5f425f411f5c", "level": "note", "message": {"text": "Unused endpoint: GET /open/:trackingId.gif"}, "properties": {"repobilityId": "aff707b301e33b0e", "scanner": "scanner-primary", "fingerprint": "7c9c5f425f411f5c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2f8ef5e95259d18f", "level": "note", "message": {"text": "Unused endpoint: GET /click/:trackingId/:linkId"}, "properties": {"repobilityId": "457b2d0a583b95ff", "scanner": "scanner-primary", "fingerprint": "2f8ef5e95259d18f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8a16fda24126d178", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/logout-all"}, "properties": {"repobilityId": "7959a96adfc90861", "scanner": "scanner-primary", "fingerprint": "8a16fda24126d178", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76f7964d6c782e43", "level": "note", "message": {"text": "Unused endpoint: POST /api/stripe/webhook"}, "properties": {"repobilityId": "b605e4de8f13eb7c", "scanner": "scanner-primary", "fingerprint": "76f7964d6c782e43", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-aa9e6eee88be93f1", "level": "note", "message": {"text": "Unused endpoint: POST /api/sendgrid/inbound"}, "properties": {"repobilityId": "135598bc29af8b34", "scanner": "scanner-primary", "fingerprint": "aa9e6eee88be93f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8bf2f7ca3faa1f1b", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth/login"}, "properties": {"repobilityId": "72ba8e8d4a04cb2f", "scanner": "scanner-primary", "fingerprint": "8bf2f7ca3faa1f1b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-def16861a13564b0", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth/register"}, "properties": {"repobilityId": "23aa655967993c70", "scanner": "scanner-primary", "fingerprint": "def16861a13564b0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0bfca63377edb533", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth/forgot-password"}, "properties": {"repobilityId": "cf33887e893a3353", "scanner": "scanner-primary", "fingerprint": "0bfca63377edb533", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6eb452fbfb454d20", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth"}, "properties": {"repobilityId": "98f7b81098f84eea", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-abbc1e2493e46ef1", "level": "note", "message": {"text": "Unused endpoint: USE /api/track"}, "properties": {"repobilityId": "df57eb7c5afc0784", "scanner": "scanner-primary", "fingerprint": "abbc1e2493e46ef1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-360c6c99547c3232", "level": "note", "message": {"text": "Unused endpoint: POST /api/sendgrid/webhook"}, "properties": {"repobilityId": "7a0ee31478fce37f", "scanner": "scanner-primary", "fingerprint": "360c6c99547c3232", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ac1c4924f32c1d79", "level": "note", "message": {"text": "Unused endpoint: USE /api/trpc"}, "properties": {"repobilityId": "09a84cd2512234d2", "scanner": "scanner-primary", "fingerprint": "ac1c4924f32c1d79", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-acbaaa9e533b33f5", "level": "note", "message": {"text": "Unused endpoint: GET /api/oauth/callback"}, "properties": {"repobilityId": "d15b53af0eaa591b", "scanner": "scanner-primary", "fingerprint": "acbaaa9e533b33f5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3c8bb190c50a9df5", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/companies/stats"}, "properties": {"repobilityId": "f59439685f407f7f", "scanner": "scanner-primary", "fingerprint": "3c8bb190c50a9df5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}