Skip to main content

The user journey

This page follows a user from sign-in to a submitted claim. It is the best single page for support: it names what the user sees, what each state means, and which part of the app is responsible. File references point into frontend/src so engineers can jump to the code.

The whole journey at a glance​

1. Sign in​

The app is gated by AdjustSquare single sign-on. An unauthenticated user is sent to the AdjustSquare login page and returns with a token, which the app exchanges for a session.

  • Pages: login, auth/callback, logout.
  • State: lib/auth.tsx holds the user and token, persists them to localStorage, and falls back to a bt_shared_data cookie for same-subdomain deployments.
  • The full sequence (redirect, JWT validation, team and user auto-provisioning) is documented in authentication.

2. The dashboard​

After sign-in the user lands on the Dashboard (app/dashboard/page.tsx), which lists their team's claims (with a per-claim Usage column) and exposes the Create claim action. Stat cards headline total claims, average items per claim, and the average processing time per catalogued item (from GET /api/dashboard/metrics). On prepaid-billing instances a persistent credits widget in the shell also shows the team's available balance and a Buy credits button; on invoiced instances it is hidden.

  • Shell: components/AppShell.tsx and components/Sidebar.tsx provide the left nav (Dashboard, Training, Help, Settings), the team and environment badge, and the user footer.

3. Create a claim and add rooms​

Creating a claim (components/CreateClaimModal.tsx) captures the claim number, date of loss, ZIP or Canadian postal code, and loss type. Opening the claim (app/claims/[id]/page.tsx) shows its rooms, and the user adds rooms with components/CreateRoomModal.tsx.

Why rooms first

Media is always uploaded into a room, and the room name becomes the room on every item the upload produces. Setting up rooms up front keeps the inventory organized.

Self-onboarding

New users can learn this whole journey hands-on in Training (/training): guided missions run the real flows inside a sandboxed training claim, with deterministic fixture media, points, badges, and a shareable certificate at the end. See Training and certification.

3b. Optional: ask the insured to start it off​

Instead of gathering everything themselves, the adjuster can hand the first pass to the person who actually knows what was lost. Ask the Insured on the claim page emails the homeowner a private link (components/InviteInsuredModal.tsx).

They open it on a phone, with no account and no sign-in, and are walked through the claim's rooms one at a time. In each room they can add photos or a video with a note on each file, type items into a table, or skip the room. It saves as they go, so they can stop and come back to the same link. When they press Send, everything lands on the claim:

What they addedWhere it landsWhat it costs
Photos of a roomA photo job per room at awaiting_grouping, each photo carrying their noteNothing until the adjuster presses Process
A videoIts own job at awaiting_confirmationNothing until the adjuster confirms it
Typed itemsInventory items on the claim, immediatelyNothing, ever: they named them, so the AI is never called

The adjuster reviews it all as normal. Nothing is auto-sent to Contents Estimation, because sending freezes a claim's items and would remove the chance to correct anything. The claim page shows how far each invitation got, and a link can be resent or revoked. See Insured inventory link.

4. Upload media​

From a room (app/rooms/[id]/page.tsx) the user drops any mix of files or folders into a single upload area (components/RoomUpload.tsx). There are no per-type tabs: the component classifies each file as photo, video, audio, or PDF by extension (lib/media.ts, with a MIME tiebreak for WEBM), queues everything, and uploads in one pass. All photos in a drop become one photo job (a "set"), and any PDFs ride with them into that same job; each video and each audio file becomes its own job. Uploads report real progress bars (chunked uploads and XMLHttpRequest in lib/api.ts).

TypeWhat happens after upload
VideoA job is created and the video pipeline starts immediately (after the credit confirmation on prepaid instances).
AudioA job is created and the audio pipeline starts immediately (after the credit confirmation on prepaid instances).
PhotosA job is created in awaiting_grouping. The user groups same-item photos in components/GroupPhotosModal.tsx, then presses Process.
PDF with photosThe job is created in importing_pdf and the photos are read out of the document in the background, then it becomes an ordinary awaiting_grouping photo job. Photos printed under one item label arrive already merged, whether the label sits on each photo or as a heading above a run of them, and any note printed beside a photo is kept and passed to the AI as a hint. A label printing more than MAX_PHOTOS_PER_ITEM (5) photos is split into several balanced groups, each one its own AI request and its own credit, and the grouping screen says so. Cover sheets and summary pages are found and skipped, so the file does not have to be trimmed first. See PDF import.
Contents list for a whole claimImported from the claim page instead of a room, because one list covers a whole house. The rooms printed in the document become rooms on the claim, each with its own awaiting_grouping photo job. See PDF import.

