A full audit of 1.x since 1.0.0-alpha12 (10 commits, 63 files, +4489/-626): the deadline-provider plugin type #3615634: Let a node's deadline be computed by a plugin, not only read from a duration or a variable, the payment step's checkout ordering and refusals #3614465: Nothing holds the payment step's subject still while it prices the charge, so the amount charged need not be the amount shown #3614892: Nothing lets a domain module refuse a checkout, so a run its rules forbid is priced and charged #3615265: The payment landing page fatals for a payer coming back mid-checkout, because it asks kessai for an accessor kessai removed #3615627: Let a payment step end its own lapsed window, instead of making every workflow draw a release step, and timeout resume-outcome declaration #3615651: Let a timeout action declare the outcomes it resumes a step with, so an author does not have to read the plugin. Reviewed for correctness, security, performance, accessibility, documentation and translations. phpcs, phpstan, cspell and stylelint are clean and the 1.x pipeline is green on every job, so everything below is something no automated check was going to report.
Correctness
- The payment step announces a checkout opening, and every deliberate way out announces it closing again. A throw does not:
resolve(),preview()and the payment creation all run inside that bracket, so a resolver or gateway that raises leaves a subscriber holding its subject for a checkout that will never charge. - The payment timeout setting tells the author the step is resumed with the
timeoutoutcome. It isexpired. A flow condition written on the word in the description is a branch never taken, which is the exact failure #3615651: Let a timeout action declare the outcomes it resumes a step with, so an author does not have to read the plugin addedresumesWithto prevent. The wrong name had been translated into French too.
Performance
- A token leaving any node carrying a timeout now forgets that node's deadline state, where before only a node-anchored one did. The bundled relative provider implements the state interface whatever its anchor, so the ordinary wait pays a variable lookup on the way out that can only ever find nothing.
- The click to pay asks for the same pending payment three times, and asks two separate questions to learn whether the step is already paid.
Accessibility
- A refused run gets the payment control as an inert span carrying
aria-disabledandtabindex, but no role.aria-disabledsays something only about a widget, so on a bare span it is dropped: the control is reachable in the tab order and announced as plain text, telling a screen-reader user nothing about why it will not act. - The reasons are what that control points at, but the id sat on the list while the sentence framing it renders outside, so it was not read out with the control.
- orchestra_payment ships no stylesheet, so the inert control looked exactly like the live one under any theme with nothing to say about
is-disabled.
Dead code
DeadlineCalculator::resolveDuration()and itsWorkflowEnginedelegate have no callers anywhere; the provider refactor copied the body into the relative provider and left the original behind, with a docblock still claiming both the park and the re-arm resolve through it.TimeoutSweeperstill takes the config factory it stopped reading.
Documentation
PaymentOrchestraHooksdescribes a two-pin design that does not exist: a field on the token naming the payment its step waits on. The hook adds two fields, both on the payment. It matters because thekindguard was dropped from the settlement bridge on the strength of it.docs/payment.mdalready describes the design that shipped.docs/concepts.mdanddocs/roadmap.mdstill described a timeout as a duration and an anchor, and the roadmap listed neither the deadline provider plugin type nor the checkout events.docs/metrics.mdwas last generated at the alpha12 commit itself.
Translations
- The two
payment_lapsedstrings went into the basetranslations/fr.po, though orchestra_payment declares its own interface translation project. - 77 msgids no longer match any source string, 11 of them orphaned by the timeout editor rewrite in this very range and the rest as old as the reword that stranded them.
- 31 translatable strings are in no
fr.poat all. Zero untranslated msgstr says nothing about a string that never reached a file.
Dependency
drupal/kessaiwas pinned to1.x-dev, so CI tracked a branch tip. Three of this range's ten commits are repairs after kessai changed underneath.
For the release notes, not defects
- The timeout config rename (
duration,until,until_offset,anchortodeadlineanddeadline_settings) has no update path and also lives inside immutable workflow version snapshots, so fixing a workflow does not fix a run already in flight. Reinstall rather than upgrade. - The payment index was renamed; core never applies an index change to an installed site, and the old one still leads with the same column, so lookups stay covered.
Issue fork orchestra-3615875
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
mably commented