Why longevity?

What we shipped at the hackathon

Architecture

Key moving parts:

Product walk-through

Home page

            <h1 className="text-3xl font-bold leading-tight text-gray-900">
              Medical Document Analysis
            </h1>
          </div>
        </header>
        <main>
          <div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
            <MedicalDocUploader />

Upload → extract → analyze → persist (client path)

  const handleFileUpload = useCallback(async (event: React.ChangeEvent<HTMLInputElement>) => {
    try {
      setIsUploading(true);
      setError(null);
      
      const file = event.target.files?.[0];
      if (!file) return;

      // Extract text based on file type
      const text = file.type === 'application/pdf' 
        ? await extractTextFromPDF(file)
        : await extractTextFromImage(file);

      // Analyze the text with Llama
      const analysis = await analyzeWithLlama(text, file.name);

      // Upload to Supabase Storage
      const { data: uploadData, error: uploadError } = await supabase.storage
        .from('medical-documents')
        .upload(analysis.renamed_file, file);

      if (uploadError) throw uploadError;

      // Store metadata in Supabase
      const { data: metaData, error: metaError } = await supabase
        .from('documents')
        .insert({
          filename: file.name,
          renamed_file: analysis.renamed_file,
          file_url: uploadData.path,
          summary: analysis.summary,
          keywords: analysis.keywords,
          categories: analysis.categories,
          word_count: countWords(text),
          report_type: detectReportType(text),
          threshold_flags: analysis.threshold_flags,
          pubmed_refs: analysis.pubmed_refs,
          ai_notes: analysis.ai_notes,
          status: 'processed',
          version: 1
        })
        .select()
        .single();

      if (metaError) throw metaError;

      setDocuments(prev => [...prev, metaData]);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'An error occurred');
    } finally {
      setIsUploading(false);
    }
  }, []);

The prompt that makes it reliable

  const analyzeWithLlama = async (text: string, originalFilename: string) => {
    const prompt = `Analyze this medical document and provide a detailed analysis in the following format:

1. Summary: Provide a clear, plain-English summary
2. Keywords: Extract key medical terms and their values (if any)
3. Categories: Classify into these categories: ${VALID_CATEGORIES.join(", ")}
4. Filename: Suggest a clear, descriptive filename
5. Threshold Flags: Identify any abnormal values and mark as "high", "low", or "normal"
6. PubMed References: Suggest relevant PubMed articles (just article titles)
7. Additional Notes: Any important medical guidance or observations

Document text:
${text}

Please format your response exactly as follows:
Summary: [summary]
Keywords: [key:value pairs]
Categories: [categories]
Filename: [filename]
Flags: [abnormal values]
References: [article titles]
Notes: [additional guidance]`;

Server-side processing (Edge Function)

    // Prepare LLaMA prompt
    const prompt = `Analyze this medical document and provide a detailed analysis in the following format:

1. Summary: Provide a clear, plain-English summary
2. Keywords: Extract key medical terms and their values (if any)
3. Categories: Classify into these categories: ${VALID_CATEGORIES.join(", ")}
4. Filename: Suggest a clear, descriptive filename
5. Threshold Flags: Identify any abnormal values and mark as "high", "low", or "normal"
6. PubMed References: Suggest relevant PubMed articles (just article titles)
7. Additional Notes: Any important medical guidance or observations

Document text:
${text}

Please format your response exactly as follows:
Summary: [summary]
Keywords: [key:value pairs]
Categories: [categories]
Filename: [filename]
Flags: [abnormal values]
References: [article titles]
Notes: [additional guidance]`
    // Insert into Supabase
    const { data: insertData, error: insertError } = await supabase
      .from('documents')
      .insert(documentData)
      .select()
      .single()

Implementation details

Database schema (Supabase Postgres)

Use JSONB where the structure can vary or expand over time.

-- documents table
create table if not exists public.documents (
  id bigint generated always as identity primary key,
  created_at timestamp with time zone default now() not null,
  user_id uuid null,
  filename text not null,
  renamed_file text not null,
  file_url text not null,
  summary text not null,
  keywords jsonb not null default '{}'::jsonb,
  categories text[] not null default '{}',
  word_count integer not null,
  report_type text not null,
  threshold_flags jsonb not null default '{}'::jsonb,
  pubmed_refs jsonb not null default '{}'::jsonb,
  ai_notes text not null default '',
  status text not null check (status in ('uploaded','processed','failed')),
  user_notes text null,
  version integer not null default 1
);

-- Optional: RLS policies for multi-tenant setups
alter table public.documents enable row level security;

-- Example policies (tune for your auth model)
create policy "Allow read to authenticated users"
  on public.documents for select
  to authenticated
  using (true);

create policy "Insert own documents"
  on public.documents for insert
  to authenticated
  with check (auth.uid() = user_id);

create policy "Update own documents"
  on public.documents for update
  to authenticated
  using (auth.uid() = user_id);

Storage bucket

Environment configuration

Example variables to configure:

For the Edge Function, set:

Deploying the Edge Function

supabase functions deploy process-medical-pdf
supabase functions list
supabase functions serve process-medical-pdf --no-verify-jwt

Wire the function behind an HTTP trigger or call it from your app to process files already stored in the bucket.

UX considerations

Reliability strategies

Security and compliance

Performance and cost

What we’d build next

Demo script (5 minutes)

Credits