On prepaid instances, video and audio jobs park at awaiting_confirmation after upload. The uploader collects every parked job from the drop and asks for one combined credit confirmation (components/ConfirmUploadsModal.tsx) instead of one dialog per file; cancelling discards the parked jobs before any credits are spent.

Photo grouping is the key difference: photos do not auto-process. The user merges shots that show the same item (so the AI treats them as one), then explicitly starts processing. See the AI pipeline.

5. Watch processing​

While a job runs, the user sees live progress (components/ProcessingStatus.tsx). The frontend opens a Server-Sent Events stream and receives progress, log lines, and final metrics as they happen.

Job statuses support should recognize​

StatusMeaning
pendingQueued, pipeline about to start.
importing_pdfReading the item photos out of an uploaded PDF. Moves to awaiting_grouping by itself when done.
awaiting_groupingPhoto job waiting for the user to group photos and press Process.
extractingPulling frames and audio from the video (or reading the audio file).
transcribingRunning Deepgram on the narration or audio.
segmentingSplitting the video into time chunks.
analyzingThe AI vision calls are running (the long stage).
synthesizingSaving items and cropping photos.
completeDone. Items are ready to review.
errorSomething failed. error_message has the detail; the pipeline logs explain it.

A job interrupted mid-run (a deploy restarting the backend, a crash) does not stay frozen: the recovery sweep requeues it automatically (stage reads "Restarting after an interruption") and it runs again from scratch. See troubleshooting.

6. Review the inventory​

The review surface is components/InventoryTable.tsx, with per-item editing in components/ItemModal.tsx. There are several ways to get through the list:

  • Manual review: scan the table, open items, edit fields inline.
  • Guided Review (components/ReviewMode.tsx): a focused, one-item-at-a-time flow with keyboard shortcuts; for audio items it can play back just the slice of the recording that mentions the item.
  • Bulk actions: select many rows and apply the same change (condition, room) at once.
  • Filtering and sorting: narrow the table by room, confidence, flag, or approval state.

Confidence is shown per item (lib/confidence.ts), and items below 0.6 arrive flagged. Source badges (lib/sourceTag.ts) mark whether an item came from video, photo, or audio.

7. Approve items​

Only approved items are submitted and exported. Users approve items one at a time, in bulk, or automatically:

  • Auto-approval rules (Settings, lib/automationSettings.tsx) approve items that clear a confidence threshold and an allowed-condition list, optionally skipping flagged items. Rules can run automatically the moment a job finishes, or on demand. See automation and prompts.

8. Submit to Adjust Square​

When the inventory is ready, the user submits with components/SubmitClaimModal.tsx. They confirm claim details, pick which rooms to send, and choose whether to send only approved items.

  • The first submission creates the claim and all items on Adjust Square in one call.
  • Later submissions add only the new (still unsubmitted) items to the same claim.
  • Photos upload and AI processing on the Adjust Square side are triggered in the background, so the modal returns quickly.

The full mechanics, including the per-user authentication, are in the Adjust Square integration.

9. Export (optional)​

At any time the user can export an inventory to Excel or CSV, for a single job or a whole room, optionally limited to approved items (lib/api.ts, backend inventory routes). The Excel export includes a summary sheet, per-room sheets, and — when the items have photos — a Photos sheet. In the Excel file every item name is a hyperlink to that item's primary photo, and the Photos sheet carries a link to each of an item's other photos, since a cell can only hold one link. The links point at the unauthenticated /api/photos/... route, made absolute with PUBLIC_BASE_URL or, when that is blank, with the origin the export was requested from.

The Help Center and the Activity Log​

  • Help Center (app/help): in-app, task-focused articles written from the home Dashboard outward. Content lives in frontend/src/content/help.
  • Activity Log (Settings): every meaningful action is recorded, and many actions can be restored (undone) from here. See observability.
Support shortcut

If a user says "my items are wrong," first check the job status and its logs (the Logs page, app/logs, admins only; filter it to the user's team). Most "wrong output" reports trace back to a quiet narration (poor transcription), a photo batch that was not grouped, or low-confidence items that were never reviewed.