← back to Norma
app/api/grants/student-finder/route.ts
329 lines
import { NextRequest, NextResponse } from 'next/server';
import { requireRole } from '@/lib/require-role';
/* ─── Static grant database ─────────────────────────────────────────────── */
export interface StudentGrant {
id: string;
name: string;
type: 'federal' | 'state' | 'university' | 'nonprofit';
source: string;
state?: string;
maxAmount: number;
incomeThreshold: number | null; // null = no income limit
description: string;
eligibility: string;
url: string;
tags: string[];
}
const ALL_GRANTS: StudentGrant[] = [
// ── Federal ──
{
id: 'pell', name: 'Federal Pell Grant', type: 'federal', source: 'U.S. Dept. of Education',
maxAmount: 7395, incomeThreshold: 60000,
description: 'Need-based grant for undergraduate students. Does not need to be repaid. The foundation of federal student aid.',
eligibility: 'Undergraduate students with demonstrated financial need (EFC below threshold)',
url: 'https://studentaid.gov/understand-aid/types/grants/pell',
tags: ['undergraduate', 'need-based', 'federal'],
},
{
id: 'fseog', name: 'Federal Supplemental Educational Opportunity Grant (FSEOG)', type: 'federal', source: 'U.S. Dept. of Education',
maxAmount: 4000, incomeThreshold: 40000,
description: 'Extra grant for students with exceptional financial need. Priority given to Pell Grant recipients.',
eligibility: 'Undergraduates with exceptional financial need; Pell recipients get priority',
url: 'https://studentaid.gov/understand-aid/types/grants/fseog',
tags: ['undergraduate', 'exceptional-need', 'federal'],
},
{
id: 'teach', name: 'TEACH Grant', type: 'federal', source: 'U.S. Dept. of Education',
maxAmount: 4000, incomeThreshold: null,
description: 'For students planning to teach in high-need fields at low-income schools. Converts to loan if service not completed.',
eligibility: 'Students in eligible programs who agree to teach 4 years in high-need fields',
url: 'https://studentaid.gov/understand-aid/types/grants/teach',
tags: ['teaching', 'service-required', 'federal'],
},
{
id: 'iraq-afghan', name: 'Iraq and Afghanistan Service Grant', type: 'federal', source: 'U.S. Dept. of Education',
maxAmount: 7395, incomeThreshold: null,
description: 'For students whose parent/guardian died as a result of military service in Iraq or Afghanistan after 9/11.',
eligibility: 'Students whose parent/guardian died in military service post-9/11',
url: 'https://studentaid.gov/understand-aid/types/grants/iraq-afghanistan-service',
tags: ['military', 'federal', 'bereavement'],
},
// ── California ──
{
id: 'cal-blue-gold', name: 'Blue and Gold Opportunity Plan', type: 'state', source: 'University of California', state: 'CA',
maxAmount: 14312, incomeThreshold: 80000,
description: 'UC covers systemwide tuition and fees for California residents with family income under $80K. Flagship CA program.',
eligibility: 'California residents at UC campuses with family income under $80,000',
url: 'https://admission.universityofcalifornia.edu/tuition-financial-aid/types-of-aid/blue-and-gold-opportunity-plan.html',
tags: ['california', 'tuition-free', 'UC-system'],
},
{
id: 'cal-grant', name: 'Cal Grant', type: 'state', source: 'California Student Aid Commission', state: 'CA',
maxAmount: 14312, incomeThreshold: 100000,
description: 'California\'s largest state grant program. Covers tuition at UC/CSU or provides funds for private/vocational schools.',
eligibility: 'CA residents, GPA 3.0+ (Cal Grant A) or 2.0+ (Cal Grant B), income/asset limits',
url: 'https://www.csac.ca.gov/cal-grants',
tags: ['california', 'need-based', 'merit-based'],
},
{
id: 'ca-middle-class', name: 'Middle Class Scholarship', type: 'state', source: 'California Student Aid Commission', state: 'CA',
maxAmount: 7548, incomeThreshold: 201000,
description: 'Covers up to 40% of tuition for middle-income CA families at UC and CSU campuses.',
eligibility: 'CA residents at UC/CSU with household income up to $201,000',
url: 'https://www.csac.ca.gov/middle-class-scholarship',
tags: ['california', 'middle-income', 'UC-CSU'],
},
{
id: 'ca-dream', name: 'California Dream Act', type: 'state', source: 'California Student Aid Commission', state: 'CA',
maxAmount: 14312, incomeThreshold: 100000,
description: 'Extends state financial aid (Cal Grant, institutional aid) to undocumented students who qualify under AB 540.',
eligibility: 'Undocumented students meeting AB 540 requirements, income limits',
url: 'https://dream.csac.ca.gov/',
tags: ['california', 'undocumented', 'dreamers'],
},
// ── New York ──
{
id: 'ny-excelsior', name: 'Excelsior Scholarship', type: 'state', source: 'New York State', state: 'NY',
maxAmount: 7070, incomeThreshold: 125000,
description: 'Tuition-free attendance at SUNY and CUNY for eligible NY residents. Last-dollar award after other aid.',
eligibility: 'NY residents, household income under $125K, 30 credits/year, live/work in NY after graduation',
url: 'https://www.hesc.ny.gov/pay-for-college/financial-aid/types-of-financial-aid/grants/excelsior-scholarship.html',
tags: ['new-york', 'tuition-free', 'SUNY-CUNY'],
},
{
id: 'ny-tap', name: 'Tuition Assistance Program (TAP)', type: 'state', source: 'New York State', state: 'NY',
maxAmount: 5665, incomeThreshold: 80000,
description: 'New York\'s largest grant program. Need-based tuition assistance for eligible NY residents.',
eligibility: 'NY residents, US citizens/eligible non-citizens, net taxable income under $80K',
url: 'https://www.hesc.ny.gov/pay-for-college/financial-aid/types-of-financial-aid/grants/tuition-assistance-program-tap.html',
tags: ['new-york', 'need-based', 'tuition'],
},
// ── Texas ──
{
id: 'tx-grant', name: 'TEXAS Grant', type: 'state', source: 'Texas Higher Education Coordinating Board', state: 'TX',
maxAmount: 10000, incomeThreshold: 60000,
description: 'Toward EXcellence, Access, and Success. Need-based aid for TX students at public universities.',
eligibility: 'Texas residents at public universities, demonstrate financial need, register for Selective Service',
url: 'https://www.highered.texas.gov/financial-aid/texas-grant/',
tags: ['texas', 'need-based', 'public-university'],
},
// ── Florida ──
{
id: 'fl-bright-futures', name: 'Florida Bright Futures', type: 'state', source: 'Florida Dept. of Education', state: 'FL',
maxAmount: 9600, incomeThreshold: null,
description: 'Merit-based scholarship rewarding FL high school graduates. Three award levels based on academic achievement.',
eligibility: 'FL residents, graduated from FL high school, meet GPA/test score/service hour requirements',
url: 'https://www.floridastudentfinancialaidsg.org/SAPBrightFutures/',
tags: ['florida', 'merit-based', 'academic'],
},
// ── Universities ──
{
id: 'yale-aid', name: 'Yale Financial Aid (No Tuition)', type: 'university', source: 'Yale University',
maxAmount: 85000, incomeThreshold: 75000,
description: 'Families earning under $75K pay nothing for tuition, room, and board. No student loans in financial aid packages.',
eligibility: 'Admitted students with family income under $75,000; no loans in any aid package',
url: 'https://finaid.yale.edu/',
tags: ['ivy-league', 'no-loan', 'full-ride'],
},
{
id: 'harvard-aid', name: 'Harvard Financial Aid', type: 'university', source: 'Harvard University',
maxAmount: 85000, incomeThreshold: 85000,
description: 'Families earning under $85K pay nothing. 55% of students receive need-based scholarships averaging $76K.',
eligibility: 'Admitted students; families under $85K pay $0, $85-150K pay 0-10% of income',
url: 'https://college.harvard.edu/financial-aid',
tags: ['ivy-league', 'no-loan', 'need-blind'],
},
{
id: 'stanford-aid', name: 'Stanford Financial Aid', type: 'university', source: 'Stanford University',
maxAmount: 82000, incomeThreshold: 100000,
description: 'Free tuition for families under $100K. Free tuition + room/board for families under $75K.',
eligibility: 'Admitted students; families under $100K = free tuition, under $75K = free everything',
url: 'https://financialaid.stanford.edu/',
tags: ['elite', 'no-loan', 'need-blind'],
},
{
id: 'princeton-aid', name: 'Princeton No-Loan Aid', type: 'university', source: 'Princeton University',
maxAmount: 82000, incomeThreshold: 100000,
description: 'All financial aid is grants — no loans ever. Families under $100K generally pay nothing.',
eligibility: 'Admitted students; 100% grant-based aid, no loans for any student',
url: 'https://admission.princeton.edu/financial-aid',
tags: ['ivy-league', 'no-loan', 'grant-only'],
},
{
id: 'mit-aid', name: 'MIT Financial Aid', type: 'university', source: 'MIT',
maxAmount: 80000, incomeThreshold: 75000,
description: 'Free tuition for families earning under $75K. Need-blind admissions for all applicants.',
eligibility: 'Admitted students; families under $75K pay $0, sliding scale above',
url: 'https://sfs.mit.edu/',
tags: ['elite', 'no-loan', 'STEM'],
},
{
id: 'rice-aid', name: 'Rice Investment (The Rice Guarantee)', type: 'university', source: 'Rice University',
maxAmount: 72000, incomeThreshold: 75000,
description: 'Full-tuition scholarship for students from families earning under $75K. No loans required.',
eligibility: 'Admitted students with family income under $75,000',
url: 'https://financialaid.rice.edu/',
tags: ['full-tuition', 'no-loan', 'Texas'],
},
// ── Nonprofit / Other ──
{
id: 'jack-kent-cooke', name: 'Jack Kent Cooke Foundation Scholarship', type: 'nonprofit', source: 'Jack Kent Cooke Foundation',
maxAmount: 55000, incomeThreshold: 95000,
description: 'One of the largest private scholarships in the US. Up to $55K/year for high-achieving students with financial need.',
eligibility: 'High school seniors with 3.5+ GPA, financial need, leadership',
url: 'https://www.jkcf.org/our-scholarships/',
tags: ['merit', 'need-based', 'leadership'],
},
{
id: 'gates', name: 'Gates Scholarship', type: 'nonprofit', source: 'Bill & Melinda Gates Foundation',
maxAmount: 70000, incomeThreshold: null,
description: 'Full cost of attendance for outstanding minority students. Covers tuition, fees, room, board, books, and personal expenses.',
eligibility: 'Minority high school seniors, Pell-eligible, 3.3+ GPA, leadership qualities',
url: 'https://www.thegatesscholarship.org/',
tags: ['full-ride', 'minority', 'leadership'],
},
{
id: 'questbridge', name: 'QuestBridge National College Match', type: 'nonprofit', source: 'QuestBridge',
maxAmount: 80000, incomeThreshold: 65000,
description: 'Matches high-achieving, low-income students with full scholarships to top colleges. Early admission binding match.',
eligibility: 'High school seniors, family income typically under $65K, strong academics',
url: 'https://www.questbridge.org/',
tags: ['full-ride', 'low-income', 'elite-colleges'],
},
];
/* ─── AI Grant Matching ──────────────────────────────────────────────────── */
function matchGrants(income: number, state?: string): (StudentGrant & { matchScore: number; reason: string })[] {
return ALL_GRANTS
.map((grant) => {
let score = 0;
let reasons: string[] = [];
// Income match
if (grant.incomeThreshold === null) {
score += 30;
reasons.push('No income limit — all students eligible');
} else if (income <= grant.incomeThreshold) {
const ratio = 1 - income / grant.incomeThreshold;
score += 40 + Math.round(ratio * 30); // 40-70 points based on how far below threshold
reasons.push(`Your income ($${income.toLocaleString()}) is within the $${grant.incomeThreshold.toLocaleString()} threshold`);
} else {
return null; // Not eligible
}
// State match bonus
if (state && grant.state && grant.state.toUpperCase() === state.toUpperCase()) {
score += 20;
reasons.push(`Matches your state: ${state.toUpperCase()}`);
}
if (!grant.state) {
score += 5; // National grants get a small bonus
}
// Amount bonus
if (grant.maxAmount >= 50000) score += 10;
else if (grant.maxAmount >= 20000) score += 7;
else if (grant.maxAmount >= 5000) score += 4;
return { ...grant, matchScore: Math.min(score, 100), reason: reasons.join('. ') + '.' };
})
.filter(Boolean)
.sort((a, b) => b!.matchScore - a!.matchScore) as (StudentGrant & { matchScore: number; reason: string })[];
}
/* ─── Route Handler ──────────────────────────────────────────────────────── */
export async function POST(request: NextRequest) {
const auth = requireRole(request, 'admin', 'staff');
if (auth instanceof NextResponse) return auth;
try {
const body = await request.json();
const { income, state } = body as { income?: number; state?: string };
if (!income || income < 0) {
return NextResponse.json({ error: 'Valid income is required' }, { status: 400 });
}
const matched = matchGrants(income, state);
// Generate AI strategy suggestions for the organization
const strategies = [
{
id: 'foundation',
title: 'Foundation Grant Applications',
description: 'Target education-focused foundations like Ford, Lumina, Arnold Ventures, and Kresge Foundation.',
impact: 'high',
effort: 'medium',
potentialAmount: '$50K - $500K',
},
{
id: 'corporate',
title: 'Corporate Sponsorship Program',
description: 'Partner with fintech companies (SoFi, Earnest, CommonBond) and student-focused brands.',
impact: 'high',
effort: 'high',
potentialAmount: '$25K - $200K',
},
{
id: 'press-outreach',
title: 'Press Outreach & Relationships',
description: 'Build relationships with journalists covering your advocacy issues. Leverage Cypress Award recognition to open doors.',
impact: 'high',
effort: 'low',
potentialAmount: 'Brand value + press',
},
{
id: 'grassroots',
title: 'Grassroots Donor Campaign',
description: 'Micro-donation campaigns via social media. Leverage supporter stories and petition signers.',
impact: 'medium',
effort: 'low',
potentialAmount: '$10K - $50K/month',
},
{
id: 'gov-advocacy',
title: 'Government Advocacy Grants',
description: 'Apply for ED.gov discretionary grants and advocacy-focused federal funding programs.',
impact: 'high',
effort: 'high',
potentialAmount: '$100K - $1M',
},
{
id: 'web-pages',
title: 'Dynamic Landing Pages',
description: 'Create targeted web pages for each grant opportunity, award program, and campaign to boost SEO and donations.',
impact: 'medium',
effort: 'low',
potentialAmount: 'Traffic + leads',
},
];
return NextResponse.json({
grants: matched,
total: matched.length,
income,
state: state || null,
strategies,
});
} catch (err) {
console.error('[grants/student-finder] Error:', (err as Error).message);
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
}
}
/* ─── GET: Return all grants (no filtering) ──────────────────────────────── */
export async function GET(request: NextRequest) {
const auth = requireRole(request, 'admin', 'staff');
if (auth instanceof NextResponse) return auth;
return NextResponse.json({ grants: ALL_GRANTS, total: ALL_GRANTS.length });
}