Schedule recurring work before a proposal is signed

Set scheduling.activation_gate.require_accepted_proposal to false, then onboard the client with lines[] attached — the service line activates and spawns jobs immediately. Assign the series, dispatch, and build the proposal anyway but leave it in draft. Re-arm the gate when the migration is done.

Yes. Turn off the activation gate, and a recurring service line spawns jobs the moment it is created — no accepted proposal required.

This is the verbal-agreement posture: the client said go on the phone, the work starts Tuesday, and the paperwork follows when it follows.

Why the gate exists at all

By default, an active recurring service line will not spawn jobs until its site has an accepted proposal. That is the paperwork-first posture: nothing lands on the schedule that the client has not signed for.

It is a good default for new business. It is the wrong default for a book of existing relationships — clients you have served for years, who are never going to sign anything, and whose service should not pause while a document sits in an inbox.

Turn the gate off

update_setting
  key: scheduling.activation_gate.require_accepted_proposal
  value: false

Record a reason when you do it. The setting stores who changed it, when, and why, and you will want that context when you come back to re-arm it.

This is a tenant-wide switch, not per client. Turn it back on once the legacy conversions are through.

Onboard the client with the service line attached

With the gate off, use the direct path — client, site, and active recurring service line in one call:

onboard_client
  legal_name, billing_email, client_type, invoicing_cadence, payment_terms_type
  sites: [{ name, address }]
  lines: [{ site_ref, service_id, frequency_id, client_rate_cents,
            day_of_week, week_of_month, anchor_date, ...line facts }]
  confirm: false     ← preview first, zero writes

The preview echoes the schedule with weekday names spelled out and the next few dates computed, plus a duplicate-client check. Read it properly. Mistakes are cheap here and expensive later.

Then repeat with confirm: true. You get the client, the site, the billing contact, the service line with its recurrence rule, and the spawned jobs — atomically. The response tells you how many jobs spawned and confirms activation_gate_passes: true.

Assign and dispatch

Assignment and dispatch are separate, deliberate acts.

assign_series(contract_service_line_id, contractor_id)

sets the contractor on the line so every future spawn inherits them, re-derives what that contractor is paid from their own rate model, and sweeps the existing scheduled occurrences onto them. It does not notify anyone. It also reports back anything it did not touch — occurrences already dispatched or completed under someone else are never silently reassigned.

Then dispatch. dispatch_job marks a visit as dispatched without an email, for when the contractor was told out of band. propose_send_work_order sends a real branded work order. Both are available; the first is honest about what it is, and warns you that no work order covers the visit.

Keep the proposal, just don't send it

Here is the part operators miss: skipping the proposal as a gate does not mean skipping the proposal as a document.

Build it anyway. Create the proposal, add the lines, render the PDF, and leave it sitting in draft. A draft proposal has no signing token minted and no email sent. It is ready the day the conversation happens.

create_proposal → add_proposal_line → render_artifact_pdf

You now have a client whose service is live and whose paperwork is ready but unsent. That is a legitimate, common, and fully supported state.

If the client later accepts, acceptance de-duplicates against the service lines that already exist — it logs a loud audit skip rather than standing the same schedule up twice.

Re-arm the gate afterwards

Once the conversions are done, set it back to true. Leaving it off permanently means a mistyped service line goes straight onto the schedule with nothing to catch it.

Related

Last updated 2026-08-28