Busy state on Start Import + drop debug logs
- disable Start Import / Back and show a spinner + 'Importing…' while the import POST is in flight, preventing duplicate submissions on large files - remove [...
Correctness, scale & PII hardening in LeadImportController
- dedup via scoped LeadRepository query instead of findAll() over all tenants (was an OOM/DoS + cross-tenant exposure risk, re-run per 1000-row batch) - cap i...
Scope import dedup query + org-guard member/vendor-product assignment
- **************** scoped, projection-only duplicate lookup for the manual importer (replaces a per-batch findAll() that hydrated every lead across all tena...
Pin markedForReassignmentBy FK to INT8 (no inherited default)
Without columnDefinition, Hibernate copies members.id (INT8 DEFAULT unique_rowid()), so CockroachDB backfilled existing leads rows with bogus member ids on ALTE...
Stop refresh icon blinking via infinite check loop
Once a domain was SSL-confirmed, checkDns unconditionally built a new domain object even when sslConfirmed was already true. The new object reference re-trigger...
Return 422 (not 500) when member has no mailbox
listFolders and other read endpoints threw IllegalStateException from MailContext.toMailCredentials() when a member had no IMAP credentials provisioned, which t...
Don't fetch org with a precision-truncated id
LabelManager derived orgIdStr from getOrgIdString() (precision-safe) with a fallback to String(organization.id). organization.id is a JS number and silently tru...
Set site region + use node-local MinIO per pod
- Add kamo.minio.region (MINIO_REGION, default us-west-ca-s-1) so SigV4 signatures match the server's enforced site region; fixes background upload and sett...
Sign requests with configurable site region
MinIO now enforces MINIO_SITE_REGION (us-west-ca-s-1) in the SigV4 authorization scope since site replication was enabled. The client was built without a region...
Drop background images that 404 instead of showing a broken frame
Track failed background image loads and filter them out of the Swiper carousel, so an incompletely provisioned theme (e.g. optionone, whose bg/2.webp was never ...
Never return 401 from proxy (was logging users out on enter-as); degrade to empty
Proxy injects X-Member-Id from session (me endpoint 400'd, so trial banner never had data)
Show trial banner on the welcome homepage (app/page.tsx) top-right, not just NavTop
Trial banner shows for any TEAM_MEMBER (system/team/admin), drop god dependency
Gate homepage trial banner to staff (team members/admins/system), hide from plain members
Trial banner signal is org-level (all members of a trialing org), not seat-based
Explicit Apply/Extend Trial buttons on platform Organizations tab (chips weren't discoverable)
Comp provisioning clears trial deadline (comp supersedes trial)
In the existing-subscription update path of provisionCompSubscription, set trialExpiresAt to null so a previously trialling org is cleanly promoted to comp with...
Retry boot-time rights sync on transient DB unavailability to avoid CrashLoopBackOff
Persist background reorder via commit endpoint (no data loss)
Save now stages new uploads to incoming, then commits the full desired order (existing-by-srcIndex or new-by-token) so reordered existing images are re-slotted ...
Stop cross-org background image leak; order-safe reorder + staging bucket
Reordering only re-uploaded new files to their new index, dropping reordered existing images and leaving imageBgCount claiming unpopulated slots; provisioning t...
Return 404 for a missing org instead of 200 with empty body
getOrganizationById returned a bare null, which Spring serialized to HTTP 200 with an empty body; clients calling response.json() then threw 'Unexpected end of ...
Map missing org (404 or empty body) to a null payload
Pairs with the SecurityService change that now returns 404 for a missing org instead of 200-with-empty-body. Callers already null-check the org, so both the pro...
Let the System User resolve any org's applied model
The cross-org gate returned 403 when orgId != session org and the caller had no Member row in the target org. The platform-wide System User operates across ever...
Stop spurious errors flooding the console
- org/[id] proxy: backend returns 200 with an empty body for null orgs; response.json() threw 'Unexpected end of JSON input' -> spurious 500. Parse defensiv...
Resolve org tab title in generateMetadata to stop title flip
Static metadata.title rendered 'Kamo' server-side; Next re-asserted it after hydration, overriding DynamicMetaLoader's client update and flipping the tab back f...
Withhold rows until Myself member id resolves
ag-grid renders rowData beneath the loading overlay, so gating only the loading prop still flashed all leads while getMemberId() was 0. Blank the rows and stay ...
Default filter to Myself on load, hide market bar for single market, relocate toolbar
- Default agentFilter to __MYSELF__ at init + gate grid on userInfo load so it no longer flashes All Leads - Single market: auto-select it and hide the market-t...
URI-encode WOPISrc + trust all api.* WOPI hosts (multi-tenant)
Opening a doc for a non-kamocrm tenant failed with 'unauthorized WOPI host'. Docs's alias_groups only trusted api.kamocrm.com (the Docs-deployment env hardcoded...
Use k1m1 registry/API 192.168.4.22 (drop deprecated WireGuard IPs)
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Use cluster MinIO service DNS; drop deprecated WireGuard/CGNAT IPs and retired k2m1/k0m1
Correct FPBXCONF heredoc + repoint universe Scylla
- freepbx: the FPBXCONF here-document closing delimiter was indented (8 spaces); bash requires <<WORD delimiters at column 0, so startup.sh died with 'unexpec...
Canonicalize webhook repo name to public-projects casing
After the cluster migration the Forgejo repos were recreated lower-cased (securityservice), but historical rows and the public-projects filter use canonical cas...
Node-local MinIO + failover template read + ImgDat dedup (fixes new-doc about:blank)
New-document creation hung ~5 min and the new tab stayed at about:blank. Root cause: DocsService pods scheduled on k3m1 read the blank template from MinIO at th...
Generate favicons via multi-node logo read, not single-node exists()
generateAndUploadFavicons() gated on minioService.exists(), which only stats the current MinIO host. When the simple logo was written to (or only replicated ont...
Re-apply live stylesheet after branding save so new colors show without hard reload
DynamicMetaLoader injects the org globals.css only once on mount, so after a color save (which correctly re-provisions globals.css + bumps themeRevision) the pa...
Pin kamo Traefik to k1m1; make auto-cert single-cluster
SSL errors: kamo Traefik is a LoadBalancer with externalIPs 192.168.4.22 (k1m1) + externalTrafficPolicy=Local, so it MUST run on k1m1 — the pod rebalance moved ...
Null-safe split of the AiPullThroughPolicy single-active index (doc 09 §8)
CRDB is NULLs-distinct, so the single (lender_profile_id, market_id) WHERE status='ACTIVE' index did NOT backstop the org-wide (market_id IS NULL) grain — two c...
Recreate deploy strategy so NATS durable consumers rebind on deploy
DaemonService binds EXCLUSIVE JetStream durable consumers (daemon-sync-trigger, **************** [the §2.8 breach loop], daemon-recording-received) in @PostCons...
Enable OutboxRelay @Scheduled backstop + @Async hot path
DaemonService activates the MLOS transactional outbox (mlos.outbox.enabled) and produces events (the compliance-timer breach emitter), but lacked @EnableSchedul...
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.
