Stop RingCentral OAuth signing white-label tenants out
Two faults, both on the same hop, and each one hides the other. RingCentral rejects every scope value this app can ask for β "invalid_request / Parameter [scop...
Show cents on an add-on rate that has them
Additional Storage is $2.50 per 10 GB block, and the catalog stores that as a number β so 2.50 arrives as 2.5 and rendered straight into the card it read "+$2.5...
Settle Additional Storage at $2.50 per 10 GB block
Confirms the block size and rate as $2.50 per 10 GB rather than the $4 per 25 GB the production row had drifted to. The seeder, the catalog row, the Stripe pric...
Price Additional Storage as $4 per 25 GB unit, FLAT not metered
Additional Storage is bought by the unit, belongs to no plan on any tier, and is not seat-based. The seeder still described it as $2.50 per 10 GB block, which i...
Attach stack traces to their log line, and fix levels I got wrong
printStackTrace() writes to stderr directly, so 186 of them survived the println sweep untouched β still unconditional, still unattributed, and now detached fro...
Finish taking SecurityService off System.out/err
The remaining 853 println calls across 43 files, none of which could be turned off: println has no level, so every one of them printed on every code path that r...
Take CNAME verification off System.out
With the session and Hibernate noise gone this was the largest recurring source left in the pod log: every CNAME lookup drew a seven-line box on stdout. That wa...
Take session lookup off System.out, and its *** id with it
After the previous commit removed the Hibernate session-metrics blocks and MemberController's per-request tracing, this was 88% of what remained: every session ...
Stop the pod log rotating faster than it can be read
Roughly 4,600 lines in four minutes, so the retention window was a couple of minutes: chasing a certificate problem on 2026-08-22 the probe output had already r...
Correct what the add-on binding gap actually was in production
The previous commit's reasoning was inferred from the loader, not measured. It claimed every KamoCRM add-on row had service_type NULL and that hosted mail was t...
Stop offering Business the add-ons it already includes
Choosing Business still presented video conferencing, the AI assistant, the HR system and e-signatures as things to buy, even though the plan bundles all four. ...
Bind add-ons to the app they sell, and stop Business granting mail free
**************** is the column **************** matches on. KamoCRMPricingLoader never wrote it, so every KamoCRM add-on row has it NULL and that comparison can...
Stop selling add-ons the chosen plan already includes
The catalog has always recorded which add-ons a plan bundles, in **************** β Business and Enterprise carry video conferencing, the AI assistant, the HR s...
Let the SSL check lower the flag, not only raise it
checkDns only ever latched sslConfirmed to true. A domain whose stored flag was set under the old any-one-host rule therefore kept a green SSL card and an unloc...
Verify-dns answers for the present, not for a stored flag
The endpoint skipped probing entirely when ssl_confirmed was already true, on the reasoning that under the all-hosts rule it could only have been set when every...
Re-verify domains already marked SSL-confirmed, and heal them
findAwaitingVerification filters confirmed domains out by design, so once ssl_confirmed was set nothing ever looked at that domain again. That was fine while th...
Open the swatch's own colour window, not the first on the page
The swatch reached its hidden <input type="color"> through document.getElementById on an id built from the picker's translated label. A label is only unique ins...
Stop the colour group fighting the colour you are choosing
ModernColorGroup was controlled and uncontrolled at the same time. It kept local state for every slot, mirrored the `value` prop into that state in one effect, ...
auto-cert: let the junk-cert cleanup actually see the junk it was written for
cleanup_orphan_certificates() listed with '-l auto-cert.kamo/fqdn'. That label is newer than the scanner certs the function exists to remove, so the selector ex...
Read the new org's id when it arrives quoted
The last step of the wizard appeared to do nothing, and clicking Create a second time answered that the organization already exists β because the first click ha...
Make post-commit org setup actually write, and heal the orgs it missed
A @Transactional method called from **************** does not open a transaction of its own. Spring fires those callbacks from processCommit BEFORE cleanupAfter...
auto-cert: issue an org's certificates as a batch, not one every 90 seconds
A new organization needs a certificate for all eleven of its hosts, and each one is a separate cert-manager Certificate. The loop waited for each host to become...
Confirm SSL only when every org host has its own certificate
Certificates are minted one per FQDN -- a single dnsName each, so the leaf CN matches the hostname the browser connected to -- and auto-cert works through an or...
Show per-host certificate progress, not a single spinner
Certificates are issued one per subdomain, and they do not all land at once, so the SSL step now reports how many of the org's hosts are live and names the ones...
Lift the wallpaper and widget shortcuts above the media pod
The profile header band laid "My Wallpapers", "My Widgets" and the media chrome out as one wrapping row, so the two shortcuts read as a fourth switch sitting al...
Point frame media at an endpoint that actually serves it
Every photo and video in a picture frame rendered as a broken image. The URL pointed at **************** I took that for a general imaging proxy β it speaks HT...
Serve frame media ourselves, with Range
Every photo rendered as a broken image. The URL pointed at MediaService's **************** which I took for a general imaging proxy because it spoke HTTP Range....
Drop the greeting block and put the masthead on one row
The launchpad's masthead carried a kicker, a "good afternoon" heading and a status line of apps/title/trial/date beside the logo, and the member's own controls ...
Move Binders and Uploads to the right of the strip
The strip now separates what a document manager IS from where it takes you. Left: Originals, Modified, Common β three views of the same documents. Right: the fo...
Make the Spirit Animal visible, and stop the palette vanishing
Two reports, two different mistakes of mine. THE PATTERN WAS INVISIBLE. It painted behind the pane, and every pane surface β FeatureCard, LauncherParentCard, W...
Rebuild 533bbeb4 now the Expression strings are in the dictionary
The image build clones kamo-translation-dictionary and copies it over messages/, then fails if a component names a key those messages do not define. 533bbeb4 wa...
Set the headline in quotation marks
Quotes around the banner line, as asked β but rendered from CSS (`open-quote`/`close-quote` against `quotes: auto`) rather than typed into the string, for two r...
Expression β colour, Spirit Animal and logo as one decision
Two corner controls become one. That split was an accident of the order the features shipped rather than a distinction anybody holds: a colour, a pattern and th...
Count on the Binders tab, and land on Selected Docs
The tab reads "Binders (n)" so the count the Selected Docs binder holds is visible from the strip β including (0), which is the case worth seeing, since it says...
The picture frame IS the pane, not something inside one
Every other widget is content in the launchpad's frosted glass card, with a header, a title and a corner control. A picture frame is not: rendered that way it i...
Drop the frozen ordinal CHECKs that were failing every new enum value
imgs_assoc_id_check allowed assoc_id 0..13. ImageAssocType.PICTURE_FRAME is ordinal 14, so EVERY Picture Frame upload violated it. Hibernate writes CHECK (col ...
Show which layers of a modified document were worked on
A document has one modified record, so the Modified tab has one row per document. The column names the layers touched rather than which of two kinds a row was: ...
Rebuild e67f59b against the dictionary commit it needs
e67f59b renamed previewBanner.nowLive -> previewBanner.headline and was pushed before the matching kamo-translation-dictionary commit (f4627d31). The build step...
Open the one modified record, whichever layer asked
getOrCreateClassic and getOrCreateFormFillable collapse into getOrCreateModified: "open this for editing" means the same thing whichever editor asked, and the a...
Trade the NOW LIVE badge for the headline it was hiding
The top banner led with a six-character pill β bordered, uppercase, pulsing β and put the actual message after it. The pill now carries the message itself: "Run...
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...
One modified record with two layers, not two records
A document had up to two derived rows β CLASSIC for edited bytes, FORM_FILLABLE for fields β and something had to decide which was based on the other, repointin...
Picture Frame β a member's own photos and videos, in a frame they build
The first INSTANCED widget. A member hangs as many frames as they like, each with its own contents, its own moulding and its own place in the grid, all from one...
Frame and media endpoints, and seed the new rights
Self only, and enforced in the QUERY. Every read and write resolves the member from the session and every repository call takes that id, including the single-fr...
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...
The schema, rights and storage domain behind frame widgets
A Picture Frame is a member's own photos and videos on their own launchpad, and a member may hang several. This is everything the platform needs to hold one. P...
Stamp last_login so "Last Login" stops reading Never
Nothing in SecurityService has ever written users.last_login. The write lived in the retired AuthenticationService and was not carried over when authentication ...
Put the four member shortcuts on one row
are one class of control, so they now share one row: the launchpad's top-right corner reads as a single strip rather than a two-line stack. styling; it uses th...
Stop /validate and /logout from mounting the signed-in shell
A load of / showed a burst of 401/403 before the session settled β user-info, ui-preferences, by-department, chat/unread, timezone/effective and tickets/pending...
Restore the status endpoint the frontend has been polling
kamo-internal polls GET /api/security/session/god-mode once on mount and every 60s thereafter. That endpoint was removed in 9c70cb7 along with the rest of the t...
Like what you see shipping?
Every one of these updates lands in your workspace automatically. Start free and watch it grow week after week.