The repeat-sound columns, for a fresh environment
EmailService runs ddl-auto: none, so neither column can appear on its own β the entity declares them and Hibernate reads the table happily without them, then fa...
System_bug.media_session_guid, and its lookup index
The column behind a report's comment thread, matching **************** β VARCHAR(36), because MEDIA_SESSIONS.GUID is itself a 36-character string column and a t...
Add denial_reason, and sweep the three retired status names
status_name holds a NAME read back through @Enumerated(STRING), so a row still saying TRIAGED after the constant is gone does not read as a default β it throws ...
Seed the $99 per-seat startup fee on every paid tier
The loader passed null for setupFee on all four plans, so a freshly seeded environment priced onboarding at nothing while production charges $99 a seat β the ki...
System_bug.published, defaulting to TRUE
The column behind the Publish flag: a god-mode operator can now file a report that stays with god mode until somebody releases it. DEFAULT TRUE is the whole re...
Make hr_job_application.member_id nullable
ddl-auto adds columns; it never relaxes constraints. Flipping optional=false to true on the entity changes what the ORM believes and nothing about what the data...
Email_signature_badges, and the columns that order them
The footer badge library plus footer_badges / footer_badge_spacing / footer_badge_height on email_signature_templates. A runner and not just ddl-auto for the u...
Scan hr.careers, and drop the frozen work-location CHECK
Two changes, both required before the careers entities can reach the database. The @EnableJpaRepositories list is an explicit array while @EntityScan is wildca...
Commerce_quotes.setup_fee
A one-off setup fee on a quote that presents a single price. The fee already existed on QuoteOption, where each alternative carries its own; a flat sheet had no...
Reprice stored quote totals through the pricing engine
Quote money columns are written, not computed on read, so the two corrections that landed on 2026-09-02 β a unit price is a per-month rate the term multiplies, ...
The columns that let an event invite its guests
Three on calendar_events, because whether a meeting invites people belongs to the meeting rather than to the moment it was saved β an edit six weeks later that ...
Commerce_quotes.billing_basis
The per-quote snapshot of the org's quoteConversionBilling choice, so a quote keeps the terms it was raised under after an administrator changes the setting. Nu...
Columns for a market's quote contact and the per-quote snapshot
A market names its answer in QUOTE_CONTACT_MODE (+ QUOTE_CONTACT_MEMBER_ID when that answer is one explicit person), and each quote keeps the contact it was rai...
Migration for KB_ARTICLE_RELATIONS
Mirrors KbArticleRelation in kamo-shared-library. Written explicitly rather than left to ddl-auto so the UID and DATE_CREATED defaults live in the database, whi...
Keep every live domain routing once verification becomes mandatory
Host to organization resolution is about to require ownership_verified on the top-level domain row, so that a domain several organizations have merely named rou...
The three per-member-type home-screen columns on a security model
CHILD_ORG_SECURITY_MODELS gains DEFAULT_MEMBER_HOME_SCREEN, DEFAULT_TEAM_MEMBER_HOME_SCREEN and DEFAULT_ORG_OWNER_HOME_SCREEN. Each holds HOME_SCREEN_DEFAULT (t...
Create org_setup_wizard_progress for the Getting Started wizard
The REVOKEs three entity javadocs already claimed existed
BillingWormGuard, BillingDispatch and BillingSyncIssue each cite "a REVOKE UPDATE, DELETE in the KamoInitializer migration". No such migration existed β the sta...
System_bug_view β who has read which report
Per VIEWER, not per bug, and that is the whole reason it is a table rather than a first_viewed_at column on system_bug: triage is worked by several people at on...
Land the company phone toggle columns before EmailService reads them
ADD COLUMN IF NOT EXISTS on **************** for user_company_phone_main and user_company_phone_toll_free. This service's ddl-auto: update would add both from ...
4 GB per seat on every plan, and seats rather than users
Storage stops being a tier differentiator. The 2/4/5 ladder put one gigabyte between Starter and Business on a page that then had to explain what "pooled" meant...
Per-seat storage, and a flat Enterprise pool
2 GB per seat on Free, 4 on Starter, 5 on Business. Enterprise stops scaling with seats entirely - a flat 150 GB for the organization - which "N GB per seat" ca...
Seed KamoPBX platform defaults
Hibernate ddl-auto adds the SYSTEM_CONFIGURATION columns; @ColumnDefault only applies to newly inserted rows, so the existing singleton needs backfilling. Seed...
Per-extension PBX billing schema, backfill and catalog
PbxBillingSchemaMigration is @Order(0) because it adds a column. The shared-library entity maps phone_cost_mode from the moment the build starts, so any runner ...
One shared calendar per org, one primary per member
Provisioning had nothing underneath it, so two simultaneous first loads both inserted. Collapses what that already made β twenty duplicate rows across seven org...
Schema for member-connected inboxes
The old member-only unique on member_imap_configs is discovered by shape rather than by its Hibernate-generated name, and dropped only after the wider key exist...
Both mail add-ons are priced per mailbox
Prices unchanged at $5 and $2; only the unit changes. Copy now states what actually counts, and that aliases are unlimited and free.
One primary member per mailbox
is_primary was unique per member only, so two members could both claim a mailbox β and PrimaryMailboxIdentityLookup returns null on an ambiguous address, so tha...
DDL for the per-member line-window gate
Adds **************** defaulting to false. A column rather than a feature flag because there is no flag system here and MemberCapabilities is a closed, fail-cl...
Widen the comms spine to an owner, in the order that keeps it safe
LEAD_CONTACT_POINTS and LEAD_COMMUNICATIONS gain the document manager's (assoc_type, assoc_object_id) pair so an account, a patient or a commerce record can own...
Add the RingCentral JWT and direct-number columns
Order 0, because the shared-library entities map both columns from the moment this build starts: every runner that loads a PhoneExtension or a MemberVoipOAuthTo...
Create member_availability_window, retire the dated slot table
Creates member_availability_window, adds **************** and rebuilds webinar_child_org_restriction around the type plus an optional weekday. Drops webinar_ava...
Read pointers for SMS, AI chat, webinars and missed calls
Three of the five conversation surfaces had no server-side notion of read at all. All four columns are nullable with no backfill: null means never looked, which...
Move status off the ordinal and onto the name
Adds STATUS_NAME / STATUS_APPLIED_NAME, fills them from the ordinals, then drops the ordinal columns β in that order, which is the only order that keeps the dat...
A system report is a bug or an enhancement
ALTER rather than folded into the CREATE, because the table already exists everywhere this has reached. DEFAULT 0 is BUG, which is what every row filed before t...
Make orgs.alias unique platform-wide
The column was never constrained. Survivable while an alias was only resolved as (security_provider_id, alias) behind a host, since two orgs under different pro...
Put tenant_id back at the front of the clinical resource keys
ddl-auto built PRIMARY KEY (logical_id, resource_type, tenant_id) on fhir_resource_current and fhir_resource_version, because Hibernate emits @EmbeddedId column...
Create the System Bugs tables
No CHECK constraint on the ordinal columns: support_ticket_status_check is what happens when Hibernate freezes one at an enum's size and the enum then grows, an...
Price the commerce children and the EHR, with a totality guard
Neither pricing map had a totality check, and the two failure modes are different and both silent. Missing from CATALOG, an app lands nowhere on the pricing mat...
Extend market grandfathering into the app-tree backfill
grandfatherExistingGatedMarkets already walked each org's active markets, resolved getRequiredService() and enabled the missing app β it was just restricted to ...
Rich-text description columns on webinar_type
Mirrors the shared-lib entity change. Two things the table needs before MediaService maps them. The description column has to be unbounded: it holds a Lexical ...
Remember the last workspace a member signed in to
users.last_org_id backs the workspace picker. An organization is no longer named by the hostname, so a member who belongs to several chooses one after signing i...
Merge the two modified records into one with two layers
Where a document has both kinds, the CLASSIC row survives β it is the one that may hold edited bytes β the design is repointed onto it, and the FORM_FILLABLE ro...
Create the picture_frames table
One row per Picture Frame widget a member has arranged on their launchpad. A table rather than a preference blob because the photos and videos in a frame are i...
Add the master-scope columns to notes
MASTER_SCOPE ('MEMBER' / 'ORG' / NULL) and ORGANIZATION_ID, plus the two indexes the entity declares and a partial unique index per scope so one live master not...
Move existing designs onto FORM_FILLABLE rows
Before versions existed, putting form fields on a document attached an esign_templates row straight to the original, and the Modified tab was "originals that ha...
Add imgs.modified_kind and imgs.original_img_id
Both stay nullable β null kind means the row is an original, so there is nothing to backfill and no NOT NULL step, unlike the usual column-add shape. The parti...
Create the chat policy schema
Six tables: the versioned ruleset, its rules and their clauses, the reply grants behind "reply only while their window is open", and the trail of what the polic...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.