Files
calendar/packages/trpc/server/routers/viewer/bookings/hasWrongAssignmentReport.handler.ts
Joe Au-YeungGitHubDevin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
c0504993a6 feat: Write wrong assignment reports to the database (#27405)
* Add DB table for wrong assignment reports

* When report is submitted write to the db

* Prevent duplicate reportings

* test: add migration and tests for WrongAssignmentReport table

Co-Authored-By: [email protected] <[email protected]>

* fix: add unique constraint on bookingUid and booking access check for hasWrongAssignmentReport

- Add @unique constraint on bookingUid in WrongAssignmentReport model to prevent duplicate reports at DB level
- Add booking ownership check using BookingAccessService in hasWrongAssignmentReport endpoint
- Refactor hasWrongAssignmentReport into separate handler and schema files

Addresses Cubic AI review feedback on PR #27405

Co-Authored-By: unknown <>

* feat: add routingFormId to WrongAssignmentReport and fix Select clearing

- Add routingFormId field to WrongAssignmentReport model in schema.prisma
- Add relation to App_RoutingForms_Form with SetNull on delete
- Update WrongAssignmentReportRepository.createReport to accept routingFormId
- Update BookingRepository.findByUidIncludeEventTypeAndTeamAndAssignmentReason to include routedFromRoutingFormReponse
- Extract routingFormId from booking in reportWrongAssignment handler
- Fix Select clearing issue: handle null case when user clears team member selection
- Update tests to include routingFormId field

Co-Authored-By: [email protected] <[email protected]>

* chore: add migration for routingFormId in WrongAssignmentReport

Co-Authored-By: [email protected] <[email protected]>

* fix: address Udit's review comments

- hasWrongAssignmentReport: throw UNAUTHORIZED error instead of returning false
- reportWrongAssignment: add try-catch for Prisma P2002 unique constraint error
- WrongAssignmentReport: add Team relation to teamId field
- WrongAssignmentReportRepository: use findUnique instead of findFirst
- reportWrongAssignment: use i18n for error messages

Co-Authored-By: [email protected] <[email protected]>

* fix: revert hasWrongAssignmentReport to return false when user lacks access

Per PR checklist, hasWrongAssignmentReport should return { hasReport: false }
when user lacks access to booking, not throw an error. This allows the UI
to gracefully treat 'no access' as 'no report exists'.

Co-Authored-By: [email protected] <[email protected]>

* test: update mocks for findUnique and i18n in unit tests

Co-Authored-By: [email protected] <[email protected]>

* fix: throw UNAUTHORIZED in hasWrongAssignmentReport and squash migrations

Co-Authored-By: [email protected] <[email protected]>

* fix: change User relation onDelete from Cascade to SetNull in WrongAssignmentReport

Address Hariom's review feedback:
- Changed reportedById from Int to Int? (nullable)
- Changed reportedBy relation from onDelete: Cascade to onDelete: SetNull
- Updated migration SQL to reflect these changes

This preserves wrong assignment reports even when the reporting user is deleted,
as the data is still useful for analysis.

Co-Authored-By: [email protected] <[email protected]>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-02-10 08:00:01 -03:00

34 lines
1.2 KiB
TypeScript

import { BookingAccessService } from "@calcom/features/bookings/services/BookingAccessService";
import { WrongAssignmentReportRepository } from "@calcom/features/bookings/repositories/WrongAssignmentReportRepository";
import prisma from "@calcom/prisma";
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
import { TRPCError } from "@trpc/server";
import type { THasWrongAssignmentReportInputSchema } from "./hasWrongAssignmentReport.schema";
type HasWrongAssignmentReportOptions = {
ctx: {
user: NonNullable<TrpcSessionUser>;
};
input: THasWrongAssignmentReportInputSchema;
};
export const hasWrongAssignmentReportHandler = async ({ ctx, input }: HasWrongAssignmentReportOptions) => {
const { user } = ctx;
const { bookingUid } = input;
const bookingAccessService = new BookingAccessService(prisma);
const hasAccess = await bookingAccessService.doesUserIdHaveAccessToBooking({
userId: user.id,
bookingUid,
});
if (!hasAccess) {
throw new TRPCError({ code: "UNAUTHORIZED", message: "You don't have access to this booking" });
}
const repo = new WrongAssignmentReportRepository(prisma);
return { hasReport: await repo.existsByBookingUid(bookingUid) };
};