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...
Remove "Not available to you" section
Stop surfacing nav features a member lacks access to. The Navigation Layout page listed every hidden nav option as locked chips; dropped the block along with th...
Generic byte endpoints refuse MLOS per-party docs (vault/loan)
The generic imaging byte endpoints (download / stream / bulk-download / thumbnail) and the binder aggregation authorized only on org + a numeric clearance ceili...
Integrate primary tabs into the header on remaining Style A pages
Follow-up to the Style A→B sweep, covering pages that don't route through SettingsView: - /kb: KbNavBar becomes a gradient hero header with the Articles/Resour...
Center the vendors-products status snackbar at top
The save/update status pill used MUI's default anchor (bottom-left, no anchorOrigin set) so it rendered off-center. Anchor it top-center.
CreatePair is idempotent for the primary pair (stops duplicate BorrowerPairs)
createPair's sole caller is the wizard's 'ensure primary borrower', but it unconditionally inserted a new pair every call, so a concurrent autosave + explicit S...
Relocate bottom count bars into the header across social, imports tabs
Applies the vendors-tab treatment to the sibling CRM settings surfaces so the standalone "x • y" summary bar at the bottom no longer eats page real estate: - S...
Don't serve soft-deleted documents on /stream and /bulk-download
getDocumentMetadata (used by the stream + bulk-download byte paths) does not filter trashed rows the way downloadDocument does, and a soft delete leaves the Min...
Move vendor/product count above the header actions, bottom-align Refresh + Add Vendor
Recaptures the page real estate the standalone bottom summary bar used to occupy — the "x vendors • x products" line now stacks above the action buttons in the ...
Integrate primary tabs into the page header (Style B) across Style A pages
Every gradient-hero page that rendered its primary tabs in a separate card below the header now renders them inside the gradient header itself, matching /accoun...
Add missing Next.js proxy routes for MLOS default-product + readiness
The vendors-products page threw 'Failed to set default product:' because the frontend PUT to **************** (and GET lead-vendors/mlos-readiness) 404'd — thos...
Back arrow in header returns to /leads
Add an optional backHref/backTooltip to SettingsView that renders a white back arrow left of the title, and wire the CRM settings page to send the member back t...
Raise NavPri z-index above NavTop so the rail overlays the top bar when it expands/peeks
Bold 'CRM Settings:' prefix, pipe separators, hover-only underline on tab links
Preface the CRM settings tab links with a bold 'CRM Settings:' label (new **************** key), separate links with ' | ' instead of a bare space, and switch t...
Add CRM settings tab links above refresh, gated like settings menu
Render a right-aligned row of white, underlined, space-separated links to each /settings/features/crm tab above the Leads header refresh button. The links reuse...
Correct trial pill remaining-time (was 20644d)
When NavPri was rewritten the minute-tick was changed from Date.now() to a counter starting at 0, and that counter was passed as the `now` argument to formatTri...
Reset button in the title row (right) + full-width content
- "Reset to Standard" now sits on the same row as the "Navigation Layout" heading, right-aligned, with the heading left-aligned (moved out of the footer). - T...
Create mlos_doc_req_borrower_idx for the vault cross-loan reuse query
Index (borrower_uid, organization_id) for vault cross-loan reuse query
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.
