- Shipped
- October 5, 2026 at 3:25 PM UTC
- Author
- Kamo
- Commit
- f6e8e8f
POST **************** (and the /create and /bulk-create paths that share MemberCreationService.create) take an optional teamIds for a person or an AI (master R1-36). Absent, null and [] name no team and need no right, so a create without teams is unchanged. - Checked after the AI checks and before the user lookup, each refusal with field teamIds and nothing written: 400 INVALID_FIELD, 403 NOT_ALLOWED without MANAGE_MEMBER_SECURITY or an open god window (Creator.maySetTeams, filled by creatorOf), 400 NOT_A_TEAM_MEMBER for a base member, 409 TOO_MANY_TEAMS over 25 (no read), 400 TEAM_NOT_FOUND for another org's or an unknown team, 400 TOO_MANY_MEMBERS for a full team (TeamValidator.newMemberTeams). - Written by TeamWriter.joinNewMember, MANDATORY with no @RetryOnDbConflict, through the new teams.NewMemberTeams, right after the member's save and before the mirror, the first applied rights (which so include the TEAM level) and an AI's hire; flushed, never caught: a member never exists with half its teams. A 40001 is retried whole by the caller (the existing 503 RETRY). - TeamService.afterCommit tells the TeamChangeListeners once the creation commits, never after a rollback; the welcome stays after the commit (a8966fd). Rulings CP01-T14A-1..3; master CP-D96.
