DUDE

02  ·  The product

Every job, from the first phone call to the closed invoice

One app, two very different faces. Here is what each part does, and why it works the way it does.

The spine

Three things hold the whole system up

If intake, status and filing are right, everything else is a feature. If any one of them is wrong, nothing else matters. This is the part we built first and guard hardest.

Smart intake and Promote

the QuickBooks bridge

Every new job is created in DUDE — third-party dispatches included — with a live type-ahead against existing QuickBooks customers. Promote then does four things in one press: creates the QuickBooks sub-customer under the right parent, captures its customer id, binds the QuickBooks Time jobcode, builds the Drive folder tree and copies in the estimate template.

A job's identity in three systems is established in one press, and bound by id, never by name — because names change and collide, and ids don't. A QuickBooks error writes nothing at all; a partial landing tells you exactly where it stopped and offers the button that finishes only the missing part.

The status spine

15 statuses, zero automatic transitions

New, Initial Contact, Needs Quote, Estimating, Estimate Pending, Waiting, Waiting on Materials, Waiting on Customer, Ready to Schedule, Active, Work Completed, Invoice Ready, Closed, Lost, Cancelled. Only admin and dispatch move a job, and every move writes a history row in the same transaction as the change.

Leads and jobs are one table — a lead is simply a job whose QuickBooks fields are still empty — so a job never has to be re-created when it becomes real.

The fifteen statuses roll up into six lifecycle phases, and the app refuses to start if those six ever stop exactly partitioning the fifteen. A sixteenth status can never quietly vanish off the board.

Documents in Google Drive

no destination choice

One shared drive, tiered by customer type: Residential, Commercial, 3rd Party, Internal → customer → [Job ID] - [Job Name] → Admin, Signed Docs, Documents, Pictures, Receipts. A backend service account does all the Drive work, so field techs keep their permissions but never have to navigate Drive.

The uploader gets exactly one decision — before, after, or today's visit — and the server turns that into a real folder. Notes append to a single Notes.txt, newest first, stamped with author and local time. A Drive read failure degrades softly: the page still renders, with a note saying what it couldn't reach.

Misfiling is structurally impossible, because the person uploading never names a destination. An "Open Job Folder" deep link exists anyway, as a required fallback.

The field day

What a tech on an iPad actually sees

The governing rule is blunt: complexity lives with admin, never the field. Field techs are not technology-inclined; several would rather use no technology at all. So the field surface is small, fixed, and fast on bad signal.

Recreation of the field job screen — nine cards in a fixed order with fixed open-or-collapsed defaults. Not a screenshot: the real screens carry live customer data.

My Week, and one tap on the clock

A tech lands on their own week, one day at a time, and nothing else. Three pinned buttons sit at the bottom: all jobs, the contacts directory, and a gas receipt. Clocking in is one tap on the job page — the job is pre-selected by definition, and the two fields every timesheet here is required to carry are filled in automatically.

DUDE stores no timesheets and no location trails. It holds a sixty-second state cache and a token-health flag, and every punch verifiably lands or visibly fails.

Punches are bounded to two attempts of ten seconds, because mobile Safari abandons a hung request at about sixty — so the honest answer from a slower retry could never have arrived anyway.

Customer sign-off on the iPad

the worst job in the company, fixed

The office pre-loads the document that needs signing. It appears under Ready to sign on the tech's screen. He taps once, hands the iPad to the customer, the customer signs on the glass, and he drags the signature into position — with optional printed name and date stamps. The backend stamps and flattens it into the PDF and files [document] - signed.pdf into Signed Docs/.

It handles scanned, rotated and inset-crop-box PDFs, which is to say the print-driver and Word exports that real customers actually send. Emailing the finished file is deliberately manual — DUDE has no email capability at all, on purpose.

Six steps of Drive-and-markup juggling became sign, drag, file. Entirely on open-source libraries, at no added monthly cost.

Job hazard analysis

A seven-category hazard matrix, a task action plan, PPE selection, site emergency information, and signature pads for the lead tech and any subcontractor. On submit, DUDE composes a formal PDF and files it into Signed Docs/. A compliance artifact, produced from a form a tech can actually fill in on a phone-sized screen.

The daily log

append-only

A per-job, per-day narrative from the field. There is no edit path and no delete path anywhere in the code — a correction is another entry. Admin can read across the whole company filtered by date range, job and tech, in any combination. When a job reaches a terminal status the whole log is written once into the job folder as Daily Log.txt.

If that final write fails, the notice on the job page is derived, not a stored flag — so it clears itself the instant the archive lands. No queue, no worker, no flag to go stale.

Expenses, with the receipt read for you

Anyone signed in can file an expense against a job. DUDE writes a real QuickBooks purchase, marks it pending review, attaches the receipt and drops a copy into the job's Receipts/ folder. The receipt image is run through Google's expense parser, and the amount, date and vendor come back as editable pre-fills marked from receipt — check it.

