Pathfinder Docs

Documentation Preview

Applicant Intake / Universal Profile Implementation

Source: `docs/product/features/APPLICANT_INTAKE_IMPLEMENTATION.md`View on GitHub

Applicant Intake / Universal Profile Implementation

Date: November 23, 2025
Status: ✅ Complete

Overview

This document describes the comprehensive Applicant Intake system that captures structured data about applicants to enable intelligent resource matching. The system serves as the foundation for Coordinated Entry and resource allocation.

Purpose

The Applicant Intake creates a Universal Applicant Profile (similar to HMIS/CE triage) that contains all the structured information needed to:

  • Match applicants with appropriate resources
  • Prioritize applicants based on vulnerability
  • Track household composition and needs
  • Support coordinated entry workflows
  • Enable automated eligibility screening

Architecture

Database Schema

Migration File: database/migrations/DATABASE_MIGRATION_APPLICANT_INTAKE.sql

Extended Tables

  1. households - Extended with comprehensive intake fields:

    • Demographics (language, interpreter needs, DV status)
    • Employment & income (status, sources, verification)
    • Citizenship & documentation
    • Housing situation & history
    • Criminal background (access-controlled)
    • Immediate needs (JSONB array)
    • Household composition (children, elderly, disabled, veterans)
    • Veteran information
    • Intake metadata (completion status, method, consent)
    • Coordinated Entry fields (vulnerability score, priority level)
  2. clients - Extended for individual demographics:

    • Personal information (preferred name, pronouns)
    • Demographics (marital status, ethnicity, language)
    • Documentation (ID type, expiration)
    • Health & disability details
    • Veteran details (branch, service dates, VA benefits)
    • Employment & education
    • Criminal background
    • Contact preferences

New Tables

  1. intake_documents - Document storage and tracking:

    • Links to household/client
    • Document type categorization
    • Supabase storage URL
    • Verification status and metadata
    • Privacy controls (sensitive flag, access levels)
    • RLS policies for data protection
  2. intake_need_types - Reference table for needs:

    • Standardized need codes and labels
    • Categories and icons
    • Display ordering
    • Pre-populated with 20 common need types

Views

  1. applicant_profiles - Complete applicant view:
    • Household summary with head of household
    • Organization and caseworker information
    • Quick access to key intake fields

Frontend Components

1. ApplicantIntakeForm Component

File: app/components/ApplicantIntakeForm.tsx

Multi-step form with 7 steps:

  1. Head of Household Information

    • Name, date of birth
    • Contact information (phone, email)
    • Demographics (gender, race/ethnicity)
    • Veteran & disability status
    • Preferred contact method
  2. Household Demographics

    • Household name and size
    • Household composition (children, elderly, disabled)
    • Current address and location
    • County and zip code
    • Preferred language and interpreter needs
  3. Income & Employment

    • Annual and monthly income
    • Employment status
    • Employer information
    • Income sources (multiple selections)
    • Verification status
  4. Housing Situation & Eligibility

    • Current housing situation
    • Homelessness duration (if applicable)
    • Prior address and landlord information
    • Eviction history
    • Citizenship status
    • Veteran details (if applicable)
  5. Immediate Needs

    • Visual grid with 14 need categories
    • Multi-select with icons
    • Categories: rent, utilities, shelter, food, transportation, ID, employment, childcare, healthcare, mental health, legal, DV services, veteran services, disability services
  6. Document Upload (Optional)

    • Select document type
    • Drag-and-drop or click to upload
    • Support for images and PDFs
    • File size limit: 10MB
    • Real-time upload status
  7. Review & Consent

    • Application summary
    • Privacy policy and consent
    • Required checkbox for data sharing
    • Next steps information

Features:

  • Progress bar showing completion percentage
  • Form validation on required fields
  • Step-by-step navigation
  • Responsive design for mobile/desktop
  • Dark mode support
  • Success confirmation screen with reference number

2. DocumentUpload Component

File: app/components/DocumentUpload.tsx

Features:

  • Document type selection (9 types)
  • File upload with drag-and-drop
  • File validation (type and size)
  • Upload progress indicator
  • Uploaded documents list
  • File size formatting
  • Common documents information panel

Supported Document Types:

  • Income verification
  • Lease agreement
  • ID document
  • Birth certificate
  • Veteran DD-214
  • Medicaid card
  • Utility bill
  • Eviction notice
  • Other

3. Public Intake Page

File: app/intake/page.tsx

Features:

  • Informational header
  • Before you begin checklist
  • Embedded intake form
  • Help section with contact information
  • Fully public (no authentication required)
  • SEO-optimized metadata

API Routes

1. Submit Intake Application

Endpoint: POST /api/intake/submit
File: app/api/intake/submit/route.ts

