feat(portfolio): score the applications you use on value, fit and risk, and see where the scores contradict the TIME class - #1200
Merged
Conversation
…ed class, the report row and CSV columns, red before the change
…ch filter and the usage page wiring, red before the change
…nals on the usage page (tests green, gates not run)
… not verified by the gate
…e docs page, and the change's tasks and design brought up to date
…life-value-assessment built, spec tags point at the main spec
…oReportDerivation, keeping the service under the complexity limit
Contributor
Quality Report — ConductionNL/stackiq @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| check-manifest | ✅ | ||||
| check-vue-demi | ✅ | ||||
| test-l10n | ✅ | ||||
| format | ✅ | ||||
| check-schema-l10n | ✅ | ||||
| check-l10n-js | ✅ | ||||
| composer | ✅ | ✅ 130/130 | |||
| npm | ✅ | ✅ 807/807 | |||
| app:check-code | ⏭️ | ||||
| info.xml | ✅ | ||||
| REUSE | ❌ | ||||
| lockfile sync | ✅ | ||||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ deferred: E2E runs locally and on the promotion path only. This pull request targets development, so the suite is asked once per promotion into beta and main rather than once per push per open pull request. Run it on any branch from the Actions tab, or locally with npx playwright test. |
||||
| Hydra gates | ✅ |
Quality workflow — 2026-09-30 03:54 UTC
Download the full PDF report from the workflow artifacts.
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.
Change:
lifecycle-application-value-assessment(archived here as2026-09-30-lifecycle-application-value-assessment; its spec is nowopenspec/specs/application-value-assessment/spec.md). It builds on the usage pages from #1194.Row moved to built:
stackiq:life-value-assessment(tender row, Helmond REQ41; rated yes now).What a user can now do: an information manager scores each application the organisation uses on business value, technical fit and risk (1 to 5) with the date, on the usage's page. On save stackiq fills in the suggested TIME class (Invest, Migrate, Tolerate or Eliminate from value and fit); the recorded TIME class stays the decision and sits beside the suggestion in a new Value assessment section. Below it, Risk signals shows whether the version in use is past its end of support or withdrawn and how many known vulnerabilities are linked to the application. The portfolio report plots business value against technical fit with annualised cost as circle size, shows the suggested class and the scores per row, offers the switch "Recorded class differs from scores", and its CSV export carries the new columns.
How:
lib/Settings/register.d/value-assessment.jsonaddsbusinessValue,technicalFit,riskScore,scoredOnandsuggestedTimeClassificationtousage(1.5.3), the suggestion as a materialisedx-openregister-calculationsexpression.PortfolioReportServiceadds the scores, the suggestion andtimeMismatchto each row and the CSV, falling back to the same rule (PortfolioReportDerivation::suggestTimeClassification) for a usage saved before the calculation existed.UsageRiskSignals(body widget on the usage page) andValueFitPlot(SVG, on the report) are custom because each joins data no built-in widget combines. The demo usages are scored into all four classes, one of them contradicting its recorded class.Design changes at build, recorded in the archived design: the plot is a small SVG component instead of
CnChartWidget(per-point colour, ring and tooltip), and the scores got their own data section on the usage page.Scenarios and the tests that prove them:
tests/Unit/Settings/ValueAssessmentFragmentTest.php(6 tests: fields and ranges, the declared calculation, the four classes, the report rule equals the expression, the schema version, the seeds). The expression also ran through OpenRegister's realCalculationAnnotationValidatorandCalculationEvaluator(OR a5832f2498): 0 validator errors, a planted typo reported ascalculation-prop-unknown, 36 value/fit combinations with 0 mismatches. Playwrighttests/e2e/workflows/portfolio-value.spec.ts.tests/vitest/valueAssessment.spec.js(riskSignals, the usage page wiring).tests/Unit/Service/PortfolioReportServiceTest.php(row fields and mismatch, CSV columns),tests/vitest/valueAssessment.spec.js(plot points sized by cost, not-scored count, mismatch filter), Playwrighttests/e2e/workflows/portfolio-value.spec.ts.The PHPUnit and vitest tests were committed red before the implementation (commits dad8c75 and 05bdb10). The Playwright spec lists (2 tests); it was not run here, because no local instance has a seeded stackiq register.
New text is in English and Dutch. Docs:
docs/features/portfolio-value-assessment.md; its screenshot waits for a seeded instance.Live check: after the register re-imports, open an application under Applications in use, edit it, set business value 5 and technical fit 2 and save: Value assessment shows Suggested TIME classification Migrate beside the recorded class. Open Reports, Portfolio rationalization, pick the organisation: the chart shows the usage as a circle; the switch Recorded class differs from scores lists it when its recorded class is not Migrate.
Checks (branch head, which contains development at 100db8c): one full run (check.sh) gave composer check:strict red only on phpmd, one NEW finding (PortfolioReportService complexity 53 over 50) plus a missing pdepend cache directory in my lane tooling; npm lint 2 NEW errors and prettier on 5 new files. Fixed in 90beb13 and 6fd45fd (the score fields moved into
PortfolioReportDerivation), then rerun: composer check:strict with lint, phpcs, psalm (no errors), phpstan (no errors) green and phpmd 0 on the two touched classes after the last commit; npm lint exit 0 (0 errors, 222 warnings inherited), format exit 0; PHPUnit (phpunit-unit.xml) 953 tests, 20 errors, all 20 inherited and identical by name to development (MigrateRegisterSlugTest x12, MigrateSchemaApplicationIdTest x7, PortfolioReportControllerTest::testCsvFormatReturnsDownloadResponse); the two touched PHPUnit files rerun green after the refactor (18 and 6 tests); stylelint, test:l10n, check:schema-l10n, check:l10n-js, check:manifest, check:vue-demi exit 0; jest exit 0; vitest 359 of 359; Hydra gates at ConductionNL/.github main, full scope with --require-full-coverage: 84 of 84 applicable gates passed.Inherited: the 20 PHPUnit errors above; 222 eslint warnings.