Vendors, categories, payment accounts and classes are cached locally, so the whole form runs fast on one bar of signal. A duplicate guard plus an idempotency key make a double tap safe.

The gas button is the neatest thing in the app: fuelling up asks for the vehicle and the odometer, and that odometer reading is the same number that later tells the fleet coordinator the van is due for service. Entered once, at the pump.

Refusals a technician can act on

a whole slice about error messages

A later hardening pass went through the money path and gave every silent branch a sentence: an amount over the ceiling, a vendor typed but never picked from the list, a date the system won't accept, a job with no folder, an upload too big to send. Each one now says what happened and what to do.

The checks were deliberately ordered so the ones a tech is likeliest to trip fire first — because every refusal costs them re-attaching the receipt photo.

Small things, from daily use

Clock in from the shift page as well as the job page. A clock-out note prompt that works with no JavaScript at all. Long dropdowns replaced with type-to-find boxes once the job list got big enough to scroll. Settings messages that appear in the section you were working in instead of somewhere off-screen.

None of these came from a plan. They came from using it, which is the advantage of the person who decides what gets built also being the person who has to live with it.

The office

Where the complexity is allowed to live

Recreation of the admin job tracker. Job names and numbers are invented.

Schedule — cached to read, write-through to change

A manual Sync Schedule button, plus a nightly backstop around 4am, pulls the QuickBooks Time schedule into DUDE's own cache. There is no polling during business hours. The field's week view and the office's tech-by-day dispatch grid read only that cache, which is why they load instantly on weak signal.

Writing goes the other way: admin schedules a shift from the job page or a plus sign on any grid cell, saves it as a draft or publishes it, and DUDE writes to QuickBooks Time first, then immediately re-syncs. Stale edits are refused rather than merged. Creates never auto-retry, because a duplicate shift is worse than a failed one.

Nobody at this company types a class, a service item or a shift address any more — all three derive from data admin already entered once. A blank class used to leave techs unable to clock out at all.

Estimates — one pipeline, two very different jobs

Big jobs are finished in the job's Google Sheet, because that is the tool the office already trusts and we were never going to out-build a spreadsheet. Import Estimate reads named ranges into DUDE's scope of work, materials list and proposed budget, behind a preview and a confirm, and it is safely re-importable — a missing named range saves nothing.

Small jobs go the other way: a tech submits an on-site estimate — labour lines, material lines, site notes — and DUDE writes it into the sheet, checking capacity first with real numbers ("the labour area fits nine lines, you entered twelve"). The tech's raw submission is preserved verbatim, forever.

Budget versus actual

The estimate's proposed budget sits beside the actuals, read live and never stored: hours from QuickBooks Time, expenses from QuickBooks purchases tagged to the job, with an "as of" timestamp and a refresh button. Labour is compared in hours, not dollars, because we don't connect payroll.

It is honest about what it can't know. Reading live rather than mirroring is what stops DUDE becoming a second book of record that disagrees with the first.

The contacts directory

deliberately not synced

Customers, vendors, subcontractors and third parties — with a distinction QuickBooks does not make: the account (a company) versus the attached person inside it, like a facility's maintenance supervisor. Directory records link to jobs with a role label, and on the field job page a tech simply taps the number to call.

The field's read-only view names its columns explicitly and never carries the QuickBooks fields, so the fence is a property of the query rather than a template's good behaviour.

Repair verbs as real features

Adopt binds a DUDE job to a QuickBooks sub-customer that already exists. Re-link fixes a mis-adopt in place, behind a confirmation that spells out what does and does not follow — and refuses outright once money has been filed against the job. Plus finish Drive setup, retry rename, link or unlink a folder, archive a daily log, and link or ignore an unmatched jobcode.

The app knows its own failure modes by name. Every partial state has a button that repairs exactly what is missing, and every one of them is safe to press twice.

One Save, and a guard against the other person

The status card used to carry four separate Update buttons — status, next step, project manager, lead technician. It now carries one Save that writes only what you actually changed, in a single transaction. The four unguarded write routes behind the old buttons were deleted rather than left open.

If anyone changed one of those fields while your page sat open, the save refuses as a whole and names the field. A partial save would need a message explaining two outcomes at once, and the page must not guess which of two people was right.

Fleet

The second module: vans and equipment

There was no system of record at all for our own machines. Maintenance history lived in people's heads and vehicle spend landed in one undifferentiated bucket. Fleet is a full module built on the same rules as the rest of the app — and unlike most of what gets written about internal tools, it is not a demo: the rollout closed on 20 October 2026 with every active vehicle entered, foldered and labelled, and equipment now gets added as ordinary use rather than as a project.

Recreation of the fleet board; the machines and readings are invented. Every line on it is computed from readings and intervals — nothing here is a stored status.

A registry where the label is not stored anywhere

Every vehicle and machine gets a permanent number and a derived label — V-1, E-2 — computed from category and id by one expression that both the list and the search read. The paint on the van and the searchable string cannot drift apart, because there is only one of them. Numbers are never reused, gaps are allowed, and correcting a machine's category flips the letter while the number never moves.

