← 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 });
}