- Shipped
- August 27, 2026 at 3:21 AM UTC
- Author
- Kamo
- Commit
- 6ca4e79
PbxBillingSchemaMigration is @Order(0) because it adds a column. The shared-library entity maps phone_cost_mode from the moment the build starts, so any runner loading an OrgBillingPolicy through JPA emits it in its SELECT - ordered late this runner never executes at all, because an earlier one dies on "column ... does not exist" and takes the whole run down. org_extension_billing_days is in public, not a schema of its own: every other voip table is. It is unique on (org_id, day, addon_code, subscription_uid), one column wider than the mail equivalent, so an org with two billing groups keeps two audit rows rather than one overwriting the other. subscription_uid is NOT NULL precisely so SQL's nulls-are-distinct rule cannot defeat that index. **************** repairs the assignments InstanceSyncService had been erasing on every sweep - nine members held one and all twenty-three extension rows read null. Only fills a blank: the config side joins on an unconstrained extension string, so it is the weaker record and never overwrites an id that is set. PbxAddonCatalogMigration seeds both add-ons into every catalog that already sells the mail ones, anchored to the EMAIL_HOSTING row for org, market and compatible plans. Scoped that way rather than by a hardcoded id because two tenants own add-ons with the same codes. KamoCRMPricingLoader gets them too, for catalogs seeded from here on - it is create-only, so editing it alone fixes nothing already in the database.