← Back to Projects
Commercial Contract • Be Act ChangeContact →

Document Parsing & AI Personalisation Pipeline

Shipped the end-to-end AI document ingestion and user coaching workflow for the PITCH coaching PWA. Automatically extracts structured context from uploaded PDF and DOCX documents to eliminate manual onboarding data entry, driving a 23-step dynamic onboarding state machine.

Engineering Architecture

01 / Extraction Engine

PDF & DOCX Text Parsing

Integrated pdfjs-dist for portable PDF text layer extraction and mammoth for structured Word (.docx) document parsing directly within the application.

02 / Guardrails

Strict Prompt Constraints & Banlists

Integrated GPT-4/4o APIs with strict negative prompt constraints, structured formatting rules, and automated fallback retries when responses fail validation.

03 / State Engine

23-Step Persistent Onboarding Flow

Engineered dynamic multi-stage onboarding state machine with automatic localStorage persistence, guaranteeing zero data loss during user session drop-offs.

04 / Interface

Chat Workflows & Persisted History

Built responsive chat assistant interfaces with conversational state persistence using Next.js, shadcn/ui, Tailwind CSS, and Framer Motion transitions.

Document Ingestion & Sanitization Wrapper

// Client-Side Multi-Format Text Extractor (pdfjs-dist + mammoth)
export async function parseUploadedDocument(file: File): Promise<string> {
  const fileType = file.name.split('.').pop()?.toLowerCase();
  
  if (fileType === 'pdf') {
    const arrayBuffer = await file.arrayBuffer();
    const pdf = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
    let fullText = '';
    
    for (let i = 1; i <= pdf.numPages; i++) {
      const page = await pdf.getPage(i);
      const textContent = await page.getTextContent();
      const pageText = textContent.items.map((item: any) => item.str).join(' ');
      fullText += pageText + '\n';
    }
    return sanitizeExtractedText(fullText);
  }
  
  if (fileType === 'docx') {
    const arrayBuffer = await file.arrayBuffer();
    const result = await mammoth.extractRawText({ arrayBuffer });
    return sanitizeExtractedText(result.value);
  }
  
  throw new Error('Unsupported document format. Please upload a PDF or DOCX file.');
}

Production Stack

Next.js (App Router)TypeScriptGPT-4 / GPT-4opdfjs-distmammothshadcn/uiTailwind CSSFramer Motion