A voided organization is left out of every listing and host lookup
Platform operators can now void an organization from Platform -> Configuration -> Organizations. The void is orgs.is_active = FALSE β the flag sign-in and host ...
Document versions, and the versioning mode an organization chooses
Documents were two records: the upload, which nothing edited, and one modified copy derived the first time anyone opened it to edit. Members found the pair conf...
A logo overlay for the nav rail and one for the careers site
Two more columns in the vocabulary home_logo_overlay established: a token, not a hex, so an org that rebrands keeps an overlay that matches its new colours. Bot...
Carry the executive's phone line on a message
ChatMessageDto gains senderPhone and senderPhoneExt, set only when the sender is KamoCRM staff: the platform org's main line plus the extension that reaches tha...
List the members who hold a platform right
countHoldersOf answered how many; the Exec2Exec desk needs who. Grant rows alone are the wrong answer to "who works the desk" β the top-level owner holds every ...
The executive channel's foundation
One standing conversation between a customer executive and the KamoCRM executives, keyed on the USER rather than on a member β which is what lets it follow some...
Record WHICH consent disclosure a signer accepted, and in which language
`consentedAt` records that somebody ticked a box. 15 U.S.C. Β§ 7001(c) is a list of specific things a consumer must be told BEFORE consenting β the right to pape...
The app, the right, and the six tables a poker game needs
HOLDEM (36) joins KAMO_UNIVERSE and CHESS under GAMES, with PLAY_HOLDEM (319). Both ids were the next free ones; nothing is renamed and nothing moves, because O...
Record when a player was last prodded to come back
DATE_LAST_NUDGE, one clock per game rather than per sender β otherwise two people can take turns nudging each other every five minutes and call it twelve messag...
An invited game starts running, and records whether it has been seen
Inviting somebody created a PENDING game nobody could touch, so the person who had just asked for a game sat in front of a board they were not allowed to use un...
Games becomes a parent app, with Kamo Universe and Chess under it
GAMES was a category with exactly one thing behind it β the nav icon launched Kamo Universe directly, so the app and the thing inside it named the same click. C...
Let the listing be narrowed to one reporter
Adds an optional reporterId predicate to findVisible (both halves) and to countGroupedByStatus, so the numbers beside the status menu keep promising what pickin...
Fifty secret easter eggs, spread across the product
The catalogue was good at rewarding the parts of the product a member already uses and bad at getting them into the parts they do not. A prompt cannot fix that ...
Loitering, nine levels of not leaving
A DERIVED track over the age of the session the member is holding right now, in minutes: 30, 45, 60, 90, 160, 360, 720, 1440, 2880. The first entry in DEDICATIO...
The storage and the platform right for a three-layer contact-effect stack
CONTACT_EFFECT_PROFILES holds the platform, org and member layers of the animation painted where a pointer touches the screen β the same shape, and for the same...
Thirty-five single-action achievements, and a trigger kind
The "have you tried this yet" half of the catalogue: one tier at a threshold of one, cheap on purpose, existing to make the product's own surface discoverable. ...
Six tracking-link achievements, ten levels each
The marketing funnel, read six ways, one track per counter already carried on MARKETING_TRACKING_CODES: DRAW_A_CROWD uniqueVisitors 1 .. 50,000 B...
How fast an organization's storage is growing
The snapshot table has recorded a daily position per organization since metering began, and nothing read two rows of it together. So the only question storage c...
SPREAD_THE_WORD, a nine-level Growth Hub track
The second entry in the catalogue, and the first that is a track rather than an event. One level per stretch of Growth Hub missions a member has had APPROVED: 1...
The requests an org asks of its people, and the evidence back
Three entities, seven rights and two enum appends behind Growth Hub: a short ordered list of things an organisation asks of everybody β leave a review, share th...
The achievement a member holds, and the record that proves it
Adds the Gamification app and the domain behind it: a catalogue of achievements in code, a member's standing in data, and a log of every unlock so that nothing ...
Every org sees every report, and improvements can be voted on
The tenancy predicate is gone from all four queries, and its absence is the feature: a defect in the platform is not one tenant's private business, and a reques...
The three letters a lead gets about a callback
A callback has always been private to the organisation. The member who books one gets a calendar entry and a reminder; the person on the other end of the call i...
New-email and unread-chat kinds, and a repeating tone
Two kinds a member can be told about and mute like any other. Both announce a condition that stays true rather than a moment that passed, so both are raised onc...
A text conversation can exist without a phone server
VOIP_CONVERSATIONS.INSTANCE_ID was NOT NULL, which quietly decided that every text thread belongs to a PBX. An organization that buys numbers and messaging from...
The two letters a customer gets when their card fails
BillingService has wanted to send these since DunningNotifier was written. It posted them to **************** β an endpoint that has never existed on EmailServi...
Telnyx, the first provider that is both a phone server and a carrier
Telnyx sells SIP trunking, DIDs and messaging, and an organization can buy those halves independently. The case this is for: DIDs and texts bought from Telnyx, ...
Shelving, failed fixes, and a report's whole comment history
A report kept exactly one sentence. `system_bug.denial_reason` was overwritten by every subsequent status move, so a bug that was denied, explained, reopened, f...
A customer-readable note on a negotiated agreement
The internal `notes` field is where staff record what was conceded and to whom. The customer's own plan page needs prose it can show them, and one careless sent...
Retire three statuses, name what Verified verified, and record why a report was denied
Removes TRIAGED, AWAITING_INFO and CANNOT_REPRODUCE. Each described how confident an operator felt rather than where the report had got to, and none of them mov...
List every provisioned account on one dev machine
findEnabledProvisioned asks existsEnabledProvisioned's two conditions of a can put one question to the agent per tick rather than one per member.
Per-org ribbon wording and tab icons
Fourteen columns on `orgs`, and two small records to keep their shapes honest. RIBBON_MSG_* carry the corner-ribbon wording for the five public pane screens β ...
Let an integration say which support queue its chats belong in
A web-chat integration had no support topic. The visitor's browser sent a hardcoded topic title instead, so an org whose topics aren't named "General Inquiry" β...
Apply from inside the workspace, and say so to both sides
The public careers board's Apply button is now a link into registration, so every application is filed against a session. Two fields carry the candidate from th...
A product's application is published, not assumed
`LeadVendorProduct` gains `applicationEnabled` and `webChatIntegrationId`. A product existing in the CRM is not a decision to publish a form the whole internet...
Record whether a borrower says this is their first home
A first-time buyer is eligible for programmes nobody else can use, so a lead that does not carry the answer costs the officer a call to ask it. The public appli...
Give a lender somewhere to put the truth about itself
The public mortgage application page composed its legal footer out of nothing β a hardcoded California licence, an invented NMLS number, a fictional address β a...
Retry the member reads that fail first after a DDL
The member-by-id load is close to the first statement an authenticated request performs, so a catalog-version bump hits it before it hits anything else. That is...
Retry a transactional method in a NEW transaction, and stop rights failing open
Two fixes that only make sense together. @RetryOnDbConflict retries a method OUTSIDE its transaction, so each attempt begins a fresh one. Retrying inside the t...
Let the console ask what a seat change costs before making it
changeSeats now raises an invoice for the startup fee on new heads, which turns a number in a dialog into a charge β ten hires on a $99 plan is $990, and on a l...
Record whether a domain's SPF authorizes us to send as it
Two columns beside the ownership and SSL flags, answering the third DNS question about a domain: may we put its name on the From line of the transactional mail ...
Charge the startup fee, per seat, and let one customer out of it
The startup fee has been half-built for as long as the model has existed. SubscriptionPlan carried a setupFee, SubscriptionOrder carried a setupFee, OrderLineTy...
Retry the database errors Yugabyte expects a client to retry
Applying DDL bumps the catalog version, and every physical backend still holding the old one fails its next statement with SQLState 40001 β "schema version mism...
Address an org's OAuth callbacks to its own domain
An OAuth redirect URI is held by a third party. A member pastes it into Google's or Microsoft's console, and from then on the value the service sends on the aut...
A detection rule an org cannot switch off, and the letter it sends
PROGRESSIVE_LOGIN_LOCKOUT joins DetectionRuleType. Every other value on that enum describes something a tenant opts into; this one describes a control SecurityS...
A distributed lock, so a scheduled sweep can survive a second replica
There is no ShedLock anywhere on this platform and there never has been. All 97 @Scheduled sweeps across 18 services are correct only because each service runs ...
A logo overlay for the sign-in and sign-up sites
Two more columns in the vocabulary home_logo_overlay already established: a token, not a hex, so an org that rebrands keeps an overlay matching its new colours....
Add a queue-group subscribe, so work is shared rather than pinned to one pod
Companion to subscribeEphemeral. Two different jobs, two different consumers: subscribeEphemeral every pod must see every message (anything ending in a STO...
Add an ephemeral subscribe, so more than one pod can serve a conversation
A durable push consumer admits exactly ONE subscriber. The second pod to bind the same name is refused with [SUB-90012] Consumer is already bound to a subscript...
The two reads the platform Users list is built on
A paged, searched finder over USERS, and a batched membership count. The finder is unfiltered by isFake on purpose. Reviewing and clearing that flag is part of...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.