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 ...
Count the files a document keeps only as old versions
A category that keeps versions holds every earlier file of a document in img_versions, each on its own content-addressed file. The storage meter, the quota and ...
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...
An organization's own domain is named in a link only once it is live
OrgLinkHosts is the one rule for the host a link to an organization may name: its own root domain once it is active, ownership-verified and SSL-confirmed ******...
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...
Rank only members whose security type includes achievements
The leaderboard grouped every member holding an achievement row, so a member whose role denies VIEW_ACHIEVEMENTS β who cannot open the page, the trophy or the w...
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...
An app id an older build cannot name must not fail every feature read
ServiceType ships inside each service's jar while ORG_FEATURES is shared, so a newly added app is ALWAYS in the database before the older readers have been rebu...
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...
What the thread design got wrong, as built
Two schema faults that only appeared on deploy β the hand-applied column that was flagged and not applied, and a frozen ddl-auto CHECK on media_sessions that wo...
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...
Cover the three shared reads a catalog bump still reached users through
Same defect as the sign-in fix, found by reading the fleet's logs rather than one report: eight hours of pod logs across email, media, docs, daemon and security...
Retry the two rights reads that stand between a password and a session
MemberRightsAppliedService carried @RetryOnDbConflict on its WRITE entry points only. The class therefore read as covered while the two methods the authenticate...
The update DTO needs the first-time-buyer field too
68ce0e0f added `isFirstTimeBuyer` to the CREATE request and wired both call sites in LeadService β but the second one reads UpdateLeadRequest's own nested Mortg...
Put back the CRLF a Python edit stripped from two files
Both files are CRLF in this repo, and rewriting them through Python's text mode converted every line β turning a fifteen-line addition into a 771-line diff in 6...
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...
Bring the organization inside the retried read instead of leaving it to fire later
Member.organization is LAZY, so findById left a proxy behind and the real SELECT happened whenever something first dereferenced it. Under open-in-view that is t...
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...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.