Skip to content

feat: booking audit log#22817

Closed
alishaz-polymath wants to merge 10 commits intomainfrom
feat/booking-audit-log
Closed

feat: booking audit log#22817
alishaz-polymath wants to merge 10 commits intomainfrom
feat/booking-audit-log

Conversation

@alishaz-polymath
Copy link
Member

@alishaz-polymath alishaz-polymath commented Jul 30, 2025

What does this PR do?

Visual Demo (For contributors especially)

A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).

Video Demo (if applicable):

  • Show screen recordings of the issue or feature.
  • Demonstrate how to reproduce the issue, the behavior before and after the change.

Image Demo (if applicable):

  • Add side-by-side screenshots of the original and updated change.
  • Highlight any significant change(s).

Mandatory Tasks (DO NOT REMOVE)

  • I have self-reviewed the code (A decent size PR without self-review might be rejected).
  • I have updated the developer docs in /docs if this PR makes changes that would require a documentation change. If N/A, write N/A here and check the checkbox.
  • I confirm automated tests are in place that prove my fix is effective or that my feature works.

How should this be tested?

  • Are there environment variables that should be set?
  • What are the minimal test data to have?
  • What is expected (happy path) to have (input and output)?
  • Any other important info that could help to test that PR

Checklist

  • I haven't read the contributing guide
  • My code doesn't follow the style guidelines of this project
  • I haven't commented my code, particularly in hard-to-understand areas
  • I haven't checked if my changes generate no new warnings

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 30, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/booking-audit-log

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the ❗️ migrations contains migration files label Jul 30, 2025
@keithwillcode keithwillcode added core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO labels Jul 30, 2025
@vercel
Copy link

vercel bot commented Jul 30, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
cal Ignored Ignored Nov 4, 2025 9:24pm
cal-eu Ignored Ignored Nov 4, 2025 9:24pm

@linear
Copy link

linear bot commented Jul 31, 2025

Comment on lines 6 to 33
export type BookingAuditData = {
version?: number;
actor?: {
type: "User" | "System" | "Attendee";
};
booking?: {
meetingTime?: string;
totalReschedules?: number;
attendeeCountChange?: number;
cancellationReason?: string;
rejectionReason?: string;
assignmentReason?: string;
reassignmentReason?: string;
};
attendee?: {
id?: string;
};
meeting?: {
provider?: string;
meetingId?: string;
meetingUrl?: string;
};
location?: {
type?: string;
address?: string;
details?: Record<string, unknown>;
};
};
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@emrysal Does this make sense as the structure? Anything I'm missing out on, or extra/unnecessary? Did you have the same vision about the versioning?

@@ -0,0 +1,8 @@
import type { BookingAudit, Prisma } from "@prisma/client";

export interface IBookingAuditRepository {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The repository interface should be lightly decoupled from Prisma - use a DTO

e.g.

import type { BookingAuditCreateInput, BookingAudit } from "./dto/bookingAudit";

type BookingAuditCreateInput = Prisma.BookingAuditCreateInput;
...

})
.optional();

export type BookingAuditData = z.infer<typeof BookingAuditDataSchema>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try not to use z.infer if possible

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

z.infer seems like the idiomatic way to infer types from the zod schema. Is there a reason why we should avoid it? 👀

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's heavy on TS, but it is idiomatic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be the recommended alternative?

data?: BookingAuditData | null;
};

const CURRENT_AUDIT_DATA_VERSION = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Versioning should be done on the action, not on the entire table.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you expand on this? I'm not sure I follow 🤔
Currently we version the data's structure to then be able to parse correctly in the future when any further changes comes in. Was that not the purpose/intention?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, but this is per payload type, not the entire table 👍

@github-actions
Copy link
Contributor

This PR is being marked as stale due to inactivity.

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 5 files

Prompt for AI agents (all 5 issues)

Understand the root cause of the following 5 issues and fix them.


<file name="packages/prisma/schema.prisma">

<violation number="1" location="packages/prisma/schema.prisma:2651">
`bookingId` is declared as `String`, but `Booking.id` is an `Int`. This mismatch will block a proper relation and require incorrect casting. Please align the field type with the booking primary key (and add the relation).</violation>

<violation number="2" location="packages/prisma/schema.prisma:2652">
`userId` is typed as `String?`, but `User.id` is an `Int`. This blocks FK enforcement and will cause type mismatches when writing audits. Please switch to the correct integer type (and wire up the relation).</violation>

<violation number="3" location="packages/prisma/schema.prisma:2655">
Rule violated: **Prevent Direct NOW() Usage in Database Queries**

`@default(now())` relies on the database server timezone, which violates the Prevent Direct NOW() Usage rule and risks non-UTC audit timestamps. Please use an explicit UTC expression instead so future server timezone changes cannot skew audit history.</violation>

<violation number="4" location="packages/prisma/schema.prisma:2656">
`BookingAudit` is missing its closing brace. Without it the Prisma schema will not compile.</violation>
</file>

<file name="packages/lib/server/service/bookingAuditService.ts">

