feat: gate treasury as an org module and group money inputs

Link optional invoice and cheque settlements to cash accounts, and let superadmin enable the finance module per organization.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-10-18 19:33:09 +03:30
co-authored by Cursor
parent ab538b8304
commit 8981a552fc
25 changed files with 509 additions and 33 deletions
+18 -5
View File
@@ -1,16 +1,19 @@
import { Body, Controller, Get, Param, Patch, Post, Query, StreamableFile, UseGuards } from '@nestjs/common';
import { Body, Controller, Get, Param, Patch, Post, Query, StreamableFile, UploadedFile, UseGuards, UseInterceptors } from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { memoryStorage } from 'multer';
import { JwtAuthGuard } from '../auth/jwt-auth.guard';
import { RolesGuard } from '../auth/roles.guard';
import { Roles } from '../auth/roles.decorator';
import { CurrentUser } from '../auth/current-user.decorator';
import { OrgModuleGuard } from '../billing/org-module.guard';
import { RequireOrgModule } from '../billing/org-module.decorator';
import { TreasuryAccessGuard } from './treasury-access.guard';
import type { Actor } from '../common/record-scope';
import { TreasuryOpsService } from './treasury-ops.service';
import { TreasuryReceivablesService } from './treasury-receivables.service';
import { TreasuryService } from './treasury.service';
@Controller('treasury')
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('owner', 'admin')
@UseGuards(JwtAuthGuard, OrgModuleGuard, TreasuryAccessGuard)
@RequireOrgModule('treasury')
export class TreasuryController {
constructor(
private readonly treasury: TreasuryService,
@@ -92,6 +95,16 @@ export class TreasuryController {
return this.treasury.createDocument(user, body);
}
@Post('documents/:id/attachments')
@UseInterceptors(FileInterceptor('file', { storage: memoryStorage(), limits: { fileSize: 8_000_000 } }))
addAttachment(
@CurrentUser() user: Actor,
@Param('id') id: string,
@UploadedFile() file: { originalname: string; mimetype: string; buffer: Buffer },
) {
return this.treasury.addAttachment(user, id, file);
}
@Post('documents/:id/settle')
settle(
@CurrentUser() user: Actor,