56 lines
1.5 KiB
TypeScript
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);
|
|
},
|
|
};
|