← Justine Acosta · PortfolioN8N BUILD PLAN · TRUSTED MOVER

Every quote, booking and move, planned before a single node is placed.

Six n8n workflows and three helpers for Trusted Mover, a moving company in Austin, TX. Claude reads and drafts, Supabase holds the jobs, Google Sheets holds the schedule, Stripe takes the money, and a person approves anything a client sees.

Tools on this page
  • n8n
  • Supabase
  • Claude
  • Gmail
  • Google Sheets
  • Cal.com
  • Telegram
  • Stripe
Client
Trusted Mover · Austin, TX
Platform
n8n
Workflows
6 + 3 helpers
Prepared by
Justine Acosta
01

Before anything is built

The outcome, the entry points and every way a job ends.

Outcome

Every quote is answered within 5 minutes, and nothing a client sees goes out without a person saying yes.

Entry points

Eight entry points: a web form, Cal.com, Stripe, two schedules, a sheet edit, a change form and n8n’s own error trigger.

Every way a job ends

  • Closed
  • Lost
  • Cancelled
  • Claim open

Out of scope

  • Payroll
  • Truck GPS
  • Accounting exports
02

Naming convention

One vocabulary for workflows, nodes, links, keys and fields.

Workflows

TM-[number] · [Trigger] → [Outcome]
TM-01 · Quote request → Qualified lead
TM-H02 · Notify ops

The number is the build order. Helpers get an H.

Nodes

[Verb] [object]
Find contact
Draft estimate
Log the quote

Default names like “HTTP Request1” never survive a build.

Webhook paths

/tm/[source]
/tm/quote
/tm/change
/tm/stripe

One path per source, all lowercase.

Credentials

TM · [Service] ([mode])
TM · Stripe (live)
TM · Stripe (test)

Test and live keys never share a name.

Supabase fields

snake_case, _at for times, _usd for money
deposit_paid_at
estimate_usd

The suffix tells you the unit.

Sheets tabs

Title Case, one job per tab
Crew schedule
Rate card

Workflows read columns by header name, never by position.

03

Where the data lives

Three tables, seven stages and five sheet tabs.

contacts

id name email phone created_at

One row per person, matched on email or phone.

jobs

id contact_id stage move_date size from_zip to_zip estimate_usd deposit_paid_at crew nudges_sent source

One row per move.

events

job_id type payload at

Every workflow writes one, so the next run knows what already happened.

Job stages

Sheets tabWhat it holds
Quote logEvery request, as it arrived
Rate cardHourly rates, truck fees and materials
Crew scheduleOne row per booked move. The crew edits it.
Test matrixThe test rows below, with results
ErrorsOne row per failed run
04

What starts each workflow

Every entry point, and the workflow it runs.

SourceEventWorkflow
Quote form on the siteWebhook /tm/quoteTM-01
Cal.comBOOKING_CREATEDTM-02
Stripecheckout.session.completedTM-03
ScheduleEvery hourTM-03
ScheduleEvery day, 07:00 CTTM-04
Crew schedule sheetRow status → DoneTM-05
Reschedule formWebhook /tm/changeTM-06
Any failureError TriggerTM-H01
TM-01

Quote request → Qualified lead

14 nodes, 2 decisions.

Outcome

Every quote becomes a job, or one clear question, within 5 minutes.

Trigger

The quote form on the site posts to /tm/quote.

Exits

  • Merged into an open job
  • Waiting on one answer
  • Survey link sent
TM-01 · Quote request → Qualified lead
noyesnoyes
  1. Quote form (Starts it, POST /tm/quote), then Normalize fields
  2. Normalize fields (Step, Edit Fields), then Find contact
  3. Find contact (Step, Supabase), then Duplicate in 24 h?
  4. Duplicate in 24 h? (Decides, If), then Extract move details if no; Merge into open job if yes
  5. Merge into open job (Ends, Supabase)
  6. Extract move details (Claude, Claude), then Anything missing?
  7. Anything missing? (Decides, If), then Create job if no; Draft one question if yes
  8. Draft one question (Claude, Claude), then Ask the client
  9. Ask the client (Step, Gmail), then Stage 0 · needs info
  10. Stage 0 · needs info (Ends, Supabase)
  11. Create job (Step, Supabase), then Log the quote
  12. Log the quote (Step, Google Sheets), then Notify ops
  13. Notify ops (Helper, TM-H02), then Send survey link
  14. Send survey link (Ends, Gmail)
TM-02

Survey → Estimate sent

15 nodes, 2 decisions.

Outcome

Every survey ends with an approved estimate and a deposit link, the same day.

Trigger

Cal.com posts BOOKING_CREATED to /tm/survey.

Exits

  • Estimate sent
  • Sent back to the owner
  • No-show, rebook link sent
