1 Change Orders
2 File Dispute
3 Resolution
Create Change Order Contractor
9:41
Request Change Order
Current Contract
Kitchen Remodel — Phase 2
HomeownerSarah Mitchell
Contract Amount$12,400.00
Timeline14 days
What needs to change?
Reason for Change
Additional Work Discovered Material Upgrade Scope Expansion Weather Delay
Price Adjustment
+
$
Updated Timeline
+
days
Photo Evidence *
Submit Change Order

ContractorChangeOrderScreen — create mode

useMutation(api.jobs.changeOrders.create), MediaUpload component

Review Change Order Poster
9:41
Change Order
Change Order Requested by Contractor
Order Number
CO-01
Pending Review

JobKitchen Remodel — Phase 2
ContractorMike's Renovation Co.
SubmittedFeb 22, 2026
Scope Comparison
Original Scope
Remove existing backsplash, install new subway tile backsplash with accent border, replace under-cabinet lighting.
Proposed Changes
Replace water-damaged drywall (approx 18 sq ft), apply moisture barrier, then install new subway tile backsplash with accent border and under-cabinet lighting.
Cost Impact
Original
$12,400
New Total
$14,250
Additional Cost+$1,850.00
Timeline Impact
Original
14 days
New Timeline
19 days
Timeline Change+5 days
Contractor's Evidence
Decline
Approve

PosterChangeOrderScreen — review mode

useMutation(api.jobs.changeOrders.approve / reject), ConfirmationDialog

Change Order History Both
9:41
Change Orders
Original Contract
$12,400.00
Current Total
$14,650.00
Net Change +$2,250.00
CO-01
Approved
Water damage repair behind backsplash — drywall replacement and moisture barrier
Amount+$1,850.00
DateFeb 22, 2026
CO-02
Pending
Upgrade cabinet hardware from brushed nickel to matte black
Amount+$400.00
DateFeb 24, 2026
CO-03
Declined
Extend kitchen island by 12 inches with additional granite countertop
Amount+$2,800.00
DateFeb 18, 2026

ChangeOrderHistoryScreen

useQuery(api.jobs.changeOrders.listByJob), audit trail pattern


File Dispute Poster
9:41
File Dispute
Step 1 of 5
Select Job
Kitchen Remodel — Phase 2
Mike's Renovation Co. · $14,250
Dispute Category
Quality Issue Timeline Missed Incomplete Work Communication Billing Discrepancy
Describe the Issue
Photo Evidence *
Desired Resolution
Partial Refund Full Refund Redo Work Mediation
Requested Amount
$
Submit Dispute

CreateDisputeScreen — Typeform wizard

useMutation(api.features.disputes.createDispute), MediaUpload, 5-step flow

Dispute Confirmation Poster
9:41
Dispute Filed
Case #DIS-000042
What Happens Next
Dispute Filed
Completed just now
Admin Reviews
Within 48 hours
Both Parties Respond
Contractor will be notified
Resolution Proposed
Fair resolution for both parties
Escrow Action
Funds released or refunded
View Dispute

SuccessScreen (inline component)

Navigation: router.replace to dispute detail

Dispute Detail Poster
9:41
Dispute #DIS-000042
#DIS-000042
Under Review
Status
Filed
Feb 22, 2026 · 2:14 PM
Under Review
Admin assigned · Est. 24h
Awaiting Response
Pending
Resolution
Pending
Closed
Pending
Case Details
CategoryQuality Issue
Amount$2,400.00
ResolutionPartial Refund
JobKitchen Remodel
ContractorMike's Renovation Co.
Evidence Submitted
3 files attached
Communication
A
SupportFeb 23, 10:30 AM
We've received your dispute and assigned it to our review team. We'll notify the contractor and request their response within 48 hours.
S
YouFeb 23, 11:15 AM
Thank you. I also have a text message from the contractor acknowledging the issue — should I upload that?

DisputeDetail (app/disputes/[id].tsx)

useQuery(api.features.disputes.getDisputeDetail), real-time messages

Dispute Response Contractor
9:41
Respond to Dispute
A dispute has been filed against you for Kitchen Remodel
Dispute #DIS-000042
Filed by Sarah Mitchell · Feb 22, 2026

