KamoCRM

Live Change Log

Every feature, fix and improvement, posted as it ships. Nothing is held back for a launch.

15,120
Total Changes
5,169
Features
4,935
Fixes
30
Projects
Filter by project
All Projects15,120AIService197APIService161BillingService143ConversionService107DaemonService129DocsService215ESigService88EmailService518InitializerService318KBService105KlusterServices697MCPGatewayService85MediaService546RAGService71SecurityService1,658TranslateService55VOIPService205VectorService11kamo-apps25kamo-asterisk-support24kamo-capcha17kamo-capcha-widget4kamo-internal6,937kamo-login330kamo-marketing625kamo-nowww20kamo-register213kamo-shared-library1,455kamo-signer-monorepo53kamolos108
Filter by type
All TypesBuild11CI523Chore738Docs2,167Feature5,169Fix4,935Other986Performance157Refactor274Revert23Style42Test94Upgrade1
August 11, 2026
Featurekamo-shared-library

Workweek and workday boundaries

The workweek is the FLSA overtime unit -- a fixed, regularly recurring 168-hour period -- and it is NOT the pay period. A biweekly period holds exactly two work...

Kamo·1mo ago
Featurekamo-shared-library

Interval resolution, stage 1 of the calculation pipeline

Punches become resolved spans. Pure, total, and over value types rather than entities so every stage is fixture-testable with no persistence context. Durations...

Kamo·1mo ago
Featurekamo-shared-library

Non-pyramiding overtime allocator with jurisdiction presets

Rules are DATA on the RequirementRule shape already used in this library, not code branches, so California is a configuration row instead of a rewrite. Allocat...

Kamo·1mo ago
Featurekamo-internal

Deliver the org timezone to the browser

The client Organization model had no timezone field, useFormatters and next-intl are both configured with no timeZone, and timezoneService's backend call 404'd ...

kamo·1mo ago
FeatureSecurityService

GET ****************

timezoneService.ts has called this endpoint since it was written and it existed in no Java service; the client swallowed the 404 and resolved to UTC. Meanwhile ...

Kamo·1mo ago
Featurekamo-shared-library

WorkSite, the jurisdiction anchor

Named WorkSite, not WorkLocation: TeamMember.workLocation is an existing office/remote enum and a second symbol by that name would collide in every grep. zoneI...

Kamo·1mo ago
Featurekamo-shared-library

Employment and effective-dated assignment revisions

Punches will reference an ASSIGNMENT, not a member. That is what makes concurrent positions, the 29 CFR 778.115 weighted-average regular rate, multi-site jurisd...

Kamo·1mo ago
Featurekamo-shared-library

Effective-dated, append-only pay rate

No employee compensation existed anywhere on this platform before this entity. It is required: overtime is computed against the FLSA regular rate, CA requires t...

Kamo·1mo ago
Featurekamo-shared-library

Append-only punch log and audit event

Both served by NARROW Repository interfaces, not JpaRepository: deleteAllInBatch and bulk JPQL bypass entity callbacks, so the interface shape is what makes app...

Kamo·1mo ago
Featurekamo-shared-library

Timezone-of-record resolver

Authority order work site -> member -> org -> UTC. The work site wins because wage-and-hour rules follow where the work is PERFORMED. A production census this ...

Kamo·1mo ago
Featurekamo-shared-library

Shared WORM refusal guard

@Column(updatable=false) does NOT enforce immutability -- Hibernate silently omits the column from the UPDATE and the stale write looks like it succeeded. The o...

Kamo·1mo ago
Featurekamo-shared-library

Domain enums and point-in-time version resolver

Enums are all @Enumerated(STRING) at the call site: ORDINAL emits a numeric range CHECK containing AND, which SchemaCleanupRunner's IN-list sweep deliberately s...

Kamo·1mo ago
Featurekamo-internal

Show members who pays for their seat, and stop offering a second one

The coverage endpoint shipped with translation keys and no component, so the question it answers — who pays for my seat — still had nowhere to be asked. SeatCov...

kamo·1mo ago
FeatureBillingService

