Allow-list countries alongside geo blocks
The geo section only ever denied: a country was blocked or it was absent. Orgs that want to serve one country had to enumerate every other one, which is unmaint...
Read quality on adjustments and guideline versions
An assembled price is a base cell PLUS the adjustments stacked onto it, so judging only the cell judges half the number: a cleanly-read 99.875 with a misread -1...
Open links back into this app in the tab the member is already in
Mail in the reading pane opens every link in a new tab, which is right for the whole internet and wrong for us. Our notification emails are almost entirely link...
Per-cell extraction confidence + eligibility-matrix provenance
Two gaps in the confidence model, both on the money path. PER-CELL. A sheet-wide floor is the wrong grain for judging one price: a single badly-read coupon dra...
Show the agent's phone, toll-free and email on the customer's copy
Show the agent's phone, toll-free and email on the preview
Each on its own line: a run-on of two numbers and an address reads as one string and gets dialled wrongly.
Resolve the agent's published contact details
Email comes from the member's primary mailbox rather than TeamMember.emailWork — that column is free text predating mailbox provisioning and routinely disagrees...
Publish every way to reach the agent, not just a name
Name and title alone tell a customer who owns the quote but not how to ask about it. The block now carries email and phone, resolved by the caller — the primary...
Extraction confidence on the catalog spine + auto sign-off basis
A price is only as trustworthy as the sheet it was assembled from, and nothing on the pricing path carried that signal: confidence existed ONLY on pre-promotion...
Quotes tab — every quote across the account's leads
A server-paged DataGrid beside Leads, with search over number and title, status, total range and created-date range. Filters share one debounce and collapse in...
GET /quotes/account/{uid} — paged, filtered, sorted
Dates arrive as ISO strings and parse leniently: a filter the client sends badly should narrow nothing rather than 400 the whole grid. A date-only "to" bound co...
Page and filter an account's quotes in the database
An account view needs every quote across all its leads. Loading them to render a page degrades every month the account is in use, and any total shown would only...
Show the assigned agent on the customer's copy
Matches the staff preview: the letterhead names the org, this names the person to ask.
Show the assigned agent on the preview
A "Your contact" panel above the footer — name, title, phone and email — so the customer knows who to ask about the price. Absent entirely when the lead is unas...
Resolve the agent alongside the customer, from one lead lookup
Both blocks come off the same lead, so the controllers fetch it once and derive each from it rather than hitting the service twice per render. Still org-scoped ...
Name the lead's assigned agent on the document
The letterhead identifies the org, but a customer with a question about a price needs the person who owns the relationship. The quote now carries the lead's ass...
Reassign the agent holding an opportunity
The approver's dialog gains an agent picker, drawn from the same pool the backend validates against. The grid's Agent column now shows who HOLDS the opportunity...
Reassign the holding agent, and email everyone it affects
An approver can now hand an opportunity to a different agent. The requester is never rewritten — applyPrimaryAgent records the move as its own history row with ...
Preview samples for the nine opportunity notifications
Without an arm here the admin Email Templates editor renders every placeholder blank, so anyone customising these nine would be editing an empty skeleton. One ...
Reassignable primary agent on a reserved opportunity
PRIMARY_AGENT_MEMBER_ID is who holds the opportunity now; REQUESTED_BY_MEMBER_ID is left untouched forever. Nullable with no backfill on purpose — null means "n...
Reassignable primary agent, and nine notification templates
An approver can hand an opportunity — and the commission with it — to a different agent. PRIMARY_AGENT_MEMBER_ID is who holds it now; REQUESTED_BY_MEMBER_ID is ...
Overall commission, market defaults, and no pre-picked units
Three changes to how commission is captured. Nothing is pre-selected any more. Percent/Amount and One-time/Recurring both start unset on every commission split...
Agree an overall commission at approval, seeded from the market
The approver now records what the organization pays on the sale to the requesting agent and their group. Omit it on approve and the lead's market default applie...
Commission columns for reserved opportunities and market defaults
Six nullable columns: the overall commission agreed on a reserved opportunity, and the market default that pre-fills it at approval. NUMERIC(19,4) to match the ...
The overall commission on a sale, and market defaults for it
A reserved opportunity now records what the organization pays out of the sale to the requesting agent and the group they share with — the pot the per-colleague ...
Render the client's details on the preview, from the lead
Removing the quote's own addressee fields left "Prepared for" blank, because customerName only ever came from a linked Account and lead-raised quotes have none....
Show the client's details on the customer's copy
Company heads the block when there is one — a quote to a business is addressed to the business, with the contact named beneath it. Matches the staff preview exa...
Resolve the addressee lead for both the staff and customer views
Org-scoped in both places. On the public page the scope comes from the share link's own organization, so a token can never surface a lead belonging to another t...
Put the client's details on the document, read off the lead
Dropping the quote's own addressee fields left the document with nothing to say about the client: customerName only ever came from a linked Account, which lead-...
Move quotes out of commerce and onto the lead
Quotes sat in the commerce pipeline, beside orders and carts rather than beside the client they are for. They now live on the lead: a Quotes tab directly after ...
Expose per-market quote settings; enforce the terms grant
market-config now tells the lead view whether to offer a Quotes tab and what wording a new quote starts with, and the market endpoints round-trip both fields. ...
Quotes belong to leads, configured per market
Quotes were a commerce-pipeline artifact, which put them beside orders and carts rather than beside the client they are for. They now hang off the lead: the mar...
Reserve, approve and audit lead opportunity claims
REST surface behind /leads/opportunities/reserved and the Reserve Opportunity control in the lead header, plus the service that owns the invariants. Rights, en...
Tables for lead opportunity reservations
Mirrors LeadOpportunityReservation, LeadOpportunityCommissionSplit and **************** in kamo-shared-library. ddl-auto:update would create them from the entit...
Entities for time-boxed lead opportunity reservations
An agent stakes an exclusive claim on closing a lead for a bounded window; an approver grants, edits or denies it, and colleagues can be offered a share of the ...
Address the quote to a person; summary stops costing header height
Moving the summary out of the right-hand column fixed the width but bought it back as a band under the title. It now sits in the gap that already existed betwee...
Address a quote to someone who is not yet an account
The addressee was derived solely from a linked Account, so any quote raised for a prospect — which is most of them — printed a blank "Prepared for" line and the...
Open a member's profile from their row
Adds a fourth action to the row's hover dock, linking to **************** It is a real NextLink rather than a click handler, so middle-click and "open in new t...
Fail the build when a component calls a key messages/ does not define
next-intl renders the key path verbatim for a missing key, and messages/ is gitignored here — populated at image-build time from kamo-translation-dictionary — s...
Pin/unpin nav options from the navs and the home launchpad
Members could move an option between the side bar and the top bar, but never take one out of the navs entirely. Adds a third placement — NONE, "unpinned" — and ...
Hide empty departments, move the status filter into the Directory
- Departments with no members no longer render. The by-department endpoint returns every department in the org including empty ones, so the roster was showi...
Rebuild the slideout as one continuous surface
Member rows now form the department body directly — no card-on-card nesting — and departments run full-bleed with sticky bands, reclaiming ~30px of row width an...
Detection and alerting over the record-access audit trail
phi_access_log has been accumulating evidence nobody looks at. That satisfies §164.312(b) — the trail exists — and satisfies nothing about §164.308(a)(1)(ii)(D)...
Preview variables for PHI_ACCESS_ALERT
Without a sampleVariables arm the admin Email Templates preview renders every placeholder blank, so whoever is asked to approve the wording of a security alert ...
PHI_ACCESS_ALERT canonical template
SecurityService's hourly review of phi_access_log needs somewhere to send what it finds. Rather than invent a channel it uses the existing transactional-email r...
Mirror the lead minimum-necessary mask on the client (§164.502(b))
SecurityService now withholds custom-form answers from a caller who is not the lead's assignee (and, in a handlesPhi tenant, even from a holder of right 161). T...
Minimum-necessary masking of lead custom-form answers (§164.502(b))
The platform's only field mask was **************** applied by LeadController.getLeadById to a caller who is neither god nor the assignee and lacks VIEW_LEAD_CO...
PHI access audit viewer — org review and per-record accounting
The trail was being written and nothing could read it. This is the screen half: an org-wide access review under Settings → Security, and a "who has accessed thi...
Retitle member page to Profile, shorten tab labels, add tab icons
The member settings page header becomes "My {memberLabel} Profile" (or "{memberLabel} Profile" for another member) and the nav-top link becomes My Profile. Tab ...
Tone slider — whitewashed to full color to blacked out
A per-member backgroundTone ui-preference (0 white / 50 full color / 100 black) rendered as a wash above the readability scrim in both the console slideshow lay...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.