Skip to main content
RapidDev - Software Development Agency

How to Build Insurance claims tool with V0

Build an insurance claims management tool with V0 using Next.js, Supabase for claims data, and a PostgreSQL state machine for status transitions. You'll create a claims submission wizard, adjuster review queue, status timeline, and management analytics — all in about 2-4 hours without touching a terminal.

What you'll build

  • Multi-step claim submission wizard with document uploads and incident details using Stepper and Input
  • Adjuster review queue with priority-based sorting, status filters, and assignment workflow
  • Claim detail page with status timeline, documents gallery, internal notes thread, and action buttons
  • PostgreSQL state machine enforcing valid status transitions (submitted > under_review > approved > paid > closed)
  • Role-based dashboard showing different views for policyholders, adjusters, and managers
  • Management analytics with claims volume trends, average processing time, and payout totals using Recharts
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced11 min read2-4 hoursV0 PremiumApril 2026RapidDev Engineering Team
TL;DR

Build an insurance claims management tool with V0 using Next.js, Supabase for claims data, and a PostgreSQL state machine for status transitions. You'll create a claims submission wizard, adjuster review queue, status timeline, and management analytics — all in about 2-4 hours without touching a terminal.

What you're building

Insurance claims management tracks the lifecycle of a claim from submission through investigation to resolution. Policyholders submit claims with supporting documents, adjusters review and process them through defined stages, and managers monitor volumes and payouts.

V0 generates the multi-step submission wizard, review queue, and analytics dashboard from prompts. Supabase handles claims data, document storage, and role-based access control.

The architecture uses Next.js App Router with a client component for the submission wizard, Server Components for the review queue and analytics, a PostgreSQL function implementing a state machine for valid status transitions, Server Actions for claim processing, and Supabase Storage for supporting documents.

Final result

An insurance claims tool with submission wizard, adjuster review queue, status timeline enforcement, document management, internal notes, and management analytics.

Tech stack

V0AI Code Generator
Next.jsFull-Stack Framework
Tailwind CSSStyling
shadcn/uiComponent Library
SupabaseDatabase, Auth & Storage
RechartsCharts

Prerequisites

  • A V0 account (Premium recommended for the complex multi-page app)
  • A Supabase project with Storage enabled for claim documents
  • Basic understanding of insurance claims (submit, review, approve/deny, pay)
  • Familiarity with role-based access (policyholder, adjuster, manager)

Build steps

1

Set up the project and claims database schema

Open V0 and create a new project. Connect Supabase via the Connect panel. Create the schema for policyholders, claims, documents, notes, and status tracking.

prompt.txt
1// Paste this prompt into V0's AI chat:
2// Build an insurance claims tool. Create a Supabase schema with:
3// 1. policyholders: id (uuid PK), user_id (uuid FK to auth.users), policy_number (text unique), full_name (text), email (text), phone (text), address (text), policy_type (text check in 'auto','home','health','life','business'), policy_start (date), policy_end (date), coverage_limit_cents (bigint)
4// 2. claims: id (uuid PK), policyholder_id (uuid FK to policyholders), claim_number (text unique), type (text check in 'auto_collision','auto_theft','home_damage','home_theft','health_medical','health_dental','life','business_liability'), description (text), incident_date (date), incident_location (text), estimated_amount_cents (bigint), approved_amount_cents (bigint), status (text default 'submitted' check in 'submitted','under_review','investigation','approved','partially_approved','denied','paid','closed'), priority (text default 'normal' check in 'low','normal','high','urgent'), assigned_adjuster_id (uuid FK to auth.users nullable), submitted_at (timestamptz), resolved_at (timestamptz)
5// 3. claim_documents: id (uuid PK), claim_id (uuid FK to claims), title (text), file_url (text), document_type (text check in 'photo','police_report','medical_record','receipt','estimate','other'), uploaded_by (uuid FK to auth.users), uploaded_at (timestamptz)
6// 4. claim_notes: id (uuid PK), claim_id (uuid FK to claims), author_id (uuid FK to auth.users), content (text), is_internal (boolean default true), created_at (timestamptz)
7// 5. claim_status_log: id (uuid PK), claim_id (uuid FK to claims), from_status (text), to_status (text), changed_by (uuid FK to auth.users), reason (text), created_at (timestamptz)
8// Add RLS: policyholders see their own claims, adjusters see assigned claims, managers see all.

