pwuexecP
Convex Community14mo ago
13 replies
pwuexec

Dynamic query builder in convex

I'm trying to do a dynamic query based on conditions

import { v } from "convex/values";
import { BookingStatus } from "./lib/bookings";
import { query } from "./_generated/server";

export const getBookings = query({
  args: {
    studentId: v.optional(v.id("users")),
    tutorId: v.optional(v.id("users")),
    status: v.optional(
      v.union(
        v.literal(BookingStatus.AWAITING_TUTOR_CONFIRMATION),
        v.literal(BookingStatus.AWAITING_STUDENT_CONFIRMATION),
        v.literal(BookingStatus.AWAITING_PAYMENT),
        v.literal(BookingStatus.PAYMENT_FAILED),
        v.literal(BookingStatus.SCHEDULED),
        v.literal(BookingStatus.CANCELED),
        v.literal(BookingStatus.COMPLETED)
      )
    ),
    startDate: v.optional(v.number()), // Unix timestamp in milliseconds
    endDate: v.optional(v.number()), // Unix timestamp in milliseconds
  },
  handler: async (ctx, args) => {
    let query = ctx.db.query("bookings");

    if (args.studentId) {
      query = query.withIndex("by_student", (q) =>
        q.eq("student", args.studentId!)
      );
    }

    if (args.tutorId) {
      query = query.withIndex("by_tutor", (q) => q.eq("tutor", args.tutorId));
    }

    if (args.status) {
      query = query.withIndex("by_status", (q) => q.eq("status", args.status));
    }

    if (args.startDate !== undefined) {
      query = query.filter((q) => q.gte(q.field("startTime"), args.startDate));
    }

    if (args.endDate !== undefined) {
      query = query.filter((q) => q.lte(q.field("startTime"), args.endDate));
    }

    return await query.collect();
  },
});


schema.ts

  bookings: defineTable({
    student: v.id("users"), // Reference to the student (user with role STUDENT)
    tutor: v.id("users"), // Reference to the tutor (user with role TUTOR)
    service: v.id("services"), // Reference to the service being booked
    type: v.union(
      v.literal(BookingType.FREE_MEETING),
      v.literal(BookingType.LESSON)
    ), // Booking type
    status: v.union(
      v.literal(BookingStatus.AWAITING_TUTOR_CONFIRMATION),
      v.literal(BookingStatus.AWAITING_STUDENT_CONFIRMATION),
      v.literal(BookingStatus.AWAITING_PAYMENT),
      v.literal(BookingStatus.PAYMENT_FAILED),
      v.literal(BookingStatus.SCHEDULED),
      v.literal(BookingStatus.CANCELED),
      v.literal(BookingStatus.COMPLETED)
    ), // Booking status
    startTime: v.number(), // Start time of the booking (timestamp)
    endTime: v.number(), // End time of the booking (timestamp)
    createdAt: v.number(), // Creation time of the booking (timestamp)
    updatedAt: v.number(), // Last updated time of the booking (timestamp)
  })
    .index("by_student", ["student", "startTime"])
    .index("by_tutor", ["tutor", "startTime"])
    .index("by_status", ["status"]),

I get a huge error, sorry for the spam

Type 'Query<{ document: { _id: Id<"bookings">; _creationTime: number; type: BookingType; tutor: Id<"users">; student: Id<"users">; service: Id<"services">; status: BookingStatus; startTime: number; endTime: number; createdAt: number; updatedAt: number; }; fieldPaths: ExtractFieldPaths<...> | "_id"; indexes: { ...; }; sear...' is missing the following properties from type 'QueryInitializer<{ document: { _id: Id<"bookings">; _creationTime: number; type: BookingType; tutor: Id<"users">; student: Id<"users">; service: Id<"services">; status: BookingStatus; startTime: number; endTime: number; createdAt: number; updatedAt: number; }; fieldPaths: ExtractFieldPaths<...> | "_id"; indexes: { ....': fullTableScan, withIndex, withSearchIndexts(2739)


and all the args need to be marked with !
Was this page helpful?