TM-02 · Survey → Estimate sent
yesnoyesno
  1. Survey booked (Starts it, Cal.com), then Stage 1
  2. Stage 1 (Step, Supabase), then Business hours
  3. Business hours (Helper, TM-H03), then Until 24 h before
  4. Until 24 h before (Waits, Wait), then Reminder
  5. Reminder (Step, Gmail), then Until the survey ends
  6. Until the survey ends (Waits, Wait), then Survey done?
  7. Survey done? (Decides, If), then Price from rate card if yes; Rebook link if no
  8. Rebook link (Ends, Gmail)
  9. Price from rate card (Step, Google Sheets), then Draft estimate
  10. Draft estimate (Claude, Claude), then Owner approves
  11. Owner approves (Person approves, Wait on form), then Approved?
  12. Approved? (Decides, If), then Deposit link if yes; Back to owner if no
  13. Back to owner (Ends, Telegram)
  14. Deposit link (Step, Stripe), then Send estimate
  15. Send estimate (Ends, Gmail)
TM-03

Deposit paid → Move booked

13 nodes, 1 decision.

Outcome

A paid deposit books the move, and an unpaid estimate never sits forgotten.

Trigger

Stripe checkout.session.completed, plus an hourly sweep.

Exits

  • Booked
  • Nudged
  • Lost after two nudges
TM-03 · Deposit paid → Move booked
012
  1. Deposit paid (Starts it, Stripe), then Verify signature
  2. Verify signature (Step, Code), then Find job
  3. Find job (Step, Supabase), then Stage 3 · Booked
  4. Stage 3 · Booked (Step, Supabase), then Add to crew schedule
  5. Add to crew schedule (Step, Google Sheets), then Confirmation
  6. Confirmation (Step, Gmail), then Notify ops
  7. Notify ops (Helper, TM-H02)
  8. Every hour (Starts it, Schedule), then Unpaid estimates
  9. Unpaid estimates (Step, Supabase), then Nudges sent?
  10. Nudges sent? (Decides, Switch), then Nudge 1 if 0; Nudge 2 if 1; Stage · Lost if 2
  11. Nudge 1 (Ends, Gmail)
  12. Nudge 2 (Ends, Gmail)
  13. Stage · Lost (Ends, Supabase)
TM-04

Move week → Crew dispatched

9 nodes, 2 decisions.

Outcome

Every move has a crew, and a client who knows when they arrive.

Trigger

Schedule, every day at 07:00 Central.

Exits

  • Packing guide sent
  • Crew confirmed
  • Ops alerted
  • Arrival window sent
TM-04 · Move week → Crew dispatched
72yesno1
  1. Every day, 07:00 (Starts it, Schedule), then Upcoming moves
  2. Upcoming moves (Step, Supabase), then Days out?
  3. Days out? (Decides, Switch), then Stage 4 · Move week if 7; Crew assigned? if 2; Arrival window if 1
  4. Stage 4 · Move week (Step, Supabase), then Packing guide
  5. Packing guide (Ends, Gmail)
  6. Crew assigned? (Decides, If), then Crew confirmation if yes; Alert ops if no
  7. Crew confirmation (Ends, Gmail)
  8. Alert ops (Helper, TM-H02)
  9. Arrival window (Ends, Gmail)
TM-05

Move done → Paid + reviewed

14 nodes, 1 decision.

Outcome

Every finished move is paid, and every reply lands with the right person.

Trigger

The crew sets status to Done on the Crew schedule sheet.

Exits

  • Closed with a review link
  • Claim open
  • Owner follow-up
TM-05 · Move done → Paid + reviewed
praisedamagecomplaint
  1. Crew marks done (Starts it, Google Sheets), then Stage 5 · Moved
  2. Stage 5 · Moved (Step, Supabase), then Final invoice
  3. Final invoice (Step, Stripe), then Until paid
  4. Until paid (Waits, Wait), then 1 day
  5. 1 day (Waits, Wait), then Feedback question
  6. Feedback question (Step, Gmail), then Until reply
  7. Until reply (Waits, Wait), then Sort the reply
  8. Sort the reply (Claude, Claude), then Kind?
  9. Kind? (Decides, Switch), then Review link if praise; Open a claim if damage; Task for the owner if complaint
  10. Review link (Step, Gmail), then Stage 6 · Closed
  11. Stage 6 · Closed (Ends, Supabase)
  12. Open a claim (Step, Supabase), then Alert ops
  13. Alert ops (Helper, TM-H02)
  14. Task for the owner (Ends, Telegram)
TM-06

Cancel or reschedule

11 nodes, 2 decisions.

Outcome

Changes are handled the same day, with refunds that follow the policy exactly.

Trigger

The reschedule form posts to /tm/change.

Exits

  • New date confirmed
  • Three dates offered
  • Cancelled and refunded
TM-06 · Cancel or reschedule
rescheduleyesnocancel
  1. Change request (Starts it, POST /tm/change), then Find job
  2. Find job (Step, Supabase), then Type?
  3. Type? (Decides, Switch), then Check crew calendar if reschedule; Refund by policy if cancel
  4. Check crew calendar (Step, Google Sheets), then Slot free?
  5. Slot free? (Decides, If), then Move the date if yes; Offer 3 dates if no
  6. Move the date (Ends, Supabase + Sheets)
  7. Offer 3 dates (Ends, Gmail)
  8. Refund by policy (Step, Code), then Stripe refund
  9. Stripe refund (Step, Stripe), then Stage · Cancelled
  10. Stage · Cancelled (Step, Supabase), then Confirm
  11. Confirm (Ends, Gmail)