CategoryQuality Issue
ClaimCracked tiles, grout inconsistencies
RequestedPartial Refund — $2,400
Your Response
Counter Evidence
Your Resolution Offer
Partial refund amount you're willing to offer:
$
Only for the grout rework, not the tile damage
Submit Response

DisputeResponseScreen (contractor-side)

useMutation(api.features.disputes.addResponse), counter-evidence upload


Resolution Proposed Both
9:41
Dispute #DIS-000042
Admin has proposed a resolution
Respond within 47 hours, 23 minutes
Proposed Resolution
From 3Bids Review Team
Recommended Action
After reviewing evidence from both parties, we recommend a partial refund of $1,200 to the homeowner. The grout inconsistencies are confirmed and warrant rework. However, the tile damage appears to have occurred after project completion based on the contractor's timestamped walkthrough photos.
Refund Breakdown
Grout Rework$800.00
Inconvenience Credit$400.00

Total Refund$1,200.00
Reasoning
The contractor's photos from the final walkthrough clearly show intact tiles. The homeowner's claim for tile replacement is not supported. The grout issue is valid and the contractor should cover rework costs.
Appeal
Accept Resolution

DisputeDetail — resolution_proposed state

useMutation(api.features.disputes.acceptResolution), 48h deadline timer

Resolved — Refund Poster
9:41
Dispute Resolved
Case #DIS-000042 has been resolved with a partial refund.
Resolution Summary
Partial refund for grout rework and inconvenience credit. Tile damage claim denied.

Refund Amount$1,200.00
Escrow Adjustment
Original Escrow$14,250.00
Refund to You-$1,200.00

Final to Contractor$13,050.00
Was this resolution fair?
Yes
No
Return to Dashboard

DisputeDetail — resolved state

Escrow adjustment via api.admin.escrow, satisfaction survey mutation

Escalated Both
9:41
Escalated to Review Board
Escalation in Progress
What Happens Now
This dispute has been escalated to the 3Bids Review Board for further investigation. A senior reviewer will evaluate all evidence from both parties.
Estimated Timeline
5–7 business days
Assigned Reviewer
David Chen
Senior Dispute Reviewer
Evidence Summary
Homeowner Evidence3 files
Contractor Evidence2 files
Admin Notes4 entries
You will be notified of the decision via email and in-app notification.
Back to Disputes

DisputeDetail — escalated state

Admin escalation via api.admin.disputes.escalate, Slack: dispute_notice channel


Data Architecture

Schema: disputes

escrowId: Id<"escrow">
jobId: Id<"jobs">
posterId: Id<"posterUsers">
contractorId: Id<"contractorUsers">
disputeNumber: string // "DIS-000001"
initiatedBy: string // poster | contractor
reason: string
description: string
status: string
  // open → under_review → awaiting_response
  // → resolution_proposed → resolved | escalated
amountInDispute: number
amountToPoster: number?
amountToContractor: number?
resolutionNotes: string?
media: Array<{storageId, type, mimeType}>
resolvedByAdminId: Id<"adminUsers">?

Schema: changeOrders

jobId: Id<"jobs">
escrowId: Id<"escrow">
changeOrderNumber: string? // "CO-01"
requestedById: string
requestedByType: string // poster | contractor
description: string
reason: string?
additionalCost: number // + or -
additionalDays: number?
status: string
  // pending_signatures → pending_funding
  // → approved | rejected | paid
media: Array<{storageId, type, mimeType}>
paymentCompleted: boolean
signedByContractorAt: number?
signedByPosterAt: number?

Hooks & Mutations

// Disputes
useQuery(api.features.disputes.getMyDisputes)
useQuery(api.features.disputes.getDisputeDetail)
useMutation(api.features.disputes.createDispute)
useMutation(api.features.disputes.addResponse)
useMutation(api.features.disputes.addEvidence)
useMutation(api.features.disputes.acceptResolution)
useMutation(api.features.disputes.withdrawDispute)

// Change Orders
useQuery(api.jobs.changeOrders.get)
useQuery(api.jobs.changeOrders.listByJob)
useMutation(api.jobs.changeOrders.create)
useMutation(api.jobs.changeOrders.approve)
useMutation(api.jobs.changeOrders.reject)
useMutation(api.jobs.changeOrders.cancel)
useMutation(api.jobs.changeOrders.markPaid)

