Skip to content

implement filter-general function#44

Merged
notjackl3 merged 1 commit intomainfrom
backend/filter-general-api
Feb 20, 2026
Merged

implement filter-general function#44
notjackl3 merged 1 commit intomainfrom
backend/filter-general-api

Conversation

@janiceelamm
Copy link
Contributor

@janiceelamm janiceelamm commented Nov 21, 2025

implement this function that filters volunteers by general information (e.g. email, phone, position,etc.)

Basic testing
test case 1: AND with one unique value (op = "AND", column = "email", values = "v1@mail.com")

Screenshot 2025-11-21 at 3 05 50 PM

test case 2: AND with two values. (op = "AND", column = "pronouns", values = "He/him", "She/her")

Should return empty rows since this is filtering one column only.
Screenshot 2025-11-21 at 3 03 02 PM

test case 3: OR with two values ((op = "AND", column = "pronouns", values = "He/him", "She/her")
Screenshot 2025-11-21 at 3 01 13 PM

test case 4: Invalid op ((op = "hello", column = "email", values = "v1@mail.com")
Screenshot 2025-11-21 at 3 06 36 PM

Copilot AI review requested due to automatic review settings November 21, 2025 19:39
@vercel
Copy link

vercel bot commented Nov 21, 2025

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
trcc Ignored Ignored Preview Feb 20, 2026 3:49am

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR implements a new filtering API endpoint that allows querying the Volunteers table with AND/OR operations on specific columns. The implementation includes both the core filtering logic and an HTTP route handler to expose this functionality.

  • Adds a filter_general function with column validation and support for AND/OR operations
  • Creates a GET endpoint at /api/filter-general to expose the filtering functionality
  • Implements validation for parameters and returns appropriate error responses

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 7 comments.

File Description
src/lib/api/filter_general.ts Core filtering logic with column whitelisting, AND/OR operation support, and Supabase query execution
src/app/api/filter-general/route.ts HTTP route handler that validates query parameters and calls the filter_general function

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


const client = await createClient();

if (values.length == 0) {
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

Use strict equality operator (===) instead of loose equality (==) to avoid type coercion issues.

Suggested change
if (values.length == 0) {
if (values.length === 0) {

Copilot uses AI. Check for mistakes.
return { data: null, error: "No values provided." };
}

if (op == "AND") {
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

Use strict equality operator (===) instead of loose equality (==) to avoid type coercion issues.

Copilot uses AI. Check for mistakes.
const result = await client.from("Volunteers").select().eq(column, value);
return result;
}
if (op == "OR") {
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

Use strict equality operator (===) instead of loose equality (==) to avoid type coercion issues.

Suggested change
if (op == "OR") {
if (op === "OR") {

Copilot uses AI. Check for mistakes.
Comment on lines 24 to 26
if (values.length == 0) {
return { data: null, error: "No values provided." };
}
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

The values.length check at line 24 is redundant since the route handler already validates this condition at line 10. This duplicate validation should be removed or the route handler's check should be removed to avoid redundancy.

Suggested change
if (values.length == 0) {
return { data: null, error: "No values provided." };
}

Copilot uses AI. Check for mistakes.
Comment on lines 3 to 7
export async function filter_general(
op: string,
column: string,
values: string[]
) {
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

Missing JSDoc documentation for this public API function. Should include descriptions of parameters (op, column, values), the return type, and examples of valid operations. See getExample.ts comments for reference style.

Copilot uses AI. Check for mistakes.
import { createClient } from "../client/supabase/server";

export async function filter_general(
op: string,
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

The 'op' parameter allows any string value but only 'AND' and 'OR' are valid. Consider using a union type (op: 'AND' | 'OR') to enforce valid values at compile time and improve type safety.

Suggested change
op: string,
op: 'AND' | 'OR',

Copilot uses AI. Check for mistakes.
const column = searchParams.get("column");
const values = searchParams.getAll("values");

if (!op || !column || values.length == 0) {
Copy link

Copilot AI Nov 21, 2025

Choose a reason for hiding this comment

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

Use strict equality operator (===) instead of loose equality (==) to avoid type coercion issues.

Suggested change
if (!op || !column || values.length == 0) {
if (!op || !column || values.length === 0) {

Copilot uses AI. Check for mistakes.
ch-iv
ch-iv previously requested changes Nov 22, 2025
Copy link
Contributor

@ch-iv ch-iv left a comment

Choose a reason for hiding this comment

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

We should generally aim to have written tests for every PR. Could you write some tests for the changes you've made?

Copy link
Contributor

Choose a reason for hiding this comment

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

I think the name of the directory filter-general is too generic. We want to convey more information about what this route does by giving it a more descriptive name.

Copy link
Contributor

Choose a reason for hiding this comment

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

We don't need to implement the route.

@@ -0,0 +1,45 @@
import { createClient } from "../client/supabase/server";

export async function filter_general(
Copy link
Contributor

Choose a reason for hiding this comment

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

Similar comment to route naming. This function should be given a more descriptive name. The current name doesn't communicate what this method does.

op: string,
column: string,
values: string[]
) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The return value of this function should be typed.

import { createClient } from "../client/supabase/server";

export async function filter_general(
op: string,
Copy link
Contributor

Choose a reason for hiding this comment

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

(nit) Not a big fan of the name op. Something like matchType is more descriptive.

import { createClient } from "../client/supabase/server";

export async function filter_general(
op: string,
Copy link
Contributor

Choose a reason for hiding this comment

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

We should rely on the TypeScript type system to enforce the validity of the value of op (as well as for other arguments.)

I suggest you created either an Enum or a literal value type for op.

type MatchType = "any" | "all";

then you can type the function argument as follows:

function filter_general(op: MatchType, ...)

and the ts compiler will let you know if the function contract is being violated when you pass in the wrong values for op.


export async function filter_general(
op: string,
column: string,
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment as for OP. This should be a type or an enum.

Comment on lines 8 to 16
const valid_columns = [
"name_org",
"pseudonym",
"pronouns",
"email",
"phone",
"position",
"opt_in_communication",
];
Copy link
Contributor

Choose a reason for hiding this comment

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

We should get rid of this in favor of introducing a type or an enum for valid columns in a centralized helper in this codebase.

"She/her",
]);
expect(result).toEqual({ data: mockData, error: null });
});
Copy link
Contributor

Choose a reason for hiding this comment

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

Great work so far, one final test you should have is when the input operator is invalid (not AND/OR)

@@ -0,0 +1,64 @@
import { describe, it, expect, beforeEach, afterEach } from "vitest";
Copy link
Contributor

Choose a reason for hiding this comment

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

You should combine unit tests and integration tests into one file, within tests/lib/api!


const volunteer = result.data[0]!;
expect(volunteer.email).toBe("a@test.com");
});
Copy link
Contributor

@notjackl3 notjackl3 Jan 26, 2026

Choose a reason for hiding this comment

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

You should add a test for AND operation on unique values. For example, email is unique, test what if you do AND operation on 2 emails


type VolunteerRow = Database["public"]["Tables"]["Volunteers"]["Row"];

export async function filter_by_general_info(
Copy link
Contributor

Choose a reason for hiding this comment

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

The function name should match the file name: getVolunteerByGeneralInfo!

Copy link
Contributor

@notjackl3 notjackl3 left a comment

Choose a reason for hiding this comment

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

LGTM!

@notjackl3 notjackl3 dismissed ch-iv’s stale review January 27, 2026 08:55

Everything is fixed!

@ch-iv ch-iv force-pushed the backend/filter-general-api branch from 66b64db to 902fc39 Compare January 27, 2026 17:14
Comment on lines 9 to 14
type MockSupabaseClient = {
from: ReturnType<typeof vi.fn>;
select: ReturnType<typeof vi.fn>;
eq: ReturnType<typeof vi.fn>;
in: ReturnType<typeof vi.fn>;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we mocking?

Copy link
Contributor

@notjackl3 notjackl3 left a comment

Choose a reason for hiding this comment

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

LGTM!

Copy link
Contributor

@ch-iv ch-iv left a comment

Choose a reason for hiding this comment

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

lgtm

Resolved comments from PR

completed unit tests

fixing vercel issue

fixing vercel issue1

fixing vercel issue3

fixing vercel issue3

fixing vercel issue2

fixing vercel issue

resolving

integration test

fixed the test

resolved comments

Implement filter-general function

changed to real database

cleaned up mock tests
@notjackl3 notjackl3 force-pushed the backend/filter-general-api branch from 708d7f4 to 3dd964e Compare February 20, 2026 03:49
@notjackl3 notjackl3 merged commit d0addac into main Feb 20, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants