🚀 Feature: Implement Global Super Admin access & bypass tenant filtering

This commit is contained in:
Hamza-Ayed
2026-04-22 22:47:53 +03:00
parent 944c82730d
commit 2f238e19c2
9 changed files with 128 additions and 84 deletions

View File

@@ -40,7 +40,7 @@ export class InvoicesController {
*/
@Get()
async findAllByTenant(@CurrentUser() user: any) {
return this.invoicesService.findAllByTenant(user.tenantId);
return this.invoicesService.findAllByTenant(user);
}
/**
@@ -48,14 +48,14 @@ export class InvoicesController {
* Upload an invoice file for a specific company
*/
@Post('upload/:companyId')
@Roles(UserRole.ADMIN, UserRole.ACCOUNTANT)
@Roles(UserRole.ADMIN, UserRole.ACCOUNTANT, UserRole.SUPER_ADMIN)
@UseInterceptors(FileInterceptor('file'))
async upload(
@CurrentUser() user: any,
@Param('companyId', ParseUUIDPipe) companyId: string,
@UploadedFile() file: Express.Multer.File,
) {
return this.invoicesService.upload(user.tenantId, companyId, file);
return this.invoicesService.upload(user, companyId, file);
}
/**
@@ -67,7 +67,7 @@ export class InvoicesController {
@CurrentUser() user: any,
@Param('companyId', ParseUUIDPipe) companyId: string,
) {
return this.invoicesService.findAll(user.tenantId, companyId);
return this.invoicesService.findAll(user, companyId);
}
/**
@@ -79,7 +79,7 @@ export class InvoicesController {
@CurrentUser() user: any,
@Param('id', ParseUUIDPipe) id: string,
) {
return this.invoicesService.findOne(user.tenantId, id);
return this.invoicesService.findOne(user, id);
}
/**
@@ -90,9 +90,9 @@ export class InvoicesController {
* Submit an invoice to the official JoFotara portal
*/
@Post(':id/submit')
@Roles(UserRole.ADMIN, UserRole.ACCOUNTANT)
@Roles(UserRole.ADMIN, UserRole.ACCOUNTANT, UserRole.SUPER_ADMIN)
async submit(@CurrentUser() user: any, @Param('id', ParseUUIDPipe) id: string) {
return this.invoicesService.submitToJoFotara(user.tenantId, id);
return this.invoicesService.submitToJoFotara(user, id);
}
/**
@@ -100,9 +100,9 @@ export class InvoicesController {
* Permanently delete an invoice
*/
@Post(':id/delete') // Using POST for delete to match frontend request style or use standard DELETE
@Roles(UserRole.ADMIN, UserRole.ACCOUNTANT)
@Roles(UserRole.ADMIN, UserRole.ACCOUNTANT, UserRole.SUPER_ADMIN)
async remove(@CurrentUser() user: any, @Param('id', ParseUUIDPipe) id: string) {
return this.invoicesService.remove(user.tenantId, id);
return this.invoicesService.remove(user, id);
}
/**
@@ -115,11 +115,11 @@ export class InvoicesController {
@Param('id', ParseUUIDPipe) id: string,
@Res({ passthrough: true }) res: Response,
) {
const streamableFile = await this.invoicesService.getFile(user.tenantId, id);
const streamableFile = await this.invoicesService.getFile(user, id);
// We need to determine the content type to ensure it opens inline in the browser (iframe)
// We can fetch the invoice details first to get the extension.
const invoice = await this.invoicesService.findOne(user.tenantId, id);
const invoice = await this.invoicesService.findOne(user, id);
let mimeType = 'application/pdf'; // Default fallback
if (invoice.original_file_path) {
const ext = invoice.original_file_path.split('.').pop()?.toLowerCase();