# Use Topline: Scheduling

Topline's scheduling engine runs inside the company's own cloud account. It
computes real drive times from the company's own road network, searches
route-aware availability, writes booked appointments back to the CRM, and
records availability numbers that no other system captures. This guide covers
the scheduling workspace every tenant receives, technician shifts and the
import assistant, booking, and the nightly metrics.

## The scheduling workspace

Every tenant with scheduling enabled receives two hosted applications, visible
to every team member from the workspace artifact list:

- **Scheduling configuration** — availability search, service regions on a
  map, scheduling rules, and technician shifts.
- **Scheduling metrics** — search, offer, and booking activity with daily
  history.

Both are ordinary Topline artifacts owned by the tenant. A Build-capable
member can fork and adapt them — the shift import assistant below is
deliberately written so the company can change how it works.

## Availability search and offers

An availability search takes a service address, a duration, and a date range,
and returns offer candidates: concrete technician / date / time-window slots
ranked by real drive time against the routes already on the schedule. Every
search and every offered slot is recorded, which is what makes the metrics
below possible. When the engine cannot offer anything, the refusal and its
reason are recorded too.

## Technician shifts

Shifts tell the engine when a technician can work.

- **Routes are the source of truth.** A technician who has a route in the CRM
  but no shift schedule is still schedulable: the interface flags the missing
  schedule, and the engine treats that technician's day as 8:00 AM–5:00 PM
  until a real schedule is saved.
- **Shifts page.** The configuration app lists every technician from the CRM
  mirror alongside their saved shifts, with missing schedules flagged.

### The shift import assistant

The shifts page includes an import assistant for bringing schedules in from
whatever the office already has — a pasted spreadsheet, an export, or plain
text like "Sam works 8 to 4 weekdays".

1. Paste the source text and start the import.
2. The assistant extracts structured shift rows and matches them to
   technicians by CRM id or unique name.
3. Review the proposed rows, correct anything in a follow-up message
   ("Sam's Friday shift ends at 3"), and save. Saves go through the same
   validation as manual edits — a shift must end after it starts.

The assistant runs on a platform-pinned model. Pasted text is treated as data
to extract from, never as instructions to follow. Imports share a per-tenant
allowance (12 requests per minute, 500 per day); past the allowance the
assistant asks you to retry later. The assistant's prompt and matching logic
live in the artifact itself, so a Build-capable member can fork the app and
tune either.

## Meetings and blocks

The Blocks & meetings page holds time out of routes and tells the engine
where each block leaves the technician standing.

- **Meetings and other blocks** are Topline-owned. A block happens once (a
  date) or repeats (weekly days, "first Monday of the month", every N weeks);
  a series can skip individual dates and carry an end date. The editor
  previews the next occurrences before saving — check that list; it is where
  a wrong rule shows itself. Rules the engine cannot expand are rejected at
  save time rather than silently blocking nothing.
- **Where the day starts.** A call-in meeting holds the clock only. Give a
  meeting a location and it can also set where the route begins: the
  technician leaves from the meeting when it ends, and routes are planned
  from there. A block can also require the technician to end the day at its
  location.
- **Blocked spots from the CRM** appear on the same page, read-only. They are
  swept from PestRoutes several times a day and absorbed as unavailability;
  edit them in the CRM, which stays their owner.
- Availability search respects all of it: blocks become solver breaks or
  fixed stops, meeting locations move route starts, and a day whose blocks
  leave no routable time is skipped with that reason.

## Booking

Booking converts one offered slot into a written CRM appointment. A booking
either succeeds and returns the CRM appointment id, or refuses with a stated,
actionable reason — for example, the offer expired, the slot was taken, or
the tenant's CRM connector cannot write. Every attempt is recorded. Booking
only writes when scheduling is enabled for the tenant and a live CRM
connector is configured; nothing else in the scheduling system writes to the
CRM.

## Scheduling metrics

The metrics application answers the questions no CRM records:

- how many availability searches ran, and how many found nothing;
- how many slots were offered, and how far out the first opening was;
- how many bookings were written.

Activity is rolled up nightly per day; the current day is computed live on
top of the stored history, so opening the app is fast even with months of
activity. The nightly rollup runs automatically — there is nothing to
schedule or maintain.

## Limits and boundaries

- The engine, its routing servers, and all scheduling data run in the
  customer's own cloud account.
- The import assistant's model, message size, and output size are
  platform-capped; it cannot call tools or take actions — it only proposes
  rows that a person reviews and saves.
- Customer-facing self-booking pages are not live yet; booking today is an
  operator action.

## Troubleshooting

- **A technician is missing from the shifts page** — they must exist in the
  CRM mirror first; check the data source connection.
- **"No technicians" after an import** — the roster could not be loaded;
  reload the page, and check the data source connection if it persists.
- **A search returns nothing** — check that shifts (or routes) exist for the
  dates searched and that the service address falls inside a service region.
- **Booking refused** — the response states the reason; expired offers need a
  fresh search, and connector refusals need an administrator to check the
  CRM credential.