Pro tip: Queue the policyholder submission flow, adjuster review interface, and manager analytics dashboard as three separate prompt sequences using V0's prompt queuing feature.

Expected result: Database schema created with 5 tables, RLS policies for role-based access, and status tracking for complete claim audit trails.

2

Build the multi-step claim submission wizard

Create the claim submission page with a step-by-step wizard for entering incident details, uploading supporting documents, and reviewing before submission.

prompt.txt
1// Paste this prompt into V0's AI chat:
2// Build a claim submission wizard at app/claims/new/page.tsx as a 'use client' component.
3// Requirements:
4// - Stepper showing 4 steps: Incident Details → Documents → Review → Confirmation
5// - Step 1 (Incident Details): Select for claim type, Input for incident_date (date picker), Textarea for description, Input for incident_location, Input for estimated_amount (currency formatted)
6// - Step 2 (Documents): File upload zone accepting multiple files, Select for document_type per file (photo, police_report, medical_record, receipt, estimate, other), Preview thumbnails for uploaded images
7// - Step 3 (Review): Summary Card showing all entered data with edit buttons per section
8// - Step 4 (Confirmation): success message with claim_number display
9// - Zod validation: incident_date <= today, estimated_amount <= coverage_limit, at least one document required for auto/home claims
10// - Server Action that: generates claim_number (CLM-{year}-{sequence}), inserts claim, uploads documents to Supabase Storage bucket 'claim-documents', inserts claim_documents rows, creates initial claim_status_log entry
11// - Navigate to /claims/[id] after submission
12// - Use Card for step content areas and Badge for document type labels

Expected result: Policyholders can submit claims through a guided 4-step wizard with document uploads, validation, and automatic claim number generation.

3

Build the claim detail page with status timeline

Create the claim detail page showing the full claim lifecycle with status timeline, documents, internal notes, and action buttons.

prompt.txt
1// Paste this prompt into V0's AI chat:
2// Build claim detail at app/claims/[id]/page.tsx.
3// Requirements:
4// - Header: claim_number, type Badge, status Badge (color-coded), priority Badge
5// - Status timeline: vertical Stepper showing each status_log entry with timestamp, author, and reason
6// - Tabs component with sections:
7// 1. Overview: incident details Card, estimated vs approved amount, assigned adjuster
8// 2. Documents: gallery grid of uploaded documents with download Button per file, document_type Badge, "Upload Additional" Button
9// 3. Notes: threaded conversation of claim_notes, Textarea to add new note, Switch for is_internal (visible only to adjusters/managers)
10// 4. History: full status_log Table with from→to transition, changed_by, reason, timestamp
11// - Action buttons (role-dependent):
12// - Adjuster: "Approve", "Deny", "Request Investigation" buttons that open Dialog with reason Textarea and approved_amount Input (for approve)
13// - Manager: "Reassign" Button with adjuster Select
14// - AlertDialog for deny action requiring a reason
15// - Server Actions for status transitions, note creation, and document upload

Expected result: The claim detail page shows a complete timeline of status changes, organized document gallery, internal notes thread, and role-appropriate action buttons.

4

Create the state machine for status transitions

Build the PostgreSQL function that validates and enforces the claims status transition rules, preventing invalid status changes.

