{"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-54141d289e96a269", "name": "Stray `console.log` in TS/JS \u2014 worker-configuration.d.ts:186", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 worker-configuration.d.ts:186"}, "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-f42bb1893f8f708f", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/presence-notify.ts:7", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/presence-notify.ts:7"}, "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-0069377618ea78dd", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/backup.ts:49", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/backup.ts:49"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e17abc3d431a9068", "name": "TODO/FIXME marker in shipping code \u2014 apps/api/src/lib/notify.ts:15", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 apps/api/src/lib/notify.ts:15"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d273e166165d41f0", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/notify.ts:16", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/notify.ts:16"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0e5aa0a13ba05c38", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/TeamBox.tsx:131", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/TeamBox.tsx:131"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e738f52e4cc5013b", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/FinanceSection.tsx:103", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/FinanceSection.tsx:103"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2eb95ea65e29594b", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/InboxSettings.tsx:299", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/InboxSettings.tsx:299"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-673345b0871e1a71", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/Layout.tsx:157", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/Layout.tsx:157"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-64c73fc40f680a99", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/TaskDrawer.tsx:129", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/TaskDrawer.tsx:129"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5de9012b5701b53e", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Dashboard.tsx:86", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Dashboard.tsx:86"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8188fb443a0edbf7", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Docs.tsx:262", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Docs.tsx:262"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-577ce51ba5583d30", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ClientDetail.tsx:180", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ClientDetail.tsx:180"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c3fcb97d06b29c4d", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/PayrollOwner.tsx:72", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/PayrollOwner.tsx:72"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-874ea024e849dbd7", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Clients.tsx:105", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Clients.tsx:105"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6e500eb04ad97b73", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ProjectDetail.tsx:114", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ProjectDetail.tsx:114"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-fb6aa2d257eebd7b", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Inbox.tsx:588", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Inbox.tsx:588"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-fff4e5b25364459c", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Payroll.tsx:74", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Payroll.tsx:74"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-272e19238d62cec0", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Expenses.tsx:182", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Expenses.tsx:182"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-43e77326befaee30", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Projects.tsx:45", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Projects.tsx:45"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a3bfdd2f23dc0400", "name": "Insecure pattern 'exec_used' in worker-configuration.d.ts:3057", "shortDescription": {"text": "Insecure pattern 'exec_used' in worker-configuration.d.ts:3057"}, "fullDescription": {"text": "Found a known-risky pattern (exec_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5d1a6b10030bbb9e", "name": "Insecure pattern 'direct_innerhtml_assignment' in mockup.html:850", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in mockup.html:850"}, "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-5c9c7d66dd70fab5", "name": "Very large file: worker-configuration.d.ts (14497 lines)", "shortDescription": {"text": "Very large file: worker-configuration.d.ts (14497 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-f19a256605b68ef3", "name": "Very large file: apps/web/src/pages/Inbox.tsx (1268 lines)", "shortDescription": {"text": "Very large file: apps/web/src/pages/Inbox.tsx (1268 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-b06b8d86f24c77f9", "name": "Node manifest has dependencies but no lockfile: apps/api/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4a9eb7dc7c6e3880", "name": "Node manifest has dependencies but no lockfile: apps/web/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7b16ae2bd0fca524", "name": "Node manifest has dependencies but no lockfile: packages/db/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/db/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "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 59 placeholder/mock markers across 15 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing lockfile. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-464fe0c980482ae0", "name": "Legacy-named symbol `certIssuerDNLegacy` in worker-configuration.d.ts:11783", "shortDescription": {"text": "Legacy-named symbol `certIssuerDNLegacy` in worker-configuration.d.ts:11783"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a5849b09d38cd519", "name": "Commented-code block (6 lines) in worker-configuration.d.ts:10183", "shortDescription": {"text": "Commented-code block (6 lines) in worker-configuration.d.ts:10183"}, "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-ea71421bec139f97", "name": "`fetch()` without try/.catch or AbortSignal \u2014 worker-configuration.d.ts:319", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 worker-configuration.d.ts:319"}, "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-ac984094e6d1ae4c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/index.ts:127", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/index.ts:127"}, "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-fe06a3466cb12d84", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/gcal-sync.ts:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/gcal-sync.ts:36"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d1007643e5740e7", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/inbox-sync.ts:46", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/inbox-sync.ts:46"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7ddf6da1bf55466e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/auth.ts:58", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/auth.ts:58"}, "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-8f3e1df4c92c831d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/calendar-connect.ts:124", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/calendar-connect.ts:124"}, "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-72d07d70ad7f2e2e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/inbox-threads.ts:534", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/inbox-threads.ts:534"}, "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-c50db4d3e434b3ef", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/inbox-settings.ts:322", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/inbox-settings.ts:322"}, "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-2dc7a91db2705b59", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/do/inbox-thread-hub.ts:16", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/do/inbox-thread-hub.ts:16"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5ccedf5f0fa88322", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/do/presence-hub.ts:10", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/do/presence-hub.ts:10"}, "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-d6c211b933d20e47", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/components/TaskDrawer.tsx:220", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/components/TaskDrawer.tsx:220"}, "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-cee7056201334ec1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/pages/Docs.tsx:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/pages/Docs.tsx:36"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3e0fa7b66c2ab63d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/pages/Expenses.tsx:67", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/pages/Expenses.tsx:67"}, "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-9e7aeea036818446", "name": "Dangling fetch: GET /api/calendar-connect/connect (apps/api/test/gcal.test.ts:177)", "shortDescription": {"text": "Dangling fetch: GET /api/calendar-connect/connect (apps/api/test/gcal.test.ts:177)"}, "fullDescription": {"text": "`apps/api/test/gcal.test.ts:177` calls `GET /api/calendar-connect/connect` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/calendar-connect/connect`\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-b70ec7cbc32041fe", "name": "Dangling fetch: GET /api/inbox/search?q=x (apps/api/test/inbox-search.test.ts:131)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/search?q=x (apps/api/test/inbox-search.test.ts:131)"}, "fullDescription": {"text": "`apps/api/test/inbox-search.test.ts:131` calls `GET /api/inbox/search?q=x` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/search`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b15905e54ea3b8b5", "name": "Dangling fetch: GET /api/inbox/search?q=${encodeURIComponent(long)} (apps/api/test/inbox-search.test.ts:182)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/search?q=${encodeURIComponent(long)} (apps/api/test/inbox-search.test.ts:182)"}, "fullDescription": {"text": "`apps/api/test/inbox-search.test.ts:182` calls `GET /api/inbox/search?q=${encodeURIComponent(long)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/search`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-1c065ae7dbdb2358", "name": "Dangling fetch: GET /api/inbox/search?q=test (apps/api/test/inbox-search.test.ts:208)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/search?q=test (apps/api/test/inbox-search.test.ts:208)"}, "fullDescription": {"text": "`apps/api/test/inbox-search.test.ts:208` calls `GET /api/inbox/search?q=test` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/search`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c7731678e5187170", "name": "Dangling fetch: GET /api/inbox/threads/${threadId} (apps/api/test/inbox-search.test.ts:246)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads/${threadId} (apps/api/test/inbox-search.test.ts:246)"}, "fullDescription": {"text": "`apps/api/test/inbox-search.test.ts:246` calls `GET /api/inbox/threads/${threadId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads/<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-184f098e79ee7442", "name": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/task-detail.test.ts:34)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/task-detail.test.ts:34)"}, "fullDescription": {"text": "`apps/api/test/task-detail.test.ts:34` calls `GET /api/tasks/${t.id}/detail` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/detail`\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-dc7d3d55162d94d4", "name": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:47)", "shortDescription": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:47)"}, "fullDescription": {"text": "`apps/api/test/task-detail.test.ts:47` calls `POST /api/tasks/${t.id}/attachments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/attachments`\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-ce0f042a2c8fe1f6", "name": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:66)", "shortDescription": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:66)"}, "fullDescription": {"text": "`apps/api/test/task-detail.test.ts:66` calls `POST /api/tasks/${t.id}/attachments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/attachments`\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-0cef99e7393c1fcf", "name": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:75)", "shortDescription": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:75)"}, "fullDescription": {"text": "`apps/api/test/task-detail.test.ts:75` calls `POST /api/tasks/${t.id}/attachments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/attachments`\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-402299aa19466950", "name": "Dangling fetch: GET /api/tasks/${t.id} (apps/api/test/task-detail.test.ts:90)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id} (apps/api/test/task-detail.test.ts:90)"}, "fullDescription": {"text": "`apps/api/test/task-detail.test.ts:90` calls `GET /api/tasks/${t.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<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-f1537f39b4fa5dda", "name": "Dangling fetch: GET /api/tasks/${t.id} (apps/api/test/task-detail.test.ts:91)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id} (apps/api/test/task-detail.test.ts:91)"}, "fullDescription": {"text": "`apps/api/test/task-detail.test.ts:91` calls `GET /api/tasks/${t.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<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-b3cab868e10d7ffc", "name": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/task-detail.test.ts:93)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/task-detail.test.ts:93)"}, "fullDescription": {"text": "`apps/api/test/task-detail.test.ts:93` calls `GET /api/tasks/${t.id}/detail` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/detail`\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-5264a88c2b047707", "name": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:42)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:42)"}, "fullDescription": {"text": "`apps/api/test/tasks.test.ts:42` calls `GET /api/projects/${p.id}/board` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/board`\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-caacf8a9fc16706d", "name": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:48)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:48)"}, "fullDescription": {"text": "`apps/api/test/tasks.test.ts:48` calls `GET /api/projects/${p.id}/board` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/board`\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-52d551be7fe03288", "name": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:52)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:52)"}, "fullDescription": {"text": "`apps/api/test/tasks.test.ts:52` calls `GET /api/projects/${p.id}/board` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/board`\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-225009c10e781d83", "name": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:78)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:78)"}, "fullDescription": {"text": "`apps/api/test/tasks.test.ts:78` calls `GET /api/projects/${p.id}/board` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/board`\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-33551358f9cb20b8", "name": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:90)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:90)"}, "fullDescription": {"text": "`apps/api/test/tasks.test.ts:90` calls `GET /api/projects/${p.id}/board` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/board`\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-ca3d12da99f1e574", "name": "Dangling fetch: DELETE /api/groups/${g1.id} (apps/api/test/tasks.test.ts:94)", "shortDescription": {"text": "Dangling fetch: DELETE /api/groups/${g1.id} (apps/api/test/tasks.test.ts:94)"}, "fullDescription": {"text": "`apps/api/test/tasks.test.ts:94` calls `DELETE /api/groups/${g1.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/groups/<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-78367781205f1377", "name": "Dangling fetch: GET /owner-only (apps/api/test/roles.test.ts:44)", "shortDescription": {"text": "Dangling fetch: GET /owner-only (apps/api/test/roles.test.ts:44)"}, "fullDescription": {"text": "`apps/api/test/roles.test.ts:44` calls `GET /owner-only` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/owner-only`\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-2c16be13cb952218", "name": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:28)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:28)"}, "fullDescription": {"text": "`apps/api/test/finance.test.ts:28` calls `GET /api/projects/${p.id}/finance` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/finance`\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-5f8b0c0ed4f6db32", "name": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:31)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:31)"}, "fullDescription": {"text": "`apps/api/test/finance.test.ts:31` calls `GET /api/projects/${p.id}/finance` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/finance`\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-837e81a4c5bcd977", "name": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:44)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:44)"}, "fullDescription": {"text": "`apps/api/test/finance.test.ts:44` calls `GET /api/projects/${p.id}/finance` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/finance`\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-1857d07f03c81348", "name": "Dangling fetch: GET /api/milestones/${ms.id} (apps/api/test/finance.test.ts:60)", "shortDescription": {"text": "Dangling fetch: GET /api/milestones/${ms.id} (apps/api/test/finance.test.ts:60)"}, "fullDescription": {"text": "`apps/api/test/finance.test.ts:60` calls `GET /api/milestones/${ms.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/milestones/<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-b98b8b1324599eaa", "name": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:61)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:61)"}, "fullDescription": {"text": "`apps/api/test/finance.test.ts:61` calls `GET /api/projects/${p.id}/finance` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/finance`\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-0995b0ca45b4332c", "name": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:39)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:39)"}, "fullDescription": {"text": "`apps/api/test/pnl.test.ts:39` calls `GET /api/projects/${p.id}/pnl` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/pnl`\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-66936f5f443197a8", "name": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:62)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:62)"}, "fullDescription": {"text": "`apps/api/test/pnl.test.ts:62` calls `GET /api/projects/${p.id}/pnl` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/pnl`\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-b0923728f6a5878a", "name": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/pnl.test.ts:68)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/pnl.test.ts:68)"}, "fullDescription": {"text": "`apps/api/test/pnl.test.ts:68` calls `GET /api/projects/${p.id}/finance` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/finance`\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-fb989799a025c3c5", "name": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:71)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:71)"}, "fullDescription": {"text": "`apps/api/test/pnl.test.ts:71` calls `GET /api/projects/${p.id}/pnl` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/pnl`\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-2d6b18c0075f5178", "name": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:82)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:82)"}, "fullDescription": {"text": "`apps/api/test/pnl.test.ts:82` calls `GET /api/projects/${p.id}/pnl` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/pnl`\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-f51ee9c487fa8272", "name": "Dangling fetch: GET /api/admin/payroll?date=2026-06-10 (apps/api/test/payroll-admin.test.ts:48)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/payroll?date=2026-06-10 (apps/api/test/payroll-admin.test.ts:48)"}, "fullDescription": {"text": "`apps/api/test/payroll-admin.test.ts:48` calls `GET /api/admin/payroll?date=2026-06-10` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/admin/payroll`\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-b77ad6d1e87af79e", "name": "Dangling fetch: GET /api/admin/payroll (apps/api/test/payroll-admin.test.ts:54)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/payroll (apps/api/test/payroll-admin.test.ts:54)"}, "fullDescription": {"text": "`apps/api/test/payroll-admin.test.ts:54` calls `GET /api/admin/payroll` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/admin/payroll`\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-6b49cae1a44cbefd", "name": "Dangling fetch: GET /api/admin/payroll/export?date=2026-06-10 (apps/api/test/payroll-admin.test.ts:75)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/payroll/export?date=2026-06-10 (apps/api/test/payroll-admin.test.ts:75)"}, "fullDescription": {"text": "`apps/api/test/payroll-admin.test.ts:75` calls `GET /api/admin/payroll/export?date=2026-06-10` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/admin/payroll/export`\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-359cc14cdc2936b2", "name": "Dangling fetch: GET /api/time/twa (apps/api/test/payroll-admin.test.ts:101)", "shortDescription": {"text": "Dangling fetch: GET /api/time/twa (apps/api/test/payroll-admin.test.ts:101)"}, "fullDescription": {"text": "`apps/api/test/payroll-admin.test.ts:101` calls `GET /api/time/twa` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/time/twa`\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-fd47d9a0d56cef3c", "name": "Dangling fetch: DELETE /api/time/twa (apps/api/test/payroll-admin.test.ts:102)", "shortDescription": {"text": "Dangling fetch: DELETE /api/time/twa (apps/api/test/payroll-admin.test.ts:102)"}, "fullDescription": {"text": "`apps/api/test/payroll-admin.test.ts:102` calls `DELETE /api/time/twa` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/time/twa`\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-1c29e2693a10e115", "name": "Dangling fetch: GET /api/payments/${created.id} (apps/api/test/clients.test.ts:42)", "shortDescription": {"text": "Dangling fetch: GET /api/payments/${created.id} (apps/api/test/clients.test.ts:42)"}, "fullDescription": {"text": "`apps/api/test/clients.test.ts:42` calls `GET /api/payments/${created.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/payments/<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-3466135a77a8c236", "name": "Dangling fetch: GET /api/clients/${cl.id} (apps/api/test/clients.test.ts:89)", "shortDescription": {"text": "Dangling fetch: GET /api/clients/${cl.id} (apps/api/test/clients.test.ts:89)"}, "fullDescription": {"text": "`apps/api/test/clients.test.ts:89` calls `GET /api/clients/${cl.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/clients/<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-8dd8dc868f5b7165", "name": "Dangling fetch: GET /api/clients/${cl.id} (apps/api/test/clients.test.ts:101)", "shortDescription": {"text": "Dangling fetch: GET /api/clients/${cl.id} (apps/api/test/clients.test.ts:101)"}, "fullDescription": {"text": "`apps/api/test/clients.test.ts:101` calls `GET /api/clients/${cl.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/clients/<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-896f766d06f6ae13", "name": "Dangling fetch: GET /api/timer (apps/api/test/time.test.ts:49)", "shortDescription": {"text": "Dangling fetch: GET /api/timer (apps/api/test/time.test.ts:49)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:49` calls `GET /api/timer` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/timer`\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-328b16a383edbf00", "name": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:56)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:56)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:56` calls `GET /api/tasks/${t.id}/time` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/time`\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-2fcc9a23fdb51082", "name": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/time.test.ts:60)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/time.test.ts:60)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:60` calls `GET /api/tasks/${t.id}/detail` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/detail`\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-48d0fb890805c371", "name": "Dangling fetch: GET /api/tasks/${t1.id}/time (apps/api/test/time.test.ts:78)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t1.id}/time (apps/api/test/time.test.ts:78)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:78` calls `GET /api/tasks/${t1.id}/time` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/time`\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-c8ae42e044d4bc1c", "name": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:116)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:116)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:116` calls `GET /api/tasks/${t.id}/time` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/time`\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-f15d852a35c0b958", "name": "Dangling fetch: GET /api/time/${created.id} (apps/api/test/time.test.ts:131)", "shortDescription": {"text": "Dangling fetch: GET /api/time/${created.id} (apps/api/test/time.test.ts:131)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:131` calls `GET /api/time/${created.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/time/<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-5c7b6809181b9854", "name": "Dangling fetch: DELETE /api/time/${created.id} (apps/api/test/time.test.ts:139)", "shortDescription": {"text": "Dangling fetch: DELETE /api/time/${created.id} (apps/api/test/time.test.ts:139)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:139` calls `DELETE /api/time/${created.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/time/<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-7d190651010c7145", "name": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:156)", "shortDescription": {"text": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:156)"}, "fullDescription": {"text": "`apps/api/test/time.test.ts:156` calls `GET /api/tasks/${t.id}/time` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/tasks/<p>/time`\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-7854f54cad239946", "name": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/overview.test.ts:60)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/overview.test.ts:60)"}, "fullDescription": {"text": "`apps/api/test/overview.test.ts:60` calls `GET /api/projects/${p.id}/board` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<p>/board`\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-972ce099c19bfc30", "name": "Dangling fetch: GET /api/inbox/threads/${thread.id} (apps/api/test/inbox-extras.test.ts:86)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads/${thread.id} (apps/api/test/inbox-extras.test.ts:86)"}, "fullDescription": {"text": "`apps/api/test/inbox-extras.test.ts:86` calls `GET /api/inbox/threads/${thread.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads/<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-1516927b1ea24583", "name": "Dangling fetch: GET /api/inbox/threads/${thread.id} (apps/api/test/inbox-extras.test.ts:104)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads/${thread.id} (apps/api/test/inbox-extras.test.ts:104)"}, "fullDescription": {"text": "`apps/api/test/inbox-extras.test.ts:104` calls `GET /api/inbox/threads/${thread.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads/<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-9e60210b3cd0f7c2", "name": "Dangling fetch: GET /api/inbox/threads (apps/api/test/inbox-threads.test.ts:119)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads (apps/api/test/inbox-threads.test.ts:119)"}, "fullDescription": {"text": "`apps/api/test/inbox-threads.test.ts:119` calls `GET /api/inbox/threads` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads`\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-70a673506c0777a0", "name": "Dangling fetch: GET /api/inbox/threads (apps/api/test/inbox-threads.test.ts:139)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads (apps/api/test/inbox-threads.test.ts:139)"}, "fullDescription": {"text": "`apps/api/test/inbox-threads.test.ts:139` calls `GET /api/inbox/threads` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads`\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-560c032a8f5d7006", "name": "Dangling fetch: GET /api/inbox/threads?folder=mine (apps/api/test/inbox-threads.test.ts:162)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads?folder=mine (apps/api/test/inbox-threads.test.ts:162)"}, "fullDescription": {"text": "`apps/api/test/inbox-threads.test.ts:162` calls `GET /api/inbox/threads?folder=mine` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads`\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-c0697f491a167c3a", "name": "Dangling fetch: GET /api/inbox/threads?folder=all&q=\u0e43\u0e1a\u0e40\u0e2a\u0e19\u0e2d (apps/api/test/inbox-threads.test.ts:185)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads?folder=all&q=\u0e43\u0e1a\u0e40\u0e2a\u0e19\u0e2d (apps/api/test/inbox-threads.test.ts:185)"}, "fullDescription": {"text": "`apps/api/test/inbox-threads.test.ts:185` calls `GET /api/inbox/threads?folder=all&q=\u0e43\u0e1a\u0e40\u0e2a\u0e19\u0e2d` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads`\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-0ed3f3dc8b987c28", "name": "Dangling fetch: GET /api/inbox/threads/${open.id} (apps/api/test/inbox-threads.test.ts:211)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/threads/${open.id} (apps/api/test/inbox-threads.test.ts:211)"}, "fullDescription": {"text": "`apps/api/test/inbox-threads.test.ts:211` calls `GET /api/inbox/threads/${open.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/threads/<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-15f4a2cf63a8796b", "name": "Dangling fetch: GET /api/inbox/attachments/${att.id}/download (apps/api/test/inbox-threads.test.ts:283)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/attachments/${att.id}/download (apps/api/test/inbox-threads.test.ts:283)"}, "fullDescription": {"text": "`apps/api/test/inbox-threads.test.ts:283` calls `GET /api/inbox/attachments/${att.id}/download` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/attachments/<p>/download`\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-bac74174888cd510", "name": "Dangling fetch: GET /api/inbox/attachments/${att.id}/download (apps/api/test/inbox-threads.test.ts:308)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/attachments/${att.id}/download (apps/api/test/inbox-threads.test.ts:308)"}, "fullDescription": {"text": "`apps/api/test/inbox-threads.test.ts:308` calls `GET /api/inbox/attachments/${att.id}/download` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/attachments/<p>/download`\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-f785ca1fa280b2e0", "name": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/helpers.ts:37)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/helpers.ts:37)"}, "fullDescription": {"text": "`apps/api/test/helpers.ts:37` calls `POST /api/auth/dev-login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/dev-login`\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-9fc741479099e0d5", "name": "Dangling fetch: GET /api/payroll/u_nam (apps/api/test/payroll.test.ts:108)", "shortDescription": {"text": "Dangling fetch: GET /api/payroll/u_nam (apps/api/test/payroll.test.ts:108)"}, "fullDescription": {"text": "`apps/api/test/payroll.test.ts:108` calls `GET /api/payroll/u_nam` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/payroll/u_nam`\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-dcf2cbe89087451b", "name": "Dangling fetch: POST /api/admin/users/${u.id}/rates (apps/api/test/admin.test.ts:43)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/users/${u.id}/rates (apps/api/test/admin.test.ts:43)"}, "fullDescription": {"text": "`apps/api/test/admin.test.ts:43` calls `POST /api/admin/users/${u.id}/rates` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/admin/users/<p>/rates`\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-7e398b09a068ad10", "name": "Dangling fetch: GET /api/users/${u.id}/rates (apps/api/test/admin.test.ts:54)", "shortDescription": {"text": "Dangling fetch: GET /api/users/${u.id}/rates (apps/api/test/admin.test.ts:54)"}, "fullDescription": {"text": "`apps/api/test/admin.test.ts:54` calls `GET /api/users/${u.id}/rates` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/users/<p>/rates`\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-c5684c85fc9ddcac", "name": "Dangling fetch: GET /api/users/u_somchai/rates (apps/api/test/admin.test.ts:64)", "shortDescription": {"text": "Dangling fetch: GET /api/users/u_somchai/rates (apps/api/test/admin.test.ts:64)"}, "fullDescription": {"text": "`apps/api/test/admin.test.ts:64` calls `GET /api/users/u_somchai/rates` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/users/u_somchai/rates`\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-10027394a1cef0bc", "name": "Dangling fetch: GET /api/docs/${root.id} (apps/api/test/docs.test.ts:36)", "shortDescription": {"text": "Dangling fetch: GET /api/docs/${root.id} (apps/api/test/docs.test.ts:36)"}, "fullDescription": {"text": "`apps/api/test/docs.test.ts:36` calls `GET /api/docs/${root.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/docs/<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-b10c7717d3a986e2", "name": "Dangling fetch: DELETE /api/docs/${a.id} (apps/api/test/docs.test.ts:67)", "shortDescription": {"text": "Dangling fetch: DELETE /api/docs/${a.id} (apps/api/test/docs.test.ts:67)"}, "fullDescription": {"text": "`apps/api/test/docs.test.ts:67` calls `DELETE /api/docs/${a.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/docs/<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-f38f5741e08cac38", "name": "Dangling fetch: POST /api/docs/images (apps/api/test/docs.test.ts:83)", "shortDescription": {"text": "Dangling fetch: POST /api/docs/images (apps/api/test/docs.test.ts:83)"}, "fullDescription": {"text": "`apps/api/test/docs.test.ts:83` calls `POST /api/docs/images` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/docs/images`\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-a86a560c65f708a5", "name": "Dangling fetch: POST /api/docs/images (apps/api/test/docs.test.ts:94)", "shortDescription": {"text": "Dangling fetch: POST /api/docs/images (apps/api/test/docs.test.ts:94)"}, "fullDescription": {"text": "`apps/api/test/docs.test.ts:94` calls `POST /api/docs/images` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/docs/images`\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-83d9075e954fc5cb", "name": "Dangling fetch: GET /api/time/${manual.id} (apps/api/test/integrity.test.ts:37)", "shortDescription": {"text": "Dangling fetch: GET /api/time/${manual.id} (apps/api/test/integrity.test.ts:37)"}, "fullDescription": {"text": "`apps/api/test/integrity.test.ts:37` calls `GET /api/time/${manual.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/time/<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-0f7150bf0f67edac", "name": "Dangling fetch: GET /api/team-hours?date=2026-06-10 (apps/api/test/integrity.test.ts:40)", "shortDescription": {"text": "Dangling fetch: GET /api/team-hours?date=2026-06-10 (apps/api/test/integrity.test.ts:40)"}, "fullDescription": {"text": "`apps/api/test/integrity.test.ts:40` calls `GET /api/team-hours?date=2026-06-10` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/team-hours`\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-42a83bbf89c608e7", "name": "Dangling fetch: GET /api/team-hours (apps/api/test/integrity.test.ts:53)", "shortDescription": {"text": "Dangling fetch: GET /api/team-hours (apps/api/test/integrity.test.ts:53)"}, "fullDescription": {"text": "`apps/api/test/integrity.test.ts:53` calls `GET /api/team-hours` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/team-hours`\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-5d043111c4ce1f9b", "name": "Dangling fetch: GET /api/team-hours?date=2026-06-10 (apps/api/test/integrity.test.ts:62)", "shortDescription": {"text": "Dangling fetch: GET /api/team-hours?date=2026-06-10 (apps/api/test/integrity.test.ts:62)"}, "fullDescription": {"text": "`apps/api/test/integrity.test.ts:62` calls `GET /api/team-hours?date=2026-06-10` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/team-hours`\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-3b93e76c0d708f8e", "name": "Dangling fetch: GET /api/inbox/mailboxes/xx/connect (apps/api/test/inbox-settings.test.ts:64)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/mailboxes/xx/connect (apps/api/test/inbox-settings.test.ts:64)"}, "fullDescription": {"text": "`apps/api/test/inbox-settings.test.ts:64` calls `GET /api/inbox/mailboxes/xx/connect` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/mailboxes/xx/connect`\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-0a780d265c2c9611", "name": "Dangling fetch: DELETE /api/inbox/clients/${client.id} (apps/api/test/inbox-settings.test.ts:113)", "shortDescription": {"text": "Dangling fetch: DELETE /api/inbox/clients/${client.id} (apps/api/test/inbox-settings.test.ts:113)"}, "fullDescription": {"text": "`apps/api/test/inbox-settings.test.ts:113` calls `DELETE /api/inbox/clients/${client.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/clients/<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-964821559db1187d", "name": "Dangling fetch: DELETE /api/inbox/clients/${client.id} (apps/api/test/inbox-settings.test.ts:122)", "shortDescription": {"text": "Dangling fetch: DELETE /api/inbox/clients/${client.id} (apps/api/test/inbox-settings.test.ts:122)"}, "fullDescription": {"text": "`apps/api/test/inbox-settings.test.ts:122` calls `DELETE /api/inbox/clients/${client.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/clients/<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-c885ecee34475bd4", "name": "Dangling fetch: GET /api/inbox/mailboxes/${box.id}/connect (apps/api/test/inbox-settings.test.ts:221)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/mailboxes/${box.id}/connect (apps/api/test/inbox-settings.test.ts:221)"}, "fullDescription": {"text": "`apps/api/test/inbox-settings.test.ts:221` calls `GET /api/inbox/mailboxes/${box.id}/connect` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/mailboxes/<p>/connect`\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-74772292adaadc65", "name": "Dangling fetch: GET /api/inbox/mailboxes/${box.id}/connect (apps/api/test/inbox-settings.test.ts:248)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/mailboxes/${box.id}/connect (apps/api/test/inbox-settings.test.ts:248)"}, "fullDescription": {"text": "`apps/api/test/inbox-settings.test.ts:248` calls `GET /api/inbox/mailboxes/${box.id}/connect` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/mailboxes/<p>/connect`\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-3fcd2f4caa328a3d", "name": "Dangling fetch: GET /api/inbox/google/callback?code=test-code&state=st-123 (apps/api/test/inbox-settings.test.ts:290)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/google/callback?code=test-code&state=st-123 (apps/api/test/inbox-settings.test.ts:290)"}, "fullDescription": {"text": "`apps/api/test/inbox-settings.test.ts:290` calls `GET /api/inbox/google/callback?code=test-code&state=st-123` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/google/callback`\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-d624f8c825ecd9b6", "name": "Dangling fetch: GET /api/inbox/google/callback?code=c&state=st-WRONG (apps/api/test/inbox-settings.test.ts:347)", "shortDescription": {"text": "Dangling fetch: GET /api/inbox/google/callback?code=c&state=st-WRONG (apps/api/test/inbox-settings.test.ts:347)"}, "fullDescription": {"text": "`apps/api/test/inbox-settings.test.ts:347` calls `GET /api/inbox/google/callback?code=c&state=st-WRONG` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/inbox/google/callback`\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-d47ef61d990bdc42", "name": "Dangling fetch: PATCH /api/projects/${p.id} (apps/api/test/projects.test.ts:62)", "shortDescription": {"text": "Dangling fetch: PATCH /api/projects/${p.id} (apps/api/test/projects.test.ts:62)"}, "fullDescription": {"text": "`apps/api/test/projects.test.ts:62` calls `PATCH /api/projects/${p.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<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-8513f8a9a414121e", "name": "Dangling fetch: GET /api/projects/${p.id} (apps/api/test/projects.test.ts:72)", "shortDescription": {"text": "Dangling fetch: GET /api/projects/${p.id} (apps/api/test/projects.test.ts:72)"}, "fullDescription": {"text": "`apps/api/test/projects.test.ts:72` calls `GET /api/projects/${p.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/projects/<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-d759bfb89ea7f0c4", "name": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:20)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:20)"}, "fullDescription": {"text": "`apps/api/test/auth.test.ts:20` calls `POST /api/auth/dev-login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/dev-login`\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-340e539b1ff7c649", "name": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:35)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:35)"}, "fullDescription": {"text": "`apps/api/test/auth.test.ts:35` calls `POST /api/auth/dev-login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/dev-login`\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-773191ac4da85fb0", "name": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:47)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:47)"}, "fullDescription": {"text": "`apps/api/test/auth.test.ts:47` calls `POST /api/auth/dev-login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/dev-login`\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-621eb7423f2b553b", "name": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:59)", "shortDescription": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:59)"}, "fullDescription": {"text": "`apps/api/test/auth.test.ts:59` calls `POST /api/auth/dev-login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/dev-login`\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-566bf6d6a6cf7501", "name": "Dangling fetch: GET /api/auth/callback?code=test-code&state=st-123 (apps/api/test/auth.test.ts:107)", "shortDescription": {"text": "Dangling fetch: GET /api/auth/callback?code=test-code&state=st-123 (apps/api/test/auth.test.ts:107)"}, "fullDescription": {"text": "`apps/api/test/auth.test.ts:107` calls `GET /api/auth/callback?code=test-code&state=st-123` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/callback`\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-5cee0aea270de5c7", "name": "Dangling fetch: GET /api/auth/callback?code=c&state=WRONG (apps/api/test/auth.test.ts:161)", "shortDescription": {"text": "Dangling fetch: GET /api/auth/callback?code=c&state=WRONG (apps/api/test/auth.test.ts:161)"}, "fullDescription": {"text": "`apps/api/test/auth.test.ts:161` calls `GET /api/auth/callback?code=c&state=WRONG` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/auth/callback`\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-694b1856a911926a", "name": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:29)", "shortDescription": {"text": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:29)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:29` calls `POST /api/expenses` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-b3467d19a858eac5", "name": "Dangling fetch: PATCH /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:40)", "shortDescription": {"text": "Dangling fetch: PATCH /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:40)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:40` calls `PATCH /api/expenses?month=2026-06` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-92087b28db923453", "name": "Dangling fetch: PATCH /api/expenses/${exp.id}/status (apps/api/test/expenses.test.ts:50)", "shortDescription": {"text": "Dangling fetch: PATCH /api/expenses/${exp.id}/status (apps/api/test/expenses.test.ts:50)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:50` calls `PATCH /api/expenses/${exp.id}/status` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses/<p>/status`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9a587b97fb912786", "name": "Dangling fetch: PATCH /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:51)", "shortDescription": {"text": "Dangling fetch: PATCH /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:51)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:51` calls `PATCH /api/expenses?month=2026-06` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-7d2e8ec521668c9a", "name": "Dangling fetch: GET /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:55)", "shortDescription": {"text": "Dangling fetch: GET /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:55)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:55` calls `GET /api/expenses?month=2026-06` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-aadc407b392ba15a", "name": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:62)", "shortDescription": {"text": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:62)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:62` calls `POST /api/expenses` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-f5071282836969b9", "name": "Dangling fetch: GET /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:65)", "shortDescription": {"text": "Dangling fetch: GET /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:65)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:65` calls `GET /api/expenses?month=2026-06` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-641f81905e1e67b1", "name": "Dangling fetch: PATCH /api/expenses/${target}/status (apps/api/test/expenses.test.ts:75)", "shortDescription": {"text": "Dangling fetch: PATCH /api/expenses/${target}/status (apps/api/test/expenses.test.ts:75)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:75` calls `PATCH /api/expenses/${target}/status` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses/<p>/status`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-00355d0a540101cb", "name": "Dangling fetch: POST /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:79)", "shortDescription": {"text": "Dangling fetch: POST /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:79)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:79` calls `POST /api/expenses?month=2026-06` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-74604f6d1ac41d99", "name": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:87)", "shortDescription": {"text": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:87)"}, "fullDescription": {"text": "`apps/api/test/expenses.test.ts:87` calls `POST /api/expenses` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/expenses`\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-d160692c5c919005", "name": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/web/src/components/TaskDrawer.tsx:220)", "shortDescription": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/web/src/components/TaskDrawer.tsx:220)"}, "fullDescription": {"text": "`apps/web/src/components/TaskDrawer.tsx:220` calls `POST /api/tasks/${t.id}/attachments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/tasks/<p>/attachments`\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-1180244ed102ccf4", "name": "Dangling fetch: POST /api/docs/images (apps/web/src/pages/Docs.tsx:36)", "shortDescription": {"text": "Dangling fetch: POST /api/docs/images (apps/web/src/pages/Docs.tsx:36)"}, "fullDescription": {"text": "`apps/web/src/pages/Docs.tsx:36` calls `POST /api/docs/images` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/docs/images`\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-d1ff81ac8ec2d563", "name": "Dangling fetch: POST /api/expenses (apps/web/src/pages/Expenses.tsx:67)", "shortDescription": {"text": "Dangling fetch: POST /api/expenses (apps/web/src/pages/Expenses.tsx:67)"}, "fullDescription": {"text": "`apps/web/src/pages/Expenses.tsx:67` calls `POST /api/expenses` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/expenses`\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-1f4ed3a0434ee9f3", "name": "Unused endpoint: USE /api/calendar/*", "shortDescription": {"text": "Unused endpoint: USE /api/calendar/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/calendar/*` 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-e69ae99d4f1ed5bb", "name": "Unused endpoint: USE /api/admin/*", "shortDescription": {"text": "Unused endpoint: USE /api/admin/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/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-dd497e674171b498", "name": "Unused endpoint: USE /api/users/*", "shortDescription": {"text": "Unused endpoint: USE /api/users/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/users/*` 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-4ff40cb10f7c8519", "name": "Unused endpoint: USE /api/users", "shortDescription": {"text": "Unused endpoint: USE /api/users"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/users` 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-6f63dbe78bf2280a", "name": "Unused endpoint: USE /api/config", "shortDescription": {"text": "Unused endpoint: USE /api/config"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/config` 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-5a1de36c70562065", "name": "Unused endpoint: USE /api/projects/*", "shortDescription": {"text": "Unused endpoint: USE /api/projects/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/projects/*` 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-728e92394c568abf", "name": "Unused endpoint: USE /api/projects", "shortDescription": {"text": "Unused endpoint: USE /api/projects"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/projects` 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-e7a7ad2bafa4fcc0", "name": "Unused endpoint: USE /api/clients", "shortDescription": {"text": "Unused endpoint: USE /api/clients"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/clients` 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-545a9d10f73ef579", "name": "Unused endpoint: USE /api/clients/*", "shortDescription": {"text": "Unused endpoint: USE /api/clients/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/clients/*` 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-bda2d9b18c036f1d", "name": "Unused endpoint: USE /api/services/*", "shortDescription": {"text": "Unused endpoint: USE /api/services/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/services/*` 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-1ff6bbbb72cf5f02", "name": "Unused endpoint: USE /api/notes/*", "shortDescription": {"text": "Unused endpoint: USE /api/notes/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/notes/*` 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-2bc3342ebb6c801c", "name": "Unused endpoint: USE /api/groups/*", "shortDescription": {"text": "Unused endpoint: USE /api/groups/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/groups/*` 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-efadc4ad6d772b81", "name": "Unused endpoint: USE /api/tasks/*", "shortDescription": {"text": "Unused endpoint: USE /api/tasks/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/tasks/*` 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-78eeddfcccad480f", "name": "Unused endpoint: USE /api/attachments/*", "shortDescription": {"text": "Unused endpoint: USE /api/attachments/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/attachments/*` 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-35d50c97a7956540", "name": "Unused endpoint: USE /api/overview", "shortDescription": {"text": "Unused endpoint: USE /api/overview"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/overview` 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-47c9999f20f47a42", "name": "Unused endpoint: USE /api/timer", "shortDescription": {"text": "Unused endpoint: USE /api/timer"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/timer` 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-bc65b671442b6a66", "name": "Unused endpoint: USE /api/timer/*", "shortDescription": {"text": "Unused endpoint: USE /api/timer/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/timer/*` 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-26a27721c1e4b47a", "name": "Unused endpoint: USE /api/time/*", "shortDescription": {"text": "Unused endpoint: USE /api/time/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/time/*` 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-f06e484773a9eaeb", "name": "Unused endpoint: USE /api/team-hours", "shortDescription": {"text": "Unused endpoint: USE /api/team-hours"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/team-hours` 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-894b5acdc7fb1543", "name": "Unused endpoint: USE /api/projects/:id/finance", "shortDescription": {"text": "Unused endpoint: USE /api/projects/:id/finance"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/projects/:id/finance` 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-76dd41a8aefeaae9", "name": "Unused endpoint: USE /api/projects/:id/pnl", "shortDescription": {"text": "Unused endpoint: USE /api/projects/:id/pnl"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/projects/:id/pnl` 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-25065b97b25b239c", "name": "Unused endpoint: USE /api/projects/:id/milestones", "shortDescription": {"text": "Unused endpoint: USE /api/projects/:id/milestones"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/projects/:id/milestones` 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-0c185cc5f751458f", "name": "Unused endpoint: USE /api/projects/:id/payments", "shortDescription": {"text": "Unused endpoint: USE /api/projects/:id/payments"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/projects/:id/payments` 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-103d9a9691888afe", "name": "Unused endpoint: USE /api/milestones/*", "shortDescription": {"text": "Unused endpoint: USE /api/milestones/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/milestones/*` 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-9257ec27c74ad679", "name": "Unused endpoint: USE /api/payments/*", "shortDescription": {"text": "Unused endpoint: USE /api/payments/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/payments/*` 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-b2aa902a56f1188d", "name": "Unused endpoint: USE /api/payroll/*", "shortDescription": {"text": "Unused endpoint: USE /api/payroll/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/payroll/*` 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-5d83a39f66cb5706", "name": "Unused endpoint: USE /api/docs", "shortDescription": {"text": "Unused endpoint: USE /api/docs"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/docs` 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-43f54fbc82b20eaa", "name": "Unused endpoint: USE /api/docs/*", "shortDescription": {"text": "Unused endpoint: USE /api/docs/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/docs/*` 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-5c42734d4d670873", "name": "Unused endpoint: USE /api/expenses", "shortDescription": {"text": "Unused endpoint: USE /api/expenses"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/expenses` 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-afd008d7dca75ef5", "name": "Unused endpoint: USE /api/expenses/*", "shortDescription": {"text": "Unused endpoint: USE /api/expenses/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/expenses/*` 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-aebdad2655c302c7", "name": "Unused endpoint: USE /api/calendar", "shortDescription": {"text": "Unused endpoint: USE /api/calendar"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/calendar` 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-2505c2f1fa0ce160", "name": "Unused endpoint: USE /api/calendar-connect", "shortDescription": {"text": "Unused endpoint: USE /api/calendar-connect"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/calendar-connect` 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-73e8cad12f8333ce", "name": "Unused endpoint: USE /api/calendar-connect/*", "shortDescription": {"text": "Unused endpoint: USE /api/calendar-connect/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/calendar-connect/*` 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-41fca4630e2b71b2", "name": "Unused endpoint: USE /api/team-activity", "shortDescription": {"text": "Unused endpoint: USE /api/team-activity"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/team-activity` 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-5e97ea47c590755e", "name": "Unused endpoint: USE /api/inbox/threads", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/threads"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/threads` 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-9cb50b5a2fa5d343", "name": "Unused endpoint: USE /api/inbox/threads/*", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/threads/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/threads/*` 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-d95c2e9c9af6956c", "name": "Unused endpoint: USE /api/inbox/attachments/*", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/attachments/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/attachments/*` 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-5841e1b1dcec1c81", "name": "Unused endpoint: USE /api/inbox/compose", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/compose"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/compose` 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-5afb31013e5db92c", "name": "Unused endpoint: USE /api/inbox/canned", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/canned"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/canned` 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-f75aab9f7d1333b9", "name": "Unused endpoint: USE /api/inbox/canned/*", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/canned/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/canned/*` 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-739cfba4c6e71560", "name": "Unused endpoint: USE /api/inbox/search", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/search"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/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-f39663683cf6cce8", "name": "Unused endpoint: USE /api/inbox/import-thread", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/import-thread"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/import-thread` 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-b297c9422eee5bd7", "name": "Unused endpoint: USE /api/inbox/settings", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/settings"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/settings` 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-5bf69465665faa8b", "name": "Unused endpoint: USE /api/inbox/clients", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/clients"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/clients` 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-fd26491d1a42b156", "name": "Unused endpoint: USE /api/inbox/clients/*", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/clients/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/clients/*` 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-a4b50624403a5c33", "name": "Unused endpoint: USE /api/inbox/mailboxes", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/mailboxes"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/mailboxes` 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-f146c478e91043be", "name": "Unused endpoint: USE /api/inbox/mailboxes/*", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/mailboxes/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/mailboxes/*` 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-94ac66d818dc798f", "name": "Unused endpoint: USE /api/inbox/google/*", "shortDescription": {"text": "Unused endpoint: USE /api/inbox/google/*"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/inbox/google/*` 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-ae4bb2d7ef8a84e3", "name": "Unused endpoint: GET /api/team-activity", "shortDescription": {"text": "Unused endpoint: GET /api/team-activity"}, "fullDescription": {"text": "`apps/web/src/components/TeamBox.tsx` declares `GET /api/team-activity` 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-3a3c45156489b020", "name": "Unused endpoint: GET /api/users", "shortDescription": {"text": "Unused endpoint: GET /api/users"}, "fullDescription": {"text": "`apps/web/src/components/TeamCalendar.tsx` declares `GET /api/users` 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/19192"}, "properties": {"repository": "SeedWebs/SeedOffice", "repoUrl": "https://github.com/SeedWebs/SeedOffice", "branch": "main"}, "results": [{"ruleId": "scanner-54141d289e96a269", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 worker-configuration.d.ts:186"}, "properties": {"repobilityId": "d983fc1ceef15440", "scanner": "scanner-primary", "fingerprint": "54141d289e96a269", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f42bb1893f8f708f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/presence-notify.ts:7"}, "properties": {"repobilityId": "f207a96a91ec4c55", "scanner": "scanner-primary", "fingerprint": "f42bb1893f8f708f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0069377618ea78dd", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/backup.ts:49"}, "properties": {"repobilityId": "0253d43087639e06", "scanner": "scanner-primary", "fingerprint": "0069377618ea78dd", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e17abc3d431a9068", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 apps/api/src/lib/notify.ts:15"}, "properties": {"repobilityId": "0cb5a27d2c694192", "scanner": "scanner-primary", "fingerprint": "e17abc3d431a9068", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-d273e166165d41f0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/notify.ts:16"}, "properties": {"repobilityId": "0f312a68ffa6f87f", "scanner": "scanner-primary", "fingerprint": "d273e166165d41f0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0e5aa0a13ba05c38", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/TeamBox.tsx:131"}, "properties": {"repobilityId": "f22a9d0e28624790", "scanner": "scanner-primary", "fingerprint": "0e5aa0a13ba05c38", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e738f52e4cc5013b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/FinanceSection.tsx:103"}, "properties": {"repobilityId": "31e23c753a50a3b4", "scanner": "scanner-primary", "fingerprint": "e738f52e4cc5013b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2eb95ea65e29594b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/InboxSettings.tsx:299"}, "properties": {"repobilityId": "6c46c3af07c0ea57", "scanner": "scanner-primary", "fingerprint": "2eb95ea65e29594b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-673345b0871e1a71", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/Layout.tsx:157"}, "properties": {"repobilityId": "df96fed43bdaa96d", "scanner": "scanner-primary", "fingerprint": "673345b0871e1a71", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-64c73fc40f680a99", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/TaskDrawer.tsx:129"}, "properties": {"repobilityId": "913202897bfc8d0e", "scanner": "scanner-primary", "fingerprint": "64c73fc40f680a99", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5de9012b5701b53e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Dashboard.tsx:86"}, "properties": {"repobilityId": "c27e630c27658f52", "scanner": "scanner-primary", "fingerprint": "5de9012b5701b53e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8188fb443a0edbf7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Docs.tsx:262"}, "properties": {"repobilityId": "7bc277807a5ddaf5", "scanner": "scanner-primary", "fingerprint": "8188fb443a0edbf7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-577ce51ba5583d30", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ClientDetail.tsx:180"}, "properties": {"repobilityId": "7537d4ba06fe6a32", "scanner": "scanner-primary", "fingerprint": "577ce51ba5583d30", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c3fcb97d06b29c4d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/PayrollOwner.tsx:72"}, "properties": {"repobilityId": "c01394f5382f8aff", "scanner": "scanner-primary", "fingerprint": "c3fcb97d06b29c4d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-874ea024e849dbd7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Clients.tsx:105"}, "properties": {"repobilityId": "b419d0f130d10c5c", "scanner": "scanner-primary", "fingerprint": "874ea024e849dbd7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6e500eb04ad97b73", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ProjectDetail.tsx:114"}, "properties": {"repobilityId": "09f9a61d49c413b1", "scanner": "scanner-primary", "fingerprint": "6e500eb04ad97b73", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fb6aa2d257eebd7b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Inbox.tsx:588"}, "properties": {"repobilityId": "c8e5504c42abbf58", "scanner": "scanner-primary", "fingerprint": "fb6aa2d257eebd7b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fff4e5b25364459c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Payroll.tsx:74"}, "properties": {"repobilityId": "fc66ea261720f27e", "scanner": "scanner-primary", "fingerprint": "fff4e5b25364459c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-272e19238d62cec0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Expenses.tsx:182"}, "properties": {"repobilityId": "5bf83d8b7152d206", "scanner": "scanner-primary", "fingerprint": "272e19238d62cec0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-43e77326befaee30", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/Projects.tsx:45"}, "properties": {"repobilityId": "d6be8b06f702b087", "scanner": "scanner-primary", "fingerprint": "43e77326befaee30", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a3bfdd2f23dc0400", "level": "error", "message": {"text": "Insecure pattern 'exec_used' in worker-configuration.d.ts:3057"}, "properties": {"repobilityId": "b18a5a697fabe8a9", "scanner": "scanner-primary", "fingerprint": "a3bfdd2f23dc0400", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "exec_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "worker-configuration.d.ts"}, "region": {"startLine": 3057}}}]}, {"ruleId": "scanner-5d1a6b10030bbb9e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in mockup.html:850"}, "properties": {"repobilityId": "f873e776d7f4121e", "scanner": "scanner-primary", "fingerprint": "5d1a6b10030bbb9e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mockup.html"}, "region": {"startLine": 850}}}]}, {"ruleId": "scanner-5c9c7d66dd70fab5", "level": "note", "message": {"text": "Very large file: worker-configuration.d.ts (14497 lines)"}, "properties": {"repobilityId": "5194c4e9c2c24b45", "scanner": "scanner-primary", "fingerprint": "5c9c7d66dd70fab5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-f19a256605b68ef3", "level": "note", "message": {"text": "Very large file: apps/web/src/pages/Inbox.tsx (1268 lines)"}, "properties": {"repobilityId": "d1d64c49650748fc", "scanner": "scanner-primary", "fingerprint": "f19a256605b68ef3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-b06b8d86f24c77f9", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "properties": {"repobilityId": "ce77cd34ed0306d4", "scanner": "scanner-primary", "fingerprint": "b06b8d86f24c77f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4a9eb7dc7c6e3880", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "properties": {"repobilityId": "6c1704bf24cf19ac", "scanner": "scanner-primary", "fingerprint": "4a9eb7dc7c6e3880", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7b16ae2bd0fca524", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/db/package.json"}, "properties": {"repobilityId": "2bddd295d559a9b6", "scanner": "scanner-primary", "fingerprint": "7b16ae2bd0fca524", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/db/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "1c63530f70c44a66", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "fe6b7cba0c3522ea", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "2c5308b5ef77c03c", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "ff555be0bc3817ff", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "4374a632fee31b52", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-464fe0c980482ae0", "level": "note", "message": {"text": "Legacy-named symbol `certIssuerDNLegacy` in worker-configuration.d.ts:11783"}, "properties": {"repobilityId": "6c07a6f3d704dfac", "scanner": "scanner-primary", "fingerprint": "464fe0c980482ae0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-a5849b09d38cd519", "level": "none", "message": {"text": "Commented-code block (6 lines) in worker-configuration.d.ts:10183"}, "properties": {"repobilityId": "6854f589359b7c67", "scanner": "scanner-primary", "fingerprint": "a5849b09d38cd519", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ea71421bec139f97", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 worker-configuration.d.ts:319"}, "properties": {"repobilityId": "a6d166d73d748c43", "scanner": "scanner-primary", "fingerprint": "ea71421bec139f97", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ac984094e6d1ae4c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/index.ts:127"}, "properties": {"repobilityId": "2439c837c062c721", "scanner": "scanner-primary", "fingerprint": "ac984094e6d1ae4c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fe06a3466cb12d84", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/gcal-sync.ts:36"}, "properties": {"repobilityId": "f491a11d731d5159", "scanner": "scanner-primary", "fingerprint": "fe06a3466cb12d84", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2d1007643e5740e7", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/inbox-sync.ts:46"}, "properties": {"repobilityId": "73e7853ac3103c43", "scanner": "scanner-primary", "fingerprint": "2d1007643e5740e7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7ddf6da1bf55466e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/auth.ts:58"}, "properties": {"repobilityId": "07ebcdfa75f7df2a", "scanner": "scanner-primary", "fingerprint": "7ddf6da1bf55466e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8f3e1df4c92c831d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/calendar-connect.ts:124"}, "properties": {"repobilityId": "768c8132dbcc4145", "scanner": "scanner-primary", "fingerprint": "8f3e1df4c92c831d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-72d07d70ad7f2e2e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/inbox-threads.ts:534"}, "properties": {"repobilityId": "cf6c0bc9961cbee0", "scanner": "scanner-primary", "fingerprint": "72d07d70ad7f2e2e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c50db4d3e434b3ef", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/inbox-settings.ts:322"}, "properties": {"repobilityId": "6cc715e98ed96376", "scanner": "scanner-primary", "fingerprint": "c50db4d3e434b3ef", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2dc7a91db2705b59", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/do/inbox-thread-hub.ts:16"}, "properties": {"repobilityId": "980be8682a078ae3", "scanner": "scanner-primary", "fingerprint": "2dc7a91db2705b59", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5ccedf5f0fa88322", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/do/presence-hub.ts:10"}, "properties": {"repobilityId": "4eaaa37f390cbff7", "scanner": "scanner-primary", "fingerprint": "5ccedf5f0fa88322", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d6c211b933d20e47", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/components/TaskDrawer.tsx:220"}, "properties": {"repobilityId": "ea0eac69d9749145", "scanner": "scanner-primary", "fingerprint": "d6c211b933d20e47", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cee7056201334ec1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/pages/Docs.tsx:36"}, "properties": {"repobilityId": "0a240e36fdc3c905", "scanner": "scanner-primary", "fingerprint": "cee7056201334ec1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3e0fa7b66c2ab63d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/web/src/pages/Expenses.tsx:67"}, "properties": {"repobilityId": "e8311e51932128fa", "scanner": "scanner-primary", "fingerprint": "3e0fa7b66c2ab63d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9e7aeea036818446", "level": "error", "message": {"text": "Dangling fetch: GET /api/calendar-connect/connect (apps/api/test/gcal.test.ts:177)"}, "properties": {"repobilityId": "54442c197bba558f", "scanner": "scanner-primary", "fingerprint": "9e7aeea036818446", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b70ec7cbc32041fe", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/search?q=x (apps/api/test/inbox-search.test.ts:131)"}, "properties": {"repobilityId": "a4b8ca14731d223f", "scanner": "scanner-primary", "fingerprint": "b70ec7cbc32041fe", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b15905e54ea3b8b5", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/search?q=${encodeURIComponent(long)} (apps/api/test/inbox-search.test.ts:182)"}, "properties": {"repobilityId": "0e06080d30a5e142", "scanner": "scanner-primary", "fingerprint": "b15905e54ea3b8b5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-1c065ae7dbdb2358", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/search?q=test (apps/api/test/inbox-search.test.ts:208)"}, "properties": {"repobilityId": "39bdafcb775e8c9e", "scanner": "scanner-primary", "fingerprint": "1c065ae7dbdb2358", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c7731678e5187170", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads/${threadId} (apps/api/test/inbox-search.test.ts:246)"}, "properties": {"repobilityId": "9778bb119e72819e", "scanner": "scanner-primary", "fingerprint": "c7731678e5187170", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-184f098e79ee7442", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/task-detail.test.ts:34)"}, "properties": {"repobilityId": "d6dffba5629da398", "scanner": "scanner-primary", "fingerprint": "184f098e79ee7442", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-dc7d3d55162d94d4", "level": "error", "message": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:47)"}, "properties": {"repobilityId": "fd4cd4f7a956b18a", "scanner": "scanner-primary", "fingerprint": "dc7d3d55162d94d4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ce0f042a2c8fe1f6", "level": "error", "message": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:66)"}, "properties": {"repobilityId": "eab2ab4364d7b42f", "scanner": "scanner-primary", "fingerprint": "ce0f042a2c8fe1f6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-0cef99e7393c1fcf", "level": "error", "message": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/api/test/task-detail.test.ts:75)"}, "properties": {"repobilityId": "23e2810fbb409d54", "scanner": "scanner-primary", "fingerprint": "0cef99e7393c1fcf", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-402299aa19466950", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id} (apps/api/test/task-detail.test.ts:90)"}, "properties": {"repobilityId": "771a2d4e3e7a3456", "scanner": "scanner-primary", "fingerprint": "402299aa19466950", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f1537f39b4fa5dda", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id} (apps/api/test/task-detail.test.ts:91)"}, "properties": {"repobilityId": "79f84a9eb142a093", "scanner": "scanner-primary", "fingerprint": "f1537f39b4fa5dda", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b3cab868e10d7ffc", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/task-detail.test.ts:93)"}, "properties": {"repobilityId": "0d428a897f0c70d8", "scanner": "scanner-primary", "fingerprint": "b3cab868e10d7ffc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5264a88c2b047707", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:42)"}, "properties": {"repobilityId": "feaa6902cca222e0", "scanner": "scanner-primary", "fingerprint": "5264a88c2b047707", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-caacf8a9fc16706d", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:48)"}, "properties": {"repobilityId": "dab23172fbc92dad", "scanner": "scanner-primary", "fingerprint": "caacf8a9fc16706d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-52d551be7fe03288", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:52)"}, "properties": {"repobilityId": "b20330a956e3e1c1", "scanner": "scanner-primary", "fingerprint": "52d551be7fe03288", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-225009c10e781d83", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:78)"}, "properties": {"repobilityId": "d6277c66ae3d057d", "scanner": "scanner-primary", "fingerprint": "225009c10e781d83", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-33551358f9cb20b8", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/tasks.test.ts:90)"}, "properties": {"repobilityId": "5d8696e69c702060", "scanner": "scanner-primary", "fingerprint": "33551358f9cb20b8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-ca3d12da99f1e574", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/groups/${g1.id} (apps/api/test/tasks.test.ts:94)"}, "properties": {"repobilityId": "0fa45a81697c44b4", "scanner": "scanner-primary", "fingerprint": "ca3d12da99f1e574", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-78367781205f1377", "level": "error", "message": {"text": "Dangling fetch: GET /owner-only (apps/api/test/roles.test.ts:44)"}, "properties": {"repobilityId": "c754d8dba47165b8", "scanner": "scanner-primary", "fingerprint": "78367781205f1377", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2c16be13cb952218", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:28)"}, "properties": {"repobilityId": "3ce3e6a0d8f4a974", "scanner": "scanner-primary", "fingerprint": "2c16be13cb952218", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5f8b0c0ed4f6db32", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:31)"}, "properties": {"repobilityId": "9fce2d97e2428619", "scanner": "scanner-primary", "fingerprint": "5f8b0c0ed4f6db32", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-837e81a4c5bcd977", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:44)"}, "properties": {"repobilityId": "cd9c7956b6bb3880", "scanner": "scanner-primary", "fingerprint": "837e81a4c5bcd977", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-1857d07f03c81348", "level": "error", "message": {"text": "Dangling fetch: GET /api/milestones/${ms.id} (apps/api/test/finance.test.ts:60)"}, "properties": {"repobilityId": "6487aeef933db434", "scanner": "scanner-primary", "fingerprint": "1857d07f03c81348", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b98b8b1324599eaa", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/finance.test.ts:61)"}, "properties": {"repobilityId": "4e12471614f61a2d", "scanner": "scanner-primary", "fingerprint": "b98b8b1324599eaa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-0995b0ca45b4332c", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:39)"}, "properties": {"repobilityId": "a2317aed55dcafed", "scanner": "scanner-primary", "fingerprint": "0995b0ca45b4332c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-66936f5f443197a8", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:62)"}, "properties": {"repobilityId": "f24620d88a3d8a75", "scanner": "scanner-primary", "fingerprint": "66936f5f443197a8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b0923728f6a5878a", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/finance (apps/api/test/pnl.test.ts:68)"}, "properties": {"repobilityId": "f4859a89d07e3757", "scanner": "scanner-primary", "fingerprint": "b0923728f6a5878a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-fb989799a025c3c5", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:71)"}, "properties": {"repobilityId": "73e6ce00bd3e225f", "scanner": "scanner-primary", "fingerprint": "fb989799a025c3c5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2d6b18c0075f5178", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/pnl (apps/api/test/pnl.test.ts:82)"}, "properties": {"repobilityId": "4bb294e952dfaf42", "scanner": "scanner-primary", "fingerprint": "2d6b18c0075f5178", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f51ee9c487fa8272", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/payroll?date=2026-06-10 (apps/api/test/payroll-admin.test.ts:48)"}, "properties": {"repobilityId": "25308fa3aa635a71", "scanner": "scanner-primary", "fingerprint": "f51ee9c487fa8272", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b77ad6d1e87af79e", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/payroll (apps/api/test/payroll-admin.test.ts:54)"}, "properties": {"repobilityId": "b12f64beaf497aad", "scanner": "scanner-primary", "fingerprint": "b77ad6d1e87af79e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-6b49cae1a44cbefd", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/payroll/export?date=2026-06-10 (apps/api/test/payroll-admin.test.ts:75)"}, "properties": {"repobilityId": "c30ba9885c2bdc7a", "scanner": "scanner-primary", "fingerprint": "6b49cae1a44cbefd", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-359cc14cdc2936b2", "level": "error", "message": {"text": "Dangling fetch: GET /api/time/twa (apps/api/test/payroll-admin.test.ts:101)"}, "properties": {"repobilityId": "c1e4c65d206ca670", "scanner": "scanner-primary", "fingerprint": "359cc14cdc2936b2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-fd47d9a0d56cef3c", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/time/twa (apps/api/test/payroll-admin.test.ts:102)"}, "properties": {"repobilityId": "693f4f4156b6c80e", "scanner": "scanner-primary", "fingerprint": "fd47d9a0d56cef3c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-1c29e2693a10e115", "level": "error", "message": {"text": "Dangling fetch: GET /api/payments/${created.id} (apps/api/test/clients.test.ts:42)"}, "properties": {"repobilityId": "d7bcaf6c732af7e7", "scanner": "scanner-primary", "fingerprint": "1c29e2693a10e115", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3466135a77a8c236", "level": "error", "message": {"text": "Dangling fetch: GET /api/clients/${cl.id} (apps/api/test/clients.test.ts:89)"}, "properties": {"repobilityId": "0b4451019cfcb373", "scanner": "scanner-primary", "fingerprint": "3466135a77a8c236", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-8dd8dc868f5b7165", "level": "error", "message": {"text": "Dangling fetch: GET /api/clients/${cl.id} (apps/api/test/clients.test.ts:101)"}, "properties": {"repobilityId": "dede02454ad52449", "scanner": "scanner-primary", "fingerprint": "8dd8dc868f5b7165", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-896f766d06f6ae13", "level": "error", "message": {"text": "Dangling fetch: GET /api/timer (apps/api/test/time.test.ts:49)"}, "properties": {"repobilityId": "15c2ba01f6cac4cb", "scanner": "scanner-primary", "fingerprint": "896f766d06f6ae13", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-328b16a383edbf00", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:56)"}, "properties": {"repobilityId": "edaa7956d473264c", "scanner": "scanner-primary", "fingerprint": "328b16a383edbf00", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-2fcc9a23fdb51082", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id}/detail (apps/api/test/time.test.ts:60)"}, "properties": {"repobilityId": "ad8250d1bfd37b44", "scanner": "scanner-primary", "fingerprint": "2fcc9a23fdb51082", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-48d0fb890805c371", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t1.id}/time (apps/api/test/time.test.ts:78)"}, "properties": {"repobilityId": "740447b88d18813f", "scanner": "scanner-primary", "fingerprint": "48d0fb890805c371", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c8ae42e044d4bc1c", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:116)"}, "properties": {"repobilityId": "fbb46c5f46714c16", "scanner": "scanner-primary", "fingerprint": "c8ae42e044d4bc1c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f15d852a35c0b958", "level": "error", "message": {"text": "Dangling fetch: GET /api/time/${created.id} (apps/api/test/time.test.ts:131)"}, "properties": {"repobilityId": "3842f5ef72acf2d0", "scanner": "scanner-primary", "fingerprint": "f15d852a35c0b958", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5c7b6809181b9854", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/time/${created.id} (apps/api/test/time.test.ts:139)"}, "properties": {"repobilityId": "83c91eca273e1aab", "scanner": "scanner-primary", "fingerprint": "5c7b6809181b9854", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-7d190651010c7145", "level": "error", "message": {"text": "Dangling fetch: GET /api/tasks/${t.id}/time (apps/api/test/time.test.ts:156)"}, "properties": {"repobilityId": "bb4c9dd75e76c105", "scanner": "scanner-primary", "fingerprint": "7d190651010c7145", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-7854f54cad239946", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id}/board (apps/api/test/overview.test.ts:60)"}, "properties": {"repobilityId": "9828729249bc4bc2", "scanner": "scanner-primary", "fingerprint": "7854f54cad239946", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-972ce099c19bfc30", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads/${thread.id} (apps/api/test/inbox-extras.test.ts:86)"}, "properties": {"repobilityId": "6224e12abc87d670", "scanner": "scanner-primary", "fingerprint": "972ce099c19bfc30", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-1516927b1ea24583", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads/${thread.id} (apps/api/test/inbox-extras.test.ts:104)"}, "properties": {"repobilityId": "b5bdbb0fea416ae3", "scanner": "scanner-primary", "fingerprint": "1516927b1ea24583", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9e60210b3cd0f7c2", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads (apps/api/test/inbox-threads.test.ts:119)"}, "properties": {"repobilityId": "fd251f6394b93cc5", "scanner": "scanner-primary", "fingerprint": "9e60210b3cd0f7c2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-70a673506c0777a0", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads (apps/api/test/inbox-threads.test.ts:139)"}, "properties": {"repobilityId": "91e28a42b8eb8ddd", "scanner": "scanner-primary", "fingerprint": "70a673506c0777a0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-560c032a8f5d7006", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads?folder=mine (apps/api/test/inbox-threads.test.ts:162)"}, "properties": {"repobilityId": "d59594ba7e5759c6", "scanner": "scanner-primary", "fingerprint": "560c032a8f5d7006", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c0697f491a167c3a", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads?folder=all&q=\u0e43\u0e1a\u0e40\u0e2a\u0e19\u0e2d (apps/api/test/inbox-threads.test.ts:185)"}, "properties": {"repobilityId": "e031892a726e0238", "scanner": "scanner-primary", "fingerprint": "c0697f491a167c3a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-0ed3f3dc8b987c28", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/threads/${open.id} (apps/api/test/inbox-threads.test.ts:211)"}, "properties": {"repobilityId": "2fa4a2cc27d955d3", "scanner": "scanner-primary", "fingerprint": "0ed3f3dc8b987c28", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-15f4a2cf63a8796b", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/attachments/${att.id}/download (apps/api/test/inbox-threads.test.ts:283)"}, "properties": {"repobilityId": "a6dd315e1a1a3e8e", "scanner": "scanner-primary", "fingerprint": "15f4a2cf63a8796b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-bac74174888cd510", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/attachments/${att.id}/download (apps/api/test/inbox-threads.test.ts:308)"}, "properties": {"repobilityId": "bed72bd43ba62a4d", "scanner": "scanner-primary", "fingerprint": "bac74174888cd510", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f785ca1fa280b2e0", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/helpers.ts:37)"}, "properties": {"repobilityId": "e6c0cc2b412544e9", "scanner": "scanner-primary", "fingerprint": "f785ca1fa280b2e0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9fc741479099e0d5", "level": "error", "message": {"text": "Dangling fetch: GET /api/payroll/u_nam (apps/api/test/payroll.test.ts:108)"}, "properties": {"repobilityId": "87be445f66c400c5", "scanner": "scanner-primary", "fingerprint": "9fc741479099e0d5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-dcf2cbe89087451b", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/users/${u.id}/rates (apps/api/test/admin.test.ts:43)"}, "properties": {"repobilityId": "133ae8f0953a63ac", "scanner": "scanner-primary", "fingerprint": "dcf2cbe89087451b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-7e398b09a068ad10", "level": "error", "message": {"text": "Dangling fetch: GET /api/users/${u.id}/rates (apps/api/test/admin.test.ts:54)"}, "properties": {"repobilityId": "16f367eb02ff126f", "scanner": "scanner-primary", "fingerprint": "7e398b09a068ad10", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c5684c85fc9ddcac", "level": "error", "message": {"text": "Dangling fetch: GET /api/users/u_somchai/rates (apps/api/test/admin.test.ts:64)"}, "properties": {"repobilityId": "7a8c9e99119c102f", "scanner": "scanner-primary", "fingerprint": "c5684c85fc9ddcac", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-10027394a1cef0bc", "level": "error", "message": {"text": "Dangling fetch: GET /api/docs/${root.id} (apps/api/test/docs.test.ts:36)"}, "properties": {"repobilityId": "0dbbeae964ffcfb2", "scanner": "scanner-primary", "fingerprint": "10027394a1cef0bc", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b10c7717d3a986e2", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/docs/${a.id} (apps/api/test/docs.test.ts:67)"}, "properties": {"repobilityId": "ab9256895c1d0874", "scanner": "scanner-primary", "fingerprint": "b10c7717d3a986e2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f38f5741e08cac38", "level": "error", "message": {"text": "Dangling fetch: POST /api/docs/images (apps/api/test/docs.test.ts:83)"}, "properties": {"repobilityId": "24aa1b625769b1b3", "scanner": "scanner-primary", "fingerprint": "f38f5741e08cac38", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-a86a560c65f708a5", "level": "error", "message": {"text": "Dangling fetch: POST /api/docs/images (apps/api/test/docs.test.ts:94)"}, "properties": {"repobilityId": "14a59848f3f370c7", "scanner": "scanner-primary", "fingerprint": "a86a560c65f708a5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-83d9075e954fc5cb", "level": "error", "message": {"text": "Dangling fetch: GET /api/time/${manual.id} (apps/api/test/integrity.test.ts:37)"}, "properties": {"repobilityId": "85057de7c0ddac3c", "scanner": "scanner-primary", "fingerprint": "83d9075e954fc5cb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-0f7150bf0f67edac", "level": "error", "message": {"text": "Dangling fetch: GET /api/team-hours?date=2026-06-10 (apps/api/test/integrity.test.ts:40)"}, "properties": {"repobilityId": "8304180ba3e9b9b0", "scanner": "scanner-primary", "fingerprint": "0f7150bf0f67edac", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-42a83bbf89c608e7", "level": "error", "message": {"text": "Dangling fetch: GET /api/team-hours (apps/api/test/integrity.test.ts:53)"}, "properties": {"repobilityId": "7d2280b0452d12aa", "scanner": "scanner-primary", "fingerprint": "42a83bbf89c608e7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5d043111c4ce1f9b", "level": "error", "message": {"text": "Dangling fetch: GET /api/team-hours?date=2026-06-10 (apps/api/test/integrity.test.ts:62)"}, "properties": {"repobilityId": "591b92987a511a42", "scanner": "scanner-primary", "fingerprint": "5d043111c4ce1f9b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3b93e76c0d708f8e", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/mailboxes/xx/connect (apps/api/test/inbox-settings.test.ts:64)"}, "properties": {"repobilityId": "58d99a6d6861c806", "scanner": "scanner-primary", "fingerprint": "3b93e76c0d708f8e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-0a780d265c2c9611", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/inbox/clients/${client.id} (apps/api/test/inbox-settings.test.ts:113)"}, "properties": {"repobilityId": "4b4cf1530218344e", "scanner": "scanner-primary", "fingerprint": "0a780d265c2c9611", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-964821559db1187d", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/inbox/clients/${client.id} (apps/api/test/inbox-settings.test.ts:122)"}, "properties": {"repobilityId": "ac0839b7285ad57c", "scanner": "scanner-primary", "fingerprint": "964821559db1187d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-c885ecee34475bd4", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/mailboxes/${box.id}/connect (apps/api/test/inbox-settings.test.ts:221)"}, "properties": {"repobilityId": "0f21fb6e35f99b76", "scanner": "scanner-primary", "fingerprint": "c885ecee34475bd4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-74772292adaadc65", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/mailboxes/${box.id}/connect (apps/api/test/inbox-settings.test.ts:248)"}, "properties": {"repobilityId": "45ce01f3857cc1ba", "scanner": "scanner-primary", "fingerprint": "74772292adaadc65", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-3fcd2f4caa328a3d", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/google/callback?code=test-code&state=st-123 (apps/api/test/inbox-settings.test.ts:290)"}, "properties": {"repobilityId": "897f5955bc28b1e2", "scanner": "scanner-primary", "fingerprint": "3fcd2f4caa328a3d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d624f8c825ecd9b6", "level": "error", "message": {"text": "Dangling fetch: GET /api/inbox/google/callback?code=c&state=st-WRONG (apps/api/test/inbox-settings.test.ts:347)"}, "properties": {"repobilityId": "c27d057891f66056", "scanner": "scanner-primary", "fingerprint": "d624f8c825ecd9b6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d47ef61d990bdc42", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/projects/${p.id} (apps/api/test/projects.test.ts:62)"}, "properties": {"repobilityId": "a3d2aefb682086a2", "scanner": "scanner-primary", "fingerprint": "d47ef61d990bdc42", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-8513f8a9a414121e", "level": "error", "message": {"text": "Dangling fetch: GET /api/projects/${p.id} (apps/api/test/projects.test.ts:72)"}, "properties": {"repobilityId": "de0973afd68eafd8", "scanner": "scanner-primary", "fingerprint": "8513f8a9a414121e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d759bfb89ea7f0c4", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:20)"}, "properties": {"repobilityId": "cb7c1b3be9f8ebc7", "scanner": "scanner-primary", "fingerprint": "d759bfb89ea7f0c4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-340e539b1ff7c649", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:35)"}, "properties": {"repobilityId": "c428bf85413d7a96", "scanner": "scanner-primary", "fingerprint": "340e539b1ff7c649", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-773191ac4da85fb0", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:47)"}, "properties": {"repobilityId": "b14cd501b1cd6095", "scanner": "scanner-primary", "fingerprint": "773191ac4da85fb0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-621eb7423f2b553b", "level": "error", "message": {"text": "Dangling fetch: POST /api/auth/dev-login (apps/api/test/auth.test.ts:59)"}, "properties": {"repobilityId": "d375d203d05fac10", "scanner": "scanner-primary", "fingerprint": "621eb7423f2b553b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-566bf6d6a6cf7501", "level": "error", "message": {"text": "Dangling fetch: GET /api/auth/callback?code=test-code&state=st-123 (apps/api/test/auth.test.ts:107)"}, "properties": {"repobilityId": "49c0c523d60e007a", "scanner": "scanner-primary", "fingerprint": "566bf6d6a6cf7501", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-5cee0aea270de5c7", "level": "error", "message": {"text": "Dangling fetch: GET /api/auth/callback?code=c&state=WRONG (apps/api/test/auth.test.ts:161)"}, "properties": {"repobilityId": "b22c1dae048c3211", "scanner": "scanner-primary", "fingerprint": "5cee0aea270de5c7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-694b1856a911926a", "level": "error", "message": {"text": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:29)"}, "properties": {"repobilityId": "1b7671ecd3e3f562", "scanner": "scanner-primary", "fingerprint": "694b1856a911926a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-b3467d19a858eac5", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:40)"}, "properties": {"repobilityId": "0c26347fc8ca1679", "scanner": "scanner-primary", "fingerprint": "b3467d19a858eac5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-92087b28db923453", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/expenses/${exp.id}/status (apps/api/test/expenses.test.ts:50)"}, "properties": {"repobilityId": "6c39a06a771435de", "scanner": "scanner-primary", "fingerprint": "92087b28db923453", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-9a587b97fb912786", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:51)"}, "properties": {"repobilityId": "4dbc3dfc3ae54a75", "scanner": "scanner-primary", "fingerprint": "9a587b97fb912786", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-7d2e8ec521668c9a", "level": "error", "message": {"text": "Dangling fetch: GET /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:55)"}, "properties": {"repobilityId": "d5b014289f0520e6", "scanner": "scanner-primary", "fingerprint": "7d2e8ec521668c9a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-aadc407b392ba15a", "level": "error", "message": {"text": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:62)"}, "properties": {"repobilityId": "7bb71ecc2a791e38", "scanner": "scanner-primary", "fingerprint": "aadc407b392ba15a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-f5071282836969b9", "level": "error", "message": {"text": "Dangling fetch: GET /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:65)"}, "properties": {"repobilityId": "2248c6d8a6250bc6", "scanner": "scanner-primary", "fingerprint": "f5071282836969b9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-641f81905e1e67b1", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/expenses/${target}/status (apps/api/test/expenses.test.ts:75)"}, "properties": {"repobilityId": "4d5c8c5291ed5222", "scanner": "scanner-primary", "fingerprint": "641f81905e1e67b1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-00355d0a540101cb", "level": "error", "message": {"text": "Dangling fetch: POST /api/expenses?month=2026-06 (apps/api/test/expenses.test.ts:79)"}, "properties": {"repobilityId": "a543aa709175c579", "scanner": "scanner-primary", "fingerprint": "00355d0a540101cb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-74604f6d1ac41d99", "level": "error", "message": {"text": "Dangling fetch: POST /api/expenses (apps/api/test/expenses.test.ts:87)"}, "properties": {"repobilityId": "5b0347df474f08bc", "scanner": "scanner-primary", "fingerprint": "74604f6d1ac41d99", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-d160692c5c919005", "level": "error", "message": {"text": "Dangling fetch: POST /api/tasks/${t.id}/attachments (apps/web/src/components/TaskDrawer.tsx:220)"}, "properties": {"repobilityId": "741442f84151df2b", "scanner": "scanner-primary", "fingerprint": "d160692c5c919005", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1180244ed102ccf4", "level": "error", "message": {"text": "Dangling fetch: POST /api/docs/images (apps/web/src/pages/Docs.tsx:36)"}, "properties": {"repobilityId": "75f3c2518e8494d8", "scanner": "scanner-primary", "fingerprint": "1180244ed102ccf4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d1ff81ac8ec2d563", "level": "error", "message": {"text": "Dangling fetch: POST /api/expenses (apps/web/src/pages/Expenses.tsx:67)"}, "properties": {"repobilityId": "04424d8cf71f80e4", "scanner": "scanner-primary", "fingerprint": "d1ff81ac8ec2d563", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1f4ed3a0434ee9f3", "level": "note", "message": {"text": "Unused endpoint: USE /api/calendar/*"}, "properties": {"repobilityId": "eb1fe6ef3491b2e7", "scanner": "scanner-primary", "fingerprint": "1f4ed3a0434ee9f3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e69ae99d4f1ed5bb", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/*"}, "properties": {"repobilityId": "0a31e83c2d1526a0", "scanner": "scanner-primary", "fingerprint": "e69ae99d4f1ed5bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dd497e674171b498", "level": "note", "message": {"text": "Unused endpoint: USE /api/users/*"}, "properties": {"repobilityId": "e47558af15909817", "scanner": "scanner-primary", "fingerprint": "dd497e674171b498", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4ff40cb10f7c8519", "level": "note", "message": {"text": "Unused endpoint: USE /api/users"}, "properties": {"repobilityId": "d96b05699306a9cf", "scanner": "scanner-primary", "fingerprint": "4ff40cb10f7c8519", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6f63dbe78bf2280a", "level": "note", "message": {"text": "Unused endpoint: USE /api/config"}, "properties": {"repobilityId": "71cd081dfdcc21df", "scanner": "scanner-primary", "fingerprint": "6f63dbe78bf2280a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5a1de36c70562065", "level": "note", "message": {"text": "Unused endpoint: USE /api/projects/*"}, "properties": {"repobilityId": "e9ad771a64a1ee86", "scanner": "scanner-primary", "fingerprint": "5a1de36c70562065", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-728e92394c568abf", "level": "note", "message": {"text": "Unused endpoint: USE /api/projects"}, "properties": {"repobilityId": "fe679efc4546857b", "scanner": "scanner-primary", "fingerprint": "728e92394c568abf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e7a7ad2bafa4fcc0", "level": "note", "message": {"text": "Unused endpoint: USE /api/clients"}, "properties": {"repobilityId": "d60940ff1c6ba3ca", "scanner": "scanner-primary", "fingerprint": "e7a7ad2bafa4fcc0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-545a9d10f73ef579", "level": "note", "message": {"text": "Unused endpoint: USE /api/clients/*"}, "properties": {"repobilityId": "e1efade7a3c0908b", "scanner": "scanner-primary", "fingerprint": "545a9d10f73ef579", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bda2d9b18c036f1d", "level": "note", "message": {"text": "Unused endpoint: USE /api/services/*"}, "properties": {"repobilityId": "f7d2ef4f3d5cb6a5", "scanner": "scanner-primary", "fingerprint": "bda2d9b18c036f1d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1ff6bbbb72cf5f02", "level": "note", "message": {"text": "Unused endpoint: USE /api/notes/*"}, "properties": {"repobilityId": "05698c2b745912e1", "scanner": "scanner-primary", "fingerprint": "1ff6bbbb72cf5f02", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2bc3342ebb6c801c", "level": "note", "message": {"text": "Unused endpoint: USE /api/groups/*"}, "properties": {"repobilityId": "055ed45ea7386289", "scanner": "scanner-primary", "fingerprint": "2bc3342ebb6c801c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-efadc4ad6d772b81", "level": "note", "message": {"text": "Unused endpoint: USE /api/tasks/*"}, "properties": {"repobilityId": "68b0857d4d22d53d", "scanner": "scanner-primary", "fingerprint": "efadc4ad6d772b81", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-78eeddfcccad480f", "level": "note", "message": {"text": "Unused endpoint: USE /api/attachments/*"}, "properties": {"repobilityId": "656dc8e9ea78d52e", "scanner": "scanner-primary", "fingerprint": "78eeddfcccad480f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-35d50c97a7956540", "level": "note", "message": {"text": "Unused endpoint: USE /api/overview"}, "properties": {"repobilityId": "0f7addd2c0733cce", "scanner": "scanner-primary", "fingerprint": "35d50c97a7956540", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-47c9999f20f47a42", "level": "note", "message": {"text": "Unused endpoint: USE /api/timer"}, "properties": {"repobilityId": "9cb35e638b72bd7b", "scanner": "scanner-primary", "fingerprint": "47c9999f20f47a42", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bc65b671442b6a66", "level": "note", "message": {"text": "Unused endpoint: USE /api/timer/*"}, "properties": {"repobilityId": "e42a6118756ff6f5", "scanner": "scanner-primary", "fingerprint": "bc65b671442b6a66", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-26a27721c1e4b47a", "level": "note", "message": {"text": "Unused endpoint: USE /api/time/*"}, "properties": {"repobilityId": "feb5d7291a8be524", "scanner": "scanner-primary", "fingerprint": "26a27721c1e4b47a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f06e484773a9eaeb", "level": "note", "message": {"text": "Unused endpoint: USE /api/team-hours"}, "properties": {"repobilityId": "16dcb85ef5bf6fd8", "scanner": "scanner-primary", "fingerprint": "f06e484773a9eaeb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-894b5acdc7fb1543", "level": "note", "message": {"text": "Unused endpoint: USE /api/projects/:id/finance"}, "properties": {"repobilityId": "eea5a07ecf586800", "scanner": "scanner-primary", "fingerprint": "894b5acdc7fb1543", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76dd41a8aefeaae9", "level": "note", "message": {"text": "Unused endpoint: USE /api/projects/:id/pnl"}, "properties": {"repobilityId": "9719f385fde7f7d7", "scanner": "scanner-primary", "fingerprint": "76dd41a8aefeaae9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-25065b97b25b239c", "level": "note", "message": {"text": "Unused endpoint: USE /api/projects/:id/milestones"}, "properties": {"repobilityId": "beff7626ae134999", "scanner": "scanner-primary", "fingerprint": "25065b97b25b239c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0c185cc5f751458f", "level": "note", "message": {"text": "Unused endpoint: USE /api/projects/:id/payments"}, "properties": {"repobilityId": "61e7a94025923d64", "scanner": "scanner-primary", "fingerprint": "0c185cc5f751458f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-103d9a9691888afe", "level": "note", "message": {"text": "Unused endpoint: USE /api/milestones/*"}, "properties": {"repobilityId": "3fd0491ec5df4f96", "scanner": "scanner-primary", "fingerprint": "103d9a9691888afe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9257ec27c74ad679", "level": "note", "message": {"text": "Unused endpoint: USE /api/payments/*"}, "properties": {"repobilityId": "5ff435a15c00e094", "scanner": "scanner-primary", "fingerprint": "9257ec27c74ad679", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b2aa902a56f1188d", "level": "note", "message": {"text": "Unused endpoint: USE /api/payroll/*"}, "properties": {"repobilityId": "80c361743bec334e", "scanner": "scanner-primary", "fingerprint": "b2aa902a56f1188d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5d83a39f66cb5706", "level": "note", "message": {"text": "Unused endpoint: USE /api/docs"}, "properties": {"repobilityId": "2d15b584499f6559", "scanner": "scanner-primary", "fingerprint": "5d83a39f66cb5706", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-43f54fbc82b20eaa", "level": "note", "message": {"text": "Unused endpoint: USE /api/docs/*"}, "properties": {"repobilityId": "1e865c35ff17019e", "scanner": "scanner-primary", "fingerprint": "43f54fbc82b20eaa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5c42734d4d670873", "level": "note", "message": {"text": "Unused endpoint: USE /api/expenses"}, "properties": {"repobilityId": "8938935d3bf99825", "scanner": "scanner-primary", "fingerprint": "5c42734d4d670873", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-afd008d7dca75ef5", "level": "note", "message": {"text": "Unused endpoint: USE /api/expenses/*"}, "properties": {"repobilityId": "d72f38af61b10e43", "scanner": "scanner-primary", "fingerprint": "afd008d7dca75ef5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-aebdad2655c302c7", "level": "note", "message": {"text": "Unused endpoint: USE /api/calendar"}, "properties": {"repobilityId": "cf57ca1b9f8a361c", "scanner": "scanner-primary", "fingerprint": "aebdad2655c302c7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2505c2f1fa0ce160", "level": "note", "message": {"text": "Unused endpoint: USE /api/calendar-connect"}, "properties": {"repobilityId": "f442a89cedad8b5b", "scanner": "scanner-primary", "fingerprint": "2505c2f1fa0ce160", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-73e8cad12f8333ce", "level": "note", "message": {"text": "Unused endpoint: USE /api/calendar-connect/*"}, "properties": {"repobilityId": "9176102536d59a0b", "scanner": "scanner-primary", "fingerprint": "73e8cad12f8333ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-41fca4630e2b71b2", "level": "note", "message": {"text": "Unused endpoint: USE /api/team-activity"}, "properties": {"repobilityId": "a94c4417977acd15", "scanner": "scanner-primary", "fingerprint": "41fca4630e2b71b2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5e97ea47c590755e", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/threads"}, "properties": {"repobilityId": "d5a71ae02e60a96d", "scanner": "scanner-primary", "fingerprint": "5e97ea47c590755e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9cb50b5a2fa5d343", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/threads/*"}, "properties": {"repobilityId": "3e10020e63011c87", "scanner": "scanner-primary", "fingerprint": "9cb50b5a2fa5d343", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d95c2e9c9af6956c", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/attachments/*"}, "properties": {"repobilityId": "cf737277d3f68654", "scanner": "scanner-primary", "fingerprint": "d95c2e9c9af6956c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5841e1b1dcec1c81", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/compose"}, "properties": {"repobilityId": "576a51588d715cb3", "scanner": "scanner-primary", "fingerprint": "5841e1b1dcec1c81", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5afb31013e5db92c", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/canned"}, "properties": {"repobilityId": "81832afd28563d76", "scanner": "scanner-primary", "fingerprint": "5afb31013e5db92c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f75aab9f7d1333b9", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/canned/*"}, "properties": {"repobilityId": "07480ae9a93e3bfd", "scanner": "scanner-primary", "fingerprint": "f75aab9f7d1333b9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-739cfba4c6e71560", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/search"}, "properties": {"repobilityId": "10f6ffe4ce44adcb", "scanner": "scanner-primary", "fingerprint": "739cfba4c6e71560", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f39663683cf6cce8", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/import-thread"}, "properties": {"repobilityId": "99b6d1606b3abe27", "scanner": "scanner-primary", "fingerprint": "f39663683cf6cce8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b297c9422eee5bd7", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/settings"}, "properties": {"repobilityId": "df9364cbf3d49475", "scanner": "scanner-primary", "fingerprint": "b297c9422eee5bd7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5bf69465665faa8b", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/clients"}, "properties": {"repobilityId": "45510c2723ef2aeb", "scanner": "scanner-primary", "fingerprint": "5bf69465665faa8b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd26491d1a42b156", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/clients/*"}, "properties": {"repobilityId": "eca2fc9355632290", "scanner": "scanner-primary", "fingerprint": "fd26491d1a42b156", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a4b50624403a5c33", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/mailboxes"}, "properties": {"repobilityId": "5dce3005044e4dad", "scanner": "scanner-primary", "fingerprint": "a4b50624403a5c33", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f146c478e91043be", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/mailboxes/*"}, "properties": {"repobilityId": "64273a7a71553b36", "scanner": "scanner-primary", "fingerprint": "f146c478e91043be", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-94ac66d818dc798f", "level": "note", "message": {"text": "Unused endpoint: USE /api/inbox/google/*"}, "properties": {"repobilityId": "023a650451d4c09d", "scanner": "scanner-primary", "fingerprint": "94ac66d818dc798f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ae4bb2d7ef8a84e3", "level": "note", "message": {"text": "Unused endpoint: GET /api/team-activity"}, "properties": {"repobilityId": "10c67318d27f5c5a", "scanner": "scanner-primary", "fingerprint": "ae4bb2d7ef8a84e3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3a3c45156489b020", "level": "note", "message": {"text": "Unused endpoint: GET /api/users"}, "properties": {"repobilityId": "f8d415b71c04546f", "scanner": "scanner-primary", "fingerprint": "3a3c45156489b020", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}