135 lines
4.9 KiB
Markdown
135 lines
4.9 KiB
Markdown
# NestJS Backend Audit Report
|
|
|
|
- **Auditor Role**: NestJS Backend Auditor
|
|
- **Date**: 2026-08-06
|
|
- **Repository HEAD**: `715873b2ecc3a72ba974bb2a2be87c5ba82bd4e7`
|
|
- **Included Scope**: `backend/src/**/*`, `backend/package.json`, `backend/tsconfig.json`, `backend/nest-cli.json`, backend tests.
|
|
- **Excluded Scope**: `**/node_modules/**`, `backend/dist/**`, `frontend/**`.
|
|
- **Files Inspected**: `backend/src/orders/orders.service.ts`, `backend/src/common/metrics.controller.ts`, `backend/prisma/seed.ts`, `backend/src/pets/pets.controller.spec.ts`, `backend/src/users/users.controller.spec.ts`, `backend/src/main.ts`.
|
|
- **Commands Executed**: `cmd /c "backend\node_modules\.bin\tsc.cmd --noEmit -p backend\tsconfig.json"`.
|
|
- **Commands Blocked**: `npm run lint` (contains `--fix`), `nest start`, `prisma db push`.
|
|
- **Audit Limitations**: Evaluated via static AST and TypeScript compiler diagnostics.
|
|
|
|
---
|
|
|
|
## Domain Overview & Confirmed Strengths
|
|
- **Modular NestJS Architecture**: Clear domain encapsulation (`auth`, `users`, `pets`, `products`, `orders`, `settings`, `redis`, `prisma`).
|
|
- **Global Pipes & Filters**: Configured `ValidationPipe` with `whitelist: true`, `forbidNonWhitelisted: true`, and custom `HttpExceptionFilter`.
|
|
|
|
---
|
|
|
|
## Evaluation of 6 Existing TypeScript Compiler Diagnostics
|
|
1. `backend/prisma/seed.ts(54,7)`: Property `slug` missing in `ProductCreateInput`. -> **Seed-only schema mismatch error**.
|
|
2. `backend/src/common/metrics.controller.ts(18,32)`: Type referenced in decorated signature requiring type import. -> **Production type-import declaration error**.
|
|
3. `backend/src/pets/pets.controller.spec.ts(71,19)`: Property `success` does not exist on pet object. -> **Stale spec test error**.
|
|
4. `backend/src/settings/settings.controller.spec.ts(65,19)`: Property `success` does not exist on setting object. -> **Stale spec test error**.
|
|
5. `backend/src/users/users.controller.spec.ts(42,12)`: `result` is possibly null. -> **Strict null check test error**.
|
|
6. `backend/src/users/users.controller.spec.ts(89,19)`: Property `success` does not exist on address object. -> **Stale spec test error**.
|
|
|
|
---
|
|
|
|
## Findings
|
|
|
|
## BE-001
|
|
|
|
### Title
|
|
Unsafe Floating Point arithmetic and Non-Atomic Calculation in Order Total Service
|
|
|
|
### Domain
|
|
NestJS Backend
|
|
|
|
### Category
|
|
Financial Calculations / Transaction Integrity
|
|
|
|
### Severity
|
|
HIGH
|
|
|
|
### Confidence
|
|
CONFIRMED
|
|
|
|
### Status
|
|
OPEN
|
|
|
|
### Affected Application
|
|
NestJS Backend (`backend/`)
|
|
|
|
### Affected Files
|
|
- `backend/src/orders/orders.service.ts`
|
|
|
|
### Relevant Symbols or Lines
|
|
- `backend/src/orders/orders.service.ts#L10-L23` (`create` method)
|
|
|
|
### Evidence
|
|
In `OrdersService.create`:
|
|
```typescript
|
|
let totalAmount = 0;
|
|
for (const item of createOrderDto.items) {
|
|
const product = await this.prisma.product.findUnique({ where: { id: item.productId } });
|
|
...
|
|
totalAmount += Number(product.priceValue) * item.quantity;
|
|
}
|
|
```
|
|
|
|
### Problem
|
|
1. Converts database `Decimal` (`priceValue`) to JavaScript native IEEE-754 floating-point `Number`, inducing rounding precision errors on large currency values or Iranian Rial/Toman amounts.
|
|
2. Performs N+1 synchronous database queries inside an un-transactional `for` loop to look up product prices individually.
|
|
|
|
### Root Cause
|
|
Use of native JS primitive numbers for monetary arithmetic instead of Prisma `Decimal` or `Decimal.js` instance operations.
|
|
|
|
### Why It Matters
|
|
Causes decimal truncation rounding inaccuracies in order subtotals and introduces N+1 performance bottlenecks during checkout under load.
|
|
|
|
### User or Business Impact
|
|
Discrepancies between calculated order totals and actual line-item sums in financial reporting and invoice billing.
|
|
|
|
### Technical Impact
|
|
Increases database latency and risks database lock timeouts during batch checkouts.
|
|
|
|
### Security or Data-Integrity Impact
|
|
High risk of financial balance miscalculations.
|
|
|
|
### Recommended Direction
|
|
Use `Decimal.js` (included with Prisma) to accumulate monetary amounts and batch product lookup using `findMany({ where: { id: { in: ids } } })`.
|
|
|
|
### Alternative Direction
|
|
Calculate total amount on the database level via interactive Prisma transaction `$transaction`.
|
|
|
|
### Implementation Complexity
|
|
MEDIUM
|
|
|
|
### Dependencies
|
|
None.
|
|
|
|
### Risks
|
|
None.
|
|
|
|
### Verification Requirements
|
|
Test creating order with 10 products having precision decimals (e.g. `150000.50` * 3) and verify total sum matches exactly without floating-point expansion (`450001.50000000006`).
|
|
|
|
### Testing Requirements
|
|
Unit test `OrdersService.create` with large decimal inputs.
|
|
|
|
### Acceptance Criteria
|
|
`totalAmount` maintains exact decimal precision in database insertion.
|
|
|
|
### Notes and Limitations
|
|
Prisma schema defines `totalAmount` as `@db.Decimal(15,2)`.
|
|
|
|
---
|
|
|
|
## Finding Summary
|
|
- **CRITICAL**: 0
|
|
- **HIGH**: 1
|
|
- **MEDIUM**: 0
|
|
- **LOW**: 0
|
|
- **INFO**: 0
|
|
|
|
- **CONFIRMED**: 1
|
|
- **HIGH_CONFIDENCE**: 0
|
|
- **NEEDS_VERIFICATION**: 0
|
|
- **SPECULATIVE**: 0
|
|
|
|
## Completion Statement
|
|
NestJS Backend audit completed. 1 HIGH severity finding confirmed. 6 compiler diagnostics classified.
|