Mobis
Give the business around the craft a better system.One slot. Two requests. One booking.
Booking and customer management for small service businesses, beginning with knife sharpening. Built to connect to the business’s website.Mobis turns service rules and existing commitments into bookable slots. The hard part is keeping reservations, customer records, and later Calendar updates consistent when requests race or fail.
RuntimeNext.js runs on Cloudflare with SQLite in a Durable Object. Local Node and hosted storage use the same booking code.
Booking · implemented in the private preview
From an available slot to a saved booking.
- 01Request a slotBrowser → serverService rules + existing commitments
- 02Recheck under lockSQLite transactionRequest ID + slot availability
- 03Commit togetherSQLite transactionCustomer + booking + outbox + audit
- 04Sync after commitBackground Calendar workerQueued → delivered or failed
The customer, booking, queued updates, and audit record commit together. Calendar delivery happens afterward.
Step 01 · Browser → server
Request a slot
The service type, item count, and address determine duration and eligibility. Business hours, existing bookings, travel buffers, and connected Calendar busy time constrain the offered slots.
- Mechanism
- Availability is calculated from current inputs.
- Tradeoff
- An offered slot can be taken before the customer submits.
Step 02 · SQLite transaction
Recheck under lock
The transaction checks for an earlier request with the same ID, then recalculates availability before accepting a new booking. A conflicting reservation returns 409.
- Mechanism
- BEGIN IMMEDIATE locally; transactionSync on Cloudflare.
- Tradeoff
- Local reservations are serialized. Google Calendar is outside this database lock.
Step 03 · SQLite transaction
Commit together
The new booking and the work it creates are saved in one transaction. If an outbox insert fails, the customer and booking writes roll back too.
- Mechanism
- All local records commit, or none do.
- Tradeoff
- Confirmation means the appointment is stored; it does not mean every external update succeeded.
Step 04 · Background Calendar worker
Sync after commit
A durable alarm processes Calendar updates after the booking is saved. The connection status exposes failures and reconciliation; the appointment remains recorded.
- Mechanism
- Calendar delivery uses a separate persistent queue.
- Tradeoff
- Calendar has a recorded private provider test. Texting remains off; Sheets is inactive.
A retry keeps the same booking.
Business ID + request ID identify the operation. Matching details return the saved booking; the same ID with a different payload fingerprint returns 409.
A lost response can be retried without creating another appointment.
Google Calendar cannot share the lock.
Busy time is checked before committing, but Google can change after that read. A saved appointment and its later Calendar update are separate outcomes.
The queue makes failed updates visible and recoverable; it cannot make two independent systems commit atomically.
Illustrative concurrent requests
Two requests for the 10:00 slot.
Both clients previously saw 10:00 as available. The transaction decides which request succeeds.
A: check slot → free
A: save customer + booking + outbox
A: commit
B: check slot → occupied
B: reject with HTTP 409The Worker test submits both requests together and expects one 201, one 409, and one booking row. A separate test makes the outbox insert throw and checks that customer and booking counts are unchanged.
Tests & limits
- Worker tests cover competing reservations, matching retries, rollback after an outbox failure, and persistence through object eviction.
- The 29 October Calendar report records isolated create, change, cancel, busy-time, and background-sync checks.
Source and recorded results were inspected for this story; the application suite was not rerun. Public capacity and real SMS delivery remain unqualified.
Source files & authorship
service.ts:createBooking/available/queue; db-contract.ts; deploy/cloudflare/database.ts; runtime.test.mjs; Calendar validation SS-VAL-006; messaging validation SS-EWP-007. Inspected 29 October 2026.
Product direction: Jaxson Mercer. Development uses AI assistance.
Screenshots
Where it started
What happens between finding a customer and doing the work?
Running a service business can mean stitching together a website, a calendar, messages, and a customer spreadsheet. I wanted to improve the small steps between finding a customer and doing the work, then bring those steps into one system. Knife sharpeners are the starting point, with room to serve other trades later.
A customer needs a clear way to ask for service, understand the estimate, and pick a time. The owner needs that request to become a usable appointment and customer record. Mobis is taking shape around that whole journey, starting with knife sharpeners.
Make the small steps work together.
In use
One request, through the business.
- 01
Describe the job.
The booking flow gathers service type, item counts, and the details needed for an estimate. At-home visits include service-area screening; drop-offs follow their own rules.
See customer booking - 02
Choose a workable time.
Configured hours, exceptions, and appointment duration determine the available slots. Availability is checked again when a booking is saved.
- 03
Keep the owner in the loop.
The workspace brings bookings, customer records, and inquiries together. Pending messages and calendar updates stay visible as pending work.
See owner workspace
Who it’s for
Being developed for small service businesses that need booking and customer follow-up around their craft. The current preview is private and uses a fictional sharpening business.
The next question
The next product question is how well the complete workflow serves a real business. Calendar has a tested private integration. Live texting, public customer access, and the broader customer-acquisition workflow still need qualification.
Private preview
Mobis is in a private owner preview. Public customer access and live messaging integrations are not open yet.