Let a group's plan be cancelled, and stop double-paying for one person

Three gaps in what shipped last: A group with a plan could never be removed. delete() refuses while a live subscription exists — correct, since the group row i...

Kamo·1mo ago
Featurekamo-internal

A group you can put people on and pay for

Creating a group produced a name and nothing else — no way to add anyone, no way for its manager to choose a plan, nowhere to pay. Opening a group now shows who...

kamo·1mo ago
FeatureBillingService

Make billing groups work end to end, and stop self-pay charging for nothing

A group can now gather people, buy a plan on its manager's own card, and hand its seats out. None of that existed: the only operations were create, approve and ...

Kamo·1mo ago
FeatureInitializerService

Schema for groups that can actually pay

Three runners: BillingGroupRosterMigration creates billing_pay_group_members — whom a group means to pay for, before it has bought anything. org_id is denormal...

Kamo·1mo ago
Featurekamo-shared-library

Let a billing group be its own payer

A group could be named and nothing else. Its subscription was never set — nothing in the platform called setSubscription — so subscription_uid stayed null forev...

Kamo·1mo ago
Featurekamo-internal

The HR course editor, assignments grid and member course player

/hr/training replaces its placeholder with the two sub-tabs the brief asked for, and the member's Assigned Training grid gains the action column it was holding ...

kamo·1mo ago
FeatureDaemonService

The hourly training reminder tick

HOURLY at :10, unlike the legal sweep's daily 13:00. Training reminds each org at its OWN local send hour, and Organization.timezone spans 21 hours (Pacific/Hon...

Kamo·1mo ago
FeatureDocsService

The complete HR Training backend

Course authoring, publishing, assignment, the member player, server-side grading, WORM evidence and the reminder sweep — the whole module behind /api/docs/train...

Kamo·1mo ago
Featurekamo-shared-library

The four training email templates

Same constant/dotted-key split as the HR legal family: the CONSTANT is the filename stem, the templateKey the platform SENDS is the dotted value inside each .js...

Kamo·1mo ago
Featurekamo-internal

One member surface for both obligations, one badge for either

The member's compliance tab had two sub-tabs, Pending and Completed, for one kind of obligation. Those are a STATE, not a kind — so they collapse into a status ...

kamo·1mo ago
FeatureDocsService

The member-facing Training API

Registers com.kamo.z.shared.hr.training in @EnableJpaRepositories — @EntityScan is broad so the entities are found either way, but repositories are not. Two au...

Kamo·1mo ago
FeatureInitializerService

Create the HR Training schema

Registers com.kamo.z.shared.hr.training in the explicit @EnableJpaRepositories list — @EntityScan is broad so the entities are found either way, but repositorie...

Kamo·1mo ago
Featurekamo-shared-library

Stream document uploads and add the HR Training schema

ImageService gains uploadDocumentStreaming, the streaming counterpart of uploadDocument. The buffered form cannot express a large upload at all: readInputStream...

Kamo·1mo ago
FeatureInitializerService

Create billing_pay_groups explicitly, and undo the legacy collision

Creating it in a migration rather than leaving it to ddl-auto, which produced a half-built table when the entity was pointed at the pre-existing billing_groups.

Kamo·1mo ago
FeatureEmailService

Size each mailbox against the organization's storage

Dovecot now enforces a per-mailbox limit, and nothing was setting the column it reads. This writes it nightly, after the storage snapshot so the capacity being ...

Kamo·1mo ago
FeatureKlusterServices

Enforce storage quota on inbound delivery, and stop shipping the DB password

Object storage already refuses content that would take an organization past its ceiling, which covers every domain going through the object store. Inbound mail ...

Kamo·1mo ago
FeatureKlusterServices

Enforce storage quota on inbound delivery, and stop shipping the DB password

Object storage already refuses content that would take an organization past its ceiling, which covers every domain going through the object store. Inbound mail ...

Kamo·1mo ago
Featurekamo-internal

Let a member license their own seat from the console

The panel that closes the loop on self-pay. It appears only where the organization's policy permits it, and only for people who are not already buying on the or...

