Intelligence type, phonetic names, AI supervision, job title/department requirements
Members: `Member.intelligenceType` (HUMAN | ARTIFICIAL, STRING, defaults HUMAN on every construction path and in the column), `aiSupervisorMemberId` (plain id —...
Checklist and ChecklistItem entities, repository and DTOs
Checklists are the Notes app's second record type: work to get through, whose tasks can wait on other tasks. Three tables — checklists, checklist_items and chec...
One query for an organization's whole reporting graph
findMemberAndManagerIds returns every (memberId, managerId) edge in one organization, for Hosted Computers' ACCESS_SUBORDINATE_COMPUTERS right — which reaches t...
The app, three rights, tier/state enums and the entities
ServiceType.HOSTED_COMPUTERS at id 37, TESTING rather than COMPLETED. The stage is carrying weight here rather than describing progress: AppCatalogService resol...
Intake endpoint counters come from a ledger and stop losing updates
**************** / total_processed / last_received_at were bumped on the endpoint row itself: once per inbound payload (~5/s during a farm import) and once per ...
Let a caller resolve a MediaObjImg by the Img id alone
DocsService's imaging endpoints (download/stream/list/delete) know an Img's id but have no reason to hold the MediaObj it was attached to — until they need to h...
Leads available and credit balances read a ledger instead of counting rows
"Leads available" was COUNT(*) over the assignable pool, and one org's pool holds ~796k leads: ~7.8 s per (market, product) count and ~11 s for the grouped one ...
A presenter's viewed stamp, so a booked session can badge them
The Support icon's webinar count reads WebinarAttendee.dateViewed. A presenter is not an attendee row, so a session booked with them was emailed and then never ...
Keep every credential field out of JSON, and guard the rule library-wide
Follow-up to 034378d2, which covered the columns NAMED as ciphertext. Read-only audits of origin/main in every repository found 61 more fields holding credentia...
A lead search matches the lead's email too
The /leads grid's boxes and the drip enroll dialog send what was typed as search terms, OR-ed across the lead's names, company, vendor lead id and number. The e...
Keep every ciphertext column out of JSON, and guard the rule library-wide
Follow-up to 096feaa1 (Organization's GoDaddy credentials were being served by an endpoint that needs no session). A scan of every **************** found fourte...
Never serialize the GoDaddy key and secret ciphertext
GET /api/security/org/{id} (and /org/domain/{host}) returns the Organization entity itself and answers without a session, and that body carried godaddyApiKey an...
People in a paused drip still leave it when their lead moves on
A paused drip's exit rules (status change, reassignment, goal click) are now listened for, so resuming it never sends to someone who should have left while it w...
Page-view counters for the marketing site
Two tables behind the view count kamo-marketing now shows at the foot of every page, written by KBService's /internal/page-views endpoints. KbArticleView (KB_A...
Lifestyle logo columns, and LIFESTYLE as the watermark default
The lifestyle logo is a fourth piece of branding artwork per brand, beside the full logo, the simple logo and the tab icon: the decorative rendition the backgro...
Chained drips hear when someone finishes a drip
A drip that starts when someone finishes another drip listens for the engine's own DRIP_COMPLETED events, but the recorder's trigger map left that kind out, so ...
Drip campaign triggers, recorded where leads and members change
Drip campaigns start when something happens in the CRM, so the places that change leads and members now hand those events to EmailService's drip engine: - Lead...
Reconcile durable consumers on the stream that owns the subject
The filter and deliver-group reconciles looked consumers up on the service's configured stream only. Subscriptions to subjects captured by another stream (socia...
Drop @Index declarations duplicated by a unique key
Each of these indexes covered exactly the same columns as a unique constraint, a unique column or the primary key on the same table, so it added a tablet and wr...
Check pool eligibility with an unordered sample, not a full-pool sort
hasEligibleAssignableLead only needs to know whether any pool lead is one the member may take, but it read a page of findAssignablePool, whose ORDER BY assigned...
Coalesce pool-availability recounts instead of recounting per lead
countAssignablePool scans every lead in the org+market and ran synchronously after every createLead commit. At ~14k leads it already cost ~165 ms, more than the...
A campaign can be archived
EmailCampaignEntity gains archivedAt (archived_at): when a member archived the campaign, null while it is not. The /marketing/email screen gets an Archived tab ...
The Email Campaigns home widget's five rights
EMAIL_CAMPAIGNS_WIDGET (321) and its four policy children (322-325), hung off VIEW_BULK_EMAIL: every read behind the widget, the campaign list, its counters and...
WebinarNotifyMember, an organization's Additionally Notified list
One row per (organization, team member) in webinar_notify_member, created by KamoInitializerService's WebinarNotifyMemberMigration and already applied. The repo...
Canonical templates for every webinar booking letter
Seven meet.webinar_* templates — the presenter's booked / attendee joined / attendee cancelled notices, the attendee's confirmation and cancellation, the sessio...
Accept the demo page's extra fields on public schedule/join requests
MediaService reads PublicScheduleWebinarRequest with a bare ObjectMapper, where FAIL_ON_UNKNOWN_PROPERTIES is true. The demo page also sends ***Payload, so ever...
The ledger keeps a person's unsubscribe unless they asked to rejoin
An unsubscribe, a complaint or a pause is the person's own choice. A member may now lift one only when the change says the person asked to be emailed again (Opt...
Saving a campaign never writes back its counts
The five counters are running totals now, moved only by EmailService with relative updates ("sent_count = sent_count + 1"). Mapped updatable = false, so a campa...
Each page transition's properties, kept per transition
**************** maps PAGE_TRANSITION_OPTIONS, a JSON object keyed by transition id, e.g. **************** Keyed by transition so tuning one survives switching ...
The page transition setting, and the right that chooses it
**************** holds a catalogue token, NULL meaning the shipped default. MANAGE_PLATFORM_TRANSITIONS gates Platform Administration → Configuration → Transiti...
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...
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.