prompt.txt
1// Paste this prompt into V0's AI chat:
2// Build the status transition system:
3// 1. Create a PostgreSQL function transition_claim_status(claim_id uuid, new_status text, changed_by uuid, reason text):
4// - Fetch current status with FOR UPDATE lock
5// - Validate against state machine rules:
6// submitted → under_review only
7// under_review → investigation, approved, partially_approved, denied
8// investigation → approved, partially_approved, denied
9// approved → paid
10// partially_approved → paid
11// denied → closed
12// paid → closed
13// - If invalid transition, RAISE EXCEPTION 'Invalid status transition from X to Y'
14// - Insert into claim_status_log (from_status, to_status, changed_by, reason)
15// - Update claims.status = new_status
16// - If new_status in ('approved','denied','paid','closed'), set resolved_at = now()
17// - Return the updated claim
18//
19// 2. Create API route at app/api/claims/[id]/status/route.ts:
20// - PATCH handler that validates role permissions and calls the RPC
21// - Adjusters can transition to under_review, investigation, approved, denied
22// - Managers can do all transitions
23// - Policyholders cannot change status
24// - Use Zod to validate input: new_status, reason (required for deny)

Pro tip: The FOR UPDATE row lock in the PostgreSQL function prevents race conditions — even if two adjusters try to transition the same claim simultaneously, only one will succeed.

Expected result: The state machine enforces valid transitions at the database level. Invalid status changes raise exceptions even if called directly, ensuring claims follow the proper workflow.

5

Build the adjuster queue and management dashboard

Create the claims list with filtering, the adjuster's work queue, and the management analytics dashboard.

prompt.txt
1// Paste this prompt into V0's AI chat:
2// Build three pages:
3// 1. app/claims/page.tsx — claims list:
4// - Table with columns: claim_number, type Badge, policyholder name, status Badge, priority Badge, submitted date, assigned adjuster
5// - Column sorting on submitted_at and priority
6// - Select filters: status, priority, claim type
7// - Search Input for claim_number or policyholder name
8// - Click row to navigate to /claims/[id]
9//
10// 2. app/page.tsx — role-based dashboard:
11// - Policyholder view: my claims list with status indicators, "File New Claim" Button
12// - Adjuster view: assigned claims queue sorted by priority DESC, unassigned claims needing pickup
13// - Manager view: KPI Cards (total claims, avg processing days, total payouts), claims volume BarChart by month, status distribution PieChart
14//
15// 3. app/admin/page.tsx — management analytics:
16// - Recharts BarChart: claims volume by month with status stacking
17// - LineChart: average processing time trend
18// - Cards: total payouts this month, denial rate, adjuster workload distribution
19// - Table: top 10 highest-value open claims
20// - Select for time period and claim type filtering
21// - Wrap all charts in 'use client' components

Expected result: Adjusters see their work queue sorted by priority. Managers see analytics with claims volume, processing times, and payout trends. Policyholders see their own claims.

Complete code

app/api/claims/[id]/status/route.ts
1import { createClient } from '@/lib/supabase/server'
2import { NextRequest, NextResponse } from 'next/server'
3import { z } from 'zod'
4
5const schema = z.object({
6 newStatus: z.enum([
7 'under_review', 'investigation', 'approved',
8 'partially_approved', 'denied', 'paid', 'closed',
9 ]),
10 reason: z.string().min(1).max(1000),
11 approvedAmount: z.number().int().nonnegative().optional(),
12})
13
14export async function PATCH(
15 request: NextRequest,
16 { params }: { params: Promise<{ id: string }> }
17) {
18 const { id } = await params
19 const supabase = await createClient()
20 const { data: { user } } = await supabase.auth.getUser()
21 if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
22
23 const body = await request.json()
24 const { newStatus, reason, approvedAmount } = schema.parse(body)
25
26 if (approvedAmount && newStatus === 'approved') {
27 await supabase
28 .from('claims')
29 .update({ approved_amount_cents: approvedAmount })
30 .eq('id', id)
31 }
32
33 const { data, error } = await supabase.rpc('transition_claim_status', {
34 claim_id: id,
35 new_status: newStatus,
36 changed_by: user.id,
37 reason,
38 })
39
40 if (error) {
41 if (error.message.includes('Invalid status transition')) {
42 return NextResponse.json({ error: error.message }, { status: 422 })
43 }
44 return NextResponse.json({ error: error.message }, { status: 500 })
45 }
46
47 return NextResponse.json({ success: true, claim: data })
48}

Customization ideas

Add fraud detection scoring

Build a risk scoring system that flags claims based on amount, frequency, claim type patterns, and known fraud indicators.

