- Ya
- 4 Septemba 2026, 19:18 UTC
- Mwandishi
- Kamo
- Ahadi ya
- 866f9be
Three additions, all of them the shared half of work that lands in SecurityService and kamo-internal. PlatformRightType.MANAGE_USERS, appended. A user account is the person; a member is one organization's relationship with that person. Every other member-facing list on the platform is scoped to one organization by construction and the Users tab deliberately is not, so it reaches every tenant at once — a strictly larger blast radius than the org estate, and therefore not MANAGE_ORGANIZATIONS' job. Appended rather than inserted because getSortOrder() is the ordinal. UserEmailChangeRequest, with its repository. USERS.EMAIL is the second of the three sign-in identifiers and the address password recovery writes to, so it cannot be written from a form: whoever reaches a signed-in browser for thirty seconds would otherwise be able to point account recovery at a mailbox they own. The new address is parked here until a code and a link prove delivery. Its own table rather than columns on email_verification_tokens — that table is NOT NULL throughout and populated, and a new non-nullable column on a populated table is silently never created without a DEFAULT. USER_EMAIL_CHANGE_VERIFY and USER_EMAIL_CHANGED. The first goes to the address being claimed and is what makes the change take effect at all. The second goes to the address being left behind and is the only notice somebody whose session was stolen will ever get, which is why it is sent although nobody asked for it. Both pinned by a test: a half-added canonical pair throws inside loadAll() and breaks seeding for every organization on the platform, not just its own.