Lead callback endpoints (schedule/list/resolve)
New **************** controller + service: persists the callback, posts scheduling/outcome notes into the lead's media stream, and mirrors the callback onto the...
Add LeadCallback entity, status enum, and repository
Backs the lead-view callback feature: a lead-owned callback record (PENDING/CONTACTED/CANCELED) keyed off leadUid, with a soft reference to the mirrored EmailSe...
Explain why the MLOS default-lead-source control is hidden instead of silently dropping it
On the vendors-products tab the "designate default lead product" control is gated on mortgage-vertical readiness — POS enabled, an active MORTGAGE commerce mark...
Rebuild against shared-lib dbNow() CAST fix
Empty commit to trigger CI, which clones kamo-shared-library at build time and picks up the **************** dbNow() CAST(now() AS timestamp) fix.
DbNow() use CAST(now() AS timestamp), not now()::timestamp
The ::timestamp shorthand is mangled by Hibernate's native-query parser (it reads ':' as a named-parameter prefix, turning ::timestamp into :timestamp) -> CRDB ...
Create a session for group chats opened by memberIds
ChatTool ignored props.memberIds: a group open arrived with an empty userId and no sessionGuid, so the 1:1 createSession bailed early and the window never got a...
Stop duplicate chat popups for the same conversation
The tool-window dedup only exact-matched a single userId key against an async-mirrored windowsRef, so the same 1:1 chat opened twice: - userId from a member ro...
Rebuild against kamo-shared-library rights-waterfall fix (5f20d29)
CI clones and builds kamo-shared-library from source, so this empty commit re-triggers the build to pick up the layered rights resolution. On boot the MemberRig...
Show all enabled-app permission groups in job title & department editors
JobTitleManager and DepartmentManager only ever rendered two permission groups — General and CRM — so **************** rights were invisible and uneditable ther...
Resolve member rights as a true waterfall instead of NUKE-always-wins
Effective rights were computed by folding every source (roles, department, job title, member) into one map where NUKE always won. That meant a member holding bo...
Revert securityProvider to self-pointing; self-heal member applied rights
Two prod issues from the securityProvider-mirror change: 1. Enter-as-System-Member failed with "No membership in the organization's security provider" for e...
Refresh provider status when OAuth popup closes
The provider now redirects to the api-gateway callback (a different origin), so its postMessage may not pass the opener origin check. Re-fetch real provider sta...
Public passthrough for email OAuth provider callback
Forward GET **************** to EmailService sessionlessly (strips auth, no redirect following), mirroring the RingCentral OAuth callback. This is the fixed pub...
Fixed public redirect + gateway-forwarded callback
Platform email OAuth (Microsoft 365 / Google / Zoho) had no valid public redirect URI: the redirect was derived from the request host, which in prod is the clus...
Serve e-sign editor PDF for any converted doc, incl native PDFs
The e-sign editor (DocumentEditor → PdfCanvas / PageThumbnailSidebar) opens any converted document, not only files uploaded through the sig-template flow. It fe...
My Docs uses MY_DOCS ordinal (3), not enum id (4)
The backend resolves ImageAssocType via `values()[assocType]` (ordinal index) and persists it @Enumerated(ORDINAL). Every imaging surface passes the ordinal, bu...
Convert deduplicated documents so e-sign edit is enabled
When an uploaded file's bytes matched an existing ImgDat, the dedup path (register-existing) reused that dat verbatim and never ran the conversion pipeline. If ...
Return 200 allFalse for unconfigured org capabilities
GET /api/voip/capabilities threw ProviderNotConfiguredException (422) when an org had no phone provider, logging a red console error on every page load for phon...
Stop 404/422 console errors for un-customized nav and phone-less orgs
Read the ui-preferences collection endpoint (always 200) for the initial navLayout load instead of the single-key GET, which 404s when a member has never custom...
Proactively provision browser-only aliases (media.*)
The log-scan discovery mechanism can never bootstrap the `media` alias: it is only ever contacted by the browser over a WebSocket/XHR subresource (SockJS /ws/in...
Gate lead contact-info by assignment + new privacy rights
Mirror the three new CRM rights. On the lead detail page, mask/lock the Primary Contact, Mailing Address and Property Address fields for leads not assigned to t...
Enforce lead contact-info privacy rights
getAllLeads now returns the lean LeadListDTO and hides unassigned leads from members without VIEW_UNASSIGNED_LEADS. getLeadById masks contact info (state preser...
Lead contact-info privacy rights + lean list DTO
Add three CRM rights (161-163): "Assigned To Others: View/Edit Lead Contact Info" and "View Unassigned Leads". Add LeadListDTO — a lean projection for the /lead...
Interpret lock LAST_EDIT_AT as UTC for epoch-millis expiry
dbNow() now returns DB-UTC wall-clock (now()::timestamp), so recover the absolute instant with toInstant(UTC) instead of the JVM default zone — keeps the browse...
DbNow() cast now()->::timestamp (TIMESTAMPTZ->Instant broke LocalDateTime)
SELECT now() returns TIMESTAMPTZ, which Hibernate materializes as java.time.Instant and cannot cast to the declared LocalDateTime return type — throwing ClassCa...
Send membership type from the /member and /team paths
/team signups create a TEAM_MEMBER (created PROSPECT, pending admin activation); /member signups create a MEMBER. RegisterFlow takes a memberType prop supplied ...
/team creates a TEAM_MEMBER (PROSPECT), /member creates a MEMBER
Public registration now honors the memberType the register site sends (from the /member vs /team path): /team creates a TEAM_MEMBER — as PROSPECT, so an admin m...
Agent filter shows member name + phone extension, not email
The Agent dropdown labelled each teammate with their email because the loader read firstName/lastName keys the backend never sends (it sends nameFirst/nameLast/...
Expose team-member work phone extension in team-members-contractors
The /leads Agent filter needs the work-phone extension to label options as "Name (ext 8080)". The extension already exists on TeamMember (getPhoneWorkExtension)...
Request-support popup shows parent-org shared topics
Point the ticket-creation topic dropdown at the new /api/support/topics/available endpoint (own-org + parent-shared topics) so child-org users can contact their...
Surface parent-org shared topics in request-support popup
Child-org users could not see their parent org's shared support topics (assignToOwnOrg=false) when requesting support, because the popup only fetched own-org to...
Correct inverted parent-shared topic query
The child-org topic query filtered on assignToOwnOrg=TRUE (own-org-only) when it should return topics SHARED with child orgs (assignToOwnOrg=FALSE). Rename the ...
New child orgs inherit their parent's securityProvider
When creating a child org from kamo-internal, set the new org's securityProvider to the parent org's securityProvider (the org it's created under) instead of le...
Show account-linked notice on ?linked=1
When register links an existing account to a new org, it redirects here with ?linked=1. Show "You already have a Kamo account — we've added this organization to...
Handle account-linked response for existing users
When the entered email already belongs to an ACTIVE account, the backend links this org to it and returns ACCOUNT_LINKED. Route those users straight to sign-in ...
Wire up member/team-member create + Prospect-gate UI
- Add the missing POST proxy routes /api/security/members/create and /create-team-member (these 405'd before, so creation never reached the backend). Status...
Reuse existing users, mirror to securityProvider, gate team-member sign-in
Reuse (no duplicate accounts for the same person): - MemberCreateController now reuses an existing user by personal email case-INSENSITIVELY (was case-sensiti...
SecurityProvider membership mirror + reuse/patch groundwork
- **************** userId): mirror a user into the org's securityProvider org as a base Member (deduped; no-op when the org secures itself or the user is al...
Send the registrant's hostname in the body so the account lands under the right org
The resolved org was available on the client but never sent to the backend — the org was conveyed only implicitly via X-Forwarded-Host, which the ingress rewrit...
File new accounts under the org of the domain, not kamocrm
/register bound the new member's org to the request Host, but the org signal never survived the hop: kamo-register proxies every signup to the shared api.kamocr...
Resolve org-by-domain with a deepest-label alias fallback
Add **************** exact domain match, then drop the deepest label once (register.optionone.com -> optionone.com) so a per-org register/branding subdomain res...
Stop viewport shaking on browsers with classic scrollbars
On machines whose Chrome uses layout-consuming (non-overlay) scrollbars, the login/recover pages fidgeted with both scrollbars flickering. Root cause: the root ...
Wire Tasks tab to real backend + delete action + live count
Adds the Next proxy routes for /leads/{id}/tasks[/{taskId}] (the tab's getTasks/ addTask/updateTask/completeTask calls were 404ing), a deleteTask action in the ...
Lead tasks REST API + real-time TASK_CHANGED
Implements the backend the /leads/view Tasks tab was already calling but that never existed: GET/POST/PUT/DELETE **************** (LeadTaskController + LeadTask...
LeadTask entity for lead follow-up tasks
Backs the /leads/view Tasks tab (previously a frontend-only stub with no persistence). LeadTask (table LEAD_TASK) mirrors the frontend TaskItem shape **********...
Real-time datagrid + live lead view with per-pane edit locks
/leads grid is now fully live over websocket (NATS→STOMP): rows add/remove/update against the active filter automatically and changed cells blink once for other...
Org-guard the /topic/leads/rt/{orgId} realtime subscription
Cross-tenant SUBSCRIBE guard for the new lead real-time topic, mirroring the existing /topic/social/feed guard: a member may only subscribe to their own org's l...
Per-pane edit-lock REST API + auto-save sweeper
Adds /api/security/leads/{id}/locks **************** backed by LeadLockService: exclusive per-pane reservation, draft-buffering heartbeats that reset a 5-min id...
Real-time NATS publishing + per-pane edit-lock entity
Publish org-scoped lead events on security.leads.rt.{orgId} (created/updated/ deleted with changed-field keys, history-appended) so the /leads grid and /leads/v...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.