The member add, delete and role-change audit rows were awaited on the
request path, so a slow audit sink held the response, and the roster was
serialized before checking whether audit logging is enabled at all.
Membership audit work is now scheduled after the transaction commits and
skipped outright when auditing is off.
member_update read the roster outside the team advisory lock and wrote
it back, so a concurrent add or delete could be lost. It now takes the
lock, rereads the roster, and builds the before and after snapshots from
that read.
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
* feat(ui): add budget duration to edit team member form
Editing a team member created a member budget with no duration, so the
budget never reset. This threads a budget reset period through the edit
flow end to end and reuses the shared duration dropdown so the options
stay in sync with the rest of the UI.
Resolves LIT-2651
* fix(proxy): validate member budget_duration and persist clears
Reject budget_duration values that can't be parsed, are non-positive, or overflow date math before any write, so a bad value can't be persisted and later crash the budget reset job.
Clearing the budget duration in the edit-member form now sends null and clears the column end to end, so the dropdown's clear control reflects a real change instead of being a no-op
* chore(ui): regenerate schema.d.ts for member budget_duration
Adds budget_duration to TeamMemberUpdateRequest/Response in the generated dashboard types so the Check UI API Types Sync gate passes