kamo·1mo ago
FeatureBillingService

Tell people their payment failed, and stand the subscription down

The dunning that did not exist. invoice.payment_failed wrote a row and returned: no email, no flag, no state change, and billing.email-service-url was configure...

Kamo·1mo ago
FeatureInitializerService

Add the dunning clock columns

past_due_since and suspension_notified_at, both nullable. Null means paying and not-yet-told respectively.

Kamo·1mo ago
Featurekamo-shared-library

Make a failed payment mean something

PAST_DUE counted as fully live in both entitlement resolvers, with no timestamp and no cap, so a customer whose card failed kept every feature for as long as St...

Kamo·1mo ago
FeatureBillingService

Let a member buy their own seat, and close a body-parameter hole

Self-pay had no route inside the console. Everything on the billing surface is account-shaped — you must already hold an AccountMember row before Plans & Billin...

Kamo·1mo ago
Featurekamo-internal

Let the owner decide who can pay, and manage the groups that do

The owner had exactly one lever over self-payment and it was the wrong shape: an irreversible promote gesture, with no way to say in advance whether it was perm...

kamo·1mo ago
FeatureBillingService

Org policy and billing group APIs

Who inside an organization may pay Kamo is now answerable and settable. Both routes are org-scoped and therefore deliberately outside /api/billing/accounts/** a...

Kamo·1mo ago
Featurekamo-internal

A Plans & billing console an owner can actually find

There was no way to buy a first subscription anywhere in the product. Plan lists were reachable only through a subscription you already held, so an organization...

kamo·1mo ago
FeatureBillingService

Default a new subscription's target org to the caller's

A first purchase has no existing subscription to copy targetOrganizationId from, and requiring it unconditionally is what made creating one from the console imp...

Kamo·1mo ago
Featurekamo-internal

Show the ceiling, not just the bytes

The panel reported stored, added, removed and lifetime bytes against no reference at all — so an owner looking at 400 GB had no way to tell whether that was com...

kamo·1mo ago
FeatureSecurityService

Gate promotion on the owner's policy, make it idempotent, add its inverse

Promoting a member to pay for themselves was unconditional, one-way and unsafe to repeat. It now refuses when the organization's policy says the organization p...

Kamo·1mo ago
FeatureInitializerService

Drop the constraint that limited a member to one billing account

Finds the constraint by shape rather than by name — Hibernate generated it and the name is not stable across environments, so any unique constraint on account_m...

Kamo·1mo ago
Featurekamo-shared-library

Let members and groups pay for themselves, under the owner's rules

Three things were missing and one was actively harmful. account_members carried a global unique on member_id — a member could administer exactly ONE billing ac...

Kamo·1mo ago
FeatureSecurityService

Expose the fail-open impact to the operator

The app catalog page already answers the org-independent question — does any plan mention this app — and raises a warning when none does. This answers the tenan...

Kamo·1mo ago
Featurekamo-shared-library

Show what turning off fail-open would cost

kamo.entitlement.fail-open grants any app the plan matrix never mentions. It is documented as a temporary valve for the catalog backfill — turn it off once the ...

Kamo·1mo ago
Featurekamo-internal

Show whether someone is there, and their extension

Every row now carries a presence dot and word beside the name, and its extension in the detail line — so choosing a person no longer means picking a name and ho...

kamo·1mo ago
FeatureSecurityService

Carry availability, presence and extension on a directory row

Picking a person is easier when the row says whether they are there and how to reach them, so each one now carries what they last declared, whether anything of ...

Kamo·1mo ago
FeatureBillingService

Buy a block when an opted-in org runs out of room

Runs shortly after the nightly snapshot sweep, because that is what produces the usage figure it decides on — expanding against yesterday's number would buy a b...

Kamo·1mo ago
FeatureInitializerService

Add the auto-expand columns

Kamo·1mo ago
Featurekamo-shared-library

Opt-in auto-expand with a ceiling

Two columns on the subscription that holds the blocks: whether to buy another one automatically when the organization runs out of room, and the most it may ever...

Kamo·1mo ago

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.

Start Free ForeverView Pricing