- Shipped
- September 6, 2026 at 9:10 PM UTC
- Author
- Kamo
- Commit
- 9d20ae7
An organization buys its numbers from one company and answers the calls with another. That is ordinary, and Kamo could not describe it: texting was a property of a member's PHONE SERVER, so an org whose DIDs and SMS came from Telnyx and whose calls were answered by their own FreePBX could not text at all. Settings → Phone → Numbers is where that is now said, and it sits between Providers and Extensions because that is the order the work happens in. A row reads as a sentence — "+1 (949) 555-1212 — Sarah Chen · Calls ring on Office PBX · Texts go through Telnyx" — not a grid of provider ids. The number and the person come first, because those are the two things an administrator actually knows. The decision worth defending, and the one NumbersTab.test.tsx exists to protect: a phone server that cannot text is OFFERED in the Texts dropdown, disabled, with the reason beside it. Filtering it out is the obvious implementation and it is the one that leaves somebody stuck — an administrator who cannot find their phone system in that list concludes the screen is broken, while one who reads "FreePBX cannot send text messages" knows to add a text provider instead. The reasons come from the server, where each provider writes its own. "Find my numbers" imports what the providers already know, because typing thirty DIDs correctly is not a thing to ask of anybody and a mistyped one fails silently. Telnyx joins both pickers. Its card spends most of its words on the webhook public key: it is on a different page of the Telnyx portal from the API key, and missing it has no symptom on sending — texts go out perfectly and every reply is refused. The card also says up front what Telnyx does not have, so that is a decision somebody makes before they commit rather than a discovery afterwards. Kamo ships no Telnyx logo; a tinted initial is honest about being ours, where something drawn to look like their mark would not be. Two things found while building it: - NumbersTab's reload depended on `t`, and useTranslations does not promise a stable identity — so the effect re-fired on every render and the screen never finished loading. Not an error, just a permanent spinner. The test caught it. - The settings menu and the provider label map both have coverage tests that demanded maintenance for a new tab and a new provider. Both were right.