Skip to main content

Welcome to Hub

Hub is the single source of truth for applicant identity. See the complete lifecycle of every person—programs they’ve applied to, benefits they’ve received, fraud flags, documents, and interactions across Terra, Pathfinder, Airtable, and beyond.
When staff need to understand an applicant’s full picture, they currently check multiple systems: Terra for submissions, Airtable for case notes, Pathfinder for screener results, and maybe a spreadsheet for payment history. Hub consolidates everything into one view.

What Hub Does

Hub is a unified applicant view with four core capabilities:

Applicant Search

Find anyone by name, email, phone, SSN, submission ID, or any other identifier. Cross-reference across all connected systems.

Lifecycle View

See everything that’s happened: applications submitted, documents uploaded, decisions made, benefits received, fraud flags, and case notes.

Cross-Reference

Find connections: “Show me other applicants at this address” or “with this bank account” or “from this IP address.”

Data Aggregation

Pull data from Terra, Pathfinder, Airtable, and external systems into a unified profile.

Who Uses Hub

Primary Users: Staff Across Systems
RoleUse Case
Case ManagerLook up applicant history before making decisions
Fraud AnalystCross-reference suspicious patterns across programs
Program ManagerUnderstand applicant journey across programs
Support StaffAnswer questions from applicants about their status

Applicant Lifecycle

Hub tracks the complete journey of every applicant:

Profile View

The Hub profile shows everything about an applicant:

Identity

interface ApplicantIdentity {
  // Core identifiers
  id: string;
  displayName: string;
  email?: string;
  phone?: string;

  // Verified fields
  firstName: VerifiedField<string>;
  lastName: VerifiedField<string>;
  dateOfBirth: VerifiedField<string>;
  ssn: VerifiedField<string>; // Masked: ***-**-1234

  // Address history
  addresses: {
    address: string;
    type: 'current' | 'previous';
    verifiedAt?: string;
    source: string;
  }[];

  // Linked accounts
  linkedSystems: {
    system: 'terra' | 'pathfinder' | 'airtable';
    externalId: string;
    linkedAt: string;
  }[];
}

Applications

ProgramStatusSubmittedDecisionAmount
ERA 2024ApprovedJan 15, 2024Jan 22, 2024$3,500
SNAPReferredJan 15, 2024--
Childcare SubsidyPending DocsFeb 1, 2024--
ERA 2023ApprovedDec 5, 2023Dec 15, 2023$2,800

Benefits Received

interface BenefitRecord {
  programId: string;
  programName: string;
  applicationId: string;
  amount: number;
  paymentDate: string;
  paymentMethod: 'ach' | 'check' | 'card';
  status: 'pending' | 'sent' | 'cleared' | 'returned';
}
DateProgramAmountMethodStatus
Jan 25, 2024ERA 2024$3,500ACHCleared
Dec 20, 2023ERA 2023$2,800CheckCleared

Documents

All documents ever submitted across all programs:
DocumentProgramUploadedVerified
Paystub - Dec 2023ERA 2024Jan 15, 2024Yes (OCR)
Driver’s LicenseERA 2024Jan 15, 2024Yes (Manual)
Lease AgreementERA 2024Jan 16, 2024Yes (Manual)
Paystub - Nov 2023ERA 2023Dec 5, 2023Yes (OCR)

Fraud Status

interface FraudStatus {
  overallRisk: 'none' | 'low' | 'medium' | 'high';
  flags: {
    programId: string;
    flagType: string;
    severity: string;
    status: 'active' | 'cleared' | 'expired';
    createdAt: string;
    clearedAt?: string;
    clearedBy?: string;
  }[];
  blocklisted: boolean;
  blocklistReason?: string;
}

Timeline

Chronological view of all events:
┌─────────────────────────────────────────────────────────────────┐
│  Timeline                                                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  Feb 1, 2024                                                   │
│  ├── 10:30am  Applied to Childcare Subsidy                     │
│  └── 10:32am  Uploaded: Proof of enrollment                    │
│                                                                 │
│  Jan 25, 2024                                                  │
│  └── 2:15pm   Payment issued: ERA 2024 - $3,500 (ACH)         │
│                                                                 │
│  Jan 22, 2024                                                  │
│  └── 4:45pm   Application approved: ERA 2024                   │
│                                                                 │
│  Jan 18, 2024                                                  │
│  └── 11:20am  Fraud review cleared: ERA 2024                   │
│               Note: "Address verified via utility bill"         │
│                                                                 │
│  Jan 17, 2024                                                  │
│  └── 9:00am   Fraud flag: ERA 2024 - Address mismatch          │
│               Auto-flagged by Sentinel                          │
│                                                                 │
│  Jan 16, 2024                                                  │
│  ├── 3:30pm   Uploaded: Lease agreement                        │
│  └── 3:35pm   Document verified (manual)                       │
│                                                                 │
│  Jan 15, 2024                                                  │
│  ├── 2:00pm   Applied to ERA 2024                              │
│  ├── 2:05pm   Uploaded: Paystub - Dec 2023                     │
│  ├── 2:06pm   Uploaded: Driver's license                       │
│  ├── 2:10pm   Referred to SNAP (Pathfinder match)              │
│  └── 2:15pm   Completed Pathfinder screener                    │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Cross-Reference Queries

