Detach the chat navigator from the window it maximizes
The conversation navigator was a child prop of ToolWindowShell, rendered inside the maximized window's content box. Clicking a row in it opens that conversation...
Company phone (main/toll free) on a member's signature, with their extension
The Content tab of **************** gains two switches: Company Phone (Main) and Company Phone (Toll Free). Enabled, they print the organization's published lin...
Persist the two company phone toggles
Reads and writes userCompanyPhoneMain / userCompanyPhoneTollFree on the signature field config, so the Content tab's new switches survive a save. saveFieldConf...
Attribute free extensions to the server they are on
An org running a busy FreePBX server beside a new, empty KamoPBX server saw "21 billable extensions — $63.00 / month" while looking at the KamoPBX one. Both num...
Land the company phone toggle columns before EmailService reads them
ADD COLUMN IF NOT EXISTS on **************** for user_company_phone_main and user_company_phone_toll_free. This service's ddl-auto: update would add both from ...
The company phone toggles an individual signature can carry
Two org-wide flags on email_signature_field_config: user_company_phone_main and user_company_phone_toll_free. They put the organization's published line on a me...
The inbound-keyword receipt, and re-key consent by campaign (MS1 Task 3)
Two things the consent ledger needs before an inbound STOP can be recorded tenant-scoped and exactly once. `SmsInboundReceipt` (comms_sms_inbound_receipt) is t...
One source of truth for the platform settings
"Test connection" reported "no master account id" on a phone server whose provisioning had just succeeded, minutes earlier, using that same id. Two sources dis...
The sync journal, and a terminal run that really is frozen
BL1 Task 5, shared-library half. Five journal enums, three entities and three repositories under **************** No stereotypes: BillingWormGuard is a plain fi...
Offer Finish setup on a KamoPBX server that was never provisioned
The card told the admin their phone system was "still being set up" and to wait. That was never going to clear: KamoPBX provisioning runs synchronously when the...
A half-provisioned phone server could never be finished, and said the wrong thing
An org's KamoPBX server has been reporting Error: Phone provider instance not found: **************** since it was created. The instance was never missing —...
Carrier-facing inbound SMS webhook (MS1 Task 2)
POST **************** -- form-encoded or JSON, guarded by the CARRIER'S OWN SIGNATURE. Why a new endpoint. /api/voip/webhook cannot receive a STOP and fails si...
Set the VM's MTU to the pod network's, and let the desktop apply updates
Two separate reasons the "Code" update could not be installed. THE UPDATE COULD NOT BE DOWNLOADED. enp1s0 came up at MTU 1500 while every other workload on thi...
E.164 normalizer and SMS keyword interpreter (MS1 Task 1)
Two pure classes with no I/O and no Spring stereotype, so every service can load them and SharedLibBeanSafetyTest stays green. E164.normalize(raw, defaultRegio...
The provider connection row, one per org
BL1 Task 1. A near-verbatim transliteration of the payroll provider enums and PayrollConnection into **************** Enums, one entity and one repository — no ...
Give every kamocrm extension WebRTC, and gate outbound calling
All 21 kamocrm team members now hold an 8XXX extension on the k1m1 PBX (Chris renumbered off 7255 to 8134). Two changes here back that. WebRTC endpoint blocks ...
The FreeSWITCH crash was mod_kazoo's default config, not the event profile
The stub kazoo.conf.xml 2600Hz ship has no definitions, event-handlers or fetch-handlers sections. mod_kazoo says as much and then faults in its own config thre...
Format the numbers in call history
The History tab was the one softphone surface rendering a raw provider number: the incoming-call banner and every number in SoftphoneCRM already run through for...
Stop unattended upgrades restarting xrdp under a live session
The black screen was apt. apt-daily-upgrade.service upgraded xrdp at 06:49 UTC on 2026-08-27 and restarted it while a desktop from 2026-08-25 was running. xrdp-...
Keep long app descriptions inside the Apps & Features row
The collapsed accordion summary already set nowrap + ellipsis on the description, but nothing in the flex chain could shrink: a flex item defaults to min-width:...
Remove the vendors tab, which could only ever show its own mocks
The three pickers classified vendors by id range — 200s appraiser, 300s title, 400s escrow. `commerce_vendors.uid` is INT8 DEFAULT unique_rowid(), about 19 digi...
Record four more KamoPBX bring-up traps
- Community mod_kazoo (FreeSWITCH v1.10.11) connects to ecallmgr, reports "Connected", and then never answers a gen_server:call. Resolved by taking 2600Hz's...
Keep FreeSWITCH's log readable while it is crash-looping
FreeSWITCH runs with -nc, so mod_logfile is the only record of what it did, and on the container filesystem that record dies with the container — precisely when...
Tighten the masthead band and sit both sides on the bottom edge
The launchpad's first band was costing more height than it earned. The page container's uniform inset gave the masthead a 40px top gutter, and the header carrie...
Call history names the far side, not the member themselves
A history row exists to answer "who was this call with", and that side flips with the direction. HistoryRow read `fromName || fromNumber` unconditionally, so ev...
Outbound external calls were missing from FreePBX call history
On an outbound external call FreePBX rewrites the CDR `src` to the trunk's outbound caller ID — the org's own DID — so a call ext 8080 placed to 9493747110 is r...
Pin the attachment sniff to real encoder output
The existing cases build a header by hand, which tests the code against my belief about the format rather than against the format. These sixty-four-byte prefixe...
ServiceJobApi.createJob, and the back-link builder
Restores the client half of SW6c Task 2, which landed as 157fa714 and was dropped by a history rewrite in a concurrent session; the create screen itself survive...
The service-request grid and client read the real endpoints
Restores the rest of SW6c Task 4, which landed as d58a6aba and was dropped by a history rewrite in a concurrent session; the detail page survived inside bddd361...
One back-link that resolves, instead of four that never did
Every service screen's back button was `/commerce?tab=service`. There has never been a tab with that id: `PipelineView.tsx:69-70` builds them as `market-${marke...
Screenshots AND videos on a bug report
Reporters were describing screen recordings in prose and then posting the file into a chat, because the report form only took stills. It now takes MP4, MOV and ...
A video on a report never reaches an AI dispatch
file and cannot watch one. The desktop agent already magic-byte-checks every attachment, but it refuses the DISPATCH rather than the one file — so a single vide...
Attach a video to a bug report, not only a screenshot
A still cannot show the three clicks before the thing broke, so reporters were describing recordings in prose and posting the file into a chat instead. The atta...
The bug-report association holds video too
SYSTEM_BUG_SCREENSHOT now carries screen recordings alongside screenshots. The constant keeps its name and its id — id 17 is written into assoc_id on every row ...
Restore the pipeline Quotes tab and wire quote conversion
`POST /quotes/{uid}/convert` shipped in SW4 and nothing has ever called it: `quotesApi` had ten methods and `convert` was not among them, so the endpoint was li...
The browser tab is named after the workspace, not the host
Enter Wienerschnitzel or Wendy's and the tab read "KamoCRM", while nothing inside the workspace said KamoCRM anywhere. ABC Mortgage was correct, which made it l...
Stop the prescribing-disclosure test being flaky
It passed alone and failed inside the full suite. The effect calls **************** and sets state in a .then(), so settling the mock's promise, running the con...
Volume bands stop pricing seats the plan does not sell
Starter admits 5 seats and Business 25, but the bands ran to 25 and 100 — four of the six priced seat counts nobody could reach. Starter's 10%-off-at-11 tier wa...
KI would not compile against the shared library on main
VendorDTO.uid became a String — a Long in the database, a string on the wire — and this call site still handed it to **************** which is a server-side req...
Stop offering 8 unroutable ICE candidates on every call
Callers hear several seconds of one-way audio at the start of a call — the other party says "hi" three or four times before the softphone user hears anything. ...
Our price comes from the catalog, and can't be typed again
The comparison pages hardcoded KamoCRM at $29 Starter and $64 Business while the catalog sold them at $34 and $72. Nine files, forty-two mentions, and the build...
The Traefik per-IP limit will 429 a QHIN invisibly
Comment only, in the file somebody opens when a partner complains. Traefik rate-limits per source IP across the whole api.* host, and a QHIN sits behind a sing...
Pin the exact JSON the clinical client parses
Every field in these bodies is read by name in app/lib/patients/ehrApi.ts and nothing was checking the server still emits them. The service tests pin that the e...
Recorded-call notice on extension-to-extension calls
Completes the third call path. Staff-to-staff calls never touch the attendant — they go from-internal -> ext-local, where the Dial belongs to FreePBX — so [from...
POST /service-jobs, gated on MANAGE_SERVICE_WORK
The create verb the work-order surface never had. app/commerce/service/new is a seventeen-line placeholder because there was nothing to call. Gated on MANAGE_S...
CreateJob, so a work order can be raised without an order
The one verb the service-job surface was missing. Until now the only thing on the platform that could produce a ServiceJob row was **************** off a paid o...
Rebuild to seed the four order and pricing rights
An empty commit built out of tree from origin's own tree. RoleRightsSyncService seeds org_role_rights at boot, so a right shipped without a SecurityService rebu...
Resolve the Kamailio question — SIP registration works end to end
Section 16 recommended a purpose-built config on stock Kamailio and recorded that "2600hz/kamailio does not exist". Both are corrected by evidence. Two further...
Match the SIP status code, not the reason phrase
sip-probe.py required the literal string "200 OK". 2600Hz's Kamailio config answers OPTIONS with "200 Rawr!!", so the probe reported a healthy, correctly config...
Like what you see shipping?
All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.
