feat: multi-tenant user delete scope + conditional keycloak wait

- Add GET /users/{user_id}/tenant-count endpoint
- Add scope query param (current|all) to DELETE /users/{user_id}
- UserService.delete_user now supports scope='all' to deactivate/remove
  user from all tenants
- Frontend users.ts: getTenantCount(), delete() accepts scope param
- Frontend +page.svelte: async openDeleteDialog fetches tenant count,
  shows 4-button dialog when user belongs to >1 tenant
- docker-entrypoint.sh: Keycloak wait now conditional on WAIT_FOR_KEYCLOAK=1
This commit is contained in:
2026-05-04 14:17:12 -05:00
parent f241e88e21
commit 7ea8a4ba8d
5 changed files with 178 additions and 26 deletions

View File

@@ -125,14 +125,33 @@ export const usersAPI = {
return response.data!;
},
/**
* Retorna en cuántos tenants está registrado el usuario.
*/
async getTenantCount(userId: string, companyId: number): Promise<number> {
const response = await api.get<{ tenant_count: number }>(
`/v1/core/users/${userId}/tenant-count?company_id=${companyId}`
);
if (response.error) {
throw new Error(response.error);
}
return response.data!.tenant_count;
},
/**
* Elimina un usuario
*/
async delete(userId: string, companyId: number, softDelete: boolean = true): Promise<void> {
async delete(
userId: string,
companyId: number,
softDelete: boolean = true,
scope: 'current' | 'all' = 'current'
): Promise<void> {
const queryParams = new URLSearchParams();
queryParams.set('company_id', companyId.toString());
queryParams.set('soft_delete', softDelete.toString());
queryParams.set('scope', scope);
const response = await api.delete(`/v1/core/users/${userId}?${queryParams}`);
if (response.error) {
throw new Error(response.error);