CluPilotCloud/app
nexxo b1e5bf8023 Fix round: match the actual selection IssueInvoice and sync use
Two of the five billing checks measured something close to, but not
the same as, what actually gates the flow they report on:

- billing.invoice_series counted distinct kinds without filtering on
  `active`, but IssueInvoice draws its series with
  where('kind', ...)->where('active', true) (IssueInvoice.php:373,
  :444) — a deactivated row is invisible to it exactly like a missing
  one. An installation with a switched-off 'invoice' series was
  reported ready while no invoice could draw a number: false-green.

- billing.catalogue_synced counted every PlanPrice with a null
  stripe_price_id, but stripe:sync-catalogue only ever mirrors
  PUBLISHED versions (SyncStripeCatalogue's own header comment). A
  draft's unsynced price is an ordinary state, not a gap; the old
  query kept this check permanently unsatisfied on any installation
  that had ever drafted a next version — an alarm always on and
  therefore never read.

Both queries now mirror the condition the real gate uses instead of a
similar-looking one of their own. Two tests added that were red before
the fix: an inactive required series that must not read as ready, and
an unpublished draft's unsynced price that must not raise an alarm.

Also strengthens the weakest breaks sentence: invoice_series_breaks
named the mechanism ("a document cannot draw a number") rather than
the consequence, unlike its four siblings. It now says what the
customer and operator actually experience — a running cloud with no
invoice, the failure only logged — matching company_details_breaks.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 12:42:09 +02:00
..
Actions Stop charging VAT to the customers who owe us none 2026-07-30 02:15:41 +02:00
Console Stop charging VAT to the customers who owe us none 2026-07-30 02:15:41 +02:00
Exceptions Refuse the sale instead of reaching Stripe without a key 2026-07-30 11:58:01 +02:00
Http Verify webhooks against the secret of the mode we are in 2026-07-30 12:13:55 +02:00
Jobs Let the export have as many destinations as somebody wants 2026-07-29 02:43:15 +02:00
Listeners Keep a register of what was sent, and answer the customer from here 2026-07-29 21:02:36 +02:00
Livewire Refuse the sale instead of reaching Stripe without a key 2026-07-30 11:58:01 +02:00
Mail Keep a register of what was sent, and answer the customer from here 2026-07-29 21:02:36 +02:00
Models Stop charging VAT to the customers who owe us none 2026-07-30 02:15:41 +02:00
Notifications Add the SSH identity to the vault, and give deployment config a console page 2026-07-29 00:52:44 +02:00
Observers Say the same thing to the customer, the register and the bank 2026-07-30 01:30:24 +02:00
Policies Move the console's identity out of the customer table 2026-07-28 10:31:43 +02:00
Providers Ask the EU register whether a VAT number is real 2026-07-29 22:42:29 +02:00
Provisioning Fix nine defects in the provisioning pipelines 2026-07-30 01:34:55 +02:00
Services Refuse the sale instead of reaching Stripe without a key 2026-07-30 11:58:01 +02:00
Support Fix round: match the actual selection IssueInvoice and sync use 2026-07-30 12:42:09 +02:00