Add logging to upload-background proxy route
Log org/index, file name/size/type, and upstream response status to diagnose why background uploads are not reaching APIService.
Add Location column to ticket datagrid
Reads **************** straight off the SupportTicketDTO (now snapshot on the ticket entity at creation time — no extra round trip). Renders flag + city/region/...
Pass folder to loadThread retry button
loadThread takes (threadId, folder); the error-state retry button only passed threadId, breaking the kamo-internal build. Match the call to the signature.
Per-ticket unread badge + 'New messages only' filter
- Ticket list shows a chat-bubble badge with the unread count next to ticket# whenever the session has messages newer than the agent's last viewed message. ...
Clear unread indicators when conversation is opened
ThreadDetailView now dispatches email:folder-changed after markConversationRead succeeds so MailButton refetches the navtop inbox badge count. ConversationListV...
Break min-w-0 chain to contain email scroll in body column only
Add min-w-0 to outer container and main content flex div so flex children cannot expand to email min-content width, which was causing the page-wide horizontal s...
Hoist providers above ToolProviders
Same root cause as the ChatWebSocketProvider hoist: SupportTicketWindow calls **************** and ChatBox calls useUnread().markAsRead(), but both tool windows...
Remove debug console.log statements and add missing routes
Remove all temporary debug logging added during WebSocket tracing from ChatBox, TicketChat, MemberItem, ChatTool, and useChatWebSocket; add redirect pages for /...
Prevent message header from expanding column on long addresses
The header's left flex child had no min-w-0, so long unbreakable email addresses in From/To/Cc forced its min-content width to grow, dragging the header (and th...
Hoist ChatWebSocketProvider above ToolProviders
ToolDock (and its tool windows like SupportTicketWindow → TicketChat) is mounted inside ToolProviders, which sits ABOVE PresenceWrapper in the tree to avoid unm...
Drop Shadow DOM in email renderer so overflow-x-auto fires
Shadow DOM was the root cause. Wide email content (fixed-width tables) inside the shadow tree painted past the host without contributing to the host's layout bo...
Align ChatWebSocketContext import path to match provider
TicketChat and ChatNotificationListener imported the context via the '@/app/contexts/...' alias while PresenceWrapper (the provider) imports it via the relative...
Temporary console.log to trace TicketChat STOMP subscription path
Adds console logs at every stage of the subscribe pipeline (effect fire, guard pass, subscribe() call, attachSessionSubscription, client.subscribe, /app/chat/su...
Force shadow host containment with inline styles + contain: layout
Class-based overflow-x-auto on the shadow host wasn't reliably winning against the shadow ':host { all: initial }' reset, so wide email content (fixed-width tab...
Scroll wide email content inside shadow DOM, not outside
The previous attempts at adding overflow-x-auto to light DOM ancestors could not catch wide email content because the shadow tree's visual paint overflow does n...
Add min-w-0 to email content div so overflow-x-auto fires
Without min-w-0, the flex-col child's default min-width:auto resolves to min-content, letting wide email tables expand the div past the column width. The outer ...
Close reconnect gap causing dropped real-time messages
Remove `connected` from subscription useEffect deps in TicketChat and ChatBox. Previously, every WebSocket reconnect triggered the effect cleanup which called u...
Contain horizontal overflow in email view pane to 3rd column
- Add overflow-x-hidden to MessageBrowser outer container as hard boundary - Add overflow-x-hidden to column 3 wrapper and overflow-x-auto to email content area...
Pre-populate FROM on reply/forward and fix send fromAddress
- DraftMessage now carries fromAddress so it flows from openNewMessage through to the composer - MessageBrowser stores the active mailbox emailAddress (includ...
Sub-tab content fills full content-area width
Drop the centered max-width constraint (was 920 / 1200 / 680 / 720 depending on tab) on SubTabShell. The page already lives inside SettingsView's content column...
Add download button to classic view attachment section
The classic view (MessageBrowser) had its own attachment list that was missing the download button — only the conversation view was fixed previously. Also align...
Proper layout, padding, and provider logos
Layout / spacing fixes: - All six tabs (Providers, Extensions, Phone Users, Devices, Voicemail, Health) now wrap their content in a TabShell with px:{xs:2,md:...
Load FROM addresses from accessible mailboxes and aliases
Replaces the broken getFromAddresses() endpoint (which sent 'email' instead of 'address') with getAccessibleMailboxes() + listMemberAliases(), matching the same...
Platform configuration tabs (General / VOIP & SMS / System User / Advanced)
Wraps **************** in SettingsView with four tabs: - General: read-only platform overview — total orgs, active phone-server instance count, active SMS-pr...
Add attachment download button and decouple mark-as-read
- Add a Download icon button to each attachment row so users can force a file download instead of only opening in a new tab - Decouple markConversationRead fr...
Parse formData before forwarding to prevent binary corruption
request.text() on multipart/form-data corrupts binary file bytes; pass parsed FormData as init.body so forwardToApi skips request.text() and lets fetch regenera...
Remove minHeight:100vh causing double scrollbars
The outer box's minHeight:100vh exceeded the layout's calc(100vh - 56px) container, which caused both the browser-level scroll and the inner overflow:auto to be...
Drop editor page header, rename General sub-tab
- Removes the back-arrow IconButton + shield icon + title + subtitle from the top of the security-model / master-model editor. The Cancel button in the stic...
Drop stale Pay column header from security-models table
When the Employee Self-Pay Kamo Fees field was removed, the matching TableCell in the row body was deleted but the header row still had the '<TeamMember> Pay' c...
Censorship sub-tab now renders ATF first per spec
Reorders the Censorship sub-tab cards to match the requested order: 1. Alcohol, tobacco & firearms 2. Allowed Member Age Ranges 3. Allowed Employee (Team ...
Platform-admin view, pagination, live search, filters, org logos
Platform admins (top-level org owner) now see every org in the system via the new /api/security/org/all-networks endpoint instead of just their own memberships....
Sub-tabs in security-model editor + cleanup
- Security-model editor on **************** is now split into four sub-tabs: General (Basic Info, Visibility, Who Can Create, Platform Settings, Domain Conf...
Remove duplicate ?type= from apiPath
forwardToApi already appends incomingSearch (?type=...) from the original request URL. Embedding ?type= a second time in the apiPath produced ?type=full?type=fu...
Restore mailbox switcher for int64 member IDs
Use getMemberIdString for mailboxes/member fetch, normalize id/mailboxId from EmailService, and drive the switcher from accessible personal mailboxes when avail...
Alias visibility UI + Subdomain Branches button on branch-types page
SubdomainBranchesDialog: - Alias editor replaced chip list with a table-style row list showing Members and Team Members checkboxes per alias — admins control ...
Cache-bust logo URLs using themeRevision from config.json
DynamicMetaLoader now stores themeRevision in sessionStorage and fires KAMO_THEME_CONFIG_LOADED after fetching config.json. ThemeLogo listens for that event and...
Settings dialog, web-alias wizard path, and DNS provisioning panel
Adds the Subdomain Branches UI across three surfaces: - **************** new "Subdomain Branches" button opens a dialog for the org-level enable toggle + ...
Mailbox checkbox reads org_domains, not provider domains
The previous wiring read /api/email/domains (email_provider_domains table). That table is only populated when a third-party email provider integration is set up...
Prefix/suffix dropdowns, mailbox domain gate, explicit status
- Name prefix and suffix are now dropdowns populated from the NamePrefixType / NameSuffixType catalogs delivered by the org-config endpoint. Displays abbrev...
Unwrap {markets:[...]} envelope in Attach dialog
GET /api/security/commerce-markets returns { markets: [...], message: "..." }, not a bare array. The Attach Commerce Market dialog was treating the whole respon...
Full-width, three-pane Add Member form layout
Reworks the create form to use the entire content area instead of a 1100px-wide centered column. - 3-column responsive layout: sticky left section nav (md+), f...
Merge OTK-redirect into proxy.ts, delete duplicate middleware.ts
Next.js 15 refuses to build when both middleware.ts and proxy.ts exist. The OTK hand-off redirect that lived in middleware.ts — sending any request with ?otk=… ...
Read new *** from Redis master and dedupe OTK POST
Replica reads missed freshly written sessions after OTK exchange, causing false failure and login redirect. Skip intro delay when otk is present; share in-fligh...
Guard against non-array responses on /platform/orgs
A non-array response (empty body, error envelope, or {data: [...]} wrapper) was landing in the orgs state and blowing up the render with 'e.map is not a functio...
Open /validate for enter-as OTK so target org session applies
ENTER linked to /?otk= which never called /api/validate; shared-domain *** cookies kept the source org. Redirect ?otk= to /validate via middleware for any stray...
Add BFF route for POST /api/security/enter-as
The /network Enter action called a non-existent Next route, yielding 404. Forward the request to APIService like other security proxies.
Proxy system-user config API routes to APIService
Configuration page called /api/security/system-user/* but no Next handlers existed, so the app returned 404. Add BFF routes matching SecurityService endpoints (...
System User Configuration page + network ENTER AS SYSTEM MEMBER
Adds Platform Administration → Configuration, a parent-org-owner-only page that grants or revokes permission to impersonate the platform System User by departme...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.