Add per-org primary application: toggle endpoint + by-host lookup
PUT **************** designates (or clears) a product's published application as the org's primary, mirroring the existing mlos-default single-active toggle. Ne...
Add a per-org primary application, and an APPLY domain alias
LeadVendorProduct gains isPrimaryApplication: at most one published application per org is "primary" and is the one kamo-apps renders at the root of the org's a...
Select-all/deselect-all for the states lead filter, default to all
The states dimension of the campaign audience panel's and drip trigger's lead filter showed nothing checked by default, even though an unset list already means ...
A computer could never restart into being able to sleep
The first real Hosted Computer reached AWAKE and then stayed awake forever. Hibernation reported resumeConfigured: false, IdleWatcher only arms when readiness i...
DKIM and DMARC steps, so email we send for an org is fully authenticated
Two new steps after the existing SPF one, written for a non-technical owner the same way SpfCard already is — plain language, a "why this matters" box, and neve...
Send the lead-filter query params the backend actually parses
**************** reads marketIds/vendorIds/ vendorProductIds/states as one comma-separated param each (splitList()), but campaignAudienceApi's appendLeadFilter(...
DKIM-sign transactional mail sent as an org's own domain
Once SecurityService confirms a domain's DKIM record is published (org_domains.dkim_verified), password resets, invitations and other transactional letters sent...
Wait long enough for a computer to finish waking
WAKE_TIMEOUT_MS was 180_000 and sat exactly on top of the VM's readiness probe, whose initialDelaySeconds was 180 and which KubeVirt renders as 190. A computer ...
DKIM and DMARC advisory endpoints for /setup/dns
Adds two endpoints alongside the existing SPF one, so an org's transactional mail (password resets, invitations, notifications) can carry a DKIM signature and t...
Start probing at 15s, not 190 — nothing could open on its first wake
A woken computer is only reachable once its Service has endpoints, and that happens when the readiness probe on 3389 first passes. initialDelaySeconds was 180, ...
Rename apps DNS alias to apply
The org's loan-application/patient-portal host is renamed from apps.<domain> to apply.<domain>. Update the Traefik IngressRoute's HostRegexp, the org-branding-b...
Rename apps DNS alias to apply
auto-cert's SUBDOMAINS list, the availability health-check URL and the middleware comment now match the apps -> apply subdomain rename in kamo-internal and secu...
Rename apps DNS alias to apply
The apps.* host serves the loan-application and patient-portal pages (kamo-apps), not app downloads, so rename the alias everywhere it is enumerated: KnownAlias...
Rename apps DNS alias to apply on the DNS setup studio
The apps.<domain> host serves the loan-application and patient-portal pages, not app downloads, so relabel the /setup/dns card and reserve "apply" instead of "a...
DKIM key fields for an org domain's transactional mail
Adds **************** to org_domains, mirroring the spf_verified/spf_checked_at pair already there — so a domain can hold a generated DKIM keypair and whether i...
Narrow a campaign's all-leads audience and drip triggers by market, vendor, product and state
The campaign editor's "All Leads" box and the drip trigger's lead filter could only match every lead the sender can see, with no way to target a market, vendor,...
**************** filters on campaign leads and drip triggers
The campaign editor's "All leads" audience source had no way to narrow who it reached beyond visibility scope. Adds a filter panel (Market -> Vendor -> Vendor P...
Xorg may not start from a remote session, so no computer opened
Guacamole connected, authenticated, and was hung up on: guacd: Security mode: Negotiate (ANY) guacd: Loading keymap "en-us-qwerty" guacd: RDP serve...
The nav opens a computer, it does not ask for a password
Being signed in to Kamo is the authentication that matters; asking again at the door of your own machine is a password prompt for its own sake. ComputeService m...
Traefik could not see the gateway, and it served at the wrong path
Opening a computer landed on the redirect service's fallback page — "the request reached the fallback page instead of being redirected. Check the Host header." ...
Opening a computer with no login yet asks for the password
Clicking a computer opened a browser tab that closed again, and said nothing. openHostedComputer opens its tab synchronously inside the click, because a popup ...
An org's own computers host gets a certificate and a route
computers is a standard alias now — every white-label org is told to point one at Kamo on /setup/dns, the way it points meet and sign — so two things had to fol...
The computers record on the DNS studio
One more card on /setup/dns, so an org configuring its domain is told about the host its Hosted Computers open on. Without it an org could follow the page to th...
Computers is a standard alias, and the link uses the org's own
Every white-label org points a fixed set of labels at Kamo and computers was not one of them, so an org could follow /setup/dns to the letter and still have a H...
Maintain commit_logs.translation_count at write time
DDL: **************** (column + partial-friendly index, applied to production already) and **************** (one-time catch-up, already run — 19,373 rows, all l...
Use the lean LeadVendorProduct reads, not the 8-way eager findById
Caller half of the kamo-shared-library fix: switches every findById() call on LeadVendorProductRepository in securityservice to whichever lean method matches wh...
CommitLog carries a maintained translation_count
Adds CommitLog.translationCount and **************** the library side of replacing the changelog translation-backfill sweep's GROUP BY .. HAVING scan with a pla...
Member_rights_applied writes only the difference, and reads roles in bulk
Two related fixes to MemberRightsAppliedService, both in the same file: 1. **************** (via recalcChunk) and **************** unconditionally deleted a...
Stop eager-fetching LeadVendorProduct's org chain for a single-id read
findById() on LeadVendorProduct pulls its default-EAGER vendor, which itself eager-fetches its own org AND its market (which eager-fetches ITS org again) — and ...
List only the Getting Started steps an organization is asked
An organization whose security model fixes every Compliance answer (no product a member may switch, one age range for each member type) was still counted agains...
A step the organization is not asked is not shown or counted
An organization whose security model fixes every Compliance answer (no product a member may switch, one age range for each member type) was still shown a ninth ...
Apply the auto-cert mirror Role on deploy
Applied to the cluster by hand when the gateway certificate was set up; this is the same grant in the deploy step, so a rebuilt cluster does not have to redisco...
Let auto-cert mirror the gateway certificate into this namespace
Listing computers.kamocrm.com for issuance is only half of it. Traefik requires a TLS secret in the IngressRoute's OWN namespace, so the cert is issued in `kamo...
Issue and mirror the certificate for computers.kamocrm.com
Opening a Hosted Computer produced a browser tab that appeared and vanished. The launch link is correct and so is the token: SecurityService builds ************...
A computer that has never restarted can never sleep
prepare-sleep writes the swap file and the resume wiring, then reports readiness — and readiness reads `resume=` from /proc/cmdline, which the kernel fixed at b...
Reinstall grub after virt-resize, or the guest boots to a rescue prompt
virt-resize renumbers partitions. Canonical's image is laid out p14 (BIOS boot), p15 (ESP), p16 (/boot) and then p1 (root) physically last, and virt-resize rewr...
Read the public changelog's commit counts from a ledger, not COUNT(*)
pg_stat_statements: `SELECT COUNT(c) FROM CommitLog c WHERE c.project IN (:~33 public projects) [AND c.commitTypeId = :t]` ran ~140K times a day at 100-200 ms e...
Fold and recount the public changelog's commit-log ledger
securityservice's create_commit_log_ledger.sql (applied by hand as the owner) adds commit_log_counts / commit_log_count_deltas: a total per (project, commit typ...
Stop asking three hot queries one row at a time
Three queries pg_stat_statements showed as kbservice's top production DB cost, all from asking in a loop (or with a plan the legacy YugabyteDB planner picked ba...
Batch two translation lookups the planner was doing badly per row
kbservice's public KB endpoints and its translation-retry sweep both asked KbArticleTranslationRepository one row at a time. Production's pg_stat_statements sho...
Only the platform namespaces can call ConversionService
The public route is gone (28ba91b), but inside the cluster any pod could still reach this service, and several endpoints take no credential because none of its ...
Gift cards take the Discounts tab's pricing rights
Listing gift cards, issuing one and editing one (including its balance, which the shared library sets again as of the companion kamo-shared-library commit) chec...
A gift card's balance is editable again, by whoever may manage pricing
19505faf stopped updateGiftCard from reading currentBalance so a member of one org could not rewrite another org's card by uid. The org-scoped lookup already cl...
Fictional people in the correspondent-name tests
They used a real lead's name and address from the report.
Fictional people in the correspondent-name tests
They used a real lead's name and address from the report.
Fictional people in the correspondent-name tests
They used a real lead's name and address from the report.
Fictional people in the correspondent-name tests
They used a real lead's name and address from the report.
The golden disk has to be RAW, or nothing boots and nothing says so
The job wrote the compressed qcow2 the build produces straight into the golden claim. KubeVirt attaches a Filesystem-PVC disk with <driver type='raw'> — always,...
The message list names a lead or contact, not their address
A row was headed by the sender's display name, or the part of the address before the @ when there was none, so a lead who wrote in read as "jlrivera1984" above ...
The message list names a lead or contact, not their address
A row was headed by the sender's display name, or the part of the address before the @ when there was none, so a lead who wrote in read as "rodarisdolgovanton" ...
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.
