mirror of
https://github.com/HeyPuter/puter.git
synced 2026-09-26 07:06:08 +00:00
feat: delete a team seat for good, once it is disabled
A disabled account persists indefinitely. Removing it is an explicit request, never a timer, and it is refused on a live account with `account_must_be_disabled_first` — which puts a reversible step in front of the only irreversible operation in the feature. The audit row is written before `cascadeDelete` runs. The FKs are ON DELETE SET NULL and the `_keep` columns carry the identifiers, so the record of what was done survives the account it names. No second billing emit here: `cascadeDelete` already captures the seat and fires `team.account.deleted` through UserAccountService, and emitting again would close the storage charge twice. Disabling closed the per-account charge; this closes the storage one, and it is the only thing that does. There is no restore window, and none was wanted: the reversible step already exists earlier at disable, a disabled account costs only the bytes it holds so nothing pressures a hasty delete, and a restore promise means retaining data the team explicitly asked to be rid of. Published in rate-limits-and-quotas.md alongside the team-deletion note, since the two are easy to confuse and only one of them frees a seat. Closes PUT-1732.
This commit is contained in:
@@ -200,6 +200,8 @@ A reset returns a temporary password once and never again. It stops working 24 h
|
||||
|
||||
Deleting a team frees the owner's slot, but it does **not** free the seats: the accounts it created still exist, still hold their files, and keep their usernames. They are disabled, not removed — deleting a team is not a way to stop paying for the accounts in it.
|
||||
|
||||
Removing a seat for good is a separate, explicit request, and it is refused unless the account is already disabled (`account_must_be_disabled_first`). That ordering puts a reversible step in front of the only irreversible operation in the feature. **There is no restore window**: deletion removes the files, returns the username to the pool, and invalidates every credential. Nothing expires a disabled account on a timer — it persists, costing only the bytes it holds, until someone asks for it to go.
|
||||
|
||||
Lowering the seat limit never disables anyone. A team already above a reduced limit keeps every account it has and is simply refused new ones until it is back under.
|
||||
|
||||
Both limits are per deployment (`max_teams_per_user`, `max_seats_per_team`) rather than per team, so raising them moves every team at once.
|
||||
|
||||
Reference in New Issue
Block a user