- Shipped
- August 19, 2026 at 2:02 AM UTC
- Author
- kamo
- Commit
- 1709c43
Sweep of the client half of the int64 id work. Each of these took an id the server had sent intact and put it through Number()/parseInt(), which rounds anything past 2^53 -- so the request named a row that does not exist. Several sat next to a sibling call that already sent the same id exactly, which is what makes them visible: - binderApi.shareBinder sent Number(memberId) while unshareBinder sends it whole, so a binder could be shared and then not unshared. - MemberCreateForm sent Number(memberId) to assign a mailbox, then used the same id intact in the primary-mailbox path one call later -- two calls, two different members. - The e-sign signer pickers rounded the member id, the account uid and the account member id, attaching signers to ids that do not exist. - Commerce orders parsed a typed purchaserUid with parseInt, so pasting a real 19-digit uid created the order against a different purchaser. - PipelineApplicationsTab adapted mortgageAppsApi's exact string uid with Number(), and that rounded uid then drove routing AND **************** -- a status write against the wrong loan application. Its dedupe Map and selection Set are now keyed by String(uid); the two endpoints answer with different JS types for the same application, so a numeric key could never match a string one. Types widen to `string | number` rather than `string`: a number is what a service that has not been rebuilt still sends, and it is already rounded by then. The two arithmetic uses of a uid were demo seeding, not identity, and now coerce explicitly and locally. scripts/check-int64-zod-ids.mjs joins npm test and closes the door on the specific trap that started this: a zod union takes the FIRST matching branch, so z.union([z.coerce.number(), z.string()]) parses an exact id straight back into a lossy double while reading almost identically to the correct order. Mutation-tested against the original OrganizationDTOSchema defect.