Derive entitlement mode through one shared, deterministic resolver
TrialAdminService picked its trial subscription with findFirst() over an unordered list, so an org holding both a pending and an active trial could report eithe...
Backfill app entitlement rows into the platform plan catalog
Entitlement now resolves on a typed service_type column, but no catalog row carried one, so every plan still resolved to 'everything included' via the fail-open...
Gate mortgage and personal-loan verticals on app entitlement
A MORTGAGE market appeared on /commerce whenever POS was on, regardless of the MLOS app, and /features/enable had no billing check at all — the padlock in the s...
Rename LOS to MLOS, add Personal Loan Origination System, gate commerce verticals
Apps tab now shows 'Commerce: Mortgage Loan Origination System' (the title is served from the backend enum, not the TS mirror) and a new 'Commerce: Personal Loa...
Resolve app entitlement by ServiceType; rename LOS to MLOS
Entitlement resolved ServiceType.name() against **************** The catalog's codes are marketing codes (USERS, VIDEO_CONF, HR_SYSTEM, ...) and never matched, ...
Email a member from their row
Adds a mail action beside chat, call and profile on a member row, opening the Messages tool with the recipient already filled in. It is hidden unless the org ha...
Accept 3 GiB attachments by streaming them to storage
file.getBytes() cannot represent an upload this large — a Java array stops just above 2 GiB — so every attachment past that died on an OutOfMemoryError regardle...
Stream content-addressed storage so an object can exceed heap
Chat attachments are moving to a 3 GiB ceiling. storeContentAddressed took a byte[], which cannot express that at all — a Java array stops at Integer.MAX_VALUE ...
Title the mortgage form panes Borrower(s)
The Loan/Borrower/Subject Property form serves every borrower on the file, so the tab and pane titles now come from translations and read Borrower(s). Loan and ...
Drive the email template off the From address, behind an on/off switch
The template picker in the composer footer is gone. Which template a message wears is not a separate decision from who it is sent as: the member's own primary a...
Switch mailboxes from the same searchable picker the composer uses
The switcher was the weaker half of the pair: a select holding every mailbox the member can open, which for org-wide access is every mailbox in the org. It also...
Let /sendable drop the alias group for callers that open mailboxes
The /messages mailbox switcher offers the same set as the composer's From field, minus one thing: an alias cannot be opened. Mail addressed to it lands in the m...
Download the executed document, and choose a real signing order
The sender had no route to the finished document at all. EnvelopeSummary advertised a signedDocumentUrl pointing inside the kamo-signer app's own BFF, authentic...
Preview variables for the e-signature templates
The admin template editor renders every placeholder blank for a key with no sampleVariables arm, so the seven esign templates previewed as a page of empty gaps ...
The five envelope-lifecycle email templates that were never written
An e-signature envelope had exactly two templates: the invite and the step-up code. Nothing existed for anything that happens AFTER a signer signs — which is wh...
Rebuild the mortgage market settings into seven coherent tabs
The MORTGAGE market page carried fifteen tabs, twelve of them lender config, and several answered the same question in two places: hedging was switched on under...
Pick the From address from a searchable dialog, not a dropdown
A select cannot hold this list. Everything the /messages switcher offers is sendable, and for a member with ACCESS_ALL_MEMBER_MAILBOXES that is every mailbox in...
Searchable, paged endpoint for the addresses a member can send from
GET /api/email/mailboxes/sendable answers the same question as /accessible — every address the member may send as — but as one merged stream that is searched an...
GET /types/{typeId}/slots so the settings editor can list slots
The settings UI has always fetched this path, but only POST/PUT/DELETE were mapped, so the Availability Slots tab got a 405 and rendered empty. Unlike /slots/av...
Assign a mailbox to a department and to the organization
The department dialog's contact email was free text, so it could name an address the org does not own. It becomes a picker over the org's real mailboxes -- the ...
Mailbox pointers for departments and orgs, and backfill the departments
DEPTS.MAILBOX_ID and ORGS.CONTACT_MAILBOX_ID, both plain UUID with no FK to email_provider.mailboxes: mailboxes sync from external providers and can be removed ...
Let a department and an org point at one of their mailboxes
A department's contact email was free text, so it could name an address the org does not own -- two of the three departments with one set today do exactly that....
A Manager field on Position, and one people picker for the whole app
The Position card gains Manager, optional. It is a search, not a dropdown: an org can hold thousands of names, and the only thing a select with all of them guar...
Set a manager, and search the directory a page at a time
GET **************** answers one page of the session org's directory. Search, ordering and paging happen in the database; a hostile ?size= is capped. Words are ...
A manager, and a directory search that survives a big org
TeamMember gains an optional self-reference for who it reports to. columnDefinition is pinned to INT8 so Hibernate cannot copy Member.ID's DEFAULT unique_rowid(...
Give a team member a manager
Adds MANAGER_ID to member_team_member, a nullable self-reference for the reporting line. Nothing is backfilled: no manager is a complete answer, both at the top...
Add DEPTS.PARENT_DEPT_ID for nested departments
Nullable with no backfill -- null means top level, which is what every existing department was and most will stay. Declared plain UUID with an explicit DROP DE...
Thread the parent department through create and update
DepartmentService now takes its request DTO instead of eight positional arguments, so the parent joins the payload rather than becoming a ninth in a row of same...
Draw departments as an org chart with a parent picker
The departments tab was a flat list, so an org with Operations > Customer Success > Onboarding had no way to say so and no way to see it. Add/edit gets a Paren...
Let a department sit under a parent department
Departments were a flat list, so an org chart with Operations > Customer Success > Onboarding had no way to say so. Department gains an optional self-referencin...
Grow the To/Cc/Bcc fields to three rows, then scroll
The recipient fields in the compose tool window were a single nowrap row that had to be dragged sideways to read, and the window is 360px wide and not resizable...
Make org creation survivable, and offer every branding option up front
The wizard could fail a customer in ways nothing on screen explained, and it asked for a fraction of what Settings → Behavior & Labeling exposes. Creation reli...
Send the editor's back button where the member came from
The wallpaper editor was a dead end — no way out but the nav rail. Both entry points (the home top-bar chip and the member profile header shortcut) now stamp th...
Show a primary mailbox under its member's profile name
A mailbox held as somebody's primary is that person's address, so suggesting it as "Sales Desk" — whatever it happened to be labelled when it was provisioned — ...
Name a primary mailbox after the member who holds it
A mailbox someone holds as their primary is that person's address, so presenting it under whatever the mailbox was labelled at provisioning time — "Sales Desk" ...
Register the commission pages in the settings nav and landing page
The tabs existed but nothing linked to them. **************** is the cautionary example already in this repo: a real page with no card, no tab and no nav entry,...
Member commissions tab and the two finance account tabs
Member tab (self-only, team members only): balance + ledger, commissioned opportunities, payout setup, and withdrawals. Account settings gains Organization Stri...
Folders you can act on, mail you can select
Right-click any folder for its actions. The menu header is not chrome — it names the folder and shows its live unread/total, so Mark all read and Empty folder c...
Act on a whole folder, not just the page you scrolled
Mark all read and Empty folder are folder-wide operations the client cannot express by batching uids: it only ever holds the page it has scrolled, so a folder w...
Browser-facing relay for the commission feature
Resolves the session, authorizes, and relays to CommissionService with the org and member stamped from that session — never from anything the caller sent. This ...
Find a member's commission splits for their own commissions view
Org-scoped rather than keyed on the member alone: ORG_ID is duplicated onto this table so a row can never be read cross-tenant by id, and a finder that ignored ...
Make the member surface a real kamo data grid
The member's packages were a card list with no motion, which is not how the rest of kamo looks. This is now the house AG Grid: Pending and Completed sub-tabs sy...
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.
