import { Knex } from 'knex'; import { Dispute, DisputeEvent, createDisputeTables } from './dispute-flow.model'; export class DisputeFlowService { constructor(private knex: Knex) {} async init(): Promise { await createDisputeTables(this.knex); } async createDispute(disputeData: Omit): Promise { const [dispute] = await this.knex('disputes').insert(disputeData).returning('*'); // Log the creation event await this.logDisputeEvent(dispute.id, 'dispute_created', disputeData.opened_by_user_id, { ...disputeData, disputeId: dispute.id }); return dispute; } async getDispute(id: number): Promise { return await this.knex('disputes').where({ id }).first(); } async updateDisputeStatus(disputeId: number, status: Dispute['status'], updatedByUserId: number): Promise { const dispute = await this.getDispute(disputeId); if (!dispute) { throw new Error(`Dispute with id ${disputeId} not found`); } await this.knex('disputes') .where({ id: disputeId }) .update({ status, updated_at: this.knex.fn.now() }); // Log the status change event await this.logDisputeEvent(disputeId, 'status_changed', updatedByUserId, { oldStatus: dispute.status, newStatus: status }); } async addEvidence(disputeId: number, evidenceData: any, uploadedByUserId: number): Promise { const dispute = await this.getDispute(disputeId); if (!dispute) { throw new Error(`Dispute with id ${disputeId} not found`); } // Log the evidence upload event await this.logDisputeEvent(disputeId, 'evidence_added', uploadedByUserId, { ...evidenceData, disputeId }); } async resolveDispute(disputeId: number, decision: string, reason: string, resolvedByUserId: number): Promise { const dispute = await this.getDispute(disputeId); if (!dispute) { throw new Error(`Dispute with id ${disputeId} not found`); } await this.knex('disputes') .where({ id: disputeId }) .update({ status: 'resolved', final_decision: decision, final_reason: reason, decided_by_user_id: resolvedByUserId, decided_at: this.knex.fn.now(), updated_at: this.knex.fn.now() }); // Log the resolution event await this.logDisputeEvent(disputeId, 'dispute_resolved', resolvedByUserId, { decision, reason, disputeId }); } async logDisputeEvent(disputeId: number, eventType: string, actorUserId: number, payload: any): Promise { await this.knex('dispute_events').insert({ dispute_id: disputeId, event_type: eventType, actor_user_id: actorUserId, payload_json: payload, created_at: this.knex.fn.now() }); } async getDisputeEvents(disputeId: number): Promise { return await this.knex('dispute_events').where({ dispute_id: disputeId }).orderBy('created_at', 'asc'); } }