Add Manage Own / Others Background Images rights (General group)
Adds MANAGE_OWN_BACKGROUND_IMAGES (165) and **************** (166) to RoleRightType, serviceType null so they land in the General settings group (mirrors the ST...
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 ...
LOAN_DOCS_READY_LO canonical template — notify assigned LO when a loan's docs are all in
Assign a loan officer to a deal from the originator section
The read-only Loan Originator section now has a loan-officer picker (org members via /members/names) + Assign, calling PUT **************** at the transaction l...
Provider config fields for cloud mail access
Add the config inputs the EmailService resolver reads to authenticate cloud mailboxes: - Google Workspace: service-account key (JSON) for domain-wide-delegation...
Route all cloud providers' mail through IMAP/SMTP with OAuth2 (XOAUTH2)
Cloud providers (Microsoft 365, Exchange Online, Google Workspace, Zoho, IceWarp) inherited read/send from **************** but the resolver never populated IMA...
Deal-scope a vault upload from the account documents tab
The upload dialog now offers an optional "Deal" selector (the account's transactions); choosing one stamps loanTransactionId so a time-sensitive doc (credit rep...
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...
Per-device background switch — plain gradient or org photo slideshow
Adds a two-icon switch top-right (under the trial pill; it rises into the pill's place once the trial ends) to choose the console background: - Plain gradient (...
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...
Transaction-first pipeline — PrimeReact expandable rows
Replaces the flat loan grid with a PrimeReact DataTable of TRANSACTIONS that start collapsed and expand IN PLACE to their member loans (no two-click drawer), so...
Re-add the trial pill top-right (color-swapped NavPri pill)
Keeps the trial line in the masthead status strip and re-adds a prominent pill in the top-right so an org's trial mode stays obvious. It's the NavPri expanded t...
Live "insert between" while dragging, not just drop-to-swap
Previously the order only changed on drop, so it read as swapping into a slot. Now the list re-flows live as you drag: dnd-kit onDragOver moves the dragged opti...
Sibling-loan switcher on the application view
A transaction can group multiple loans; the app header now shows a switcher to jump between the deal's sibling loans (hidden for single-loan deals) instead of o...
LoanFileDTO.loanTransactionId (app view knows its deal)
Surfaces the loan's transaction so the /applications view can show/switch sibling loans. Verified: mvn install clean.
**************** (FE type)
Mirrors the backend field for the pipeline Transaction # column. Verified: tsc --noEmit clean.
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...
Drag-and-drop to rearrange launchpad options, saved per member
Members can now reorder their home options by dragging, and the arrangement is persisted server-side per member (survives reloads and follows them across device...
Make Materials the first tab + default landing; remove Overview
Overview tab removed; Materials is now first. The /marketing index redirects to the first accessible tab (Materials by default), so anyone opening Marketing lan...
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...
Loan Originator section is read-only / system-managed
The Loan Originator card no longer hand-edits URLA §9 data (the duplication of **************** it was re-capturing). It renders read-only: a LIVE projection of...
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 ...
Originator/transaction-first columns (@Order 90)
Additive nullable columns + org-unique transaction-number index for the MLOS originator/transaction refactor: mlos_loan_transaction (transaction_number + assign...
Originator/transaction-first schema — LO assignment, WORM freeze, deal-scoped docs
Backbone for the system-managed-originator + transaction-first refactor (spec 2026-07-08): - LoanTransaction: transactionNumber (org-unique) + assignedLoanOffic...
Add Product filter dependent on Vendor
Adds a Product filter to the /leads filter bar, immediately right of the Vendor filter. It behaves like the Status/SubStatus pair: disabled until a vendor is se...
Shared AusEngineClassifier — one source of truth for the §8.2 agency mapping
The program→engine, run→engine, and decision→gate mappings were local to **************** The capital-markets lock-stage AUS hard-stop needs the identical class...
AI auto-tag + caption UI; provider cost-tier/vision settings (P3)
Settings → AI → Providers: each provider gains a Cost tier (Light/Medium/Heavy) select and a Supports vision toggle (+ list chips). Materials drawer: 'Suggest t...
Provider cost-tier/vision passthrough + internal one-shot vision endpoint
AiProviderController reads/echoes costTier + supportsVision. ProviderRoutingService gains selectVisionProvider(orgId, tier). **************** runs a one-shot vi...
AI auto-tag + caption via org's providers (P3)
MaterialAiController POST **************** verifies ownership, mints a short-lived signed material URL, and calls AIService's internal vision endpoint (org's ow...
AiProvider cost tier + vision flag (two orthogonal capability axes)
Adds costTier (LIGHT/MEDIUM/HEAVY via new AiProviderTier enum) and supportsVision boolean to AiProvider, so integrations can pick how expensive a provider to us...
Server-side "display external images" consent
Replaces the client-local (localStorage) remembering of the external-image choice with a durable per-member record. New RemoteImageConsentService (fail-soft rea...
EmailRemoteImageConsent entity + repository
Member-scoped record that a member has chosen to display external (remote) images for a specific message, keyed by member_id + normalized RFC Message-ID (unique...
Add INVESTOR_PRICE column to rate_locks + loan_pricing_snapshots
@Order(80) idempotent ADD COLUMN IF NOT EXISTS (DECIMAL(9,4), matching the price-to-100 grids) so the MLOS RCE can record the true non-par investor execution pr...
Record the true non-par investor price on RateLock + LoanPricingSnapshot
The binding rate-lock-of-record and its bound quote carried only rate + lockDays; discount/origination points were left null, so the core entities read PAR whil...
Let admins connect RingCentral on a member's behalf
On another member's phone settings, an admin with manage-VOIP rights (canManageVoipConfig) now sees Connect/Reconnect/Disconnect for the member's RingCentral ac...
Allow admins to connect RingCentral on a member's behalf
The per-member RingCentral flow was self-serve only, so an admin managing another member's profile saw "they must connect it themselves". Sysadmins commonly cre...
Usage analytics + Insights view (P2)
Records **************** events and an Insights dialog with org totals + the most-used materials (by downloads + previews).
MaterialAnalyticsController — record events + aggregates
POST **************** (record) + GET /analytics (per-material counts by type + org totals).
MaterialEvent entity+repo (usage analytics)
Append-only usage events **************** with a per-(imgId,type) aggregate query. Table MATERIAL_EVENTS (targeted CRDB DDL; KI auto-scans).
Approval workflow UI + load-all filtering (P2)
Status control in the drawer **************** status badge on tiles, and a status filter in the toolbar. Also loads all material pages up-front (capped) so sear...
MaterialReviewController — status map + set-status
GET /api/media/materials/reviews (org-wide imgId→status map) + POST to set a material's status (validated, reviewer-stamped, upsert).
MaterialReview entity+repo (approval status side-table)
DRAFT/PENDING/APPROVED/ARCHIVED per material, keyed by imgId (imaging schema untouched). Table MATERIAL_REVIEWS (targeted CRDB DDL; KI auto-scans).
Per-member RingCentral connect + softphone web-phone v2 fixes
Softphone SDK fixes (ringcentral-web-phone is v2.4.0, not the v0.x the adapter targeted — the old wp.userAgent.* usage threw on init): - Rewrite RingCentralPhon...
Per-member RingCentral OAuth identity + softphone SIP fixes
Softphone SIP credential fixes: - getSipCredentials: map outboundProxyBackup + stunServers (web-phone v2 needs them for WSS failover + ICE/media); throw Provi...
Add MemberVoipOAuthToken for per-member RingCentral connections
Per-member OAuth token keyed (memberId, provider, instanceId) backing extension-scoped RingCentral operations — softphone sip-provision plus the member's person...
Collections/campaigns UI (P2)
Left-nav Collections section (create/select/delete), campaign filter on the collection view, and a collections editor in the detail drawer (add/remove material,...
MaterialCampaignController — CRUD + item map + add/remove
/api/media/materials/campaigns: list/create/update/delete, GET /items (org-wide imgId↔campaignId map), POST /add + /remove with org-ownership checks.
MaterialCampaign + item entities/repos (collections)
First-class named collections grouping materials across folders. Tables MATERIAL_CAMPAIGNS + MATERIAL_CAMPAIGN_ITEMS (targeted CRDB DDL; KI auto-scans on next r...
Tags UI + access-level control (P2)
Tags (org-scoped, cross-cutting): tag chips on tiles, a tag filter bar (AND across selected), and a tag editor in the detail drawer (assign/remove existing, cre...
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.
