per-user trade-direction access scope

This commit is contained in:
Marshal
2026-08-02 22:29:58 +00:00
parent c055abe8c1
commit f4fd469643
47 changed files with 1451 additions and 107 deletions

View File

@@ -9,7 +9,11 @@ import {
import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger";
import type { Response } from "express";
import { CurrentUser } from "@edr/api-common";
import type { TCurrentUser } from "@tria-plc/api-common/modules/auth/types/current-user.type";
import { BookingView } from "../../common/booking-guards";
import { UserTradeAccessService } from "../user-trade-access/user-trade-access.service";
import { BillingService } from "./billing.service";
import { FilterInvoiceDto } from "./dto/filter-invoice.dto";
@@ -18,14 +22,26 @@ import { FilterInvoiceDto } from "./dto/filter-invoice.dto";
@BookingView()
@ApiBearerAuth()
export class BillingController {
constructor(private readonly billingService: BillingService) {}
constructor(
private readonly billingService: BillingService,
private readonly userTradeAccessService: UserTradeAccessService,
) {}
@Get("invoices")
@ApiOperation({
summary: "List invoices (paginated, filterable by company/status/search)",
})
findAll(@Query() query: FilterInvoiceDto) {
return this.billingService.findAllPaginated(query);
async findAll(
@Query() query: FilterInvoiceDto,
@CurrentUser() user: TCurrentUser,
) {
// Per-user trade-direction scope, applied via each invoice's source booking.
const allowed =
await this.userTradeAccessService.resolveAllowedDirections(user);
return this.billingService.findAllPaginated({
...query,
tradeDirections: allowed ?? undefined,
});
}
@Get("invoices/:id")

View File

@@ -4,6 +4,7 @@ import { TypeOrmModule } from "@nestjs/typeorm";
import { BillingController } from "./billing.controller";
import { PortalBillingController } from "./portal-billing.controller";
import { PaymentController } from "./payment.controller";
import { UserTradeAccessModule } from "../user-trade-access/user-trade-access.module";
import { BillingService } from "./billing.service";
import { DocumentsModule } from "./documents/documents.module";
import { Invoice } from "./entities/invoice.entity";
@@ -19,6 +20,7 @@ import { CompaniesModule } from "../companies/companies.module";
forwardRef(() => PaymentModule),
CompaniesModule,
DocumentsModule,
UserTradeAccessModule,
],
controllers: [BillingController, PortalBillingController, PaymentController],
providers: [BillingService, InvoiceRepository, InvoiceLineRepository],

View File

@@ -11,6 +11,7 @@ import { EventEmitter2 } from "@nestjs/event-emitter";
import { DataSource, EntityManager, In } from "typeorm";
import { CompaniesService } from "../companies/companies.service";
import { applyBookingRefDirectionScope } from "../user-trade-access/trade-scope.util";
import { PaymentService } from "../payment/payment.service";
import { InitiateResponseDto, IntentStatusDto } from "../payment/payments.dto";
import {
@@ -167,6 +168,8 @@ export class BillingService {
search?: string;
page?: number;
pageSize?: number;
/** Per-user trade-direction scope, applied via the source booking. */
tradeDirections?: string[];
} = {},
): Promise<{ items: Invoice[]; total: number }> {
const page = filter.page && filter.page > 0 ? filter.page : 1;
@@ -196,6 +199,14 @@ export class BillingService {
);
}
if (filter.tradeDirections) {
applyBookingRefDirectionScope(
qb,
"invoice.source_id",
filter.tradeDirections,
);
}
const [items, total] = await qb.getManyAndCount();
return { items, total };
}