Expose US state/region from GeoLite lookups
GeoLookupResult gains subdivisionCode/subdivisionName (GeoLite2 subdivision_1 = US state incl. DC; territories PR/GU/VI/AS/MP arrive as countryCode with no usab...
Anonymous GET /portal/assigned-lo — accepting LO identity for the guid's lead
Powers the borrower portal's top-left LO card the moment an LO accepts the lead (pre-login, pre-application): guid header + org host → lead → assignedTeamMember...
'Meet your loan officer' — the borrower hears the moment their lead is accepted
On accept (ASSIGNED), best-effort MEET_YOUR_LO email to the mortgage lead's borrower: the accepting LO's real name + NMLS + email + a continue-application link....
Preferred name fills AKA+first; pool entry publishes the realtime lead event
(1) The funnel's preferred name now writes nameFirstAKA AND stands in for nameFirst until the legal name arrives (owner rule) — it was landing on first name onl...
The lead→application conversion seam — POST /portal/promote
The funnel was a closed loop: nothing ever converted the portal lead into an application (blank mints only — no sourceLead, no seeded fields, no LO inheritance)...
Borrower pricing-quote endpoint — party-gated, integration-config-gated
POST **************** caller must be a loan party (or pipeline steward); resolves the tenant's PRICING_PPE integration — NOT_CONFIGURED / EXTERNAL_VENDOR_PENDIN...
Integrations-status endpoint — the portal's honest view of the org's vendor wiring
GET **************** per-category **************** runtimeVendor from the market integrations config via the runtime resolver. Session-gated; no secrets.
AI vision document extraction — docs → org's vision provider → VerifiedFact(OCR)
The first producer of VerifiedFactSource.OCR: POST **************** reads a vault document (bank **************** ID) with the ORG'S OWN configured vision provi...
ClaimedFactsDTO carries the FULL mortgage lead (35 fields)
Adds the 16 fields the portal structurally couldn't send (monthlyDebts, taxes, insurance, HOA, currentPayment, sellerCredits, renovationCost, borrowerAge, isVet...
Weld the LO chain — portal leads enter the accept-lead pool; accepted LO survives conversion
(1) PortalLeadService routes a portal lead into the credit-based assignment pool (requiresAssignment=true) the moment it has a contact point — portal leads were...
Rebuild against shared-lib (sellerCredits + JsonIgnoreProperties lead DTO tolerance)
Rebuild against shared-lib Phase-4 fields (renovationCost + currentLoanType + LeadFieldPatch)
Rebuild against kamo-shared-library
Pick up LeadListDTO mortgage figures (loan amount/purpose + LTV/DTI inputs) so the /leads grid's Residential-Mortgage columns are served. No code change; CI bui...
Rebuild against shared-lib isVeteran (LeadClaimMortgage col + LeadFieldPatch + mapper)
Internal LOS apply endpoint for inbound sync
POST **************** {leadUid, provider, loXmlFields} — server-to-server (no session/rights). Constant-time X-Internal-Auth check against the cluster internal-...
Lead create/open LOS application endpoints + market-config MLOS fields
Real soft-delete + reactivate-on-upsert for LOS connection; safe test-connection message
I1: view()/testConnection() now read via the shared-lib's active-filtered finder so a soft-deleted (market,provider) connection reads as "not configured" instea...
Market LOS connection service/controller
Phase 3 (Tasks 3.1-3.2) of the MeridianLink external-LOS integration: CRUD + Test-Connection for a market's MeridianLink connection. - MarketLosConnectionServi...
Rebuild to pick up shared-lib mortgage fields (LeadClaimMortgage +6)
Fail the upload if resize fails (no full-size fallback)
Reverts the store-original fallback: if ConversionService cannot resize the image, return 422 instead of storing the full-size original (a huge image would then...
Fall back to the original image when resize fails
ConversionService can native-crash (libwebp-imageio SIGSEGV) or be unavailable, which made every member wallpaper upload fail ("Failed to process image" -> 500)...
Rebuild to pick up shared-lib Organization.bgWatermark
No source change. Triggers CI to re-clone kamo-shared-library main (now carrying the bg_watermark org column added in bc45b97) so the org GET/PUT serialize and ...
Closing-forecast read passthrough (operator-gated, org from session)
Steward passthrough to recompute pipeline-funding P(fund) projections
POST **************** → MlosCapitalMarketsClient (X-Internal-Auth, org stamped from session) → MLOSCapitalMarketsService recompute. Operator-gated like the othe...
Scenario-insights endpoint — LIGHT-tier AI narrative via the org's provider
POST **************** takes a factual (estimated) scenario summary, calls MlosAiClient.text(orgId, prompt, LIGHT) through the org's configured AI provider, retu...
Persist borrower-stated financials + phone onto the mortgage lead
ClaimedFactsDTO gains purchasePrice, downPayment, currentLoanBalance, cashOutAmount and phone; PortalLeadService.applyFacts maps them onto LeadClaimMortgage / t...
Process member uploads like org bg + gate by new rights
- New ImageResizeClient runs member background uploads through the SAME post-processing as org backgrounds (POST **************** and stores the result as ....
Notify the assigned loan officer when a loan's borrower docs are all received
Fires LOAN_DOCS_READY_LO at the satisfy points alongside the borrower DOC_COMPLETE. Resolves the LO via loanFile -> **************** -> Member; self-guarded to ...
Lock the system-managed originator (projection, freeze, assignment)
8 tests over LoanTransactionService: live projection fills name/NMLS/subject-state license + org and marks LIVE; stale hand-entry is cleared when no LO is assig...
Vault upload can deal-scope a document (loanTransactionId)
The vault upload now accepts an optional loanTransactionId, stamped onto the MemberDocument so a time-sensitive doc (credit report / bank statement) can be boun...
Freeze the originator snapshot at initial Loan Estimate (Reg Z/TRID)
Completes the originator lifecycle: a shared resolveProjection() now feeds BOTH the live read projection and the freeze (no drift). On issuing an INITIAL_LE dis...
Surface transactionNumber on TransactionSummaryDTO (pipeline Transaction #)
The per-transaction pipeline row now carries the human transaction number. Verified: mvn compile clean.
Originator projection resolves the per-state license
Completes the live originator projection: the assigned LO's StewardLicense (NMLS_MLO) for the SUBJECT PROPERTY's state (from property.address.subdivision, norma...
Live originator projection — org + assigned LO, on read
GET /mortgage-apps/{uid} now overlays a LIVE, system-managed originator projection (computed on read, never stored) unless the row is frozen: org name/NMLS/addr...
Transaction-level loan-officer assignment + transaction number
ensureTransactionForApp now stamps an org-unique transactionNumber (TXN-<uid>). New **************** + PUT /mortgage-apps/transactions/ {uid}/loan-officer sets ...
Persist mapped Material ID on manual import + API intake
Both setDirectFieldOnCreateRequest switches lack a default case, so an unmapped systemFieldPath is silently dropped. Add a materialId case to the manual-import ...
Include both desktops in every SSO token, deep-link to the chosen one
Each token carried only its own connection, so the browser's reused json session lacked the other one -> opening Windows after Linux gave 'connection does not e...
Route borrower submit through the pipeline so it fires **************** (audit #3)
patchLoanFile's borrower submit (DRAFT->APPLICATION_TAKEN) now calls **************** instead of a raw updateLoanFile status set, so the submit produces the has...
Resolve session from X-***-Token header in CallerSessionResolver
The kamo-internal -> APIService BFF path forwards the session as the X-***-Token header, but the resolver only read the X-OTK attribute or the *** cookie — so B...
PatchLoanFile is no longer a status backdoor; unblocking a condition needs the underwrite right; clear cascades
**************** status changes are the pipeline state machine's job (POST /transitions enforces legal arrows + per-arrow role gate + open-blocking-condition ga...
Inject KamoDesktop SSO env directly + wire guac-sso into tracked k8s deployment
- @Value reads KAMO_GUAC_SIGNING_KEY / DESKTOP_PASSWORD from env directly (runtime application.yml is configmap-mounted, so property indirection wouldn't bind...
KamoDesktop SSO token endpoint for god members
GET **************** (god-eligible only) mints a 5-minute guacamole-auth-json token (HMAC-SHA256 + AES-128-CBC, per the extension's wire format) and returns an ...
Borrower submit fires the Application-Taken side effects (doc checklist + notify)
The portal borrower submit is PATCH loan-file {statusId:2}, which bypassed the operator /transitions endpoint where the Application-Taken side effects live — so...
Borrower cannot escalate loan-file status or edit the URLA after submission
Two related borrower-authorization holes on the self-service app endpoints: - Privilege escalation (#2): patchLoanFile applied any statusId with no caller-ri...
Borrower self-create idempotency + orphan compensation; don't relay an empty checklist as success
MortgageAppController.create() borrower self-create branch: - Idempotency (#2): resume an existing owned DRAFT via findOwnedDraft instead of minting a duplica...
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...
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.
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...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.