Functionality:

  • Creates household record with all intake data
  • Creates head of household client record
  • Calculates vulnerability score based on:
    • Housing situation (homeless: +30, sheltered: +25, couch surfing: +20, at risk: +15)
    • Household composition (children: +10, elderly: +10, disabled: +10)
    • Veteran status (+5)
    • DV status (+15)
    • Duration of homelessness (over 1 year: +10)
    • Employment status (unemployed: +5)
  • Determines priority level:
    • Urgent: 70+ score
    • High: 50-69 score
    • Medium: 30-49 score
    • Low: <30 score
  • Sets intake metadata (method, completion date, consent)
  • Returns household ID and reference number

Request Body:

{
  // Head of Household
  hohFirstName: string
  hohLastName: string
  hohDateOfBirth: string
  hohPhone: string
  hohEmail?: string
  
  // Household
  householdSize: number
  annualIncome: string
  city: string
  state: string
  zipCode: string
  
  // Housing
  housingSituation: string
  
  // Needs
  immediateNeeds: string[]
  
  // ... additional fields
}

Response:

{
  success: true,
  householdId: string,
  referenceNumber: string,
  vulnerabilityScore: number,
  priorityLevel: string
}

2. Upload Document

Endpoint: POST /api/intake/upload-document
File: app/api/intake/upload-document/route.ts

Functionality:

  • Validates file type and size
  • Uploads to Supabase Storage bucket intake-documents
  • Creates document record in database
  • Handles sensitive documents with restricted access
  • Returns document ID and URL
  • Cleans up on database errors

Form Data:

{
  file: File
  documentType: string
  householdId?: string
  clientId?: string
}

Response:

{
  success: true,
  documentId: string,
  fileUrl: string
}

Storage

Supabase Storage Bucket: intake-documents

Structure:

intake-documents/
  households/
    {household-id}/
      {timestamp}-{random}.{ext}
  intake/
    {timestamp}-{random}.{ext}

Data Flow

1. Applicant Self-Service Flow

1. Applicant visits /intake
2. Completes 7-step form
3. Submits application
4. System creates household + client records
5. Calculates vulnerability score
6. Assigns priority level
7. Returns reference number
8. (Optional) Uploads documents
9. Caseworker notified (TODO)
10. Confirmation email sent (TODO)

2. Staff-Entered Flow

1. Staff accesses intake form
2. Interviews applicant
3. Enters data on behalf of applicant
4. Sets intake_method = 'staff_entered'
5. Same processing as self-service
6. Assigns caseworker
7. Links to organization

Vulnerability Scoring

The system automatically calculates a vulnerability score (0-100) based on multiple factors:

Scoring Algorithm

FactorPoints
Homeless (unsheltered)+30
In emergency shelter+25
Couch surfing+20
At risk of homelessness+15
Has children+10
Has elderly (65+)+10
Has disabled members+10
Veteran in household+5
DV status+15
Homeless over 1 year+10
Unemployed+5

Priority Levels

  • Urgent (70-100): Requires immediate intervention
  • High (50-69): High priority for services
  • Medium (30-49): Standard priority
  • Low (0-29): Lowest priority

Privacy & Security

Access Controls

  1. Sensitive Fields:

    • DV status and details
    • Criminal background
    • Marked with is_sensitive flag
  2. Access Levels:

    • public: Anyone
    • org: Organization members
    • caseworker_only: Assigned caseworker only
    • admin_only: Administrators only
  3. RLS Policies:

    • Staff/Admin: View all
    • Caseworkers: View own org only
    • Document access based on sensitivity

Consent Management

  • Required checkbox for data sharing
  • Consent date recorded
  • Consent can be withdrawn
  • Privacy policy displayed before submission

Integration Points

With Resource Library

  • immediate_needs maps to resource categories
  • Enables automatic resource matching
  • Feeds into get_matched_resources() function

With Referral System

  • Pre-fills referral application data
  • Household info automatically populated
  • Priority level determines urgency

With Coordinated Entry

  • Vulnerability score for prioritization
  • Assessment date tracking
  • Next assessment scheduling
  • HMIS-compatible data structure

UI/UX Features

Form Experience

  • ✅ Multi-step wizard with progress bar
  • ✅ Visual feedback and validation
  • ✅ Mobile-responsive design
  • ✅ Dark mode support
  • ✅ Icon-based need selection
  • ✅ Conditional field display
  • ✅ Form state persistence (client-side)

Accessibility

  • ✅ Semantic HTML
  • ✅ ARIA labels
  • ✅ Keyboard navigation
  • ✅ High contrast mode support
  • ✅ Screen reader friendly

Navigation

The intake form is accessible via:

  • Public URL: /intake
  • CRM Navigation: "Intake" menu item (📝 icon)
  • No authentication required for public access

Future Enhancements

