Pest Control CRM
Screenshots
Key points
-
Each control station has a QR label. The technician scans it and records on-site the finding (for example, bait consumption), the device's condition, the pests found and a photo. The report cannot be signed while a station of the service is still missing.
-
Once the client and the technician sign, the system generates the PDF in the company's format and archives it unchanged: it is the evidence shown in an audit. If the client is a legal entity and products were applied, it also issues the pest control certificate with the owner's signature.
-
I integrated Meta's WhatsApp Cloud API to send the client a template message when their report is signed, and Google Maps to pin client addresses on the map and open directions from the technician's phone.
-
The field app, built with Expo and React Native, lets the technician finish the whole report without signal: it stores every step on the phone and sends it on its own when the connection returns, without duplicating reports or payments.
-
The office side has a schedule by month, week, day and technician, clients with their addresses and stations, PDF quotes, recurring services, income and receivables, and statistics on pests and station trends.
Problem
In a health audit, a pest control company has to prove what happened at every visit: which stations were checked, what was found, which product was applied and who signed. The service report was the company's printed form, and the pest control certificate was issued by hand. On top of that, technicians work in warehouses and basements where the signal drops.
Solution
A single FastAPI API serves a web app with three views and a mobile app. In the office, staff schedule visits, manage clients with their addresses and stations, prepare quotes and follow up on payments. In the field, the technician opens their day, scans the QR code on each station and completes the report in four steps: stations, applied products, evidence, and the client's and technician's signatures. On signing, the system archives the PDF, issues the certificate when it applies and notifies the client on WhatsApp. In the portal, each client checks their services, upcoming visits, stations and certificates.
Technical decisions
- FastAPI is the only way into the data: neither the browser nor the app talks to Supabase, and photos, signatures and PDFs are served through the API.
- Permissions are granted by capability, not by role. Each endpoint declares the one it requires, and a record outside the user's scope returns 404 so it does not reveal which clients exist.
- A signed report is never edited: the PDF is archived at signing time and is not regenerated from catalogs that may have changed since.
- Development runs against a local Supabase in Docker with anonymized data. The backend, the web app and the mobile app refuse to start in development if they point to production.
Failure handling
- The WhatsApp notice runs in the background after the response is sent: if it fails, the report is still signed. Only transient errors are retried, up to three times.
- In the field app, every action goes into a SQLite queue. Closing the report and declaring the payment carry a key generated on the phone, so resending them after a lost response does not create a second report or a second income record.
- If the server rejects a submission, nothing is deleted: it stays under “Needs attention” with the reason, and the technician decides whether to retry, fix or discard it.
My role
I build the project on my own, end to end. I designed the database in Supabase (PostgreSQL) and maintain it through versioned migrations; built the FastAPI API, organized by business module; implemented the web app in React, TypeScript and Material UI from a Figma prototype, and the field app with Expo and React Native. I integrated the WhatsApp Cloud API and Google Maps, set up the deployment on Render and wrote more than a thousand automated tests for the backend.
Results
- The client also contracted ongoing maintenance.
Next steps
Build and test the app on iOS, make the phone's camera open the app when scanning a label (today it opens the web app) and build the expenses module.
Code kept private due to client confidentiality; screenshots, architecture, and a demo available upon request.