Skip to content

feat(nav): surface the four Exposures pages that have real data - #342

Merged
0xmanhnv merged 1 commit into
developfrom
feat/wire-exposures-children
Aug 1, 2026
Merged

feat(nav): surface the four Exposures pages that have real data#342
0xmanhnv merged 1 commit into
developfrom
feat/wire-exposures-children

Conversation

@0xmanhnv

@0xmanhnv 0xmanhnv commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

/exposures/{vulnerabilities,secrets,code,misconfigurations} are 1,393 lines of
finished, working screens with no route into them.

Each is scoped to its own finding type — this is what separates them from the
scaffolds around them:

useFindingTypeStats(tenantId, ['secret'])
useFindingTypeStats(tenantId, ['sast'])
useFindingTypeStats(tenantId, ['iac'])
useFindingTypeStats(tenantId, VULNERABILITY_SOURCES)

Shape

Exposures becomes a collapsible. NavCollapsible carries no url in
src/components/types.ts, so the parent page is reached through an Overview
child — the same shape Integrations already uses a few hundred lines down in the
same file.

What is deliberately absent

/exposures/credentials. It reads useDashboardStats and renders every
finding in the tenant under a "Credential Exposures" heading.

Wiring it would put a chart labelled as credentials in front of users showing
unrelated numbers — in a security product that is worse than no page, because it
will be read as fact. It is also the same defect ui#339 just removed: a nav
entry that looks shipped and is not.

That distinction is the entire reason this PR is four pages and not eleven. An
earlier draft of docs/nav-coverage.md called eleven of these "easy wins, all
data-wired"
. Checking what they actually render showed seven were scaffolds
driven by dashboard totals — /controls/* derives "controls" from
stats.assets.byType. See ui#341 for the classification of all 107 pages
outside the sidebar.

Effect

Sidebar coverage: 64 → 68 of 171 static pages.

Verification

tsc --noEmit clean, eslint clean, prettier-formatted, and the palette-drift
gate from ui#340 passes on this branch.

/exposures/{vulnerabilities,secrets,code,misconfigurations} are 1,393 lines of
finished, working screens with no route into them. Each is scoped to its own
finding type:

    useFindingTypeStats(tenantId, ['secret'])
    useFindingTypeStats(tenantId, ['sast'])
    useFindingTypeStats(tenantId, ['iac'])
    useFindingTypeStats(tenantId, VULNERABILITY_SOURCES)

Exposures becomes a collapsible. NavCollapsible carries no `url` in
src/components/types.ts, so the parent page is reached through an Overview child —
the same shape Integrations already uses in this file.

/exposures/credentials is deliberately NOT listed. It reads useDashboardStats and
renders EVERY finding in the tenant under a "Credential Exposures" heading. Wiring
it would put a chart labelled as credentials in front of users showing unrelated
numbers, which in a security product is worse than no page at all — and it is the
same defect ui#339 just removed, a nav entry that looks shipped and is not.

That distinction is the whole reason this change is four pages and not eleven. An
earlier draft of docs/nav-coverage.md called eleven of these "easy wins, all
data-wired"; checking what they actually render showed seven were scaffolds
driven by dashboard totals. See docs/nav-coverage.md for the classification of all
107 pages outside the sidebar.

Sidebar coverage goes from 64 to 68 of 171 static pages.
@0xmanhnv
0xmanhnv merged commit 9eff33e into develop Aug 1, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant