{"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-480d641ddd905a2e", "name": "Stray `console.log` in TS/JS \u2014 server.js:70", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server.js:70"}, "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-a8e382aea6c931e8", "name": "Stray `console.log` in TS/JS \u2014 scripts/virginie-overrides.js:57", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/virginie-overrides.js: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-9f983d824138ca75", "name": "Stray `console.log` in TS/JS \u2014 src/screenshot-worker.js:91", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/screenshot-worker.js:91"}, "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-52099724e1205e31", "name": "Stray `console.log` in TS/JS \u2014 src/email-sender.js:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/email-sender.js:32"}, "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-6ae2dbf6549d7f5d", "name": "Stray `console.log` in TS/JS \u2014 src/name-cleaner.js:209", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/name-cleaner.js:209"}, "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-7aba98993529507e", "name": "Stray `console.log` in TS/JS \u2014 src/db.js:325", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/db.js:325"}, "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-cbd2e119ecf906cf", "name": "Stray `console.log` in TS/JS \u2014 src/provisioning-worker.js:64", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/provisioning-worker.js:64"}, "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-25add8f2f11e4384", "name": "Stray `console.log` in TS/JS \u2014 src/routes/caddy.js:77", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/caddy.js:77"}, "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-fb2e432d06a78cf4", "name": "Stray `console.log` in TS/JS \u2014 src/routes/landing.js:254", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/landing.js:254"}, "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-333e6b51d1da7b5f", "name": "Stray `console.log` in TS/JS \u2014 src/routes/stripe-webhook.js:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/stripe-webhook.js:46"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bbc5416b31b8fbbb", "name": "Stray `console.log` in TS/JS \u2014 src/routes/recover.js:96", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/recover.js:96"}, "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-0b02a68acb28f927", "name": "Stray `console.log` in TS/JS \u2014 src/routes/admin-recover.js:77", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/admin-recover.js:77"}, "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-97f4e2f456647e1f", "name": "Stray `console.log` in TS/JS \u2014 src/routes/photo-picker.js:71", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/photo-picker.js: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-1383cf2d7da68404", "name": "Stray `console.log` in TS/JS \u2014 src/routes/checkout.js:248", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/checkout.js:248"}, "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-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-0977cca8ba31adb0", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9924160a26696288", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/i18n.js:530", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/i18n.js:530"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d3399d9bb2b57218", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/stats.html:371", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/stats.html:371"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea4bacd570bd7734", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/admin.js:72", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/admin.js:72"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5c5b739cefe6efdf", "name": "Insecure pattern 'insert_adjacent_html' in public/admin/admin.js:645", "shortDescription": {"text": "Insecure pattern 'insert_adjacent_html' in public/admin/admin.js:645"}, "fullDescription": {"text": "Found a known-risky pattern (insert_adjacent_html). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-86bccb5d99f85b63", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/photos.html:131", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/photos.html:131"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d860d78511449216", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/demo/index.html:144", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/demo/index.html:144"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-19f4e510d5ea602d", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/edit/edit.js:373", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/edit/edit.js:373"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1bcfcd43822fcb14", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/edit/onboarding.js:97", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/edit/onboarding.js:97"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-db7e525a53f561b0", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/site/pricing-modal.js:128", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/pricing-modal.js:128"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-15017b851d0f5b08", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/site/preview-onboarding.js:100", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/preview-onboarding.js:100"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b2245f95ab300123", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/site/banner.js:104", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/banner.js:104"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3429168d7c13e319", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/site/waiting-screen.js:35", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/waiting-screen.js:35"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1b304569c1dbc81e", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/site/main.js:23", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/main.js:23"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-25db58a53a3bf3b9", "name": "Very large file: public/admin/admin.js (1321 lines)", "shortDescription": {"text": "Very large file: public/admin/admin.js (1321 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": "4 test file(s) for 61 source file(s) (ratio 0.07). 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 160 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 17 placeholder/mock markers across 5 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-59370c9c3d1a9eb1", "name": "Commented-code block (6 lines) in server.js:15", "shortDescription": {"text": "Commented-code block (6 lines) in server.js:15"}, "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-b203f007c04b32c7", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/night-proofs.mjs:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/night-proofs.mjs:20"}, "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-18c35f2329172840", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/ovh-buy-domain.mjs:43", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/ovh-buy-domain.mjs:43"}, "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-675baa844f499a6d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/resume-provisioning.mjs:22", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/resume-provisioning.mjs:22"}, "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-bbd87cea13aed47e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-stack-icons.mjs:79", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-stack-icons.mjs:79"}, "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-b817ff7fda477fd4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/proof-gallery-modes.mjs:19", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/proof-gallery-modes.mjs:19"}, "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-a8d12458fc03e300", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/domain-suggester.js:99", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/domain-suggester.js:99"}, "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-c207992d9aa3259e", "name": "Commented-code block (5 lines) in src/screenshot-worker.js:81", "shortDescription": {"text": "Commented-code block (5 lines) in src/screenshot-worker.js:81"}, "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-f037aaf0d8ca3a2f", "name": "Commented-code block (5 lines) in src/ssr.js:47", "shortDescription": {"text": "Commented-code block (5 lines) in src/ssr.js:47"}, "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-44425c5e761704a3", "name": "Commented-code block (5 lines) in src/picker-core.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/picker-core.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e45b0eadc76c550c", "name": "Commented-code block (6 lines) in src/ovh-client.js:125", "shortDescription": {"text": "Commented-code block (6 lines) in src/ovh-client.js:125"}, "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-efccb1a4f9c3b67f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/ovh-client.js:57", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/ovh-client.js: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-06360fee8c3a5eb5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/presentation-cleaner.js:90", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/presentation-cleaner.js:90"}, "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-5e3e10427529ca06", "name": "Commented-code block (5 lines) in src/picker-azure.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/picker-azure.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3e5ae249e3647ddd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/name-cleaner.js:107", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/name-cleaner.js:107"}, "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-81c2c91162c139c5", "name": "Commented-code block (6 lines) in src/provisioning-worker.js:190", "shortDescription": {"text": "Commented-code block (6 lines) in src/provisioning-worker.js:190"}, "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-3b74428fe7337257", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/provisioning-worker.js:489", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/provisioning-worker.js:489"}, "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-4968796725540ed5", "name": "Commented-code block (5 lines) in src/photo-apply.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/photo-apply.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-86be3dc2450ff0a4", "name": "Commented-code block (15 lines) in src/defaults.js:4", "shortDescription": {"text": "Commented-code block (15 lines) in src/defaults.js:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bb4a993aeb32412e", "name": "Commented-code block (9 lines) in src/routes/caddy.js:37", "shortDescription": {"text": "Commented-code block (9 lines) in src/routes/caddy.js:37"}, "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-ee6ed85aaf1a7129", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/routes/landing.js:65", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/routes/landing.js:65"}, "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-e4d0b326100e0220", "name": "Commented-code block (5 lines) in src/routes/stripe-webhook.js:125", "shortDescription": {"text": "Commented-code block (5 lines) in src/routes/stripe-webhook.js:125"}, "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-c7ab7636f44ddfad", "name": "Commented-code block (8 lines) in src/routes/edit.js:19", "shortDescription": {"text": "Commented-code block (8 lines) in src/routes/edit.js:19"}, "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-05450e3474fd8d27", "name": "Commented-code block (6 lines) in src/routes/recover.js:65", "shortDescription": {"text": "Commented-code block (6 lines) in src/routes/recover.js:65"}, "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-3e38f8a95c6d9b3f", "name": "Commented-code block (5 lines) in src/routes/demo-tool.js:64", "shortDescription": {"text": "Commented-code block (5 lines) in src/routes/demo-tool.js:64"}, "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-9c2fda8ec32d9ec6", "name": "Commented-code block (14 lines) in src/routes/photo-picker.js:5", "shortDescription": {"text": "Commented-code block (14 lines) in src/routes/photo-picker.js:5"}, "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-167c7f943bcee41c", "name": "Commented-code block (5 lines) in src/routes/checkout.js:27", "shortDescription": {"text": "Commented-code block (5 lines) in src/routes/checkout.js:27"}, "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-15baa6c6b97fe6d0", "name": "Commented-code block (5 lines) in src/routes/admin.js:353", "shortDescription": {"text": "Commented-code block (5 lines) in src/routes/admin.js:353"}, "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-a44261085ff35188", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/routes/admin.js:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/routes/admin.js:32"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-241f1c00eacf2047", "name": "Commented-code block (5 lines) in public/admin/admin.js:118", "shortDescription": {"text": "Commented-code block (5 lines) in public/admin/admin.js:118"}, "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-bc5793224672809b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/admin/admin.js:34", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/admin/admin.js:34"}, "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-30a64c6246aecac0", "name": "Commented-code block (5 lines) in public/edit/edit.js:224", "shortDescription": {"text": "Commented-code block (5 lines) in public/edit/edit.js:224"}, "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-9b43c3bff2b69e08", "name": "Commented-code block (5 lines) in public/site/pricing-modal.js:484", "shortDescription": {"text": "Commented-code block (5 lines) in public/site/pricing-modal.js:484"}, "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-b7f0fc65537be32f", "name": "Commented-code block (5 lines) in public/site/preview-onboarding.js:279", "shortDescription": {"text": "Commented-code block (5 lines) in public/site/preview-onboarding.js:279"}, "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-e3e14d9dd58c626c", "name": "Commented-code block (7 lines) in public/site/home.js:12", "shortDescription": {"text": "Commented-code block (7 lines) in public/site/home.js:12"}, "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-b39db73e344e8a7f", "name": "Commented-code block (8 lines) in public/site/waiting-screen.js:98", "shortDescription": {"text": "Commented-code block (8 lines) in public/site/waiting-screen.js:98"}, "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-a71601bd13c7794e", "name": "Commented-code block (8 lines) in public/site/main.js:521", "shortDescription": {"text": "Commented-code block (8 lines) in public/site/main.js:521"}, "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-be98a2727e1b316a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/site/main.js:16", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/site/main.js: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-ef22fd58bfde6f76", "name": "51 env vars used in code but missing from .env.example", "shortDescription": {"text": "51 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_EMAIL_PROD`, `ADMIN_PASSWORD`, `ADMIN_PWD`, `AZURE_MAX_CONCURRENT`, `AZURE_OPENAI_API_KEY`, `AZURE_OPENAI_API_VERSION`, `AZURE_OPENAI_DEPLOYMENT`, `AZURE_OPENAI_DEPLOYMENT_EMBED` + 43 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-3599bfc001df627f", "name": "Dangling fetch: GET https://api.cloudflare.com/client/v4${path} (scripts/resume-provisioning.mjs:43)", "shortDescription": {"text": "Dangling fetch: GET https://api.cloudflare.com/client/v4${path} (scripts/resume-provisioning.mjs:43)"}, "fullDescription": {"text": "`scripts/resume-provisioning.mjs:43` calls `GET https://api.cloudflare.com/client/v4${path}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.cloudflare.com/client/v4/<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-8f5f9aa48d66b9ba", "name": "Dangling fetch: POST https://api.resend.com/emails (src/routes/landing.js:301)", "shortDescription": {"text": "Dangling fetch: POST https://api.resend.com/emails (src/routes/landing.js:301)"}, "fullDescription": {"text": "`src/routes/landing.js:301` calls `POST https://api.resend.com/emails` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.resend.com/emails`\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-8e2ec6059452d867", "name": "Dangling fetch: PUT /admin/salon/${encodeURIComponent(slug)}/nom-final (public/admin/admin.js:332)", "shortDescription": {"text": "Dangling fetch: PUT /admin/salon/${encodeURIComponent(slug)}/nom-final (public/admin/admin.js:332)"}, "fullDescription": {"text": "`public/admin/admin.js:332` calls `PUT /admin/salon/${encodeURIComponent(slug)}/nom-final` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/salon/<p>/nom-final`\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-08c085c36dab0dbc", "name": "Dangling fetch: POST /admin/upload-csv (public/admin/admin.js:446)", "shortDescription": {"text": "Dangling fetch: POST /admin/upload-csv (public/admin/admin.js:446)"}, "fullDescription": {"text": "`public/admin/admin.js:446` calls `POST /admin/upload-csv` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/upload-csv`\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-2353c875d23f0b83", "name": "Dangling fetch: POST /admin/logout (public/admin/admin.js:561)", "shortDescription": {"text": "Dangling fetch: POST /admin/logout (public/admin/admin.js:561)"}, "fullDescription": {"text": "`public/admin/admin.js:561` calls `POST /admin/logout` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/logout`\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-d4b1422e7f18c7dc", "name": "Dangling fetch: GET /api/edit/${encodeURIComponent(state.slug)}${tokenQS()} (public/edit/edit.js:58)", "shortDescription": {"text": "Dangling fetch: GET /api/edit/${encodeURIComponent(state.slug)}${tokenQS()} (public/edit/edit.js:58)"}, "fullDescription": {"text": "`public/edit/edit.js:58` calls `GET /api/edit/${encodeURIComponent(state.slug)}${tokenQS()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/edit/<p>/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c86afca12cf7c731", "name": "Dangling fetch: PUT /api/edit/${encodeURIComponent(state.slug)}${tokenQS()} (public/edit/edit.js:69)", "shortDescription": {"text": "Dangling fetch: PUT /api/edit/${encodeURIComponent(state.slug)}${tokenQS()} (public/edit/edit.js:69)"}, "fullDescription": {"text": "`public/edit/edit.js:69` calls `PUT /api/edit/${encodeURIComponent(state.slug)}${tokenQS()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/edit/<p>/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-78c615667af52282", "name": "Dangling fetch: DELETE /api/edit/${encodeURIComponent(state.slug)}/overrides${tokenQS()} (public/edit/edit.js:83)", "shortDescription": {"text": "Dangling fetch: DELETE /api/edit/${encodeURIComponent(state.slug)}/overrides${tokenQS()} (public/edit/edit.js:83)"}, "fullDescription": {"text": "`public/edit/edit.js:83` calls `DELETE /api/edit/${encodeURIComponent(state.slug)}/overrides${tokenQS()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/edit/<p>/overrides/<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-e0987396b0690e70", "name": "Dangling fetch: POST /api/edit/${encodeURIComponent(state.slug)}/upload-image${tokenQS()} (public/edit/edit.js:95)", "shortDescription": {"text": "Dangling fetch: POST /api/edit/${encodeURIComponent(state.slug)}/upload-image${tokenQS()} (public/edit/edit.js:95)"}, "fullDescription": {"text": "`public/edit/edit.js:95` calls `POST /api/edit/${encodeURIComponent(state.slug)}/upload-image${tokenQS()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/edit/<p>/upload-image/<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-e7249f2f256161b5", "name": "Unused endpoint: USE /webhook", "shortDescription": {"text": "Unused endpoint: USE /webhook"}, "fullDescription": {"text": "`server.js` declares `USE /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-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`server.js` declares `USE /api` 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-a58e737b8b02d702", "name": "Unused endpoint: USE /api/caddy", "shortDescription": {"text": "Unused endpoint: USE /api/caddy"}, "fullDescription": {"text": "`server.js` declares `USE /api/caddy` 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-bd5fe0f6ad153b91", "name": "Unused endpoint: USE /screenshots", "shortDescription": {"text": "Unused endpoint: USE /screenshots"}, "fullDescription": {"text": "`server.js` declares `USE /screenshots` 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-1bc898b3b7565990", "name": "Unused endpoint: USE /uploads", "shortDescription": {"text": "Unused endpoint: USE /uploads"}, "fullDescription": {"text": "`server.js` declares `USE /uploads` 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-bcd762d17b21b91b", "name": "Unused endpoint: USE /legal", "shortDescription": {"text": "Unused endpoint: USE /legal"}, "fullDescription": {"text": "`server.js` declares `USE /legal` 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-f02a079c69b52f2d", "name": "Unused endpoint: USE /", "shortDescription": {"text": "Unused endpoint: USE /"}, "fullDescription": {"text": "`server.js` declares `USE /` 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-9244047f68bde53d", "name": "Unused endpoint: GET /recover", "shortDescription": {"text": "Unused endpoint: GET /recover"}, "fullDescription": {"text": "`server.js` declares `GET /recover` 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-e7f059540834e0d4", "name": "Unused endpoint: USE /edit-app", "shortDescription": {"text": "Unused endpoint: USE /edit-app"}, "fullDescription": {"text": "`server.js` declares `USE /edit-app` 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-b2d8849fb6b1ac47", "name": "Unused endpoint: USE /admin", "shortDescription": {"text": "Unused endpoint: USE /admin"}, "fullDescription": {"text": "`server.js` declares `USE /admin` 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-d6c8f076249de027", "name": "Unused endpoint: GET /admin/:slug", "shortDescription": {"text": "Unused endpoint: GET /admin/:slug"}, "fullDescription": {"text": "`server.js` declares `GET /admin/:slug` 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-953ec1a0ee6df50d", "name": "Unused endpoint: GET /admin", "shortDescription": {"text": "Unused endpoint: GET /admin"}, "fullDescription": {"text": "`server.js` declares `GET /admin` 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-015af72088b86fec", "name": "Unused endpoint: USE /_assets", "shortDescription": {"text": "Unused endpoint: USE /_assets"}, "fullDescription": {"text": "`server.js` declares `USE /_assets` 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-7388dbfa7be50c3d", "name": "Unused endpoint: GET /preview/:slug", "shortDescription": {"text": "Unused endpoint: GET /preview/:slug"}, "fullDescription": {"text": "`server.js` declares `GET /preview/:slug` 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.js` 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-0d1755e0301de825", "name": "Unused endpoint: GET /check-hostname", "shortDescription": {"text": "Unused endpoint: GET /check-hostname"}, "fullDescription": {"text": "`src/routes/caddy.js` declares `GET /check-hostname` 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-2083a87719497893", "name": "Unused endpoint: POST /stripe", "shortDescription": {"text": "Unused endpoint: POST /stripe"}, "fullDescription": {"text": "`src/routes/stripe-webhook.js` declares `POST /stripe` 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-169e347ffd292ad4", "name": "Unused endpoint: GET /edit/:slug", "shortDescription": {"text": "Unused endpoint: GET /edit/:slug"}, "fullDescription": {"text": "`src/routes/edit.js` declares `GET /edit/:slug` 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-dcff5438ec5d51c6", "name": "Unused endpoint: PUT /edit/:slug", "shortDescription": {"text": "Unused endpoint: PUT /edit/:slug"}, "fullDescription": {"text": "`src/routes/edit.js` declares `PUT /edit/:slug` 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-ebaa32f558410d63", "name": "Unused endpoint: DELETE /edit/:slug/overrides", "shortDescription": {"text": "Unused endpoint: DELETE /edit/:slug/overrides"}, "fullDescription": {"text": "`src/routes/edit.js` declares `DELETE /edit/:slug/overrides` 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-fd659fe7f44901c1", "name": "Unused endpoint: POST /edit/:slug/upload-image", "shortDescription": {"text": "Unused endpoint: POST /edit/:slug/upload-image"}, "fullDescription": {"text": "`src/routes/edit.js` declares `POST /edit/:slug/upload-image` 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-c50727bbaad4e34b", "name": "Unused endpoint: DELETE /edit/:slug/upload-image", "shortDescription": {"text": "Unused endpoint: DELETE /edit/:slug/upload-image"}, "fullDescription": {"text": "`src/routes/edit.js` declares `DELETE /edit/:slug/upload-image` 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-dc1154d30e2fb8ed", "name": "Unused endpoint: POST /api/recover", "shortDescription": {"text": "Unused endpoint: POST /api/recover"}, "fullDescription": {"text": "`src/routes/recover.js` declares `POST /api/recover` 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-e9084aac01b84235", "name": "Unused endpoint: GET /recover/confirm", "shortDescription": {"text": "Unused endpoint: GET /recover/confirm"}, "fullDescription": {"text": "`src/routes/recover.js` declares `GET /recover/confirm` 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-5c74e6393e6f44ef", "name": "Unused endpoint: GET /:secret", "shortDescription": {"text": "Unused endpoint: GET /:secret"}, "fullDescription": {"text": "`src/routes/demo-tool.js` declares `GET /:secret` 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-b0aedc54b083bf7a", "name": "Unused endpoint: GET /:secret/api/search", "shortDescription": {"text": "Unused endpoint: GET /:secret/api/search"}, "fullDescription": {"text": "`src/routes/demo-tool.js` declares `GET /:secret/api/search` 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-80713abf53d14820", "name": "Unused endpoint: POST /:secret/api/send-email", "shortDescription": {"text": "Unused endpoint: POST /:secret/api/send-email"}, "fullDescription": {"text": "`src/routes/demo-tool.js` declares `POST /:secret/api/send-email` 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-d26c5ed86a5f1af8", "name": "Unused endpoint: GET /salons", "shortDescription": {"text": "Unused endpoint: GET /salons"}, "fullDescription": {"text": "`src/routes/api.js` declares `GET /salons` 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-5c2bcdc3fe9f6f1b", "name": "Unused endpoint: GET /csv-imports", "shortDescription": {"text": "Unused endpoint: GET /csv-imports"}, "fullDescription": {"text": "`src/routes/api.js` declares `GET /csv-imports` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cd8dc4599ec52a08", "name": "Unused endpoint: GET /stats", "shortDescription": {"text": "Unused endpoint: GET /stats"}, "fullDescription": {"text": "`src/routes/api.js` declares `GET /stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3d6b2afb59d831d9", "name": "Unused endpoint: POST /sync/:slug", "shortDescription": {"text": "Unused endpoint: POST /sync/:slug"}, "fullDescription": {"text": "`src/routes/sync.js` declares `POST /sync/:slug` 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-23e1514567b41917", "name": "Unused endpoint: DELETE /sync/:slug", "shortDescription": {"text": "Unused endpoint: DELETE /sync/:slug"}, "fullDescription": {"text": "`src/routes/sync.js` declares `DELETE /sync/:slug` 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-ab7d61f6e9a40f06", "name": "Unused endpoint: USE /photos-files", "shortDescription": {"text": "Unused endpoint: USE /photos-files"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `USE /photos-files` 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-65197b248dd51d78", "name": "Unused endpoint: POST /api/picker/import-index", "shortDescription": {"text": "Unused endpoint: POST /api/picker/import-index"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/import-index` 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-e446e18585f67fd3", "name": "Unused endpoint: GET /api/picker/stats", "shortDescription": {"text": "Unused endpoint: GET /api/picker/stats"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `GET /api/picker/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-89b4b5990519384d", "name": "Unused endpoint: GET /api/picker/criteria", "shortDescription": {"text": "Unused endpoint: GET /api/picker/criteria"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `GET /api/picker/criteria` 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-ea4ac96d62373edf", "name": "Unused endpoint: PUT /api/picker/criteria", "shortDescription": {"text": "Unused endpoint: PUT /api/picker/criteria"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `PUT /api/picker/criteria` 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-e2689b85657938a4", "name": "Unused endpoint: POST /api/picker/batch", "shortDescription": {"text": "Unused endpoint: POST /api/picker/batch"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/batch` 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-cfd54e302cea93f6", "name": "Unused endpoint: GET /api/picker/batch/:id", "shortDescription": {"text": "Unused endpoint: GET /api/picker/batch/:id"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `GET /api/picker/batch/: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-daf0964136cda8f2", "name": "Unused endpoint: GET /api/picker/results", "shortDescription": {"text": "Unused endpoint: GET /api/picker/results"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `GET /api/picker/results` 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-c0180f9a044f137f", "name": "Unused endpoint: GET /api/picker/results/:id", "shortDescription": {"text": "Unused endpoint: GET /api/picker/results/:id"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `GET /api/picker/results/: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-6719542513a66fff", "name": "Unused endpoint: POST /api/picker/feedback", "shortDescription": {"text": "Unused endpoint: POST /api/picker/feedback"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/feedback` 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-d04ea9baeb58f652", "name": "Unused endpoint: POST /api/picker/apply-hero", "shortDescription": {"text": "Unused endpoint: POST /api/picker/apply-hero"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/apply-hero` 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-02f6c04cd01553d5", "name": "Unused endpoint: GET /api/picker/salon/:slug/photos", "shortDescription": {"text": "Unused endpoint: GET /api/picker/salon/:slug/photos"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `GET /api/picker/salon/:slug/photos` 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-b93051e86ce9813b", "name": "Unused endpoint: POST /api/picker/salon/:slug/hero", "shortDescription": {"text": "Unused endpoint: POST /api/picker/salon/:slug/hero"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/salon/:slug/hero` 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-255adb0b8424126f", "name": "Unused endpoint: POST /api/picker/salon/:slug/gallery", "shortDescription": {"text": "Unused endpoint: POST /api/picker/salon/:slug/gallery"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/salon/:slug/gallery` 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-55dd2f1adbd0db42", "name": "Unused endpoint: POST /api/picker/salon/:slug/reset-images", "shortDescription": {"text": "Unused endpoint: POST /api/picker/salon/:slug/reset-images"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/salon/:slug/reset-images` 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-39c5e576e9dd4d66", "name": "Unused endpoint: POST /api/picker/salon/:slug/score", "shortDescription": {"text": "Unused endpoint: POST /api/picker/salon/:slug/score"}, "fullDescription": {"text": "`src/routes/photo-picker.js` declares `POST /api/picker/salon/:slug/score` 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-60bd9caaa11e0409", "name": "Unused endpoint: GET /signup/status", "shortDescription": {"text": "Unused endpoint: GET /signup/status"}, "fullDescription": {"text": "`src/routes/checkout.js` declares `GET /signup/status` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`src/routes/admin.js` declares `POST /login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/24593"}, "properties": {"repository": "BillyBob36/outil-coiffure", "repoUrl": "https://github.com/BillyBob36/outil-coiffure", "branch": "main"}, "results": [{"ruleId": "scanner-480d641ddd905a2e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server.js:70"}, "properties": {"repobilityId": "a9deebb5fdc93edc", "scanner": "scanner-primary", "fingerprint": "480d641ddd905a2e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a8e382aea6c931e8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/virginie-overrides.js:57"}, "properties": {"repobilityId": "8519b8c54e2613cd", "scanner": "scanner-primary", "fingerprint": "a8e382aea6c931e8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9f983d824138ca75", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/screenshot-worker.js:91"}, "properties": {"repobilityId": "060fba312f24b1e5", "scanner": "scanner-primary", "fingerprint": "9f983d824138ca75", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-52099724e1205e31", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/email-sender.js:32"}, "properties": {"repobilityId": "24ebbaada2e01c3d", "scanner": "scanner-primary", "fingerprint": "52099724e1205e31", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6ae2dbf6549d7f5d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/name-cleaner.js:209"}, "properties": {"repobilityId": "edc5c612f0ff8984", "scanner": "scanner-primary", "fingerprint": "6ae2dbf6549d7f5d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7aba98993529507e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/db.js:325"}, "properties": {"repobilityId": "c5b6306b58ef6c6f", "scanner": "scanner-primary", "fingerprint": "7aba98993529507e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cbd2e119ecf906cf", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/provisioning-worker.js:64"}, "properties": {"repobilityId": "8bbb25b33badf183", "scanner": "scanner-primary", "fingerprint": "cbd2e119ecf906cf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-25add8f2f11e4384", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/caddy.js:77"}, "properties": {"repobilityId": "e6ce8b27b003fd85", "scanner": "scanner-primary", "fingerprint": "25add8f2f11e4384", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fb2e432d06a78cf4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/landing.js:254"}, "properties": {"repobilityId": "943f4e0900063f76", "scanner": "scanner-primary", "fingerprint": "fb2e432d06a78cf4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-333e6b51d1da7b5f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/stripe-webhook.js:46"}, "properties": {"repobilityId": "375cf45e9f2ed1e2", "scanner": "scanner-primary", "fingerprint": "333e6b51d1da7b5f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bbc5416b31b8fbbb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/recover.js:96"}, "properties": {"repobilityId": "8b6482b814f51a89", "scanner": "scanner-primary", "fingerprint": "bbc5416b31b8fbbb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0b02a68acb28f927", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/admin-recover.js:77"}, "properties": {"repobilityId": "4fcecee94bed57d8", "scanner": "scanner-primary", "fingerprint": "0b02a68acb28f927", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-97f4e2f456647e1f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/photo-picker.js:71"}, "properties": {"repobilityId": "b2030e0e5dac2cf1", "scanner": "scanner-primary", "fingerprint": "97f4e2f456647e1f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1383cf2d7da68404", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/routes/checkout.js:248"}, "properties": {"repobilityId": "7e3aedcd7d19452a", "scanner": "scanner-primary", "fingerprint": "1383cf2d7da68404", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-0977cca8ba31adb0", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-bookworm-slim"}, "properties": {"repobilityId": "e6d3672bca4d8469", "scanner": "scanner-primary", "fingerprint": "0977cca8ba31adb0", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-9924160a26696288", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/i18n.js:530"}, "properties": {"repobilityId": "a5e67a8a92d62766", "scanner": "scanner-primary", "fingerprint": "9924160a26696288", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/admin/i18n.js"}, "region": {"startLine": 530}}}]}, {"ruleId": "scanner-d3399d9bb2b57218", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/stats.html:371"}, "properties": {"repobilityId": "16ab89e0a0eadf5f", "scanner": "scanner-primary", "fingerprint": "d3399d9bb2b57218", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/admin/stats.html"}, "region": {"startLine": 371}}}]}, {"ruleId": "scanner-ea4bacd570bd7734", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/admin.js:72"}, "properties": {"repobilityId": "ed921bb0ddff002c", "scanner": "scanner-primary", "fingerprint": "ea4bacd570bd7734", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/admin/admin.js"}, "region": {"startLine": 72}}}]}, {"ruleId": "scanner-5c5b739cefe6efdf", "level": "warning", "message": {"text": "Insecure pattern 'insert_adjacent_html' in public/admin/admin.js:645"}, "properties": {"repobilityId": "220a0b960af2bb11", "scanner": "scanner-primary", "fingerprint": "5c5b739cefe6efdf", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "insert_adjacent_html"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/admin/admin.js"}, "region": {"startLine": 645}}}]}, {"ruleId": "scanner-86bccb5d99f85b63", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/admin/photos.html:131"}, "properties": {"repobilityId": "a92bb1284b959a33", "scanner": "scanner-primary", "fingerprint": "86bccb5d99f85b63", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/admin/photos.html"}, "region": {"startLine": 131}}}]}, {"ruleId": "scanner-d860d78511449216", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/demo/index.html:144"}, "properties": {"repobilityId": "a789b89f92756a21", "scanner": "scanner-primary", "fingerprint": "d860d78511449216", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/demo/index.html"}, "region": {"startLine": 144}}}]}, {"ruleId": "scanner-19f4e510d5ea602d", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/edit/edit.js:373"}, "properties": {"repobilityId": "51951cee000102e3", "scanner": "scanner-primary", "fingerprint": "19f4e510d5ea602d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/edit/edit.js"}, "region": {"startLine": 373}}}]}, {"ruleId": "scanner-1bcfcd43822fcb14", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/edit/onboarding.js:97"}, "properties": {"repobilityId": "d3bcc948eb483f88", "scanner": "scanner-primary", "fingerprint": "1bcfcd43822fcb14", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/edit/onboarding.js"}, "region": {"startLine": 97}}}]}, {"ruleId": "scanner-db7e525a53f561b0", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/pricing-modal.js:128"}, "properties": {"repobilityId": "ea2e755d3b8e5555", "scanner": "scanner-primary", "fingerprint": "db7e525a53f561b0", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/site/pricing-modal.js"}, "region": {"startLine": 128}}}]}, {"ruleId": "scanner-15017b851d0f5b08", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/preview-onboarding.js:100"}, "properties": {"repobilityId": "efe7a855d842aa81", "scanner": "scanner-primary", "fingerprint": "15017b851d0f5b08", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/site/preview-onboarding.js"}, "region": {"startLine": 100}}}]}, {"ruleId": "scanner-b2245f95ab300123", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/banner.js:104"}, "properties": {"repobilityId": "104b55952d684cb4", "scanner": "scanner-primary", "fingerprint": "b2245f95ab300123", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/site/banner.js"}, "region": {"startLine": 104}}}]}, {"ruleId": "scanner-3429168d7c13e319", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/waiting-screen.js:35"}, "properties": {"repobilityId": "b210faf0d45cdf21", "scanner": "scanner-primary", "fingerprint": "3429168d7c13e319", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/site/waiting-screen.js"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-1b304569c1dbc81e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/site/main.js:23"}, "properties": {"repobilityId": "3b9fc84a0f51119f", "scanner": "scanner-primary", "fingerprint": "1b304569c1dbc81e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/site/main.js"}, "region": {"startLine": 23}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-25db58a53a3bf3b9", "level": "note", "message": {"text": "Very large file: public/admin/admin.js (1321 lines)"}, "properties": {"repobilityId": "d60cfeb82eb4e00d", "scanner": "scanner-primary", "fingerprint": "25db58a53a3bf3b9", "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": "86d5e6874f5981dc", "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": "9f9ea80f3c11d0ad", "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": "fe6682bd00e8283a", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "2abeb405bfad3bcf", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "1e1395d8840f93da", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "bb20364aa9a88d3c", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-59370c9c3d1a9eb1", "level": "none", "message": {"text": "Commented-code block (6 lines) in server.js:15"}, "properties": {"repobilityId": "fa829c4330b5416c", "scanner": "scanner-primary", "fingerprint": "59370c9c3d1a9eb1", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b203f007c04b32c7", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/night-proofs.mjs:20"}, "properties": {"repobilityId": "01e572278ad53782", "scanner": "scanner-primary", "fingerprint": "b203f007c04b32c7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-18c35f2329172840", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/ovh-buy-domain.mjs:43"}, "properties": {"repobilityId": "ca9c44586e27fe40", "scanner": "scanner-primary", "fingerprint": "18c35f2329172840", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-675baa844f499a6d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/resume-provisioning.mjs:22"}, "properties": {"repobilityId": "7fc29c35fa4330dd", "scanner": "scanner-primary", "fingerprint": "675baa844f499a6d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bbd87cea13aed47e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/generate-stack-icons.mjs:79"}, "properties": {"repobilityId": "ce52f2d466af0471", "scanner": "scanner-primary", "fingerprint": "bbd87cea13aed47e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b817ff7fda477fd4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/proof-gallery-modes.mjs:19"}, "properties": {"repobilityId": "1d3890ecdfeb7565", "scanner": "scanner-primary", "fingerprint": "b817ff7fda477fd4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a8d12458fc03e300", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/domain-suggester.js:99"}, "properties": {"repobilityId": "c671aeccd74d3d69", "scanner": "scanner-primary", "fingerprint": "a8d12458fc03e300", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c207992d9aa3259e", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/screenshot-worker.js:81"}, "properties": {"repobilityId": "0d94b27b8047250c", "scanner": "scanner-primary", "fingerprint": "c207992d9aa3259e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f037aaf0d8ca3a2f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/ssr.js:47"}, "properties": {"repobilityId": "d25f8fb4072d292e", "scanner": "scanner-primary", "fingerprint": "f037aaf0d8ca3a2f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-44425c5e761704a3", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/picker-core.js:1"}, "properties": {"repobilityId": "10f71ff9223e457d", "scanner": "scanner-primary", "fingerprint": "44425c5e761704a3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e45b0eadc76c550c", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/ovh-client.js:125"}, "properties": {"repobilityId": "ae3e69a52f6382e4", "scanner": "scanner-primary", "fingerprint": "e45b0eadc76c550c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-efccb1a4f9c3b67f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/ovh-client.js:57"}, "properties": {"repobilityId": "d727869b4d4c256f", "scanner": "scanner-primary", "fingerprint": "efccb1a4f9c3b67f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-06360fee8c3a5eb5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/presentation-cleaner.js:90"}, "properties": {"repobilityId": "20cacefd2e65ead5", "scanner": "scanner-primary", "fingerprint": "06360fee8c3a5eb5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5e3e10427529ca06", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/picker-azure.js:1"}, "properties": {"repobilityId": "5653819dd307660a", "scanner": "scanner-primary", "fingerprint": "5e3e10427529ca06", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3e5ae249e3647ddd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/name-cleaner.js:107"}, "properties": {"repobilityId": "b629b3c10af29031", "scanner": "scanner-primary", "fingerprint": "3e5ae249e3647ddd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-81c2c91162c139c5", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/provisioning-worker.js:190"}, "properties": {"repobilityId": "de9718a27b04c49d", "scanner": "scanner-primary", "fingerprint": "81c2c91162c139c5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3b74428fe7337257", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/provisioning-worker.js:489"}, "properties": {"repobilityId": "f76f3a9b0b5d96e6", "scanner": "scanner-primary", "fingerprint": "3b74428fe7337257", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4968796725540ed5", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/photo-apply.js:1"}, "properties": {"repobilityId": "bd482b047443beb1", "scanner": "scanner-primary", "fingerprint": "4968796725540ed5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-86be3dc2450ff0a4", "level": "none", "message": {"text": "Commented-code block (15 lines) in src/defaults.js:4"}, "properties": {"repobilityId": "d74b11773c030dda", "scanner": "scanner-primary", "fingerprint": "86be3dc2450ff0a4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bb4a993aeb32412e", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/routes/caddy.js:37"}, "properties": {"repobilityId": "b0f1b06bf1a6abc6", "scanner": "scanner-primary", "fingerprint": "bb4a993aeb32412e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ee6ed85aaf1a7129", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/routes/landing.js:65"}, "properties": {"repobilityId": "92649909960bf244", "scanner": "scanner-primary", "fingerprint": "ee6ed85aaf1a7129", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e4d0b326100e0220", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/routes/stripe-webhook.js:125"}, "properties": {"repobilityId": "b7a6d7cc2164ae2e", "scanner": "scanner-primary", "fingerprint": "e4d0b326100e0220", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c7ab7636f44ddfad", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/routes/edit.js:19"}, "properties": {"repobilityId": "a9e93246e5163094", "scanner": "scanner-primary", "fingerprint": "c7ab7636f44ddfad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-05450e3474fd8d27", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/routes/recover.js:65"}, "properties": {"repobilityId": "55beed56b683b04c", "scanner": "scanner-primary", "fingerprint": "05450e3474fd8d27", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3e38f8a95c6d9b3f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/routes/demo-tool.js:64"}, "properties": {"repobilityId": "0d5c89152f591ed8", "scanner": "scanner-primary", "fingerprint": "3e38f8a95c6d9b3f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9c2fda8ec32d9ec6", "level": "none", "message": {"text": "Commented-code block (14 lines) in src/routes/photo-picker.js:5"}, "properties": {"repobilityId": "4fa95c741b1853de", "scanner": "scanner-primary", "fingerprint": "9c2fda8ec32d9ec6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-167c7f943bcee41c", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/routes/checkout.js:27"}, "properties": {"repobilityId": "c100e44989b13274", "scanner": "scanner-primary", "fingerprint": "167c7f943bcee41c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-15baa6c6b97fe6d0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/routes/admin.js:353"}, "properties": {"repobilityId": "2585bc2355605b78", "scanner": "scanner-primary", "fingerprint": "15baa6c6b97fe6d0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a44261085ff35188", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/routes/admin.js:32"}, "properties": {"repobilityId": "7e6e4a23c130b367", "scanner": "scanner-primary", "fingerprint": "a44261085ff35188", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-241f1c00eacf2047", "level": "none", "message": {"text": "Commented-code block (5 lines) in public/admin/admin.js:118"}, "properties": {"repobilityId": "fdbbc173bc761d8e", "scanner": "scanner-primary", "fingerprint": "241f1c00eacf2047", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bc5793224672809b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/admin/admin.js:34"}, "properties": {"repobilityId": "c538688ecc3c1f25", "scanner": "scanner-primary", "fingerprint": "bc5793224672809b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-30a64c6246aecac0", "level": "none", "message": {"text": "Commented-code block (5 lines) in public/edit/edit.js:224"}, "properties": {"repobilityId": "add19ba65f4ef801", "scanner": "scanner-primary", "fingerprint": "30a64c6246aecac0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9b43c3bff2b69e08", "level": "none", "message": {"text": "Commented-code block (5 lines) in public/site/pricing-modal.js:484"}, "properties": {"repobilityId": "d120b6975f836895", "scanner": "scanner-primary", "fingerprint": "9b43c3bff2b69e08", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b7f0fc65537be32f", "level": "none", "message": {"text": "Commented-code block (5 lines) in public/site/preview-onboarding.js:279"}, "properties": {"repobilityId": "49aade4429c2b1a8", "scanner": "scanner-primary", "fingerprint": "b7f0fc65537be32f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e3e14d9dd58c626c", "level": "none", "message": {"text": "Commented-code block (7 lines) in public/site/home.js:12"}, "properties": {"repobilityId": "ee5cfaf5d3582107", "scanner": "scanner-primary", "fingerprint": "e3e14d9dd58c626c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b39db73e344e8a7f", "level": "none", "message": {"text": "Commented-code block (8 lines) in public/site/waiting-screen.js:98"}, "properties": {"repobilityId": "e55ee500a6af5050", "scanner": "scanner-primary", "fingerprint": "b39db73e344e8a7f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a71601bd13c7794e", "level": "none", "message": {"text": "Commented-code block (8 lines) in public/site/main.js:521"}, "properties": {"repobilityId": "fc21309feff9e2cd", "scanner": "scanner-primary", "fingerprint": "a71601bd13c7794e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-be98a2727e1b316a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/site/main.js:16"}, "properties": {"repobilityId": "95be1051559ac090", "scanner": "scanner-primary", "fingerprint": "be98a2727e1b316a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ef22fd58bfde6f76", "level": "note", "message": {"text": "51 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "3022eac3b673b267", "scanner": "scanner-primary", "fingerprint": "ef22fd58bfde6f76", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-3599bfc001df627f", "level": "error", "message": {"text": "Dangling fetch: GET https://api.cloudflare.com/client/v4${path} (scripts/resume-provisioning.mjs:43)"}, "properties": {"repobilityId": "e9148181783332c7", "scanner": "scanner-primary", "fingerprint": "3599bfc001df627f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8f5f9aa48d66b9ba", "level": "error", "message": {"text": "Dangling fetch: POST https://api.resend.com/emails (src/routes/landing.js:301)"}, "properties": {"repobilityId": "4f5d92c62d5ed0cf", "scanner": "scanner-primary", "fingerprint": "8f5f9aa48d66b9ba", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8e2ec6059452d867", "level": "error", "message": {"text": "Dangling fetch: PUT /admin/salon/${encodeURIComponent(slug)}/nom-final (public/admin/admin.js:332)"}, "properties": {"repobilityId": "cf0fa532f22d887c", "scanner": "scanner-primary", "fingerprint": "8e2ec6059452d867", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-08c085c36dab0dbc", "level": "error", "message": {"text": "Dangling fetch: POST /admin/upload-csv (public/admin/admin.js:446)"}, "properties": {"repobilityId": "bfcecb7decbf0506", "scanner": "scanner-primary", "fingerprint": "08c085c36dab0dbc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2353c875d23f0b83", "level": "error", "message": {"text": "Dangling fetch: POST /admin/logout (public/admin/admin.js:561)"}, "properties": {"repobilityId": "0b8459b3d2a13329", "scanner": "scanner-primary", "fingerprint": "2353c875d23f0b83", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d4b1422e7f18c7dc", "level": "error", "message": {"text": "Dangling fetch: GET /api/edit/${encodeURIComponent(state.slug)}${tokenQS()} (public/edit/edit.js:58)"}, "properties": {"repobilityId": "c0f34d50b8683921", "scanner": "scanner-primary", "fingerprint": "d4b1422e7f18c7dc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c86afca12cf7c731", "level": "error", "message": {"text": "Dangling fetch: PUT /api/edit/${encodeURIComponent(state.slug)}${tokenQS()} (public/edit/edit.js:69)"}, "properties": {"repobilityId": "9489af4268061664", "scanner": "scanner-primary", "fingerprint": "c86afca12cf7c731", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-78c615667af52282", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/edit/${encodeURIComponent(state.slug)}/overrides${tokenQS()} (public/edit/edit.js:83)"}, "properties": {"repobilityId": "2157c8156ca1e840", "scanner": "scanner-primary", "fingerprint": "78c615667af52282", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e0987396b0690e70", "level": "error", "message": {"text": "Dangling fetch: POST /api/edit/${encodeURIComponent(state.slug)}/upload-image${tokenQS()} (public/edit/edit.js:95)"}, "properties": {"repobilityId": "4cf06ab9c941fbca", "scanner": "scanner-primary", "fingerprint": "e0987396b0690e70", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e7249f2f256161b5", "level": "note", "message": {"text": "Unused endpoint: USE /webhook"}, "properties": {"repobilityId": "b0238af3e3f76ed8", "scanner": "scanner-primary", "fingerprint": "e7249f2f256161b5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "a3eddf5065ffbf6c", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a58e737b8b02d702", "level": "note", "message": {"text": "Unused endpoint: USE /api/caddy"}, "properties": {"repobilityId": "0ba689019ce13b7b", "scanner": "scanner-primary", "fingerprint": "a58e737b8b02d702", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bd5fe0f6ad153b91", "level": "note", "message": {"text": "Unused endpoint: USE /screenshots"}, "properties": {"repobilityId": "350174fe88811ec0", "scanner": "scanner-primary", "fingerprint": "bd5fe0f6ad153b91", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1bc898b3b7565990", "level": "note", "message": {"text": "Unused endpoint: USE /uploads"}, "properties": {"repobilityId": "ff548f29fd0f83df", "scanner": "scanner-primary", "fingerprint": "1bc898b3b7565990", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bcd762d17b21b91b", "level": "note", "message": {"text": "Unused endpoint: USE /legal"}, "properties": {"repobilityId": "3da6eb20d7cecd32", "scanner": "scanner-primary", "fingerprint": "bcd762d17b21b91b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f02a079c69b52f2d", "level": "note", "message": {"text": "Unused endpoint: USE /"}, "properties": {"repobilityId": "11b055fa2670dbdf", "scanner": "scanner-primary", "fingerprint": "f02a079c69b52f2d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9244047f68bde53d", "level": "note", "message": {"text": "Unused endpoint: GET /recover"}, "properties": {"repobilityId": "1c9c968dd152610c", "scanner": "scanner-primary", "fingerprint": "9244047f68bde53d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e7f059540834e0d4", "level": "note", "message": {"text": "Unused endpoint: USE /edit-app"}, "properties": {"repobilityId": "0e958a638fc85418", "scanner": "scanner-primary", "fingerprint": "e7f059540834e0d4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b2d8849fb6b1ac47", "level": "note", "message": {"text": "Unused endpoint: USE /admin"}, "properties": {"repobilityId": "2752bb9f19ba5dbb", "scanner": "scanner-primary", "fingerprint": "b2d8849fb6b1ac47", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d6c8f076249de027", "level": "note", "message": {"text": "Unused endpoint: GET /admin/:slug"}, "properties": {"repobilityId": "f2078fa262e72cab", "scanner": "scanner-primary", "fingerprint": "d6c8f076249de027", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-953ec1a0ee6df50d", "level": "note", "message": {"text": "Unused endpoint: GET /admin"}, "properties": {"repobilityId": "20a301044ef91485", "scanner": "scanner-primary", "fingerprint": "953ec1a0ee6df50d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-015af72088b86fec", "level": "note", "message": {"text": "Unused endpoint: USE /_assets"}, "properties": {"repobilityId": "71f732890687a6c3", "scanner": "scanner-primary", "fingerprint": "015af72088b86fec", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7388dbfa7be50c3d", "level": "note", "message": {"text": "Unused endpoint: GET /preview/:slug"}, "properties": {"repobilityId": "7e81ae7323fe9941", "scanner": "scanner-primary", "fingerprint": "7388dbfa7be50c3d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "9b883326e67da4e4", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0d1755e0301de825", "level": "note", "message": {"text": "Unused endpoint: GET /check-hostname"}, "properties": {"repobilityId": "fed910567e80346d", "scanner": "scanner-primary", "fingerprint": "0d1755e0301de825", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2083a87719497893", "level": "note", "message": {"text": "Unused endpoint: POST /stripe"}, "properties": {"repobilityId": "3baa5a6d49f3fc40", "scanner": "scanner-primary", "fingerprint": "2083a87719497893", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-169e347ffd292ad4", "level": "note", "message": {"text": "Unused endpoint: GET /edit/:slug"}, "properties": {"repobilityId": "fb812b28a897cac7", "scanner": "scanner-primary", "fingerprint": "169e347ffd292ad4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dcff5438ec5d51c6", "level": "note", "message": {"text": "Unused endpoint: PUT /edit/:slug"}, "properties": {"repobilityId": "54c24cca099774bf", "scanner": "scanner-primary", "fingerprint": "dcff5438ec5d51c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ebaa32f558410d63", "level": "note", "message": {"text": "Unused endpoint: DELETE /edit/:slug/overrides"}, "properties": {"repobilityId": "a1aad184cc5f32a5", "scanner": "scanner-primary", "fingerprint": "ebaa32f558410d63", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd659fe7f44901c1", "level": "note", "message": {"text": "Unused endpoint: POST /edit/:slug/upload-image"}, "properties": {"repobilityId": "f3a2590db6f71d94", "scanner": "scanner-primary", "fingerprint": "fd659fe7f44901c1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c50727bbaad4e34b", "level": "note", "message": {"text": "Unused endpoint: DELETE /edit/:slug/upload-image"}, "properties": {"repobilityId": "30b44eeacafa659c", "scanner": "scanner-primary", "fingerprint": "c50727bbaad4e34b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dc1154d30e2fb8ed", "level": "note", "message": {"text": "Unused endpoint: POST /api/recover"}, "properties": {"repobilityId": "c3618c140fd0e46f", "scanner": "scanner-primary", "fingerprint": "dc1154d30e2fb8ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e9084aac01b84235", "level": "note", "message": {"text": "Unused endpoint: GET /recover/confirm"}, "properties": {"repobilityId": "dd62924fd2ec8af9", "scanner": "scanner-primary", "fingerprint": "e9084aac01b84235", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5c74e6393e6f44ef", "level": "note", "message": {"text": "Unused endpoint: GET /:secret"}, "properties": {"repobilityId": "911006cf71cd1b4f", "scanner": "scanner-primary", "fingerprint": "5c74e6393e6f44ef", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b0aedc54b083bf7a", "level": "note", "message": {"text": "Unused endpoint: GET /:secret/api/search"}, "properties": {"repobilityId": "9f2b2ab6cb3e3c5d", "scanner": "scanner-primary", "fingerprint": "b0aedc54b083bf7a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-80713abf53d14820", "level": "note", "message": {"text": "Unused endpoint: POST /:secret/api/send-email"}, "properties": {"repobilityId": "954c46268b8641e1", "scanner": "scanner-primary", "fingerprint": "80713abf53d14820", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d26c5ed86a5f1af8", "level": "note", "message": {"text": "Unused endpoint: GET /salons"}, "properties": {"repobilityId": "de68a1fbf76cb4b0", "scanner": "scanner-primary", "fingerprint": "d26c5ed86a5f1af8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5c2bcdc3fe9f6f1b", "level": "note", "message": {"text": "Unused endpoint: GET /csv-imports"}, "properties": {"repobilityId": "84482f91ac2a7083", "scanner": "scanner-primary", "fingerprint": "5c2bcdc3fe9f6f1b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd8dc4599ec52a08", "level": "note", "message": {"text": "Unused endpoint: GET /stats"}, "properties": {"repobilityId": "e7755e6923044938", "scanner": "scanner-primary", "fingerprint": "cd8dc4599ec52a08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3d6b2afb59d831d9", "level": "note", "message": {"text": "Unused endpoint: POST /sync/:slug"}, "properties": {"repobilityId": "a923617d9e770654", "scanner": "scanner-primary", "fingerprint": "3d6b2afb59d831d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-23e1514567b41917", "level": "note", "message": {"text": "Unused endpoint: DELETE /sync/:slug"}, "properties": {"repobilityId": "59ff0db805e20993", "scanner": "scanner-primary", "fingerprint": "23e1514567b41917", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ab7d61f6e9a40f06", "level": "note", "message": {"text": "Unused endpoint: USE /photos-files"}, "properties": {"repobilityId": "2abb660c4d034196", "scanner": "scanner-primary", "fingerprint": "ab7d61f6e9a40f06", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-65197b248dd51d78", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/import-index"}, "properties": {"repobilityId": "8a3aedb4302ad240", "scanner": "scanner-primary", "fingerprint": "65197b248dd51d78", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e446e18585f67fd3", "level": "note", "message": {"text": "Unused endpoint: GET /api/picker/stats"}, "properties": {"repobilityId": "9a5268a9a34c9b91", "scanner": "scanner-primary", "fingerprint": "e446e18585f67fd3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-89b4b5990519384d", "level": "note", "message": {"text": "Unused endpoint: GET /api/picker/criteria"}, "properties": {"repobilityId": "76b8d14b915cb749", "scanner": "scanner-primary", "fingerprint": "89b4b5990519384d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ea4ac96d62373edf", "level": "note", "message": {"text": "Unused endpoint: PUT /api/picker/criteria"}, "properties": {"repobilityId": "c190412868984645", "scanner": "scanner-primary", "fingerprint": "ea4ac96d62373edf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e2689b85657938a4", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/batch"}, "properties": {"repobilityId": "b6b1516e8f288629", "scanner": "scanner-primary", "fingerprint": "e2689b85657938a4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cfd54e302cea93f6", "level": "note", "message": {"text": "Unused endpoint: GET /api/picker/batch/:id"}, "properties": {"repobilityId": "0b34ad2876641557", "scanner": "scanner-primary", "fingerprint": "cfd54e302cea93f6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-daf0964136cda8f2", "level": "note", "message": {"text": "Unused endpoint: GET /api/picker/results"}, "properties": {"repobilityId": "0132991634000371", "scanner": "scanner-primary", "fingerprint": "daf0964136cda8f2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c0180f9a044f137f", "level": "note", "message": {"text": "Unused endpoint: GET /api/picker/results/:id"}, "properties": {"repobilityId": "fb90bfcc1f646343", "scanner": "scanner-primary", "fingerprint": "c0180f9a044f137f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6719542513a66fff", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/feedback"}, "properties": {"repobilityId": "e0fc56917411984d", "scanner": "scanner-primary", "fingerprint": "6719542513a66fff", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d04ea9baeb58f652", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/apply-hero"}, "properties": {"repobilityId": "287d0833152ed6cb", "scanner": "scanner-primary", "fingerprint": "d04ea9baeb58f652", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-02f6c04cd01553d5", "level": "note", "message": {"text": "Unused endpoint: GET /api/picker/salon/:slug/photos"}, "properties": {"repobilityId": "ee1497a48ebab7a4", "scanner": "scanner-primary", "fingerprint": "02f6c04cd01553d5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b93051e86ce9813b", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/salon/:slug/hero"}, "properties": {"repobilityId": "e909c4216ab2ad2f", "scanner": "scanner-primary", "fingerprint": "b93051e86ce9813b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-255adb0b8424126f", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/salon/:slug/gallery"}, "properties": {"repobilityId": "60f9732dd7d1c5fd", "scanner": "scanner-primary", "fingerprint": "255adb0b8424126f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-55dd2f1adbd0db42", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/salon/:slug/reset-images"}, "properties": {"repobilityId": "cb68ff133ec85533", "scanner": "scanner-primary", "fingerprint": "55dd2f1adbd0db42", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-39c5e576e9dd4d66", "level": "note", "message": {"text": "Unused endpoint: POST /api/picker/salon/:slug/score"}, "properties": {"repobilityId": "1bb64c3f5ec8608b", "scanner": "scanner-primary", "fingerprint": "39c5e576e9dd4d66", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-60bd9caaa11e0409", "level": "note", "message": {"text": "Unused endpoint: GET /signup/status"}, "properties": {"repobilityId": "6fd017c596814e42", "scanner": "scanner-primary", "fingerprint": "60bd9caaa11e0409", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "3b8ca51b571a953f", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}