Disable Docker BuildKit cache so every pipeline run does a full rebuild
Sets no-cache on both image build steps so npm ci and npm run build always run, even when the source tree is unchanged.
Bust Docker BuildKit cache per commit so npm run build runs every push
Identical checkout trees (e.g. empty commits) reused cached layers and skipped a real Next build. Pass GIT_COMMIT from the workflow and label the image revision...
Allow top-level org owners and system members to manage any org's domains
Sync members.email when primary mailbox is assigned, changed, or removed
When a mailbox was assigned to a member in a KAMO_MAIL org, members.email was never updated, causing EmailCredentialService to fail to resolve IMAP credentials ...
Prevent duplicate root domains and fix primary domain display
ONE_DOMAIN_PER_ORG check incorrectly excluded .kamocrm.com web-alias domains, allowing an org to accumulate multiple root domains (and 10 aliases each) by retry...
Serialize member-security and members PUT calls to avoid CockroachDB conflict
Two concurrent writes to the same `members` row caused a serializable isolation conflict — member-security read the row while the members endpoint wrote to it (...
Reduce org creation latency and fix translation cascade failures
- OrganizationController: replace ensureTeamMembersForAllOrgs (full org table scan) with ensureTeamMemberForOrg (single org) — eliminates the ~400ms×N DB ro...
Widen commit_log_translations.title to TEXT to match DB column
The column was VARCHAR(512) in both the annotation and the DB, causing translation inserts to fail for long translated titles. The DB column is now STRING (appl...
Unwrap catalog and calculation from backend response envelope
getSubscriptionCatalog returned { catalog: {...} } but was cast directly as SubscriptionCatalog, leaving catalog.plans undefined and the plan selection step bla...
Add @JsonProperty to is*-prefixed boolean DTO fields
Lombok generates isXxx() is-getters for boolean fields named isXxx. Jackson strips the leading 'is' from is-getters and serializes them as 'xxx' rather than 'is...
Use ss instead of fuser to kill stale port-forward (fuser not on k0m1)
fuser and lsof are not installed on the runner host. Use ss -tlnp with grep to extract the PID holding port 18080 and kill it directly. Also switch pkill to SIG...
Clean up stale port-forward so cancelled translate job doesn't block next run
Bash doesn't forward signals to backgrounded processes, so kubectl port-forward outlived cancelled workflow runs and held port 18080, blocking every subsequent ...
Restore all broken placeholder values across pages
Salvage-keys script had grabbed CSS classNames, inline styles, and JS template literals instead of the original English text for 114 message keys spanning notes...
Restore leads page hero title and subtitle from git history
heroTitle was 'Hero Title' (placeholder), heroSubtitle was 'flex gap-2' (salvage-keys accidentally grabbed the adjacent CSS class name). Correct values recovere...
Enable Finish button by polling widget.getState() and switching to auto=onload
The statechange event listener was not reliably enabling the Finish button after *** verification. Two root causes: 1. The drain logic read widgetAny.state whi...
Include subscription-targeting accounts in org list
listForOrg now also returns accounts whose subscriptions target the requested org — not just accounts directly owned by it. In the multi-org model the paying Ac...
Add statusWindow labels namespace and fix all setting placeholders
- Add **************** (50 keys) so the settings nav sidebar shows real text instead of key paths - Fix branchTypesLabel ICU format: \${branchLabel} → {branch...
Match other tool windows' size + color scheme
- defaultSize and minSize now 320x650, resizable: false (matches Softphone, Chat, Calculator, SMS, AI Chat) - Switched from dark slate gradient to the standard ...
Forward Range header so audio playback can scrub
Without this the VOIPService recording-streaming endpoint always returns the full file (Range header is dropped by buildForwardHeaders), which works for play-fr...
Rewrite /etc/odbc.ini to point at $MARIADB_HOST on every boot
The escomputers/freepbx:17 image bakes /etc/odbc.ini with Server=db (the docker-compose link target). On this Kubernetes deployment MariaDB lives at \$MARIADB_H...
Resolve member→extension before VM/CDR provider lookup
CallController was passing memberId where FreePBX (and other PBX-style providers) expect an extension number — voicemail listing returned empty because no PBX e...
Auto-assign first seat, Free as floor, broader org invalidation
BillingSetupService now activates the first open license slot for the creator when seeding a sub-org subscription (and same for promote-to-billing-owner) — othe...
Top-level org members get platform-owner plan, bypass billing gates
KamoCRM (top-level) org members are not subject to the billing system — they get the OWNER_UNLIMITED plan's feature matrix outright (with Free as a defensive fa...
Top-level org bypass + Free baseline fallback for orgs without subs
The org-level entitlement check **************** walks subscriptions targeting an org. With the new target_org model, orgs that don't yet have a targeting Accou...
Remove redundant Field history title from history panel
Tab label already conveys context — title and subtitle were wasting screen space. Reload button moved inline into the toolbar.
Remove layout prop causing email body bouncing
The outer motion.div's `layout` prop fought with the inner AnimatePresence height: 'auto' animation, creating a FLIP feedback loop on emails with unstable heigh...
Resolve duplicate column mapping by overriding embedded address columns to MAILING_*
Update RetailService and provider adapters for Account.notes removal and CurrencyType conversion
Always show Create Document button on doc manager page
Removed the getMemberId() > 0 guard that was hiding the button during the useUserInfo loading window. The page is already behind auth so no client-side membersh...
Restore organization import removed by accident
organization.id is still needed in the handleCreateDocument request body; only the isDocsEditor condition should have been removed.
Show Create Document button to all logged-in members
The org feature flag check (isDocsEditor → isDocs → hasFeature DOCS) was returning false because org features use deprecated key types. The button is now shown ...
Remove datagrid field-level filters and floating filter row
Disabled all column filters and the floating filter input row so the grid shows only column headers and data rows. Also removed the Filters tool panel from the ...
Move Upload button into DocManager toolbar
The Upload trigger was only in the /doc/manager page's actions prop, making it invisible when DocManager is embedded in other pages. Moved the Upload button dir...
Allow upload options to scroll in embedded DocManager
Uploads tab container was overflow:hidden, clipping per-file options (description, folder, doc type, access level) in height-constrained embedded contexts. Chan...
Fix 400 feed error and add communications sub-tabs with URL params
Fix double-? bug in MediaStream where feedEndpoint already contained query params but the fetch appended ?page=... instead of &page=..., causing a malformed URL...
Make 'All Leads' a real menu item with icons in agent filter
- Replace placeholder empty-value item with __ALL__ so the dropdown never shows blank when All Leads is selected - Add Group icon to All Leads and PersonOff i...
Consume *** secret so X-Internal-Auth matches downstream services
DaemonService -> ConversionService **************** was returning 401 Unauthorized because DaemonService was stamping its X-Internal-Auth header from INTERNAL_A...
Use @CreationTimestamp(source=DB) on ****************
The DB is the single source of truth for timestamps in this codebase. The canonical Hibernate pattern is @CreationTimestamp(source = SourceType.DB), which makes...
Let DB fill **************** via @Generated(INSERT)
INSERTs were failing with: null value in column "date_created" violates not-null constraint @ColumnDefault only declares the DB-side default for new rows; Hi...
Drop the [from-internal-custom] _X. catch-all that broke softphone calls
The catch-all exten => _X.,1 in [from-internal-custom] was intercepting every internal dial — softphones started reporting "phone is not registered" / calls wou...
Enable JPA repos for commerce + email + dao.repositories packages
ConversionService new pod CrashLoopBackOff with the same error DaemonService hit earlier: Parameter 0 of constructor in **************** required a bean of ...
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.