05

Helpers

Three small workflows the others call.

TM-H01 · Error handler

Every failure is logged and reaches ops with a link to the run.

TM-H01 · Error handler
  1. Any failure (Starts it, Error Trigger), then Log it
  2. Log it (Step, Google Sheets), then Tell ops
  3. Tell ops (Ends, Telegram)

TM-H02 · Notify ops

One place formats every ops message.

TM-H02 · Notify ops
  1. Called by a workflow (Starts it, Execute Workflow Trigger), then Format
  2. Format (Step, Edit Fields), then Send
  3. Send (Ends, Telegram)

TM-H03 · Business-hours gate

Nobody gets a message at 2 am.

TM-H03 · Business-hours gate
  1. Called by a workflow (Starts it, Execute Workflow Trigger), then Next allowed time
  2. Next allowed time (Step, Code), then Wait until then
  3. Wait until then (Waits, Wait)
06

Test matrix

One row per branch. Tick each one as it passes.

0 of 20 passed
PassedIDWorkflowBranchTestExpected
t01TM-01New quoteA fresh email with every field filledJob at stage 0, a Quote log row, survey link sent
t02TM-01DuplicateThe same email again within 24 hNotes merged into the open job, no second job
t03TM-01Missing detailNo move dateOne question sent, stage 0 needs info
t04TM-01Bad JSON from ClaudeForce a parser errorTM-H01 logs it and pings Telegram
t05TM-02ReminderSurvey booked for Tuesday 10:00Reminder arrives Monday 10:00 CT
t06TM-02No-showNo inventory form within 3 hOne rebook link sent
t07TM-02Owner approvesApprove the draftEstimate and 20% deposit link sent, stage 2
t08TM-02Owner editsSend it back with a noteNote on Telegram, nothing sent to the client
t09TM-03Deposit paidStripe test card 4242 4242 4242 4242Stage 3, a crew schedule row, confirmation sent
t10TM-03Replayed eventResend the same Stripe eventStill one booking and one email
t11TM-03Unsigned callPOST without Stripe-SignatureRejected with 400, nothing changes
t12TM-03Unpaid for 72 hAn estimate sent 73 h agoNudge 1, then nudge 2, then Lost
t13TM-04Seven days outMove date is today + 7Stage 4, packing guide sent
t14TM-04No crewMove in 2 days, crew blankUrgent Telegram alert
t15TM-04Day beforeMove date is tomorrowArrival window email
t16TM-05Paid and happyPay the invoice, reply “Great crew”Review link sent, stage 6
t17TM-05DamageReply “They scratched the table”Claim event and urgent alert, no review link
t18TM-06Reschedule, slot freeA new date with a free crewDate moved, schedule updated, confirmation sent
t19TM-06Cancel 10 days outCancel a move 10 days awayHalf the deposit refunded, stage Cancelled
t20TM-06Cancel 3 days outCancel a move 3 days awayNo refund, still confirmed
07

Build order

Five phases, in the order they are built.

  1. 1 · Foundation

    • Create the Supabase tables: contacts, jobs, events
    • Add the credentials: TM · Supabase, TM · Stripe (test), TM · Gmail, TM · Telegram, TM · Anthropic
    • Create the Sheets tabs: Quote log, Rate card, Crew schedule, Test matrix, Errors
    • Build TM-H01, TM-H02 and TM-H03, and set TM-H01 as the error workflow
  2. 2 · Intake

    • Build TM-01 and point the site’s quote form at /tm/quote
    • Build TM-02 with the Cal.com webhook and the approval form
    • Run tests t01–t08
  3. 3 · Money

    • Build TM-03 with the Stripe webhook and the hourly sweep
    • Build TM-05 with the invoice and the feedback steps
    • Run tests t09–t12, t16 and t17
  4. 4 · Operations

    • Build TM-04
    • Build TM-06 with the refund policy
    • Run tests t13–t15 and t18–t20
  5. 5 · Test and hand over

    • Switch Stripe to live keys
    • Run the whole matrix again with a real card and a real refund
    • Walk the owner through the handover page
    • Turn every workflow on
08

Handover

What the owner keeps.

What it does

  • Answers every quote within 5 minutes, or asks one question.
  • Books surveys and drafts estimates for you to approve.
  • Takes deposits, fills the crew calendar and chases unpaid estimates.
  • Reminds clients and crews before every move.
  • Invoices, asks for feedback and sends damage reports to you.

What breaks it

  • Renaming or moving a column in the Crew schedule sheet.
  • An expired or rotated Stripe key.
  • Changing the Cal.com event type or its questions.
  • Turning a workflow off without turning off its schedule.

Who to call

Justine Acosta, who built it. Errors already reach the ops Telegram group with a link to the run.

Where the logs are

Every failure is a row in the Errors tab and a Telegram message. Every job change is a row in the Supabase events table.