<violation number="1" location="packages/lib/server/service/bookingAuditService.ts:97">
The host no-show helper requires a userId even though the actor is recorded as an attendee; make the userId optional so attendee-triggered updates can be logged without fabricating a user record.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

userId String?
type BookingAuditType
action BookingAuditAction?
timestamp DateTime @default(now())
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rule violated: Prevent Direct NOW() Usage in Database Queries

@default(now()) relies on the database server timezone, which violates the Prevent Direct NOW() Usage rule and risks non-UTC audit timestamps. Please use an explicit UTC expression instead so future server timezone changes cannot skew audit history.

Prompt for AI agents
Address the following comment on packages/prisma/schema.prisma at line 2655:

<comment>`@default(now())` relies on the database server timezone, which violates the Prevent Direct NOW() Usage rule and risks non-UTC audit timestamps. Please use an explicit UTC expression instead so future server timezone changes cannot skew audit history.</comment>

<file context>
@@ -2609,6 +2609,52 @@ model RolePermission {
+  userId    String?
+  type      BookingAuditType
+  action    BookingAuditAction?
+  timestamp DateTime            @default(now())
+  data      Json?
+
</file context>
Suggested change
timestamp DateTime @default(now())
timestamp DateTime @default(dbgenerated("CURRENT_TIMESTAMP AT TIME ZONE 'UTC'"))
Fix with Cubic

model BookingAudit {
id String @id @default(uuid()) //TODO: Use uuid7() for time-sortable ID once Prisma updates to 7.
bookingId String
userId String?
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

userId is typed as String?, but User.id is an Int. This blocks FK enforcement and will cause type mismatches when writing audits. Please switch to the correct integer type (and wire up the relation).

Prompt for AI agents
Address the following comment on packages/prisma/schema.prisma at line 2652:

<comment>`userId` is typed as `String?`, but `User.id` is an `Int`. This blocks FK enforcement and will cause type mismatches when writing audits. Please switch to the correct integer type (and wire up the relation).</comment>

<file context>
@@ -2609,6 +2609,52 @@ model RolePermission {
+model BookingAudit {
+  id        String              @id @default(uuid()) //TODO: Use uuid7() for time-sortable ID once Prisma updates to 7.
+  bookingId String
+  userId    String?
+  type      BookingAuditType
+  action    BookingAuditAction?
</file context>
Fix with Cubic

type BookingAuditType
action BookingAuditAction?
timestamp DateTime @default(now())
data Json?
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BookingAudit is missing its closing brace. Without it the Prisma schema will not compile.

Prompt for AI agents
Address the following comment on packages/prisma/schema.prisma at line 2656:

<comment>`BookingAudit` is missing its closing brace. Without it the Prisma schema will not compile.</comment>

<file context>
@@ -2609,6 +2609,52 @@ model RolePermission {
+  type      BookingAuditType
+  action    BookingAuditAction?
+  timestamp DateTime            @default(now())
+  data      Json?
+
 enum PhoneNumberSubscriptionStatus {
</file context>
Fix with Cubic


model BookingAudit {
id String @id @default(uuid()) //TODO: Use uuid7() for time-sortable ID once Prisma updates to 7.
bookingId String
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bookingId is declared as String, but Booking.id is an Int. This mismatch will block a proper relation and require incorrect casting. Please align the field type with the booking primary key (and add the relation).

Prompt for AI agents
Address the following comment on packages/prisma/schema.prisma at line 2651:

<comment>`bookingId` is declared as `String`, but `Booking.id` is an `Int`. This mismatch will block a proper relation and require incorrect casting. Please align the field type with the booking primary key (and add the relation).</comment>

<file context>
@@ -2609,6 +2609,52 @@ model RolePermission {
+
+model BookingAudit {
+  id        String              @id @default(uuid()) //TODO: Use uuid7() for time-sortable ID once Prisma updates to 7.
+  bookingId String
+  userId    String?
+  type      BookingAuditType
</file context>
Fix with Cubic

*/
async onBookingCreated(
bookingId: string,
userId: string,
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The host no-show helper requires a userId even though the actor is recorded as an attendee; make the userId optional so attendee-triggered updates can be logged without fabricating a user record.

Prompt for AI agents
Address the following comment on packages/lib/server/service/bookingAuditService.ts at line 97:

<comment>The host no-show helper requires a userId even though the actor is recorded as an attendee; make the userId optional so attendee-triggered updates can be logged without fabricating a user record.</comment>

<file context>
@@ -0,0 +1,500 @@
+   */
+  async onBookingCreated(
+    bookingId: string,
+    userId: string,
+    data?: Partial&lt;BookingAuditData&gt;
+  ): Promise&lt;BookingAudit&gt; {
</file context>
Suggested change
userId: string,
userId?: string,
Fix with Cubic

@alishaz-polymath
Copy link
Member Author

Closing in favor of #25125

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core area: core, team members only enterprise area: enterprise, audit log, organisation, SAML, SSO High priority Created by Linear-GitHub Sync ❗️ migrations contains migration files size/XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Define and migrate BookingAudit table

4 participants