From 6459e5b5009fe68a9fdf379b10916b2f7cf594aa Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 7 Mar 2026 04:44:42 -0800 Subject: [PATCH] fix(tenants): allow platform_admin to delete tenants; fix invite/user cleanup - DELETE /api/v1/admin/tenants/:id now accepts platform_admin role - Fix cascade cleanup to use tenant slug (not UUID) for users/invites/api_keys Co-Authored-By: Claude Sonnet 4.6 --- .../interfaces/rest/controllers/tenant.controller.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/services/auth-service/src/interfaces/rest/controllers/tenant.controller.ts b/packages/services/auth-service/src/interfaces/rest/controllers/tenant.controller.ts index 5e71f82..ac0f6a8 100644 --- a/packages/services/auth-service/src/interfaces/rest/controllers/tenant.controller.ts +++ b/packages/services/auth-service/src/interfaces/rest/controllers/tenant.controller.ts @@ -397,7 +397,7 @@ export class TenantController { * DELETE /api/v1/admin/tenants/:id */ @Delete(':id') - @Roles('platform_super_admin') + @Roles('platform_admin', 'platform_super_admin') async deleteTenant(@Param('id') id: string) { const tenant = await this.findTenantOrFail(id); @@ -409,8 +409,14 @@ export class TenantController { this.logger.error(`Failed to deprovision schema for "${tenant.slug}":`, err); } - // 2. Delete all invites for this tenant - await this.inviteRepository.delete({ tenantId: id }); + // 2. Delete related records (use slug — invite.tenantId stores slug) + await this.inviteRepository.delete({ tenantId: tenant.slug }); + await this.dataSource.query( + `DELETE FROM public.users WHERE tenant_id = $1`, [tenant.slug], + ); + await this.dataSource.query( + `DELETE FROM public.api_keys WHERE tenant_id = $1`, [tenant.slug], + ); // 3. Delete the tenant record await this.tenantRepository.remove(tenant);