Add SLA tracking

Set target resolution times per claim type and priority, with automated escalation when SLAs are at risk of being breached.

Add email notifications

Send automated emails to policyholders at each status transition and to adjusters when claims are assigned using Resend.

Add claim templates

Create pre-filled claim forms for common scenarios (fender bender, water damage, theft) that reduce submission time.

Add document OCR

Use an AI service to extract text from uploaded receipts and police reports, auto-filling claim fields from the documents.

Common pitfalls

Pitfall: Allowing arbitrary status changes without validation

How to avoid: Implement a PostgreSQL function that validates each transition against a defined state machine and raises an exception on invalid changes.

Pitfall: Not logging status transitions

How to avoid: Automatically insert into claim_status_log within the transition function, capturing from_status, to_status, changed_by, reason, and timestamp.

Pitfall: Storing monetary amounts as floats

How to avoid: Store all amounts as bigint in cents (estimated_amount_cents, approved_amount_cents) and format for display client-side.

Pitfall: Not restricting document access by role

How to avoid: Configure Supabase Storage bucket RLS to restrict reads to the claim owner and assigned adjuster only.

Best practices

  • Implement status transitions as a PostgreSQL function with a state machine to enforce valid workflow at the database level.
  • Log every status change in a claim_status_log table for complete audit trails required by insurance regulations.
  • Store all monetary values as bigint in cents to avoid floating-point rounding errors in financial calculations.
  • Use FOR UPDATE row locks in the transition function to prevent race conditions during concurrent claim processing.
  • Configure Supabase Storage bucket RLS to restrict document access by role — policyholders see their own, adjusters see assigned claims.
  • Use Clerk custom claims for role-based access (policyholder, adjuster, manager) with middleware.ts enforcement.
  • Validate that estimated_amount does not exceed coverage_limit in the submission Server Action using Zod.

AI prompts to try

Copy these prompts to build this project faster.

ChatGPT Prompt

I'm building an insurance claims tool with Next.js and Supabase. I need a PostgreSQL function that implements a state machine for claim status transitions — validating that each transition follows allowed paths (submitted→under_review→investigation|approved|denied, etc.), logging the change, and locking the row to prevent concurrent updates. Show me the function SQL, the valid transitions map, and how to call it from a Next.js API route.

Build Prompt

Build the claim submission wizard for an insurance claims tool. Create a 'use client' component with a 4-step Stepper: Step 1 has Select for claim type, date picker for incident_date, Textarea for description, Input for estimated_amount. Step 2 has a file upload zone with document_type Select per file. Step 3 shows a review Card with all entered data. Step 4 shows confirmation with claim_number. Validate with Zod that incident_date is not in the future and estimated_amount is within coverage_limit.

Frequently asked questions

Can I build this with the free V0 plan?

The core submission wizard and claims list fit within the free tier. V0 Premium is recommended for the full multi-page system with analytics dashboards.

How does the status state machine work?

A PostgreSQL function validates each transition against a predefined map of allowed paths. For example, a claim in submitted status can only move to under_review. Attempting an invalid transition raises a database exception.

What authentication should I use?

Clerk is recommended for role-based access. Set custom claims (policyholder, adjuster, manager) in the Clerk Dashboard metadata and enforce them in middleware.ts and Server Actions.

How are documents secured?

Claim documents are stored in a Supabase Storage bucket with RLS policies restricting access to the claim owner and the assigned adjuster. Internal notes are filtered by role on the server side.

Can I add email notifications?

Yes. Add a Resend integration that sends emails at each status transition. Call Resend from within the PostgreSQL transition function trigger or from the API route after a successful transition.

How do I deploy?

Publish via V0's Share menu. Set SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, and Clerk credentials in the Vars tab. Configure the claim-documents Storage bucket and RLS policies.

Can RapidDev help build a custom claims platform?

Yes. RapidDev has built 600+ apps including insurance platforms with fraud detection, SLA tracking, and regulatory compliance features. Book a free consultation to discuss your needs.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Need help building your app?

Our experts have built 600+ apps and can accelerate your development. Book a free consultation — no strings attached.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.