Commerce_quotes.billing_basis
The per-quote snapshot of the org's quoteConversionBilling choice, so a quote keeps the terms it was raised under after an administrator changes the setting. Nu...
Bill the whole term up front, and say so on the quote
An org that charges up front saw the monthly rate on a three-year deal. The setting deciding that already existed — **************** — but it reached only Quote...
Tick SecurityService's scheduled-report sweep
Every five minutes. A schedule is set to the minute, so a finer tick buys nothing a member would notice and a coarser one makes an 8:00 report arrive at 8:15. ...
Run the reports that are due, and send them
One internal endpoint, X-Internal-Auth gated and constant-time compared, that DaemonService ticks. The cron stays in the daemon because it is replicas: 1 with s...
Let a transactional send carry one attachment
Added for scheduled reports, which are a rendered PDF or workbook that has to reach people who may have no account — a link would not be a delivery for them. T...
The email a scheduled report arrives in
REPORT_SCHEDULED, registered in CANONICAL_KEYS — absent from that list a template is a permanent 404, whatever files exist beside it. The body states the data ...
The lists a share dialog picks from, and a share target that fits every id
GET **************** returns the organization's people, departments and roles as picker options, in one call and in one shape. Built on the reporting option pro...
Step through every search hit, not only the newest
The search at the top of a chat window marked every occurrence of the query and then scrolled to exactly one of them — the newest — with nothing to say how many...
A service-work report, and a share target that fits every id
ServiceWorkReport is the tenth seed report and the one that makes row-level scope real rather than merely present. Commerce carries the platform's own/all pair ...
Pin the well-known folders to the top of the sidebar
Inbox, Drafts, Sent, Junk, Trash and Archive stop moving. They hold that order at the top of the folder list, and everything the member made sits underneath und...
Rebuild the index as a map of the product
It was one recursive list of all three hundred articles, indented by depth. Everything was on the page and nothing was findable, and the page weighed 3.9 MB. T...
The Report Studio — a library, and one renderer for every report
/reports is a shelf, not a card grid: two hundred identical rounded boxes is a wall to scan, and a row gives a report's name room to be read. Saved views nest u...
Run, export and schedule the Report Studio's reports
The service half of the framework: the catalogue, the run, the pickers, four exporters, saved views and schedules. Authorization is explicit on every path, bec...
The Report Studio framework, and nine reports built on it
A report is now a Java class here and nothing anywhere else. ReportDefinition describes what a report is, what it may be asked, which columns it has and how eac...
The importer, and three things it taught us
Publishes the corpus by driving the real KBService API rather than writing rows -- a direct INSERT skips the version row, the kb.article.published event that is...
Persist a market's quote-contact rule, and refuse a half-stated one
The DTOs carried quoteContactMode and quoteContactMemberId but no writer read them, so the setting round-tripped through the form and was silently dropped. Both...
Choose who a quote names as the customer's contact
The market dialog gains "Quote's Future Contact" under Enable quotes: the lead's assigned agent, a choice made per quote, or one explicit person picked with the...
Honour a market's contact rule wherever a quote names somebody
The staff detail, the staff preview and the customer's own page now resolve the contact through one method, so they cannot disagree about who is printed on the ...
The article corpus, and the pipeline that builds it
307 articles across 16 categories and 29 sections, from the 248 draft articles under Documentation/ plus 59 written here: every category and section landing pag...
A market decides who a quote names as the customer's contact
QuoteContactMode gives a LeadMarket three answers: the lead's assigned agent (resolved per read, which is what every quote does today and what a null column mea...
Columns for a market's quote contact and the per-quote snapshot
A market names its answer in QUOTE_CONTACT_MODE (+ QUOTE_CONTACT_MEMBER_ID when that answer is one explicit person), and each quote keeps the contact it was rai...
Curate an article's related articles
KbRelatedPanel is one component in three places: it curates in the composer and the editor, and reads back on the article view. Adding an article here also adds...
Related articles, and a public path that keeps the tree
Three things, all reaching the same page. Related articles. KbArticleRelationService owns the symmetric "see also" links: list, set, suggest, and a clear that ...
Migration for KB_ARTICLE_RELATIONS
Mirrors KbArticleRelation in kamo-shared-library. Written explicitly rather than left to ddl-auto so the UID and DATE_CREATED defaults live in the database, whi...
Article-to-article relations
KB_ARTICLE_RELATIONS holds the curated "see also" links between articles in one knowledge base. Rows are per direction and the pair is kept symmetric by KbArtic...
Page and search the org directory, and stop two row builders drifting
The networks endpoints answer with the whole set in one body. That is fine for a member of a dozen orgs and impossible for an operator on an estate meant to rea...
Starter base up $10 on every term
69 / 59 / 49, from 59 / 49 / 39. The commitment ladder is untouched by design — still exactly $10 off for a year and $20 for three — which is the standard every...
The running offer, on Plans & billing and on the launchpad
The console quoted list prices while kamocrm.com advertised a third off the same plan, because nothing in kamo-internal could see that an offer existed. It now ...
Serve the running offer, and say whether a seat is actually PAID for
Adds GET /markets/{id}/promotion. There was no way for an in-app buying surface to know an offer was running at all — the marketing site read promotions through...
The offer reaches the hero and the pricing strip
The hero had a countdown ribbon already, and it had been rendering NOTHING since the catalog moved to a percentage: `pickHeroOffer` filtered on FLAT_PER_SEAT be...
A three-term commitment rail, and a promotion the page can prove
New prices: Starter $59/$49/$39 and Business $119/$109/$99 per seat per month on monthly, yearly and three-year terms. The rail replaces the monthly/annual pair...
Sell the three-year term, and stop four copies of the cycle drifting
The billing cycles were typed out by hand in five places. One of them, the plan-pricing editor, offered "BIENNIAL" — a value the server has never had — so choos...
Bill the three-year term, and quote its rate to the console
BillingCycles gains TRIENNIAL, expressed to Stripe as three YEARs rather than thirty-six MONTHs so the renewal tracks the signup anniversary — the same reason A...
A three-year term, and the promotion rules that were never read
Adds BillingCycle.TRIENNIAL so a subscriber can commit for three years. The column is varchar with no CHECK constraint anywhere, so this needs no migration — bu...
Show the report title in Send To AI, editable
The dialog let an operator edit the instruction and the description but never showed the title, and the title was not in the message either — the session at the...
Put the report title in the message, and let it be corrected
A dispatch composed the operator's instruction and the bug description with the separator between them. The title was never in it, so the session opening the me...
Carry the report title through a Send To AI dispatch
The dispatch sent the operator's instruction and the bug description and nothing else, so the one line saying what the report is ABOUT never reached the session...
Reply to a message, and take the reader to what it answers
MediaService has carried a reply's parent and the quote to draw for it since "send the quote with a reply, not just the pointer"; this is the half that shows it...
Offer Move on a right-clicked message, not only on a ticked one
Right-clicking a message offered Reply, Reply all, Forward, Report Spam, Archive, Label and Delete. Filing it anywhere other than Archive meant dismissing the m...
Go To Settings leads the Settings menu, above the app list
Reported with two screenshots — one org with eleven enabled apps, one with two — each circling "Go To Settings" at the bottom of the Settings sub-option menu wi...
64G swap on the dev machine, and catch access that fails intermittently
The blank white page was the VM out of memory. 16Gi of guest RAM with NO swap means "out of memory" goes straight to the OOM killer: applications die mid-work, ...
Make smart folders reachable, and make clicking one work
A smart folder is a saved search that sits where a folder sits: name a question once ("unread, with an attachment") and it is one click away, current every time...
Send the quote with a reply, not just the pointer
media_objs_msg.parent_id has been there all along and this endpoint has accepted parentId on the way in since threading was modelled, but a reply crossed the wi...
Leave a group chat, and keep the line that records it
Leaving is offered at the foot of the roster popover, separated from the rows above it because it belongs to the member rather than to anyone in the list, and c...
Leave a group chat, and keep join/leave lines in the transcript
Leaving is DELETE /sessions/{guid}/membership, not removeMember aimed at yourself — that route refuses self-removal on purpose. Removal is done TO somebody and ...
Open on Chats, a Favourites section, and a group chat you can manage
Five requests from a member, all of them about the same gap: the Chats panel could show you conversations but gave you nothing to do with them. Chats is now th...
Name a group chat, star a conversation, remove somebody from a room
Three routes, and each refusal is a rule somebody has to be able to tell apart from an outage — so each carries its own code rather than a shared 4xx. DELETE *...
A chat can be named, starred, and have somebody removed from it
Three fields and one method, all of which the chat feature already had the shape for and none of which it could record. MEDIA_SESSION_CHAT gains TITLE. That ta...
Bulk add members and team members, with a CSV/XLS import
Two new screens beside the existing Add buttons on /account?tab=members and ?tab=team-members, at /settings/member/bulk-new and /settings/team-member/bulk-new. ...
Bulk-create members and team members, one transaction per record
The two bulk-add screens need to create a spreadsheet of people in one submission and report on each of them individually. That could not be built on the existi...
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.