Planned Features

  1. Email Notifications:

    • Confirmation email to applicant
    • Alert to caseworkers for new intakes
    • Document upload notifications
  2. Form Save/Resume:

    • Save partial progress
    • Resume with unique link
    • Expiration after 30 days
  3. Digital Signature:

    • E-signature for consent
    • Audit trail
  4. Multi-Language Support:

    • Spanish translation
    • Russian translation
    • Dynamic language switching
  5. SMS Integration:

    • Text reference number
    • Status updates via SMS
  6. Duplicate Detection:

    • Check for existing households
    • Merge/update workflows
  7. Automated Matching:

    • Trigger resource matching on submission
    • Auto-create referrals for high matches
    • Notify providers
  8. Reporting Dashboard:

    • Intake metrics
    • Completion rates
    • Priority level distribution
    • Vulnerability trends

Database Setup

Running the Migration

-- Run this in your Supabase SQL Editor
-- File: database/migrations/DATABASE_MIGRATION_APPLICANT_INTAKE.sql

Dependencies:

  • Requires existing households table
  • Requires existing clients table
  • Requires existing organizations table
  • Requires existing profiles table

Creates:

  • Extended fields on households and clients
  • New table: intake_documents
  • New table: intake_need_types
  • New view: applicant_profiles
  • Indexes for performance
  • RLS policies for security

Storage Setup

Create Supabase Storage Bucket:

  1. Go to Storage in Supabase Dashboard
  2. Create new bucket: intake-documents
  3. Set as public or private (recommend private)
  4. Enable RLS policies:
    -- Allow authenticated users to upload
    CREATE POLICY "Authenticated users can upload intake documents"
    ON storage.objects FOR INSERT
    TO authenticated
    WITH CHECK (bucket_id = 'intake-documents');
    
    -- Allow users to view their own documents
    CREATE POLICY "Users can view intake documents"
    ON storage.objects FOR SELECT
    TO authenticated
    USING (bucket_id = 'intake-documents');
    

Testing

Manual Testing Checklist

  • Complete intake form as applicant
  • Verify household record created
  • Verify client record created
  • Check vulnerability score calculation
  • Test document upload
  • Verify document storage
  • Check RLS policies
  • Test form validation
  • Test mobile responsive design
  • Test dark mode
  • Verify navigation links
  • Test success screen
  • Check reference number generation

Test Data

See database/test-data/ for sample intake submissions.

Files Changed/Created

New Files

  • database/migrations/DATABASE_MIGRATION_APPLICANT_INTAKE.sql
  • app/components/ApplicantIntakeForm.tsx
  • app/components/DocumentUpload.tsx
  • app/intake/page.tsx
  • app/api/intake/submit/route.ts
  • app/api/intake/upload-document/route.ts
  • docs/features/APPLICANT_INTAKE_IMPLEMENTATION.md

Modified Files

  • app/components/CRMNavigation.tsx - Added "Intake" menu item

Usage Examples

For Applicants

  1. Visit the intake page (share URL: https://yoursite.com/intake)
  2. Complete all 7 steps
  3. Upload supporting documents (optional)
  4. Save reference number for follow-up

For Caseworkers

  1. Log in to CRM
  2. Click "Intake" in navigation
  3. Complete form on behalf of client
  4. System automatically assigns to your organization
  5. View client in "Clients" page after submission

For Administrators

  1. Access intake submissions via "Clients" page
  2. Filter by intake_completed = true
  3. Sort by priority_level or vulnerability_score
  4. Review uploaded documents
  5. Assign caseworkers
  6. Initiate referrals

API Usage

Programmatic Submission

const response = await fetch('/api/intake/submit', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    hohFirstName: 'John',
    hohLastName: 'Doe',
    householdSize: 3,
    annualIncome: '25000',
    city: 'Portland',
    state: 'Oregon',
    zipCode: '97201',
    housingSituation: 'homeless',
    immediateNeeds: ['rent_assistance', 'food_assistance'],
    consentToShare: true,
    // ... other fields
  })
})

const data = await response.json()
console.log('Reference:', data.referenceNumber)
console.log('Score:', data.vulnerabilityScore)

Document Upload

const formData = new FormData()
formData.append('file', fileInput.files[0])
formData.append('documentType', 'income_verification')
formData.append('householdId', householdId)

const response = await fetch('/api/intake/upload-document', {
  method: 'POST',
  body: formData
})

Support

Common Issues

Q: Form submission fails with "Failed to create household record"
A: Check that all required fields are filled. Verify database migration has been run.

Q: Document upload fails
A: Verify Supabase storage bucket intake-documents exists. Check file size is under 10MB.

Q: Can't see intake in navigation
A: Clear browser cache. Verify CRMNavigation.tsx has been updated.

Q: Vulnerability score seems incorrect
A: Review scoring algorithm in route.ts. Adjust weights as needed for your community.

Contact

For questions or issues:

  • Check documentation in docs/features/
  • Review database migration file
  • Check Supabase logs for errors

Implementation Complete: November 23, 2025
Next Steps: Configure email notifications, test with pilot users, gather feedback


Use links in each imported doc to open its source.