saveinmed/backoffice/src/disputes/disputes.service.ts
Tiago Yamamoto 36d6fa4ae0 feat: Implement Phase 4 features
Backend (Go):
- FCM Push Notifications (fcm.go, push_handler.go)
- Credit Lines (credit_line.go, credit_handler.go)
- Payment Config (admin_handler.go, seller_payment_handler.go)
- Team Management (team_handler.go)

Backoffice (NestJS):
- Dashboard module (KPIs, revenue charts)
- Audit module (tracking changes)
- Disputes module (CRUD, resolution)
- Reports module (CSV export)
- Performance module (seller scores)
- Fraud module (detection, alerts)

Frontend (Marketplace):
- ThemeContext for Dark Mode
- HelpCenter page with FAQ
- OrderDetails with timeline
- Team management page
- Persistent cart (Zustand)
2025-12-27 10:07:05 -03:00

107 lines
3.3 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
interface DisputeFilter {
page: number;
limit: number;
status?: string;
}
@Injectable()
export class DisputesService {
constructor(private prisma: PrismaService) { }
async list(filter: DisputeFilter) {
const offset = (filter.page - 1) * filter.limit;
let whereClause = '';
if (filter.status) {
whereClause = `WHERE status = '${filter.status}'`;
}
const disputes = await this.prisma.$queryRawUnsafe<any[]>(`
SELECT d.*,
o.id as order_id,
o.total_cents,
buyer.name as buyer_name,
seller.corporate_name as seller_name
FROM disputes d
LEFT JOIN orders o ON d.order_id = o.id
LEFT JOIN users buyer ON d.buyer_id = buyer.id
LEFT JOIN companies seller ON d.seller_id = seller.id
${whereClause}
ORDER BY d.created_at DESC
LIMIT ${filter.limit} OFFSET ${offset}
`);
const countResult = await this.prisma.$queryRawUnsafe<[{ count: bigint }]>(`
SELECT COUNT(*) as count FROM disputes ${whereClause}
`);
return {
disputes,
total: Number(countResult[0]?.count || 0),
page: filter.page,
limit: filter.limit,
};
}
async getById(id: string) {
const disputes = await this.prisma.$queryRaw<any[]>`
SELECT d.*,
o.id as order_id,
o.total_cents,
o.status as order_status,
buyer.name as buyer_name,
buyer.email as buyer_email,
seller.corporate_name as seller_name
FROM disputes d
LEFT JOIN orders o ON d.order_id = o.id
LEFT JOIN users buyer ON d.buyer_id = buyer.id
LEFT JOIN companies seller ON d.seller_id = seller.id
WHERE d.id = ${id}::uuid
`;
return disputes[0] || null;
}
async create(data: {
orderId: string;
buyerId: string;
sellerId: string;
reason: string;
description: string;
}) {
await this.prisma.$executeRaw`
INSERT INTO disputes (id, order_id, buyer_id, seller_id, reason, description, status, created_at, updated_at)
VALUES (
gen_random_uuid(),
${data.orderId}::uuid,
${data.buyerId}::uuid,
${data.sellerId}::uuid,
${data.reason},
${data.description},
'open',
NOW(),
NOW()
)
`;
return { status: 'created' };
}
async resolve(id: string, data: {
resolution: string;
refundAmountCents?: number;
notes: string;
}) {
await this.prisma.$executeRaw`
UPDATE disputes
SET status = 'resolved',
resolution = ${data.resolution},
refund_amount_cents = ${data.refundAmountCents || 0},
admin_notes = ${data.notes},
resolved_at = NOW(),
updated_at = NOW()
WHERE id = ${id}::uuid
`;
return { status: 'resolved' };
}
}