Hub enables powerful cross-reference queries:

By Address

“Show me all applicants at 123 Main St”
SELECT DISTINCT a.*
FROM applicants a
JOIN applicant_addresses aa ON a.id = aa.applicant_id
WHERE aa.address_normalized = '123 MAIN ST APT 4 SEATTLE WA 98101';

By Bank Account

“Show me all applicants with this bank account”
SELECT DISTINCT a.*
FROM applicants a
JOIN submissions s ON a.id = s.applicant_id
WHERE s.data->>'bank_account_hash' = 'abc123...';

By IP Address

“Show me all applications from this IP”
SELECT s.*, a.display_name
FROM submissions s
JOIN applicants a ON s.applicant_id = a.id
WHERE s.metadata->>'ip_address' = '192.168.1.1'
ORDER BY s.created_at DESC;

By Household

“Show me all members of this household”
SELECT a.*
FROM applicants a
WHERE a.household_id = 'household-123'
ORDER BY a.relationship_to_head;

Data Aggregation

Hub pulls data from multiple sources:

Source Priority

When data conflicts between sources, Hub uses priority rules:
FieldPriority Order
NameAdmin-verified > OCR-verified > Self-reported
AddressMost recent verified > Most recent self-reported
IncomeMost recent verified > Average of reported
SSNAny verified source
Application StatusSource system of record

Data Model

Core Tables

