DEV Community

Cover image for Enquiry to Quote: Turning Customer Messages into Less Admin for Tradies
fab-pe
fab-pe

Posted on

Enquiry to Quote: Turning Customer Messages into Less Admin for Tradies

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Enquiry to Quote helps Australian trade businesses turn customer messages into organised, editable drafts.

A customer enquiry might arrive as an email, text message or notes from a phone call. Before preparing a quote, the business owner needs to understand the job, identify missing details and write a reply.

My app takes that message and generates four sections:

Job summary: the key facts from the enquiry.

Missing information: questions to help assess the work.

Customer reply: an editable response to the customer.

Quote scope: a provisional starting point for a quote.

Each section has its own text box and Copy button. The business owner reviews and edits everything before using it.

The first version focuses on electricians. For example, someone might request three ceiling fan installations, mention that they have already purchased the fans, and ask about next Friday. The app organises those details without confirming a booking or inventing a price.

Who would pay for it? My target customer is a small trade business handling its own enquiries and quoting. The value I want to test is whether reducing this repetitive admin makes a paid service worthwhile.

Demo

👉 Try Enquiry to Quote

Click Try an example, then Generate draft. Review the four sections, edit the wording and copy what you need.

The public demo allows five generation requests per IP address every 15 minutes. The backend uses Render’s free hosting, so the first request after a period of inactivity may take longer.

Please use sample enquiries and avoid entering sensitive information. Generation uses hosted third-party AI providers.

Code

GitHub repository

The project has two main folders:

client: React interface built with Vite.

server: Express API, model request and response validation.

How I Built It

The AI at the core is Meta’s open-weight Llama 3.3 70B Instruct, accessed through OpenRouter.

The application flow is:

React sends the enquiry to my Express backend.

Express validates the input and checks the request limit.

The backend sends the enquiry and task instructions to the model.

A JSON schema defines the four expected output fields.

The backend parses and validates the response.

React displays the drafts for editing and copying.

The model does the central work: interpreting an unstructured message, identifying gaps and drafting useful text.

I wrote the instructions around Australian English and the practical limits of the product. The model is told not to invent prices, promise availability, confirm bookings or provide electrical installation instructions. Unconfirmed work should be marked as subject to confirmation.

The idea grew out of my work building a website for AVP Electrical, a small electrical business in Forster, NSW. I wanted to explore a tool that could help a business like theirs spend less time organising enquiries and preparing replies.

AVP is the first business I’d like to test it with. The app is working, but its usefulness and willingness to pay still need to be validated with real users.

The frontend is deployed on Netlify, and the backend runs on Render. The API key stays on the backend.

Why Does Open Innovation Matter?

For this project, the benefit is choice and a path to running the model elsewhere.

Using an open-weight model means I can evaluate the same model through different hosting arrangements, or explore self-hosting later, subject to its licence and hardware requirements. I’m not limited to accessing the model through one company’s closed API.

The model name is configured through an environment variable. The app’s interface works with four defined fields, so I can test another compatible model without redesigning the frontend. Any replacement would still need testing for output quality and instruction-following.

That matters for a small side hustle. Inference costs, response quality and provider availability all affect whether the service is practical to sell.

This version uses hosted inference: it isn’t offline, it isn’t free to operate, and enquiries leave the user’s device. Open weights give me more options for how the product could evolve.

My Agent Session

One useful debugging lesson came when the interface appeared to be generating forever. A direct request using curl showed that the backend and model were working—the draft returned in around 11 seconds.

Chrome’s console revealed the actual problem: my React handler referenced data before it was defined. The error occurred outside the request’s error-handling block, leaving the loading state active.

Fixing the handler taught me more than simply getting the button working. I learned to trace a request across the frontend, backend and model provider, and to use evidence to isolate the failure.

We also refined the model instructions after an early draft assumed existing light fittings would be removed. That was a reminder that correctly formatted AI output still needs human review.

Top comments (0)