Inspiration

What it doesProofDesk: Project Story

What Inspired Us The idea for ProofDesk was born from watching a freelancer friend spend over an hour each morning sifting through scattered client communications: PDF attachments, blurry screenshots of meeting notes, and long text messages with buried action items. She kept a messy spreadsheet of tasks, often missed deadlines, and spent too long drafting email replies that sounded professional.

We asked ourselves: What if an AI could read any document and instantly turn it into a clean task list with deadlines and a draft reply?

That single question became ProofDesk — a tool that transforms unstructured documents into structured, actionable output.

How We Built It Technology Stack Layer Technology Frontend React 18 + TypeScript + Vite UI Components shadcn/ui + Tailwind CSS State Management React Context + Hooks Backend Supabase (Postgres + Auth + Storage + Edge Functions) AI Processing Groq API (OpenAI-compatible chat completions) Email Delivery Resend API Design Aesthetic Minimal (airy whitespace, restrained palette) Architecture Overview The application follows a clean, modular architecture:

$$ \text{User} \xrightarrow{\text{Upload/Paste}} \text{Dashboard} \xrightarrow{\text{Store}} \text{Supabase Storage} $$

$$ \text{Edge Function} \xrightarrow{\text{AI Call}} \text{Groq API} \xrightarrow{\text{JSON Response}} \text{Database (tasks + outputs)} $$

$$ \text{Results Page} \xleftarrow{\text{Query}} \text{Supabase Database} $$

Key Components Document Ingestion: Users upload PDFs/images (stored in Supabase Storage) or paste raw text directly.

AI Processing Pipeline: A Supabase Edge Function handles sanitization, rate limiting, and structured JSON extraction. We used a two-pass strategy — primary extraction followed by a retry with a stricter prompt if the first attempt fails to return valid JSON.

Task Management: Extracted tasks are persisted in a relational tasks table linked to their parent documents, with real-time status toggling between open and done.

Email Notifications: The send-email Edge Function sends transactional emails via Resend, with clean HTML/text dual-format templates optimized for inbox delivery.

What We Learned

  1. Prompt Engineering for Structured Output Getting an LLM to return strict, parseable JSON every time is harder than it sounds. We learned that:

System prompts must be explicit: Return ONLY valid JSON. No markdown. A validation + retry loop dramatically improves reliability. Temperature settings matter: $\theta = 0.2 \text{--} 0.3$ works best for deterministic extraction.

  1. Rate Limiting at the Edge We implemented a sliding-window rate limiter directly in the Edge Function:

$$ \text{Rate Check} = \begin{cases} \text{allowed} & \text{if } t_{\text{elapsed}} < T_{\text{window}} \text{ and } n_{\text{requests}} < N_{\text{limit}} \ \text{reset} & \text{if } t_{\text{elapsed}} \geq T_{\text{window}} \end{cases} $$

This protects both our API budget and prevents abuse without adding complex infrastructure.

  1. Security by Design Prompt injection attacks are a real threat when users can paste arbitrary text. We implemented a regex-based sanitizer that blocks common injection patterns (ignore previous instructions, system:, <|im_start|>, etc.) before the text ever reaches the AI model.

  2. Email Deliverability To ensure transactional emails land in the Main Inbox and not Spam/Promotions, we learned:

Always include a plain-text alternative alongside HTML. Use proper headers: Reply-To, List-Unsubscribe, X-Entity-Ref-ID. Maintain a high text-to-image ratio and avoid trigger words. Use authenticated sending domains (Resend handles SPF/DKIM). Challenges We Faced Challenge 1: Inconsistent AI JSON Output Problem: The AI sometimes wrapped JSON in markdown code blocks (json ... ), sometimes returned trailing commentary, and occasionally hallucinated keys.

Solution: We built a validateJSONResponse function that:

Strips markdown code blocks using regex. Validates required keys (summary, draft_reply, tasks). Coerces invalid priorities to medium. Truncates overly long fields to safe limits. Falls back to a retry call with an even stricter system prompt. Challenge 2: File Upload + Text Input in One Flow Problem: The UI needed to support both drag-and-drop file uploads and direct text pasting, each with different processing paths.

Solution: We unified both paths into a single process-document Edge Function. Files are first uploaded to Supabase Storage, then their text is extracted client-side (for images/PDFs, we pass the raw text if available; for pure text, we send directly). This keeps the backend simple and stateless.

Challenge 3: Authentication Flow Complexity Problem: New users need to sign up, verify email is valid, complete a profile (name, DOB, work, organization), and only then access the dashboard. Any incomplete step should redirect appropriately.

Solution: We built a RouteGuard component that checks auth state + profile completion on every protected route. Profile data lives in a profiles table linked to auth.users via a trigger that auto-creates the profile row on signup.

Challenge 4: Edge Function Secret Management Problem: AI API keys must never reach the client, but Edge Functions need them at runtime.

Solution: All secrets (Groq API key, Resend API key) are stored as Supabase Function Secrets, injected into Edge Functions via Deno.env.get(). The client only ever sees the Supabase Anon key, which has limited scope.

Future Roadmap Team Collaboration: Multi-user workspaces with shared documents. Calendar Integration: Auto-export extracted tasks with due dates to Google/Outlook Calendar. Email Verification: Verify email addresses before full access. Scheduled Reminders: Cron-based Edge Function for upcoming deadline alerts. Export Functionality: Download task lists and summaries as PDF or CSV. Reflection Building ProofDesk taught us that the gap between "AI can do this" and "AI does this reliably for real users" is significant. Every edge case — a malformed JSON response, a 429 rate limit, a prompt injection attempt — required deliberate design. But seeing a messy client PDF turn into a clean, prioritized task list in under 10 seconds makes every hour of debugging worth it.

$$ \text{Messy Input} \xrightarrow{\text{Sanitize}} \text{Clean Text} \xrightarrow{\text{Groq}} \text{Structured JSON} \xrightarrow{\text{Validate}} \text{Actionable Tasks} $$

This is the equation that drives ProofDesk.

How we built it

Challenges we ran into

Accomplishments that we're proud of

What we learned

What's next for ProofDesk AI: Document Processing & Task Automation AI Tool

Built With

Share this project:

Updates