- Shipped
- September 6, 2026 at 9:55 PM UTC
- Author
- Kamo
- Commit
- ae95b01
VOIP_CONVERSATIONS.INSTANCE_ID was NOT NULL, which quietly decided that every text thread belongs to a PBX. An organization that buys numbers and messaging from a carrier and answers no calls at all — texting-only, no phone server anywhere — has no VoipProviderInstance for a thread to belong to. Those orgs could SEND (a number's own text route needs no phone server) and had every reply dropped, because ingest could not build a conversation to file it under. Null is now a real state and the javadoc says what it means, including the thing it must never be: a BulkTextProviderInstance id. Both tables are UUID-keyed and handing an id to the wrong factory fails as "no such instance" rather than failing loudly. Dedupe survives the null, but not for free — SQL treats NULLs as distinct, so the existing unique index stops covering these rows. The DDL beside VOIPService adds a partial unique index on (ORG_ID, MEMBER_ID, EXTERNAL_PHONE_NUMBER) WHERE INSTANCE_ID IS NULL for exactly that case.