Skip to content
92 changes: 49 additions & 43 deletions backend/disputes/disputeController.ts
Original file line number Diff line number Diff line change
@@ -1,47 +1,53 @@
import { disputeService } from "./disputeService";

export const create = async (req, res) => {
try {
const data = await disputeService.create(req.body, req.user.id);
res.json(data);
} catch (e) {
res.status(400).json({ error: e.message });
import type { Request, Response } from "express";
import { asyncHandler, AppError } from "../src/middleware/errorHandler.js";
import { disputeService } from "./disputeService.js";
import type { CreateDisputeDto, ResolutionOutcome } from "./disputeModel.js";

function requireUser(req: Request): { id: string; tenantId: string; role: string } {
if (!req.user) {
throw new AppError(401, "Authentication required", "UNAUTHORIZED");
}
};

export const respond = async (req, res) => {
const data = await disputeService.respond(
req.params.id,
req.user.id,
req.body.content
);
res.json(data);
};

export const uploadEvidence = async (req, res) => {
const data = await disputeService.addEvidence(
req.params.id,
req.user.id,
{
url: `/uploads/${req.file.originalname}`,
name: req.file.originalname,
size: req.file.size,
description: req.body.description,
}
);
return req.user;
}

export const create = asyncHandler(async (req: Request, res: Response) => {
const user = requireUser(req);
const dto = req.body as CreateDisputeDto;
const data = await disputeService.create(dto, user.id, user.tenantId);
res.status(201).json(data);
});

export const respond = asyncHandler(async (req: Request, res: Response) => {
const user = requireUser(req);
const data = await disputeService.respond(req.params.id, user.tenantId, user.id, req.body.content);
res.json(data);
};

export const resolve = async (req, res) => {
try {
const data = await disputeService.resolve(
req.params.id,
req.user,
req.body
);
res.json(data);
} catch (e) {
res.status(403).json({ error: e.message });
});

export const uploadEvidence = asyncHandler(async (req: Request, res: Response) => {
const user = requireUser(req);
if (!req.file) {
throw new AppError(400, "A file is required", "DISPUTE_EVIDENCE_FILE_REQUIRED");
}
};

const data = await disputeService.addEvidence(req.params.id, user.tenantId, user.id, {
url: `/uploads/${req.file.originalname}`,
name: req.file.originalname,
size: req.file.size,
description: req.body.description,
});

res.status(201).json(data);
});

export const resolve = asyncHandler(async (req: Request, res: Response) => {
const user = requireUser(req);
const payload = req.body as { outcome: ResolutionOutcome; resolutionNote: string; refundAmount?: number };
const data = await disputeService.resolve(req.params.id, user.tenantId, user, payload);
res.json(data);
});

export const getAnalytics = asyncHandler(async (req: Request, res: Response) => {
const user = requireUser(req);
const data = await disputeService.getAnalytics(user.tenantId);
res.json(data);
});
9 changes: 7 additions & 2 deletions backend/disputes/disputeRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ import {
respond,
uploadEvidence,
resolve,
} from "./disputeController";
getAnalytics,
} from "./disputeController.js";

const router = express.Router();
// In-memory storage: evidence files are re-hosted at a stable URL by the
// upload handler itself (see disputeController.uploadEvidence), not served
// directly from multer's buffer.
const upload = multer();

router.post("/", create);
router.get("/analytics", getAnalytics);
router.post("/:id/respond", respond);
router.post("/:id/evidence", upload.single("file"), uploadEvidence);
router.post("/:id/resolve", resolve);

export default router;
export default router;
Loading
Loading