-
Notifications
You must be signed in to change notification settings - Fork 117
Expand file tree
/
Copy pathdispute.service.ts
More file actions
85 lines (76 loc) · 2.29 KB
/
Copy pathdispute.service.ts
File metadata and controls
85 lines (76 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import {
ConflictException,
Injectable,
NotFoundException,
} from '@nestjs/common';
import {
DisputeRecord,
DisputeState,
EscrowRecord,
PrismaService,
toDisputeRecord,
} from '../../prisma/prisma.service';
import { EscrowRepository } from '../../escrow/escrow.repository';
import { ContractService } from '../../stellar/contract.service';
@Injectable()
export class DisputeService {
constructor(
private readonly escrowRepository: EscrowRepository,
private readonly contractService: ContractService,
private readonly prisma: PrismaService,
) {}
async getDisputes(query: {
status?: string;
page?: number;
limit?: number;
}): Promise<{
data: DisputeRecord[];
total: number;
page: number;
limit: number;
}> {
const page = Math.max(1, query.page ?? 1);
const limit = Math.min(100, Math.max(1, query.limit ?? 20));
const skip = (page - 1) * limit;
const where = query.status
? { status: query.status as DisputeState }
: undefined;
const [data, total] = await Promise.all([
this.prisma.dispute.findMany({
where,
orderBy: { createdAt: 'desc' },
skip,
take: limit,
}),
this.prisma.dispute.count({ where }),
]);
return { data: data.map(toDisputeRecord), total, page, limit };
}
/** Resolves a dispute by submitting the contract action and finalizing escrow state. */
async resolve(
escrowId: string,
resolution: 'RELEASE' | 'REFUND',
): Promise<EscrowRecord> {
const escrow = await this.escrowRepository.findById(escrowId);
if (!escrow) {
throw new NotFoundException('Escrow not found');
}
if (escrow.state === 'COMPLETED' || escrow.state === 'REFUNDED') {
throw new ConflictException('Dispute has already been resolved');
}
await this.contractService.resolveDispute(escrowId, resolution);
const dispute = await this.prisma.dispute.findFirst({
where: { escrowId, status: 'OPEN' },
});
if (dispute) {
await this.prisma.dispute.update({
where: { id: dispute.id },
data: { status: 'RESOLVED', resolvedAt: new Date() },
});
}
if (resolution === 'RELEASE') {
return this.escrowRepository.markCompleted(escrowId);
}
return this.escrowRepository.markRefunded(escrowId);
}
}