Integrations

// Slack Alerts
Channel: dispute_notice
  → New dispute filed
  → Resolution accepted/appealed
  → Escalation triggered
Channel: ops_alerts
  → Change order created
  → Change order funded

// Escrow (refund processing)
api.admin.escrow.processRefund
api.payments.escrow.adjustForDispute

// Stripe
api.stripe.stripe.createChangeOrderPaymentIntent
api.stripe.stripe.createRefund

// Transactional Email (SendGrid)
dispute_filed → poster + contractor
dispute_resolved → both parties
change_order_submitted → poster
Create Change Order + Poster Review
9:41
Change Orders
Current Contract
Kitchen Remodel — Phase 2
HomeownerSarah Mitchell
Contract Amount$12,400.00
Timeline14 days
What needs to change?
During demolition, we discovered water damage behind the existing backsplash that extends to the subwall. Drywall needs replacement before tile installation can proceed safely.
Reason for Change
Additional Work Material Upgrade Scope Expansion
Price Adjustment
$
Timeline Change
days
Photo Evidence
Submit Change Order
Change Order Requested by Contractor
Order Number
CO-01
Pending Review

JobKitchen Remodel — Phase 2
ContractorMike's Renovation Co.
SubmittedFeb 22, 2026
Scope Comparison
Original Scope
Remove existing backsplash, install new subway tile with accent border, replace under-cabinet lighting.
Proposed Changes
Replace water-damaged drywall (18 sq ft), apply moisture barrier, then install subway tile and lighting.
Cost Impact
Original
$12,400
New
$14,250
Timeline Impact
Original
14 days
New
19 days
Decline
Approve
Dispute Timeline + Resolution Proposed
9:41
Dispute #DIS-000042
#DIS-000042
Under Review
Status
Filed
Feb 22, 2026 · 2:14 PM
Under Review
Admin assigned · Est. 24h
Awaiting Response
Pending
Resolution
Pending
Closed
Pending
Case Details
CategoryQuality Issue
Amount$2,400.00
ResolutionPartial Refund
JobKitchen Remodel
ContractorMike's Renovation Co.
Evidence Submitted
3 files attached
Admin has proposed a resolution
Respond within 47 hours, 23 minutes
Proposed Resolution
From 3Bids Review Team
Recommended Action
After reviewing evidence, we recommend a partial refund of $1,200. Grout inconsistencies confirmed. Tile damage occurred after project completion per contractor's timestamped walkthrough photos.
Refund Breakdown
Grout Rework$800.00
Inconvenience Credit$400.00

Total Refund$1,200.00
Communication
A
SupportFeb 23, 10:30 AM
We've received your dispute and assigned it to our review team. We'll notify the contractor within 48 hours.
S
YouFeb 23, 11:15 AM
Thank you. I also have a text from the contractor acknowledging the issue — should I upload that?
Appeal
Accept Resolution
Disputes & Change Orders Dashboard
https://app.3bids.io/disputes
3Bids
All Cases ⌘1
Open ⌘2
Resolution ⌘3
Change Orders ⌘4
History ⌘5
Trends ⌘6
Settings ⌘7
SM
Sarah Mitchell
Homeowner
Settings ⌘,

Disputes & Change Orders

18 Open 92% Resolved
247
Total Cases
18
Open
92%
Resolution Rate
2.8d
Avg Resolution
Active Disputes
DSP-2847 — Johnson Roof
Scope dispute · Filed 2 days ago · $2,400
Open
DSP-2845 — Park Plumbing
Quality issue · Filed 4 days ago · $1,800
In Review
DSP-2843 — Miller HVAC
Timeline · Resolution proposed · $600
Proposed
DSP-2844 — Chen Gutters
Timeline · Resolved 3 days ago · $1,200
Resolved
Change Orders
Original
$12,400
Current
$14,650
CO-01 — Water Damage Repair
Feb 22 · Approved
+$1,850
CO-02 — Cabinet Hardware Upgrade
Feb 24 · Pending
+$400
CO-03 — Island Extension
Feb 18 · Declined
+$2,800
Resolution Performance
91%
Resolved
2.1d
Avg Time
$850
Avg Value

Key Design Decisions

Design Pattern
TODO: Add design decision