From 8a7da0fd93234bf54fff4e06d7508e0bcd2ebc94 Mon Sep 17 00:00:00 2001 From: Matt Date: Tue, 17 Feb 2026 21:34:30 +0100 Subject: [PATCH] Fix standalone award eligibility to send rich project data matching filtering pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Re-evaluate button was producing fewer eligible results because the standalone job sent minimal project data (title, description, tags) while the integrated filtering pass sent full data (files, team, institution). - Fetch rich project data in award-eligibility-job (files, team, institution, etc.) - Relax AI prompt to be inclusive like the integrated pass — strong primary criterion fit is sufficient, don't require all dimensions above 0.5 Co-Authored-By: Claude Opus 4.6 --- src/server/services/ai-award-eligibility.ts | 6 ++- src/server/services/award-eligibility-job.ts | 48 ++++++++++++-------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/server/services/ai-award-eligibility.ts b/src/server/services/ai-award-eligibility.ts index f795f3f..2a95162 100644 --- a/src/server/services/ai-award-eligibility.ts +++ b/src/server/services/ai-award-eligibility.ts @@ -63,7 +63,9 @@ quality_score is a 0-100 integer measuring how well the project fits the award c ## Guidelines - Base evaluation only on provided data — do not infer missing information -- eligible=true only when ALL required dimensions score above 0.5 +- Be inclusive: if the project reasonably fits the criteria, mark eligible=true +- eligible=true when the project's location, category, or topic aligns with the award criteria +- Do not require perfection across all dimensions — strong fit in the primary criterion (e.g. geographic) is sufficient - confidence reflects how clearly the data supports the determination - No personal identifiers in reasoning` @@ -90,7 +92,7 @@ interface ProjectForEligibility { institution?: string | null foundedAt?: Date | null wantsMentorship?: boolean - submissionSource?: SubmissionSource + submissionSource?: SubmissionSource | string submittedAt?: Date | null _count?: { teamMembers?: number diff --git a/src/server/services/award-eligibility-job.ts b/src/server/services/award-eligibility-job.ts index e3e0bee..ff96272 100644 --- a/src/server/services/award-eligibility-job.ts +++ b/src/server/services/award-eligibility-job.ts @@ -20,6 +20,25 @@ export async function processEligibilityJob( include: { program: true }, }) + // Rich select matching the data the integrated filtering pass sends + const projectSelect = { + id: true, + title: true, + description: true, + competitionCategory: true, + country: true, + geographicZone: true, + tags: true, + oceanIssue: true, + institution: true, + foundedAt: true, + wantsMentorship: true, + submissionSource: true, + submittedAt: true, + _count: { select: { teamMembers: true, files: true } }, + files: { select: { fileType: true, size: true, pageCount: true } }, + } as const + // Get projects — scoped to filtering round PASSED projects if provided let projects: Array<{ id: string @@ -30,6 +49,13 @@ export async function processEligibilityJob( geographicZone: string | null tags: string[] oceanIssue: string | null + institution: string | null + foundedAt: Date | null + wantsMentorship: boolean + submissionSource: string + submittedAt: Date | null + _count: { teamMembers: number; files: number } + files: Array<{ fileType: string | null; size: number; pageCount: number | null }> }> if (filteringRoundId) { @@ -57,16 +83,7 @@ export async function processEligibilityJob( id: { in: passedIds }, programId: award.programId, }, - select: { - id: true, - title: true, - description: true, - competitionCategory: true, - country: true, - geographicZone: true, - tags: true, - oceanIssue: true, - }, + select: projectSelect, }) } else { const statusFilter = includeSubmitted @@ -78,16 +95,7 @@ export async function processEligibilityJob( programId: award.programId, status: { in: [...statusFilter] }, }, - select: { - id: true, - title: true, - description: true, - competitionCategory: true, - country: true, - geographicZone: true, - tags: true, - oceanIssue: true, - }, + select: projectSelect, }) }