Pair the meeting-invite fields into two columns when maximized
The invite form stacks eight full-width rows, which in a maximized compose window pushed the body editor most of the way off screen while leaving half the windo...
Apply page operations and modifiers to the signed document
The designer has always offered page rotate, delete, reorder and add-blank, plus watermark, page-number and label modifiers, and the flatten read none of it: it...
Give every popup tool window 40px more room in both axes
Each tool's defaultSize and minSize in the registry grows by 40x40, and the geometry that was hardcoded alongside it moves with it rather than drifting out of a...
Drag, cut, copy and paste recipient chips between To, Cc and Bcc
Moving someone from To to Bcc meant deleting the chip and typing the address again from memory. Chips are now selectable and can be dragged or carried on the cl...
Rotate the field overlay with the page, flag unread imports, order fields for reading
Three things that only start to matter once a document arrives carrying forty detected fields instead of two hand-placed ones. Page rotation: rotating a page t...
Read Acrobat format actions when detecting fillable fields
Acrobat stores a field's intended format as JavaScript in /AA, which pdf.js surfaces as actions.Format. That is the author's declaration rather than a guess off...
Insert a new meeting link at the coder from the composer
Adds a footer action to the compose window that creates a meeting with the organization's configured provider and writes its join link into the body wherever th...
Rebuild a fillable PDF's AcroForm fields as native Kamo fields
Opening an editable PDF in the document editor now reads its AcroForm widget annotations off the pdf.js document and recreates each one as a DesignField on the ...
Create the email search_vector column and its inverted index
**************** never existed. EmailService's own V1__email_metadata_schema.sql declares it, but that migration never ran -- the table came from this service's...
A contact card behind every name on a message
Every person shown in a read view was a dead end. To and Cc rendered as displayNameFor(a).join(', ') — a comma wall of display names with no address, no hover, ...
Resolve the people behind the addresses on a message
A message header knows an address and whatever display name the sender chose to put beside it. The organization already knows far more — colleagues, address boo...
Resources tab is the org's HR document library
Replaces the Resources placeholder with DocManager on a document collection of its own — ImageAssocType.HR_RESOURCE, bucket imaging-hr-resources — org-scoped th...
HR_RESOURCE assoc type for the org HR resource library
The /hr Resources tab publishes handbooks, policies, forms and reference material to the whole team, and no existing assoc type fits: MY_DOCS is a person's own ...
Human Resources module shell with five route-backed tabs
Adds /hr with the accounts-page chrome in its route-backed form (the same one /marketing already uses): a layout owning the gradient hero and underlined tab bar...
Complete the Communications tab
Each sub-tab now holds its own data, and All interleaves every channel by date. Notes keeps MediaStream, because notes are authored here — but readOnlyChrome s...
Unified communications timeline API
GET **************** returns one date-ordered page across notes, calls, voicemails, texts, e-mails and chat; ?channel= narrows it. Three sources are merged. Ca...
Drive the mail-to-lead association sweep
Five-minute tick against EmailService's internal sweep endpoint, mirroring VoipGlobalSyncJob. The schedule lives here because EmailService runs several pods and...
Associate lead correspondence, and fix the dead push indexer
Adds the mail half of the lead Communications tab, plus the ingestion it needed to exist at all. The platform has no working mail push: IMAP IDLE is hardcoded ...
Persist calls and associate calls, texts and voicemail with leads
Calls were never recorded anywhere — VoipCallEventService published a NATS event for the browser and kept nothing, and RECORDINGS only exists when audio was cap...
Schema and contact-point seed for lead communications
Hibernate creates the three new tables from the shared-lib entities; this adds what it cannot express — the partial unique index that keeps at most one open con...
Point-in-time contact-point index and lead communication links
Adds the spine the lead Communications tab reads from. LEAD_CONTACT_POINTS records every phone number and e-mail a lead has ever had, as a window with activeFr...
Capture the demo lead before the booking step
The marketing site's demo form collected name, email, company, company size, industry and a message, then advanced to scheduling without telling anyone. Lead cr...
Public demo-request lead capture primitives
A visitor who fills in the marketing site's demo form but never books a time left no trace: the lead was only ever written inside the booking transaction. Captu...
Register Provider Setup in navigation, and write the quick tips
The Provider Setup tab rendered inside SettingsView but was reachable only by typing the URL — it was missing from both places that list settings destinations: ...
Enforce geo and IP access rules on page loads
checkAccess evaluated the rules itself and matched nothing for its entire life: it compared rule types against **************** while the publisher writes the e...
Enforce tenant access rules at the gateway
This filter has been inert since it was written. resolveOrgId read org:domain:<host> from Redis, nothing ever wrote that key, and the null return fell through t...
Actually enforce geo and IP access rules
The rules were stored, cached to Redis and never consulted. AccessCheckController was the only caller of the evaluation and nothing called AccessCheckController...
Platform registration card for the Zoom Marketplace app
Completes Zoom's one-click connect path. The backend already resolves PlatformOAuthProviderType.ZOOM, but with no card here a platform operator had nowhere to e...
Microsoft Teams Phone provider, front to back
Adds Teams to **************** and wires the whole path through: provider selection, the Entra + Azure Communication Services config, tenant admin consent, the ...
Microsoft Teams Phone as a provider
Teams is not one API, so the provider glues three control planes together: • Graph, app-only — call history (getPstnCalls), presence reads, directory and...
Provider Setup tab and capability-gated meeting settings
Adds the Provider Setup tab to /settings/features/meets and makes every other tab honest about the provider it is configuring. useMeeting no longer builds meet...
MICROSOFT_TEAMS provider type
Appends MICROSOFT_TEAMS to VoipProviderType. The enum persists as ORDINAL on **************** so the position is load-bearing and the constant goes last; the cl...
Route the meeting provider OAuth callback
Zoom and Microsoft redirect the browser to this gateway after an org authorises Kamo's app. The popup lands here with no tenant session — the org travels in ?st...
Meeting provider abstraction with Zoom and Microsoft Teams
Meetings were Kamo Meets by construction — MeetService persisted a Meet room name and nothing else. This introduces the abstraction and two remote providers beh...
Schema for the multi-provider meeting layer
Creates **************** and org_meeting_oauth_tokens, adds the provider-identity columns to MEETING_RECORDS and MEETING_RECORDINGS and the Zoom/Teams-capable s...
Model meetings as provider-agnostic
Kamo Meets was the only possible backend: OrgMeetConfig was a flat Meet settings bag and a MeetingRecord held nothing but a room name. This adds the schema for ...
Allow-list countries on the geo-blocking card
The card could only deny countries, so an org that serves one country had to enumerate every other one. It now has both lists: a mode toggle picks which list th...
Allow-list countries alongside geo blocks
The geo section only ever denied: a country was blocked or it was absent. Orgs that want to serve one country had to enumerate every other one, which is unmaint...
Read quality on adjustments and guideline versions
An assembled price is a base cell PLUS the adjustments stacked onto it, so judging only the cell judges half the number: a cleanly-read 99.875 with a misread -1...
Open links back into this app in the tab the member is already in
Mail in the reading pane opens every link in a new tab, which is right for the whole internet and wrong for us. Our notification emails are almost entirely link...
Per-cell extraction confidence + eligibility-matrix provenance
Two gaps in the confidence model, both on the money path. PER-CELL. A sheet-wide floor is the wrong grain for judging one price: a single badly-read coupon dra...
Show the agent's phone, toll-free and email on the customer's copy
Show the agent's phone, toll-free and email on the preview
Each on its own line: a run-on of two numbers and an address reads as one string and gets dialled wrongly.
Resolve the agent's published contact details
Email comes from the member's primary mailbox rather than TeamMember.emailWork — that column is free text predating mailbox provisioning and routinely disagrees...
Publish every way to reach the agent, not just a name
Name and title alone tell a customer who owns the quote but not how to ask about it. The block now carries email and phone, resolved by the caller — the primary...
Extraction confidence on the catalog spine + auto sign-off basis
A price is only as trustworthy as the sheet it was assembled from, and nothing on the pricing path carried that signal: confidence existed ONLY on pre-promotion...
Quotes tab — every quote across the account's leads
A server-paged DataGrid beside Leads, with search over number and title, status, total range and created-date range. Filters share one debounce and collapse in...
GET /quotes/account/{uid} — paged, filtered, sorted
Dates arrive as ISO strings and parse leniently: a filter the client sends badly should narrow nothing rather than 400 the whole grid. A date-only "to" bound co...
Page and filter an account's quotes in the database
An account view needs every quote across all its leads. Loading them to render a page degrades every month the account is in use, and any total shown would only...
Show the assigned agent on the customer's copy
Matches the staff preview: the letterhead names the org, this names the person to ask.
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.