Scope calendars to the member, and add the org-wide publishing right
UserCalendar and CalendarEvent hung off USER_ID alone and carried no organisation. A user is global and a member is that user inside one organisation, so an acc...
PublicChatApiKey.scopes jsonb binding
A field with an initializer was skipped by the earlier jsonb sweep, so this one still bound as varchar: 'column scopes is of type jsonb but expression is of typ...
CockroachDB-only SQL that PostgreSQL rejects
CockroachDB spells the text type STRING; PostgreSQL and YugabyteDB use TEXT. 25 casts across native queries were still emitting CAST(x AS STRING) and ::STRING, ...
@Lob String must pin LONGVARCHAR or PostgreSQL reads it as an OID
Hibernate's PostgreSQL dialect maps @Lob String to an OID (large-object reference) and reads it with getLong(). CockroachDialect mapped the same annotation to p...
Count each file once per organization, not once per upload
Billing was per imgs record, so an organization that uploaded the same file five times was charged five times. The owner's rule is one charge per distinct file ...
Match stored content on BLAKE3 alone, so a browser can afford to ask
Proving possession required both hashes, and a browser has no fast SHA3-256 — js-sha3 is pure JavaScript at ~25 MB/s. Measured on a 358 MB video that was ~20 se...
Bill generated thumbnails to the organization
Thumbnails and per-channel tracks are storage an organization's uploads cause, so on the owner's instruction they now count toward that organization's total rat...
Count branding and Docstive document storage
Almost everything an organization stores records its own size somewhere — an imgs row, a kb_media row, a mailbox measurement. Two things do not. Branding assets...
Count text message attachments
MMS attachments are stored, and were not counted. They are also not what they look like: VoipMessageService encodes the attachment as a data: URI and writes it ...
Count each kind of stored file as its own category
Call recordings, voicemails, chat attachments, HR resources, marketing materials, meeting recordings and every kind of document are all rows in imgs, distinguis...
Measure the mail Kamo actually hosts, per mailbox
EMAIL was sourced from email_metadata.search_index, which was wrong in both directions. It missed KamoMail entirely — an org on KAMO_MAIL has its messages and a...
Read the latest snapshot date without loading the history
A summary needs one date. It was reading it by loading a two-year range of snapshots and taking the max — five domains times every day of history, on every page...
Per-organization storage usage model
Nothing has ever summed storage per organization. Six entities carry a byte count per file, and no code aggregated any of them, which is why the account stats t...
A platform product is not one of its own tenants
isOrgEntitledToApp exempted only the top-level org, so an org marked isPlatformProduct was billed as if it were a customer. sign.pink sits on a FREE_DEFAULT sub...
Stop a page load from persisting the entitlement projection
computeEffectiveFeatures added the caller's Hibernate-managed OrgFeature rows straight to its output and then flipped isActive on them. Its own javadoc calls th...
Pin the deprecated-alias exclusion
The catalog key is ServiceType's numeric id, and several retired constants deliberately share one with the app that replaced them — DOC_MANAGER with DOCS on 8, ...
Stop mortgage endpoints enforcing a personal-loan right
The LOS_* -> MLOS_* rename was applied to the enum declaration and nowhere else. Because the freed names were immediately re-declared as the personal-loan right...
Answer the plan-matrix question for every app in one pass
The Apps & Features tab asks whether each app appears in the plan matrix, and the per-app form scans the plan-feature and add-on tables once per app — two dozen...
Resolve deprecation through the app catalog
An app the operator retires has to disappear everywhere, not just from the apps page — otherwise it keeps showing up in the security-model editor and in entitle...
Make app availability and stage editable at runtime
Every attribute the apps settings page renders — display name, description, stage, deprecation — was a compile-time constant in the ServiceType enum, and "Avail...
Resolve app entitlement by ServiceType; rename LOS to MLOS
Entitlement resolved ServiceType.name() against **************** The catalog's codes are marketing codes (USERS, VIDEO_CONF, HR_SYSTEM, ...) and never matched, ...
Stream content-addressed storage so an object can exceed heap
Chat attachments are moving to a 3 GiB ceiling. storeContentAddressed took a byte[], which cannot express that at all — a Java array stops at Integer.MAX_VALUE ...
Script the half of the scan invariant this repo cannot see
SharedLibBeanSafetyTest can only police the library: it knows a bean requires a repository from some package, and nothing about whether the ~40 services scan it...
Detect the unsafe repository dependencies instead of listing them
The guard carried 29 baselined offenders and a location exemption, and caught none of the four outages it exists to prevent. Both were guesses standing in for a...
Stop the mailbox pointer from failing startup platform-wide
DepartmentService is a @Service, and every service carries @ComponentScan("com.kamo"), so all ~40 of them construct it. Giving it a MailboxRepository therefore ...
The five envelope-lifecycle email templates that were never written
An e-signature envelope had exactly two templates: the invite and the step-up code. Nothing existed for anything that happens AFTER a signer signs — which is wh...
Let a department and an org point at one of their mailboxes
A department's contact email was free text, so it could name an address the org does not own -- two of the three departments with one set today do exactly that....
A manager, and a directory search that survives a big org
TeamMember gains an optional self-reference for who it reports to. columnDefinition is pinned to INT8 so Hibernate cannot copy Member.ID's DEFAULT unique_rowid(...
Let a department sit under a parent department
Departments were a flat list, so an org chart with Operations > Customer Success > Onboarding had no way to say so. Department gains an optional self-referencin...
Stamp AccountAddress dates so an address can actually be saved
DATE_CREATED is NOT NULL with a DEFAULT now(), but nothing ever set the field. Hibernate names every insertable column in its INSERT, so it sent an explicit NUL...
Make the atomic claims actually atomic, and stop starving the oldest payout
An adversarial review of the money path found the concurrency design was not running at all. @Modifying without @Transactional. Spring Data opens no transactio...
Find a member's commission splits for their own commissions view
Org-scoped rather than keyed on the member alone: ORG_ID is duplicated onto this table so a row can never be read cross-tenant by id, and a finder that ignored ...
Team-member commission ledger and Stripe payout domain
Adds com.kamo.z.shared.commission: an append-only signed ledger, a per-member balance row that exists purely to serialize concurrent withdrawals, the Commission...
Stop HTML-escaping the package title in the four HR subjects
EmailTemplateService renders a template's SUBJECT and BODY from ONE variable map, and all four canonical HR subjects carry {{packageTitle}} — which LegalNotific...
Four canonical HR legal-package templates
hr.package_assigned, hr.package_reminder, hr.package_voided and hr.package_completed, as {json,html} pairs plus four CANONICAL_KEYS entries. The CONSTANT is no...
Let a caller own the realtime announcement of the message it is still building
createMessage announced every new message on the session's realtime subject the moment the row was saved — inside the caller's transaction, before the caller ha...
One security right per Human Resources tab
The /hr tabs were gated on whichever pre-existing HR right happened to be an OR-term in the front end: Attendance opened on VIEW_SCHEDULES, Training on VIEW_EMP...
Expose the content-addressed store so chat attachments can dedup
Chat attachments never went through the hashing pipeline — they wrote a private "<imgId>/<fileName>" object per upload, so the same file attached three times oc...
Store every image in one bucket so dedup means one copy
Association is metadata, not a storage boundary. Each ImageAssocType used to name its own MinIO bucket, which contradicted the hashing pipeline: dedup is scoped...
Copy a deduplicated document's objects into its own association bucket
Object storage is bucket-per-association (every reader resolves img.getAssocId().getBucket()), but deduplication is scoped ORG-wide or GLOBALly and so crosses a...
Let sync progress and domain state be announced instead of polled
Two hooks for the push conversion in SecurityService, where several platform screens refreshed on timers because there was no way to tell them anything. Retail...
Make the audience FKs and the attested wording actually hold
Five defects from the whole-branch review, all in the evidence path. The audience FKs did not cascade. cascade = CascadeType.DETACH is a persistence-context ca...
Record package attestation as append-only evidence
The package-level 'I have read and agree' is a different legal instrument from the E-SIGN consent to transact and from any per-document signature, and it is the...
Add per-member assignments and per-document progress
The document row is the join that makes N e-sign envelopes read as one package. The badge count comes off the assignment status, not e-sign status: recipient st...
Freeze package content into immutable versions
Pins the ImgDat blob id and its SHA-256, not just imgId — a Docs save repoints the same Img at new bytes, so imgId alone would let two members sign different do...
Target a package at departments, job types or named members
Shaped on SystemUserAccess. Adds the audience resolver to TeamMemberRepo, which was an empty interface; the ACTIVE + recordState predicate is what keeps termina...
Add the legal package template entities
A package is an ordered set of binders plus an audience. Binder references are soft ids because binders are user-deletable and cascade their items. The attestat...
Narrow binder visibility to one document collection
Replaces findVisibleToMember with a scoped variant and drops the two unreferenced finders that sorted by the dead date_updated column.
Give a binder the document collection it belongs to
Binders had no assoc scoping, so every DocManager rendered the same global per-member pool and a binder built under Marketing could be filled with HR documents....
Map the metadata array columns as Java arrays, not List
Both entities declared their array columns as List<T> under an explicit @JdbcTypeCode(SqlTypes.ARRAY). On Hibernate 6.2.13 that combination resolves the array's...
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.