Each asset gets its own Drive folder for photos, registration and service records, renamed and moved automatically when the asset is renamed or recategorised.

Readings, intervals, and a working board

Usage readings are a dated, append-only log — hand-entered, baseline, gas fill-up, or captured at a service. Current usage is derived as the latest non-voided reading, so voiding one bad odometer entry corrects everything downstream instantly. Service intervals run every N days and/or every N miles or hours, whichever comes first.

The landing page is a board, not a menu: Overdue, Coming due, Not computable yet, Recently completed. "Coming due" is the last tenth of the interval, so the warning scales with the job. "Not computable yet" names its own reason for each machine, and the fix. And the slice that closed the rollout added a line counting the machines with no schedule at all — the ones no board can warn about — linking to the registry filtered to exactly those.

Implausible readings get a confirmation, never a rejection. The tech at the pump is usually right and always in a hurry.

A maintenance pipeline that starts outside the module

Techs report problems from their own week screen — machine, description, one urgent flag, optional photo. Never a severity menu. The button shipped dark behind a single setting and was switched on once the registry held the real fleet; it has been live for every technician since 16 October 2026, and the first two reports — real records against a real van — were filed that same afternoon, on an iPad, as the pass that proved the button worked. Reports land in a queue, urgent first then oldest, and the coordinator moves each one through a matrix that only ever offers the legal next verbs: acknowledge, schedule, start, park as waiting on parts or shop or budget, re-slot, reject, complete.

Completing a record happens in one transaction: what was done, preventive or reactive, in-house or a validated vendor, the date, the usage reading, and an optional pass-or-fail inspection checklist. Costs file as ordinary QuickBooks purchases against a permanent internal fleet job, and the coordinator never picks an accounting code — DUDE derives it.

A tech's report can be attached to the schedule it satisfies instead of being rejected as a duplicate. "Rejected" is reserved for work that isn't real, always.

Inspections, costs, and what the report won't claim

A completed job can carry an inspection checklist — pass, fail or not-applicable per item, with notes. The checklist lives in code rather than in the database, so rewording an item is a deploy and old answers stay attached to what was actually asked. A failed item records the problem and triggers nothing: raising the work is a person's decision.

The cost report gives maintenance, fuel and total per machine, by year or lifetime, including retired and zero-cost machines.

It prints its own limits on the page: this is not total cost of ownership — no depreciation, insurance or registration — and fleet costs start where DUDE started, because nothing was imported from before.

And a second product

The client portal

Our first client has had a door of their own since September: a separate application, now at portal.donedone.services, where a facility contact files a maintenance request from their phone, follows it through six plain-language states, and talks to us on the request itself. It is a window into DUDE with a letterbox in it — the work never leaves here.

How the portal works, and the tenant fence underneath it →

The split

Two products wearing one name

 Field tech, on an iPadOffice, on a desktop
Lands onMy Week — their own shifts, one day at a timeA dashboard with glanceable alerts
NavigationThree pinned buttons. Nothing else.Full top nav: jobs, schedule, contacts, daily log, fleet, settings, guide
Job pageNine cards, fixed order, fixed defaults. The page remembers nothing.Collapsible blocks that remember themselves per device
WhyField support needs "what do you see?" to have exactly one answerAdmin is trainable; a block you work in daily should be where you left it
Money visibleMaterial unit prices and subtotal, so a tech can shop to budget. Never labour rates, fees, margin or variance.Everything
PackagingAdded to the home screen — full screen, no browser chrome. No offline mode, on purpose.An ordinary browser tab

No offline pretence. There is no service worker and no offline mode. The weak-signal story is "pages that read from a local cache and load instantly", not a synchronisation model that lies to a tech standing in a basement.

Around the edges

The manual is a screen

The three user guides are not a separate artifact that can rot — their source is rendered inside the app at /guide, behind the same sign-in, and served by role: techs get the field guide, admins the office one, fleet-access holders get fleet appended. Moving the manual is part of a slice's definition of done.

Sign-in, and exactly one exception

Google sign-in restricted to the company domain. No passwords anywhere. Everyone is admin or tech — until fleet needed a coordinator who wasn't either, which became a single boolean beside the role rather than a third role. A third role would have been mutually exclusive with admin, so every fleet gate would have had to spell out both — the rule written once per gate instead of once, full stop.

The not-to-exceed calculator

A faithful port of a standalone script the office already trusted: type a destination, pick regular, overtime or emergency, and it looks up the one-way driving distance from the shop and returns the number to quote — same rates, same boundary, same rounding. Stateless; nothing stored.

What it deliberately doesn't do

DUDE itself sends no email, ever — signed documents are emailed by hand, on purpose. No automated migration of historical jobs. No automatic status changes. No payroll connection. Every one of those is a written decision with reasoning attached, not an omission. (The client portal does send transactional email; DUDE still doesn't, and the two are separate applications for exactly that kind of reason.)