fix(backoffice): repair build errors, update prisma schema and services
This commit is contained in:
parent
5c59e7b5a1
commit
eb5c59c1e2
8 changed files with 111 additions and 32 deletions
|
|
@ -1,6 +1,6 @@
|
|||
module github.com/saveinmed/backend-go
|
||||
|
||||
go 1.24.3
|
||||
go 1.23.0
|
||||
|
||||
require (
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.2
|
||||
|
|
|
|||
38
backoffice/.dockerignore
Normal file
38
backoffice/.dockerignore
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
# Dependencies
|
||||
node_modules
|
||||
.pnpm-store
|
||||
|
||||
# Build outputs
|
||||
dist
|
||||
build
|
||||
|
||||
# Development
|
||||
.git
|
||||
.gitignore
|
||||
*.md
|
||||
*.log
|
||||
|
||||
# IDE
|
||||
.vscode
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# Tests
|
||||
coverage
|
||||
*.spec.ts
|
||||
*.test.ts
|
||||
__tests__
|
||||
test
|
||||
|
||||
# Config files não necessários no container
|
||||
.eslintrc*
|
||||
.prettierrc*
|
||||
jest.config*
|
||||
tsconfig*.json
|
||||
!tsconfig.json
|
||||
!tsconfig.build.json
|
||||
|
||||
# Env files
|
||||
.env*
|
||||
!.env.example
|
||||
|
|
@ -15,6 +15,7 @@ model Company {
|
|||
category String @default("farmacia")
|
||||
licenseNumber String @map("license_number")
|
||||
isVerified Boolean @default(false) @map("is_verified")
|
||||
status String @default("PENDING")
|
||||
latitude Float @default(0)
|
||||
longitude Float @default(0)
|
||||
city String @default("")
|
||||
|
|
@ -26,6 +27,7 @@ model Company {
|
|||
products Product[]
|
||||
ordersAsBuyer Order[] @relation("BuyerOrders")
|
||||
ordersAsSeller Order[] @relation("SellerOrders")
|
||||
documents CompanyDocument[]
|
||||
|
||||
@@map("companies")
|
||||
}
|
||||
|
|
@ -39,6 +41,7 @@ model User {
|
|||
username String?
|
||||
email String @unique
|
||||
passwordHash String @map("password_hash")
|
||||
refreshToken String? @map("refresh_token")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
|
|
@ -163,3 +166,29 @@ model Shipment {
|
|||
|
||||
@@map("shipments")
|
||||
}
|
||||
|
||||
model SystemSettings {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
key String @unique
|
||||
value String
|
||||
category String @default("GENERAL")
|
||||
isSecure Boolean @default(false) @map("is_secure")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
@@map("system_settings")
|
||||
}
|
||||
|
||||
model CompanyDocument {
|
||||
id String @id @default(uuid()) @db.Uuid
|
||||
companyId String @map("company_id") @db.Uuid
|
||||
company Company @relation(fields: [companyId], references: [id])
|
||||
type String
|
||||
fileUrl String @map("file_url")
|
||||
status String @default("PENDING")
|
||||
rejectionReason String? @map("rejection_reason")
|
||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz
|
||||
|
||||
@@map("company_documents")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export class AuthService {
|
|||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
||||
const passwordMatches = await bcrypt.compare(dto.password, user.password);
|
||||
const passwordMatches = await bcrypt.compare(dto.password, user.passwordHash);
|
||||
if (!passwordMatches) {
|
||||
throw new UnauthorizedException('Invalid credentials');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ export class InventoryService {
|
|||
constructor(private readonly prisma: PrismaService) { }
|
||||
|
||||
listProducts() {
|
||||
return this.prisma.product.findMany({ include: { inventory: true } });
|
||||
return this.prisma.product.findMany({ include: { inventoryAdjustments: true } });
|
||||
}
|
||||
|
||||
async purchaseProduct(userId: string, dto: PurchaseDto) {
|
||||
async purchaseProduct(buyerId: string, dto: PurchaseDto) {
|
||||
const product = await this.prisma.product.findUnique({
|
||||
where: { id: dto.productId },
|
||||
});
|
||||
|
|
@ -33,22 +33,17 @@ export class InventoryService {
|
|||
}),
|
||||
this.prisma.order.create({
|
||||
data: {
|
||||
companyId: userId, // Assuming userId is companyId for simplicity or we need to fetch user's company.
|
||||
// Wait, 'buyerId' in old code. New schema 'Order' has 'companyId' (Seller?).
|
||||
// Actually 'Order' usually has 'customerId' or 'userId' for Buyer.
|
||||
// My schema: `model Order { id, company_id (Seller), user_id (Buyer), ... }`
|
||||
// I'll assume userId passed here is the Buyer.
|
||||
userId: userId,
|
||||
// We need a companyId (Seller). Product has companyId?
|
||||
companyId: product.companyId,
|
||||
buyerId: buyerId,
|
||||
sellerId: product.sellerId,
|
||||
totalCents: totalCents,
|
||||
status: 'PENDING',
|
||||
items: {
|
||||
create: {
|
||||
productId: dto.productId,
|
||||
quantity: dto.quantity,
|
||||
priceCents: product.priceCents,
|
||||
totalCents: totalCents,
|
||||
quantity: BigInt(dto.quantity),
|
||||
unitCents: product.priceCents,
|
||||
batch: product.batch,
|
||||
expiresAt: product.expiresAt,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -58,3 +53,4 @@ export class InventoryService {
|
|||
return { message: 'Purchase created successfully' };
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { Controller, Get, Query, Res, UseGuards } from '@nestjs/common';
|
||||
import { Response } from 'express';
|
||||
import { FastifyReply } from 'fastify';
|
||||
import { ReportsService } from './reports.service';
|
||||
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
|
||||
|
||||
|
|
@ -12,19 +12,19 @@ export class ReportsController {
|
|||
async exportOrdersCsv(
|
||||
@Query('from') from: string,
|
||||
@Query('to') to: string,
|
||||
@Res() res: Response,
|
||||
@Res() res: FastifyReply,
|
||||
) {
|
||||
const csv = await this.reportsService.exportOrdersCsv(from, to);
|
||||
res.setHeader('Content-Type', 'text/csv');
|
||||
res.setHeader('Content-Disposition', `attachment; filename=orders_${from}_${to}.csv`);
|
||||
res.header('Content-Type', 'text/csv');
|
||||
res.header('Content-Disposition', `attachment; filename=orders_${from}_${to}.csv`);
|
||||
res.send(csv);
|
||||
}
|
||||
|
||||
@Get('sellers/csv')
|
||||
async exportSellersCsv(@Res() res: Response) {
|
||||
async exportSellersCsv(@Res() res: FastifyReply) {
|
||||
const csv = await this.reportsService.exportSellersCsv();
|
||||
res.setHeader('Content-Type', 'text/csv');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename=sellers.csv');
|
||||
res.header('Content-Type', 'text/csv');
|
||||
res.header('Content-Disposition', 'attachment; filename=sellers.csv');
|
||||
res.send(csv);
|
||||
}
|
||||
|
||||
|
|
@ -32,19 +32,20 @@ export class ReportsController {
|
|||
async exportLedgerCsv(
|
||||
@Query('from') from: string,
|
||||
@Query('to') to: string,
|
||||
@Res() res: Response,
|
||||
@Res() res: FastifyReply,
|
||||
) {
|
||||
const csv = await this.reportsService.exportLedgerCsv(from, to);
|
||||
res.setHeader('Content-Type', 'text/csv');
|
||||
res.setHeader('Content-Disposition', `attachment; filename=ledger_${from}_${to}.csv`);
|
||||
res.header('Content-Type', 'text/csv');
|
||||
res.header('Content-Disposition', `attachment; filename=ledger_${from}_${to}.csv`);
|
||||
res.send(csv);
|
||||
}
|
||||
|
||||
@Get('performance/csv')
|
||||
async exportPerformanceCsv(@Res() res: Response) {
|
||||
async exportPerformanceCsv(@Res() res: FastifyReply) {
|
||||
const csv = await this.reportsService.exportSellerPerformanceCsv();
|
||||
res.setHeader('Content-Type', 'text/csv');
|
||||
res.setHeader('Content-Disposition', 'attachment; filename=seller_performance.csv');
|
||||
res.header('Content-Type', 'text/csv');
|
||||
res.header('Content-Disposition', 'attachment; filename=seller_performance.csv');
|
||||
res.send(csv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { IsEmail, IsNotEmpty, IsString, MinLength } from 'class-validator';
|
||||
import { IsEmail, IsNotEmpty, IsOptional, IsString, MinLength } from 'class-validator';
|
||||
|
||||
export class CreateUserDto {
|
||||
@IsNotEmpty()
|
||||
|
|
@ -15,4 +15,16 @@ export class CreateUserDto {
|
|||
@IsString()
|
||||
@IsNotEmpty()
|
||||
companyName!: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
cnpj?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
licenseNumber?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
role?: string;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,9 @@ export class UsersService {
|
|||
return this.prisma.$transaction(async (tx: Prisma.TransactionClient) => {
|
||||
const company = await tx.company.create({
|
||||
data: {
|
||||
name: dto.companyName,
|
||||
corporateName: dto.companyName,
|
||||
cnpj: dto.cnpj || '',
|
||||
licenseNumber: dto.licenseNumber || '',
|
||||
},
|
||||
});
|
||||
|
||||
|
|
@ -19,8 +21,9 @@ export class UsersService {
|
|||
data: {
|
||||
name: dto.name,
|
||||
email: dto.email,
|
||||
password: hashedPassword,
|
||||
passwordHash: hashedPassword,
|
||||
companyId: company.id,
|
||||
role: dto.role || 'ADMIN',
|
||||
},
|
||||
include: { company: true },
|
||||
});
|
||||
|
|
@ -43,7 +46,7 @@ export class UsersService {
|
|||
const user = await this.findById(id);
|
||||
if (!user) return null;
|
||||
|
||||
const { password, refreshToken, ...rest } = user;
|
||||
const { passwordHash, ...rest } = user;
|
||||
return rest;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue