The opt-out ledger says when an organization's list changed
An optional listener, told after the change commits, so the screens showing the list can refresh live instead of loading once. It carries only the organization:...
Count PLAY_CHESS, PLAY_HOLDEM and MANAGE_EMAIL_OPT_OUTS
The two game roots shipped without moving the audited shape, so RoleRightHierarchyTest had been red on main since. The opt-out right is a child of MANAGE_EMAIL_...
One opt-out ledger, topics, pauses and a history of every change
The do-not-email list could be written to but not read, changed or explained. This adds the one place it is read and written from, for every service: email_o...
MANAGE_OUTBOUND_EMAIL_HOSTS, the platform console's outbound e-mail hosts
A platform right for the outbound e-mail hosts campaign mail leaves through: the hosts shared with every organization and the ones kept for the platform organiz...
Read the platform's hex secret as hex, and stretch a short key instead of refusing it
JWTUtils decoded security-service.*** as Base64 only. The platform's secret is 64 hex digits (32 bytes), which Base64 turns into 48 meaningless bytes; those wer...
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...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.