release prep v0.2.0
- CHANGELOG.md: convert [Unreleased] to [0.2.0] — 2026-05-03 with release narrative + link reference at the foot of the file. Empty [Unreleased] re-seeded for the next cycle. - PLAN.md: top status line gains v0.2.0 (shipped 2026-05-03); §13 v0.2.0 entry rewritten as the shipped recap (matches the v0.1.0 / v0.1.1 / v0.1.2 narrative-then-bullet style) plus the three carried-forward items with their parking rationales. No code changes — release narrative + link plumbing only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
13
CHANGELOG.md
13
CHANGELOG.md
@@ -6,7 +6,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
This section tracks work landing on `dev` toward **v0.2.0** (next minor; pre-1.0 SemVer permits API breaks). See PLAN.md §13 for the full v0.2.0 scope.
|
||||
### Added
|
||||
|
||||
- (none yet — next changes land here)
|
||||
|
||||
## [0.2.0] — 2026-05-03
|
||||
|
||||
First minor release. Pre-1.0 SemVer permits API breaks; the only one is `ModelPublisher::publishEntityChange()`'s `string $op` → `BridgeOp $op` signature change. Apps that only consumed the framework via the makers, the Doctrine listener, and the QML module are unaffected.
|
||||
|
||||
The release closes the post-v0.1.2 architecture audit (interfaces, typed enum, `BridgeBundleInfo`, maker DRY, DTO-shaped controller scaffold) and delivers the §12 *Operations* row from PLAN.md (port negotiation, pre-migration auto-backup, `bridge:export`, periodic auto-update check, native-dialogs boundary doc) plus two new makers (`make:bridge:event`, `make:bridge:read-model`) and `qmltestrunner`-based QML unit tests in CI.
|
||||
|
||||
### Added
|
||||
|
||||
@@ -105,7 +113,8 @@ First public preview. Phases 0 through 4a in PLAN.md are complete plus the Phase
|
||||
- The bundle ships without `composer.lock` (it's a library); the skeleton and the todo example carry their own.
|
||||
- Licensed under **LGPL-3.0-or-later** (`LICENSE` + `LICENSE.GPL` at the repo root). Chosen to align with Qt 6's LGPLv3 licensing — see PLAN.md §12 for the relinkability obligations the AppImage build already honours.
|
||||
|
||||
[Unreleased]: https://src.bundespruefstelle.ch/magdev/php-qml/compare/v0.1.2...HEAD
|
||||
[Unreleased]: https://src.bundespruefstelle.ch/magdev/php-qml/compare/v0.2.0...HEAD
|
||||
[0.2.0]: https://src.bundespruefstelle.ch/magdev/php-qml/releases/tag/v0.2.0
|
||||
[0.1.2]: https://src.bundespruefstelle.ch/magdev/php-qml/releases/tag/v0.1.2
|
||||
[0.1.1]: https://src.bundespruefstelle.ch/magdev/php-qml/releases/tag/v0.1.1
|
||||
[0.1.0]: https://src.bundespruefstelle.ch/magdev/php-qml/releases/tag/v0.1.0
|
||||
|
||||
40
PLAN.md
40
PLAN.md
@@ -1,6 +1,6 @@
|
||||
# php-qml — Plan for a Symfony/FrankenPHP + Qt/QML Desktop Framework
|
||||
|
||||
> **Status (2026-05):** v0.1.0 + v0.1.1 + v0.1.2 shipped 2026-05-03 (LGPL-3.0-or-later). Planning is version-based — see §13.
|
||||
> **Status (2026-05):** v0.1.0 + v0.1.1 + v0.1.2 + v0.2.0 shipped 2026-05-03 (LGPL-3.0-or-later). Planning is version-based — see §13.
|
||||
>
|
||||
> **Where else to look:**
|
||||
>
|
||||
@@ -550,41 +550,23 @@ Bugfix release. Bundles the v0.1.1 follow-up that surfaced during the cycle (cle
|
||||
- **`SessionAuthenticator` problem+json on entry-point path.** `onAuthenticationFailure` already returned RFC 7807 `application/problem+json` for *bad-token* requests, but Symfony's default entry point fired for *no-token* requests — yielding a Form-flavoured 302/401 instead. Implemented `AuthenticationEntryPointInterface::start`, factored the response into a `problemJson()` helper, so QML's RestClient sees one shape regardless of which path the firewall takes. Added test coverage.
|
||||
- **`CorrelationKeyListener::onTerminate` sub-request guard.** `onRequest` already had `isMainRequest()`, but `onTerminate` cleared unconditionally — so a sub-request finishing mid-controller would wipe the main request's correlation key, causing the matching Mercure echo to lose its `correlationKey` field and the optimistic UI to never reconcile. Defensive: real-world impact is low (FrankenPHP worker mode does not currently emit sub-requests), but cheap to fix and the obvious correctness bug.
|
||||
|
||||
### v0.2.0 — next minor
|
||||
### v0.2.0 — shipped 2026-05-03
|
||||
|
||||
Pulls in the originally-Phase-3/5-deferred items that don't need new operational dependencies, plus the smaller §12 risks **and** the public-API / DX items surfaced by the post-v0.1.2 audit. Cross-platform packaging is parked at v0.9.0 — the operational lift (self-hosted runners + platform certs) is too big to fold into the next minor and Linux remains the primary target until the framework's surface stabilises.
|
||||
First minor release. Closes the post-v0.1.2 architecture audit, the §12 *Operations* row from PLAN.md (port negotiation, pre-migration auto-backup, `bridge:export`, periodic auto-update check, native-dialogs boundary doc), two new makers (`make:bridge:event`, `make:bridge:read-model`), and `qmltestrunner`-based QML unit tests in CI. Pre-1.0 SemVer permits API breaks; the only one is `ModelPublisher::publishEntityChange()`'s `string $op` → `BridgeOp $op` signature change. Full entry in `CHANGELOG.md`.
|
||||
|
||||
**Shipped on `dev` toward v0.2.0** (audit-driven cleanup batch — see CHANGELOG `[Unreleased]` for full notes):
|
||||
**Public-API surface (audit-driven):** `PublisherInterface` / `ModelPublisherInterface` / `CorrelationContextInterface` — internal typehints switched over, autowire continues to inject the implementations. `BridgeOp` string-backed enum replacing the raw op strings. `BridgeBundleInfo` VO replacing the publisher canary in `HealthController` (`/healthz` `bundle` field reports the bundle FQCN, new `name` field reports `php-qml/bridge`).
|
||||
|
||||
- ✅ `PublisherInterface` / `ModelPublisherInterface` / `CorrelationContextInterface`. Concrete classes implement them; internal typehints switched over.
|
||||
- ✅ `BridgeOp` enum (`Upsert` / `Delete` / `Replace` / `Event`). `ModelPublisher::publishEntityChange()` now takes `BridgeOp` instead of `string` (pre-1.0 SemVer break).
|
||||
- ✅ `BridgeBundleInfo` VO. `HealthController` constructor-injects this instead of `PublisherInterface` as the deep-load canary; `/healthz` `bundle` field reports `PhpQml\Bridge\BridgeBundle`, plus a new `name` field (`php-qml/bridge`).
|
||||
- ✅ `Maker\Support\NameInput::askOrFail()` + `Maker\Support\Naming::camelTo()`. The duplicated name-prompt closure and camel-conversion regex collapsed into single call sites.
|
||||
- ✅ `make:bridge:resource --with-dto` opt-in. Generates `Create<Name>Dto` + `Update<Name>Dto` and rewrites controller actions to `#[MapRequestPayload]` dispatch — closes the input-validation gap (malformed JSON → 400 problem+json automatically; no more `if (isset($data['title']))` boilerplate). Skeleton + example/todo composer.json pull `symfony/validator`. Snapshot test covers both modes.
|
||||
**Maker + DX:** `Maker\Support\NameInput` + `Naming` helpers collapse the duplicated prompt closure + camel-conversion regex. `make:bridge:resource --with-dto` opt-in generates `Create<Name>Dto` + `Update<Name>Dto` and dispatches via `#[MapRequestPayload]`, closing the input-validation gap. New `make:bridge:event` and `make:bridge:read-model` makers cover the third + fourth rows of §8's makers table.
|
||||
|
||||
**Still open for v0.2.0** (PLAN.md notes preserved below):
|
||||
**Operations:** Bundled-mode port negotiation via `QTcpServer` port-0 trick (`var/bridge.port` sentinel for tests). Pre-migration `var/data.sqlite` auto-backup (5 most recent). `bridge:export` command + `BackendConnection.exportDatabase()` Q_INVOKABLE. Periodic auto-update check (10 s after first Online + every 6 h; `BRIDGE_AUTO_UPDATE_DISABLE=1` to opt out).
|
||||
|
||||
- **Generated controller `findOr404` boilerplate.** `update()` and `delete()` still inline the find-or-404 problem+json response. Audit suggested factoring a private helper or migrating to Symfony's `#[MapEntity]` attribute. MapEntity changes the 404 response shape away from problem+json unless framework-level error config is updated; a private helper is net-zero on lines. Parking until either (a) we bake skeleton-level RFC 7807 error wiring (so MapEntity preserves shape), or (b) we flip `--with-dto` to default-on and the legacy template's polish becomes irrelevant.
|
||||
- **Flip `--with-dto` to default-on.** Once snapshot-test churn settles and the DTO templates have surface-feedback, make it the default and gate `--no-dto` for users who want the legacy shape.
|
||||
**Docs + testing:** `docs/native-dialogs.md` (Qt.labs.platform boundary). `qmltestrunner` harness under `framework/qml/tests/` wired into CTest, `make qmltest`, and the Gitea Actions Quality job.
|
||||
|
||||
**Makers + reactive types (Phase 3.x deferred):**
|
||||
**Still open** (carried into later minors):
|
||||
|
||||
- **`make:bridge:event` maker.** Generate an event class + listener stub for app-side domain events.
|
||||
- **`make:bridge:read-model` maker.** Generate a read-only projection (one or more entities → one denormalised view).
|
||||
- ~~**`ReactiveObject` cursor pagination.**~~ Closed N/A on inspection. ReactiveObject already has `pending` / `invoke()` / Idempotency-Key correlation / version-gap detection at parity with ReactiveListModel; the only feature it lacks is *pagination*, which is meaningless for a single-entity model. If the surface-feedback later flags a real reactive-feature gap (related-collection fetches, sub-resource navigation), that's a separate item with its own design.
|
||||
|
||||
**Testing (Phase 3/5 deferred + §12 testing-strategy row):**
|
||||
|
||||
- **`qmltestrunner`-driven QML unit tests.** Wires into the `quality` job alongside qmllint.
|
||||
- **End-to-end UI test (Squish or Qt Test).** Was §12's deferral; bridge-integration covers IPC, this would catch UI-only regressions.
|
||||
|
||||
**Operations (§12):**
|
||||
|
||||
- **Bundled-mode port negotiation.** `BackendConnection::m_port` is hardcoded to 8765 with no env override or negotiation, so two php-qml apps installed on the same machine collide on first launch (whichever loses the race goes Offline). Fix: bind a transient `QTcpServer` to `QHostAddress::LocalHost` port 0, grab `serverPort()`, hand it to FrankenPHP via the `PORT` env var. Needs a port-discovery mechanism for tests/perfsmoke that currently hardcode 8765 — likely write the chosen port to a sentinel file under the user data dir on supervisor activation. Surfaced from a v0.1.1 follow-up question; deferred to v0.2.0 because the test/consumer migration is wider than v0.1.x scope.
|
||||
- **Pre-migration auto-backup** (§12, *Migrations on schema change*). Supervisor copies `var/data.sqlite` to `var/data.sqlite.<timestamp>.bak` before invoking `doctrine:migrations:migrate`; trims to N most recent.
|
||||
- **`bridge:export` console command + UI hook** (§12, *Data backup / export*). Lets users copy their data out before machine moves or risky migrations.
|
||||
- **Periodic auto-update check.** Phase 5 noted this as a polish item but didn't ship; v0.1.0 only has menu-triggered manual checks.
|
||||
- **Native dialogs boundary doc.** §12 noted file pickers / notifications belong on the QML side via Qt — document the boundary and ship a small `Q_INVOKABLE` helper for the common cases.
|
||||
- **Generated controller `findOr404` boilerplate.** Update + delete still inline the find-or-404 problem+json response. Audit suggested factoring a private helper or migrating to Symfony's `#[MapEntity]` attribute. MapEntity changes the 404 response shape away from problem+json unless framework-level RFC 7807 error config is updated; a private helper is net-zero on lines. Parking until either (a) we bake skeleton-level RFC 7807 error wiring, or (b) we flip `--with-dto` to default-on and the legacy template's polish becomes irrelevant.
|
||||
- **Flip `--with-dto` to default-on.** Once surface-feedback validates the DTO templates, make it the default and gate `--no-dto` for users who want the legacy shape.
|
||||
- **End-to-end UI test (Squish or Qt Test).** Was §12's deferral; bridge-integration covers IPC, this would catch UI-only regressions. Moved to a later minor because the framework / runner choice is its own decision.
|
||||
|
||||
### v0.3.0 — later minor
|
||||
|
||||
|
||||
Reference in New Issue
Block a user