feat(components): version currency — 'behind latest patch' signal (BomLens parity #18)#503
Merged
Merged
Conversation
…mLens parity #18) Adds a component-level 'version currency' signal, a sibling of the EOL flag that answers a different question: not 'is this release line dead?' but 'is this version behind the newest patch of its (still-supported) release line?'. Fully OFFLINE — reuses the already-vendored endoflife.date snapshot, whose every cycle carries its newest patch (latest + latestReleaseDate). The same purl->product->cycle matcher the EOL evaluator uses now also compares the installed version to the cycle's latest via the tolerant cross-ecosystem comparator (upgrade_recommendation.compare_versions): installed < latest => outdated, >= => current, no cycle/latest/unparseable => unknown. No new network at scan time. Backend: migration 0040 adds component_versions.currency_* catalog columns (mirrors the 0038 EOL columns + a partial index on 'outdated'); evaluate() carries currency alongside EOL in one pass; stamp_component_version writes it, so BOTH the scan-persist hook and the weekly refresh beat stamp it for free. Exposed on the components list/detail and a project-Overview outdated_count, with an outdated=true filter mirroring the eol=true one. Frontend: CurrencyBadge (mirrors EolBadge, one tone below at medium — a maintenance signal, never Critical/High), a Components column, a drawer row, an Overview 'N outdated' chip deep-linking to the filter, and the toolbar toggle. EN/KO, a FE<->BE CURRENCY_STATES parity contract, seed fixture on a component separate from the EOL one so both assert independently. The deps.dev 'absolute-newest across the ecosystem / N releases behind' enrichment is a separate opt-in egress path (air-gap gated), not in this MVP. Tests: currency evaluation matrix (outdated/current/unknown/no-latest/no-match) + stamp idempotency, list/detail exposure + outdated filter + IDOR ordering, CurrencyBadge render + a11y, Overview chip render + deep-link, mirror contract. OpenAPI snapshot regenerated. Updates parity #18 (closed, offline MVP).
|
|
||
| from alembic import op | ||
|
|
||
| revision: str = "0040" |
| from alembic import op | ||
|
|
||
| revision: str = "0040" | ||
| down_revision: str | None = "0039" |
|
|
||
| revision: str = "0040" | ||
| down_revision: str | None = "0039" | ||
| branch_labels: str | Sequence[str] | None = None |
| revision: str = "0040" | ||
| down_revision: str | None = "0039" | ||
| branch_labels: str | Sequence[str] | None = None | ||
| depends_on: str | Sequence[str] | None = None |
…nd-built completeness) The AST hand-built-response completeness contract requires every ProjectOverviewResponse field to be passed explicitly at the endpoint construction site; outdated_count (0040) was in the service payload but not threaded through, so it would silently default on the wire.
haksungjang
added a commit
that referenced
this pull request
Jul 18, 2026
…den path, screenshots (#505) Close the doc-code drift and onboarding gaps found by the 2026-07 docs quality review: - Document the two shipped-but-undocumented user-facing features, EN+KO, with docs-uat assertions and freshly captured screenshots: * Vulnerabilities "Group by upgrade" view (W9-#53, #500) * Version currency "behind latest patch" signal (#503) - Onboarding golden path: intro now leads with a recommended single route (5-min demo -> first real scan -> production); quickstart gains step 5 "Scan your first real project"; the docker-compose evaluation section delegates its duplicated boot steps to the quickstart (also removing its stale seed command that lacked --demo-only). - ci-integration/github-actions: add a "Before you begin" block covering the three unmet prerequisites a new user hits (network-reachable portal vs localhost demo, API key, project id). - reference/faq: fix the reachability contradiction ("planned" vs shipped for Go via govulncheck). - contributor-guide/releasing: add a pre-tag documentation sweep to the release checklist (release notes from CHANGELOG [Unreleased], guide coverage for every user-facing entry, screenshot capture) so features can no longer ship without guide coverage. - Screenshots: new capture spec (capture_feature_additions.spec.ts, split from the bulk matrix for isolated re-capture) and a deterministic fixed_version fixture in seed_e2e_user.py so the By-upgrade view renders real upgrade clusters; delete eight orphaned 68-byte placeholder PNGs under docs/user-guide/img/. Verified: Docusaurus EN+KO build green (0 broken links/anchors), docs-uat extract 201 steps, ko-style S1/S2 0, seed unit tests 10 passed, both capture specs green against the live dev stack.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a component-level version currency signal — a sibling of the EOL flag that answers a different question: not "is this release line dead?" but "is this version behind the newest patch of its (still-supported) release line?".
Fully offline. It reuses the already-vendored endoflife.date snapshot, whose every cycle carries its newest patch (
latest+latestReleaseDate). The same purl→product→cycle matcher the EOL evaluator uses now also compares the installed version to the cycle'slatestvia the tolerant cross-ecosystem comparator (upgrade_recommendation.compare_versions): installed<latest → outdated,>=→ current, no cycle/latest/unparseable → unknown. No new network at scan time — the deps.dev "absolute-newest / N releases behind" enrichment is a separate opt-in egress path, deliberately not in this MVP.Backend
component_versions.currency_*catalog columns (mirrors the 0038 EOL columns + a partial index onoutdated).evaluate()carries currency alongside EOL in one pass;stamp_component_versionwrites it — so BOTH the scan-persist hook and the weekly refresh beat stamp it for free (no new task, no new gate; ridesEOL_ENABLED/the same snapshot).outdated_count, with an?outdated=truefilter mirroring?eol=true.Frontend
CurrencyBadge(mirrorsEolBadge, one tone below — medium, a maintenance signal, never Critical/High), a Components column, a drawer row, an Overview "N outdated" chip deep-linking to the filter, and the toolbar toggle. EN/KO, a FE↔BECURRENCY_STATESparity contract, and a seed fixture on a component separate from the EOL one so both badges/chips assert independently.Test plan
latest/ no-cycle-match) + stamp idempotency (6 new catalog cases; 63 EOL-suite tests green incl. the scan-stamp + refresh-beat paths)?outdated=truefilter + permission-before-state (IDOR) orderingCurrencyBadgerender + a11y (renders only foroutdated), Overview chip render + deep-link, FE↔BE mirror contractmypy+ ruff clean; FE typecheck/lint/i18n clean; OpenAPI snapshot regeneratedoutdated(parallel to the EOL fixture), so the badge/chip are demonstrable; the e2e otherwise auto-skips without the dev stack.Closes BomLens parity #18 (offline MVP).