Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 1 | /** |
| 2 | * Deleting an account. Mirrors `crates/contracts/src/account_deletion.rs`; | |
| 3 | * identity's `account_deletion.rs` does it. | |
| 4 | * | |
| 5 | * A person deletes their own account from Settings, typing their username | |
| 6 | * and proving it is them; g1t's staff can delete one from sudo with a | |
| 7 | * reason. Neither works while the account is the only owner of a live | |
| Merge sudo: delete an account with the workspaces it alone owns, purge each | 8 | * workspace, or for a protected account; staff may instead delete those |
| 9 | * workspaces with it (`withSoleWorkspaces`), unless one is protected or its | |
| 10 | * billing cannot settle. It is soft first: everything it | |
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 11 | * could sign in with ends at once and it leaves every workspace, and it is |
| 12 | * kept for `ACCOUNT_RESTORE_DAYS` for staff to restore. Then it is purged, | |
| 13 | * its username is never given to anyone again, and what it wrote shows as | |
| 14 | * `GHOST_USERNAME`. There is no API route for it: the site and sudo only. | |
| 15 | */ | |
| 16 | ||
| 17 | /** How long a deleted account is kept, for g1t's staff to restore, before it is purged. */ | |
| 18 | export const ACCOUNT_RESTORE_DAYS = 30; | |
| 19 | ||
| 20 | /** Who wrote what a purged account wrote. Reserved: nobody may register it. */ | |
| 21 | export const GHOST_USERNAME = "ghost"; | |
| 22 | ||
| 23 | /** `ghost`'s account id. */ | |
| 24 | export const GHOST_ID = "usr_ghost"; | |
| 25 | ||
| 26 | /** A live workspace the account is the only owner of: in the way until it has another owner or is deleted. */ | |
| 27 | export type SoleOwnedWorkspace = { | |
| 28 | slug: string; | |
| 29 | name: string; | |
| 30 | /** Everyone in it, the account included. */ | |
| 31 | members: number; | |
| Merge sudo: delete an account with the workspaces it alone owns, purge each | 32 | /** What billing needs before the workspace itself can be deleted; null when nothing. */ |
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 33 | billing: string | null; |
| Merge sudo: delete an account with the workspaces it alone owns, purge each | 34 | /** It can never be deleted, by anyone, so staff cannot delete it with the account either. */ |
| 35 | protected: boolean; | |
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 36 | }; |
| 37 | ||
| Merge sudo: delete an account with the workspaces it alone owns, purge each | 38 | /** A workspace staff deleted together with the account that alone owned it. */ |
| 39 | export type WorkspaceDeletedWith = { | |
| 40 | workspaceId: string; | |
| 41 | slug: string; | |
| 42 | }; | |
| 43 | ||
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 44 | /** What deleting an account takes with it, and what stands in the way. */ |
| 45 | export type AccountDeletion = { | |
| 46 | username: string; | |
| 47 | /** Live workspaces it is in, which it leaves. */ | |
| 48 | workspaces: number; | |
| 49 | /** Personal access tokens, classic and fine-grained. */ | |
| 50 | tokens: number; | |
| 51 | ssh_keys: number; | |
| 52 | /** Applications signed in as it. */ | |
| 53 | applications: number; | |
| 54 | /** Repositories it has a role on directly. */ | |
| 55 | repositories: number; | |
| 56 | sole_owner_of: SoleOwnedWorkspace[]; | |
| 57 | /** It can never be deleted, by anyone. */ | |
| 58 | protected: boolean; | |
| 59 | }; | |
| 60 | ||
| 61 | /** What went with a deleted account, counted when it was deleted, and who deleted it when it was staff. */ | |
| 62 | export type AccountWent = { | |
| 63 | workspaces: number; | |
| 64 | teams: number; | |
| 65 | repositories: number; | |
| 66 | tokens: number; | |
| 67 | sshKeys: number; | |
| 68 | /** The staff member who deleted it; null when the person did. */ | |
| 69 | staff: string | null; | |
| 70 | reason: string | null; | |
| Merge sudo: delete an account with the workspaces it alone owns, purge each | 71 | /** The workspaces it alone owned that staff deleted with it; each is restored or purged on its own. */ |
| 72 | deletedWorkspaces: WorkspaceDeletedWith[]; | |
| Merge account deletion: soft delete for 30 days, staff restore and purge, ghost for what remains (identity 0037) | 73 | }; |
| 74 | ||
| 75 | /** An account deleted and kept until `purgeAfter` for staff to restore. */ | |
| 76 | export type DeletedAccount = { | |
| 77 | userId: string; | |
| 78 | username: string; | |
| 79 | /** RFC 3339. */ | |
| 80 | deletedAt: string; | |
| 81 | /** RFC 3339: when it is purged unless restored first. */ | |
| 82 | purgeAfter: string; | |
| 83 | went: AccountWent; | |
| 84 | /** Whether staff can still restore it. */ | |
| 85 | restorable: boolean; | |
| 86 | }; |
This file's history is long; its oldest lines are credited to the oldest commit read.