Files
2026-05-09 00:55:40 +07:00

56 lines
1.5 KiB
TypeScript

import { tripRepo } from "@/server/repositories/trip.repo";
import { participantRepo } from "@/server/repositories/participant.repo";
import { reviewRepo } from "@/server/repositories/review.repo";
import { isPastTripLastDayForReview } from "@/lib/trip-dates";
export type OrganizerReviewItem = Awaited<
ReturnType<typeof reviewRepo.findByOrganizer>
>[number];
export const reviewService = {
async upsertReview(
tripId: string,
userId: string,
input: { rating: number; comment?: string | null }
) {
const trip = await tripRepo.findById(tripId);
if (!trip) {
throw new Error("Trip tidak ditemukan");
}
if (trip.organizerId === userId) {
throw new Error("Organizer tidak bisa mengulas trip sendiri");
}
const participation = await participantRepo.findByTripAndUser(
tripId,
userId
);
if (!participation || participation.status !== "CONFIRMED") {
throw new Error(
"Hanya peserta yang terdaftar (aktif) yang bisa memberi ulasan"
);
}
if (!isPastTripLastDayForReview(trip.date, trip.endDate)) {
throw new Error(
"Ulasan bisa diberikan setelah tanggal selesai trip (hari terakhir aktivitas)"
);
}
return reviewRepo.upsert({
tripId,
userId,
rating: input.rating,
comment: input.comment ?? null,
});
},
async getReviewsByOrganizer(
organizerId: string,
limit?: number
): Promise<OrganizerReviewItem[]> {
return reviewRepo.findByOrganizer(organizerId, limit);
},
};