Repository navigation
Release v3.15.0
v3.15.0
Changelog
Performance: UiKit page contract (scaffolds, dialogs, server-side SVG charts), PSR-20 clock, 100% coverage; review/Twig components/DDL fixes; SEC-004 BP: literal-boolean switches, bad dates ignored, export-ignore See UPGRADING.
Performance: dashboard on the UiKit page contract (REQ-UI-003), canonical web_ui keys, PSR-20 clock. See
UPGRADING.
Security (SEC-004 re-audit 2026-10-30, Appendix BP: Pass (good) / Low)
- L1 —
web_ui.enabledmust be a literal boolean. The 3.15 load-time cast turned an%env(bool:…)%placeholder
(also through the deprecateddashboard.enabled) intotrue, so an environment variable could no longer switch the
dashboard off. Anything buttrue/falsenow fails the container build with anInvalidConfigurationException. - I1 — the same literal-boolean rule for
security.allow_unauthenticated(an env placeholder was truthy in dev /
test kernels). - I3 — malformed date query parameters (
date_from,date_to,start_date,end_date) are ignored instead of
raising a 500 (routes page, exports, access statistics, access records). - I4 —
.gitattributeskeepsdemo/,tests/,specs/,.specify/,.cursor/,.scripts/,scripts/,
.githooks/,.github/,docs/images/and the tooling configs out of the GitHub / Packagist dist archives.
Added
- UiKit page contract (REQ-UI-003). The dashboard pages extend the UiKit scaffolds: routes and access records
page/list, advanced statistics and access statisticspage/dashboard, diagnosepage/show. View models come from
Ui\PerformancePageFactory; layout / per-page template resolution fromUi\PerformancePages. Page map, data blocks
and view-model fields: TEMPLATES.md. Contract test:tests/Integration/Contract/PageContractTest.php. - Canonical configuration keys
web_ui.enabled,web_ui.path_prefix,web_ui.layout_template(defaultnull=
nowo_ui_kit.layouts.admin) andweb_ui.templates.<page>(index,statistics,access_statistics,
access_records,diagnose). The route prefix is%nowo_performance.web_ui.path_prefix%. - Area navigation
Ui\PerformanceAreaNav: page-header tabs on every page andnowo_ui_area_nav('performance')for
host menus (DashboardMenu). - Server-side charts: daily request-time trend, metric histograms, accesses by hour and the access heatmap are
inline SVG partials (_bar_chart,_heatmap); no chart library, no JavaScript. with_submitoption (defaulttrue) onPerformanceFiltersType,RecordFiltersType,ClearPerformanceDataTypeand
DeleteRecordsByFilterType: the pages passfalsebecause the UiKit filters / Action render the button.- PSR-20 clock (REQ-DI-001).
PerformanceController,PerformanceMetricsServiceandPurgeAccessRecordsCommand
take an optionalPsr\Clock\ClockInterface(symfony/clockis now required);RouteData::markAsReviewed()/
RouteDataRepository::markAsReviewed()accept an optional review time.
Changed
- Template contract. Destructive actions (clear all, delete route, delete matching records) use the UiKit confirm
<dialog>with their CSRF form; review and purge open in a UiKitdialog; flashes, filters, pagination and empty
states come from UiKit. No inlineonclick/onsubmit/confirm(), no CDN (Bootstrap, Tailwind, Chart.js).
Auto refresh is a<meta http-equiv="refresh">; the statistics environment selector auto-submits through UiKit
(data-nowo-ui-autosubmit). - The form types and the FormKit
performanceprofile carry no framework utility classes any more (form-control,
form-select,btn btn-*,mb-2): the host form theme and the UiKit theme slots style them. - The UiKit
css_framework/icon_setseed only happens when the host still sets the deprecated
dashboard.css_framework/dashboard.templateandnowo_ui_kithas nocss_frameworkof its own. nowo-tech/ui-kit-bundleconstraint raised to^2.17.3.api/chart-datarounds averages / maxima to 4 decimals (was 2).- 100% statement coverage without exclusions (REQ-TEST-003):
PerformanceController, both table commands and
QueryTrackingMiddlewareRegistryare no longer excluded inphpunit.xml.dist;make test-coverageand CI fail
below 100%. Code that cannot run on the supported dependencies was removed instead of ignored: DBAL 2 fallbacks
(getSchemaManager(),quoteIdentifier(),Type::getType()), impossiblecatchblocks, a dead$limit >= 1000
branch, the internal-connection probe of the middleware registry and the composer.json / class heuristics of its
DoctrineBundle version detection (Composer runtime data only). The CSV export streams throw aRuntimeException
whenphp://outputcannot be opened instead of silently returning nothing; diagnose always uses
Connection::createSchemaManager();NotificationChannelsPassbuilds its tagged iterator with one
version-agnostic constructor call; the deprecatedLogHelperno longer guardsfunction_exists('error_log'). No@codeCoverageIgnoreis left insrc/:
the DBAL 2 fallback ofTableStatusChecker, the unreachable outercatchofQueryTrackingConnectionSubscriber
and the pool guard of the statistics cache generation (now aLogicExceptioninvariant) are gone; the deprecated
ChartFiltersTypeno longer sets an inlineonsubmit.make test-coveragenow fails on test failures too
(pipefail) and runs without--process-isolation(PHPUnitmemory_limit1G).
Deprecated
dashboard.enabled,dashboard.path,dashboard.prefix,dashboard.layout_template→web_ui.*;
dashboard.css_frameworkanddashboard.template→nowo_ui_kit.css_framework(removed in 4.0).- A
layout_templatethat does not render the UiKit canonical blocks is wrapped in
Performance/_legacy_layout.html.twig(deprecated bridge, removed in 4.0). - The Twig components
nowo_performance.Statistics,.Filters,.Charts,.RoutesTable(they render through the new
slot-based partials) andChartFiltersType; the Twig globalsnowo_performance_layout_template/
nowo_performance_css_framework; theDeleteRecordTypeoptionsubmit_attr_class(ignored).
Removed
- Templates
Performance/base.html.twig,Performance/layout.html.twig(CDN demo shell) and the per-framework partials
Performance/components/_{statistics,filters,charts,routes_table}_{bootstrap,tailwind}.html.twig,_paginator,
_dependency_modal. ThechartFiltersFormvariable is no longer passed to the routes page. NowoPerformanceBundle::boot()no longer looks up the kernel in the container nor replaces the global VarDumper
handler in CLI debug runs (REQ-DI-001).
Fixed
- Review from the dashboard crashed.
review()called an undefined$this->trans()after a successful review
(fatal "Call to undefined method"); the controller now takes an optionalTranslatorInterface(last constructor
argument) for its flashes. With access records enabled, the review form was also rebuilt withoutroute_data/
enable_access_records, so every review was rejected as "Invalid form data". - Twig components were never registered: the extension checked a
ComponentInterfacethat
symfony/ux-twig-componentdoes not ship; it now checksAsTwigComponent. nowo:performance:create-table/create-records-table:- the MySQL
AUTO_INCREMENTpatch now matches only theidcolumn (it also hitroute_data_id INT, giving two auto
columns and a failedCREATE TABLEfor access records); --update --drop-obsoleteno longer treats theroute_data_idjoin column as obsolete (dropped on
PostgreSQL/SQLite, failed on MySQL because of the foreign key);--updateno longer flags theidcolumn as changed on every run (the comparison includes the platform's
auto-increment / identity declaration) and no longer emits the MySQL-onlyMODIFY COLUMN ... AUTO_INCREMENTrepair
on other platforms (a warning points to Doctrine migrations);MODIFY COLUMN idno longer declaresAUTO_INCREMENTtwice;- a string field without a length no longer crashes on MySQL (
TypeError); it falls back toVARCHAR(255).
- the MySQL
- Translated label for the statistics environment selector (was the literal
Environment). - Flex recipe:
security.access_roles: ['ROLE_ADMIN']instead of the formerdashboard.roles: [], which an empty list
now refuses at container compilation.
Commits
- Release v3.15.0: Performance: UiKit page contract (scaffolds, dialogs, server-side SVG charts), PSR-20 cloc (16fa965)
- Merge pull request #70 from nowo-tech/req100 (17e8e52)
- fix(security): SEC-004 Appendix BP L1, I1, I3, I4 (edd2fcf)
- ci: run the table-command database tests on MySQL and PostgreSQL (261e229)
- test(coverage): drop the last coverage ignores, fail test-coverage on test failures (4d1cf41)
- feat(ui): dashboard on the UiKit page contract, 100% coverage, PSR-20 clock (875c359)