-- Unified applicant profile (extends @unify/identity)
CREATE TABLE hub_profiles (
  id UUID PRIMARY KEY,
  applicant_id UUID REFERENCES applicants,

  -- Aggregated data
  total_applications INTEGER DEFAULT 0,
  total_approved INTEGER DEFAULT 0,
  total_benefits_received BIGINT DEFAULT 0, -- cents
  first_application_at TIMESTAMPTZ,
  last_application_at TIMESTAMPTZ,

  -- Risk summary
  overall_risk_level TEXT DEFAULT 'none',
  active_fraud_flags INTEGER DEFAULT 0,

  -- Sync metadata
  last_synced_at TIMESTAMPTZ,
  sync_sources JSONB, -- {terra: timestamp, pathfinder: timestamp, ...}

  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- Cross-system application tracking
CREATE TABLE hub_applications (
  id UUID PRIMARY KEY,
  applicant_id UUID REFERENCES applicants,
  profile_id UUID REFERENCES hub_profiles,

  -- Source identification
  source_system TEXT NOT NULL, -- 'terra', 'pathfinder', 'airtable'
  source_id TEXT NOT NULL, -- ID in source system

  -- Application data
  program_id UUID,
  program_name TEXT,
  status TEXT,
  submitted_at TIMESTAMPTZ,
  decided_at TIMESTAMPTZ,
  decision TEXT, -- 'approved', 'denied', 'pending'

  -- Benefit data (if approved)
  benefit_amount BIGINT, -- cents
  payment_date TIMESTAMPTZ,
  payment_status TEXT,

  -- Sync metadata
  last_synced_at TIMESTAMPTZ,
  raw_data JSONB,

  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW(),

  UNIQUE(source_system, source_id)
);

-- Unified timeline events
CREATE TABLE hub_timeline (
  id UUID PRIMARY KEY,
  profile_id UUID REFERENCES hub_profiles,
  applicant_id UUID REFERENCES applicants,

  -- Event data
  event_type TEXT NOT NULL,
  event_subtype TEXT,
  description TEXT,
  metadata JSONB,

  -- Source tracking
  source_system TEXT,
  source_id TEXT,

  occurred_at TIMESTAMPTZ NOT NULL,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

-- Saved cross-reference queries
CREATE TABLE hub_saved_queries (
  id UUID PRIMARY KEY,
  name TEXT NOT NULL,
  description TEXT,
  query_type TEXT NOT NULL, -- 'address', 'bank', 'ip', 'custom'
  query_config JSONB NOT NULL,
  created_by UUID REFERENCES users,
  created_at TIMESTAMPTZ DEFAULT NOW()
);

UI Wireframe

Search & Results

┌─────────────────────────────────────────────────────────────────┐
│  Hub                                      [User] [Settings]     │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  🔍 Search by name, email, phone, SSN, or submission ID │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
│  Recent Searches                     Saved Queries              │
│  ────────────────                   ─────────────              │
│  • john.doe@email.com               • Same address cluster      │
│  • SUB-2024-12345                   • Shared bank accounts      │
│  • 206-555-1234                     • High-risk IP addresses    │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│  Search Results for "john doe"                                  │
│  ═════════════════════════════                                 │
│                                                                 │
│  ┌─────────────────────────────────────────────────────────┐   │
│  │  John Doe                                    [View →]   │   │
│  │  john.doe@email.com • 206-555-1234                      │   │
│  │  4 applications • $6,300 received • No fraud flags      │   │
│  ├─────────────────────────────────────────────────────────┤   │
│  │  Johnny Doe                                  [View →]   │   │
│  │  johnny.d@email.com • 206-555-5678                      │   │
│  │  1 application • Pending • ⚠️ 1 fraud flag              │   │
│  └─────────────────────────────────────────────────────────┘   │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

Profile View

┌─────────────────────────────────────────────────────────────────┐
│  ← Back to Search                                John Doe       │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│  [Overview] [Applications] [Documents] [Timeline] [Fraud]       │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│  Identity                              Summary                  │
│  ════════                             ═══════                  │
│  Name: John Michael Doe ✓             Total Applications: 4     │
│  DOB: 01/15/1985 ✓                    Approved: 3               │
│  SSN: ***-**-1234 ✓                   Benefits Received: $6,300 │
│  Email: john.doe@email.com            First Application: Dec '23│
│  Phone: 206-555-1234                  Last Application: Feb '24 │
│                                                                 │
│  Addresses                             Fraud Status             │
│  ═════════                            ════════════             │
│  Current:                              Risk Level: None ✓       │
│  123 Main St Apt 4                     Active Flags: 0          │
│  Seattle, WA 98101 ✓                   Cleared Flags: 1         │
│                                                                 │
│  Previous:                                                      │
│  456 Oak Ave                                                    │
│  Seattle, WA 98102                                              │
│                                                                 │
│  ─────────────────────────────────────────────────────────────  │
│                                                                 │
│  Recent Activity                                                │
│  ═══════════════                                               │
│  Feb 1   Applied to Childcare Subsidy           [Pending Docs] │
│  Jan 25  Payment received: ERA 2024 - $3,500    [Cleared]      │
│  Jan 22  Application approved: ERA 2024         [Complete]     │
│                                                                 │
│                                         [View Full Timeline →]  │
└─────────────────────────────────────────────────────────────────┘

Integration Points

Terra Sync

// Webhook from Terra on submission events
app.post('/api/webhooks/terra', async (req, res) => {
  const { event, submission, applicant } = req.body;

  await syncTerraSubmission({
    submissionId: submission.id,
    applicantId: applicant.id,
    formId: submission.formId,
    status: submission.status,
    data: submission.data,
  });

  await addTimelineEvent({
    applicantId: applicant.id,
    eventType: 'application',
    eventSubtype: event, // 'submitted', 'updated', 'approved', etc.
    sourceSystem: 'terra',
    sourceId: submission.id,
  });
});

Airtable Sync

// Scheduled sync from Airtable
async function syncAirtableDecisions() {
  const records = await airtable.select({
    filterByFormula: `{Last Modified} > '${lastSyncTime}'`,
  });

  for (const record of records) {
    await updateApplication({
      sourceSystem: 'airtable',
      sourceId: record.id,
      status: record.fields['Status'],
      decision: record.fields['Decision'],
      notes: record.fields['Case Notes'],
    });
  }
}

Sentinel Sync

// Fraud assessment sync
async function syncFraudAssessment(assessment: RiskAssessment) {
  await updateProfile({
    applicantId: assessment.applicantId,
    overallRiskLevel: calculateRiskLevel(assessment.overallScore),
    activeFraudFlags: assessment.flags.filter(f => f.status === 'active').length,
  });

  for (const flag of assessment.flags) {
    await addTimelineEvent({
      applicantId: assessment.applicantId,
      eventType: 'fraud_flag',
      eventSubtype: flag.status,
      description: flag.description,
      sourceSystem: 'sentinel',
    });
  }
}

Implementation Phases

Phase 1: Core Profile View

  • Applicant search (name, email, phone)
  • Basic profile display
  • Terra submission sync
  • Timeline view

Phase 2: Cross-Reference

  • Address-based queries
  • Bank account queries
  • IP address queries
  • Saved query management

Phase 3: Full Integration

  • Airtable bidirectional sync
  • Sentinel fraud flag sync
  • Pathfinder screener data
  • Benefit payment tracking

Next Steps