FREESMS
Open source · early version

The workshop system that works in the pit.

For independent car repair shops. Built for a phone in a dirty hand, wifi that does not reach under the car, and a front desk that has to have an answer when the customer rings.

No licence fee · your own server · an SIE file for the books

One car, a whole working day

From the car being dropped off to the job closing itself: the front desk, the technician, the customer, the parts desk and the owner, each on their own screen. A part that is not in, a car that goes home and comes back – an ordinary week.

Words, amounts, rounding and who may see the customer come from the product’s own code when the page is generated. The whole flow runs against the real product, one browser per role, on every change to the code – read the test. Registrations, names and amounts are examples.

A car, from the door to the books

Take in a vehicle

Registration, odometer and what is wrong. The desk prices it from the workshop’s own book of times.

Fix it

The technician sees the car and the job, clocks on, photographs and speaks up – with or without a connection.

Invoice it

Invoices that cannot be changed, numbered without gaps, and the month to the accountant as an SIE file.

Closer

Each part on its own, closer. Every scene is a flow that runs against the real product on every change to the code.

When the wifi goes

The technician sees something else that needs doing and tells the front desk, from the pit. There is no connection. It is kept in the phone, waits, and is sent once when the connection is back.

The words in the scene are the product’s own: the page is generated from the same catalogue and the same code as FreeSMS’s screens. The flow runs against the real product in a browser on every change to the code – read the test. Registrations, cars, customers and names are examples.

A morning, from the door to the books

A car is taken in, the technician does the work without seeing the customer’s details, the desk invoices, and the month’s invoices go to the accountant as a file, not as an integration to pay for.

The invoice’s amounts are worked out by the product’s money code and the SIE lines written by its accounting code, when the page is generated. The flow runs against the real product in a browser, and the test reads the real file – read the test. Registrations, cars, customers and names are examples.

“When will it be ready?”

The customer rings and asks. The answer is on the job: what was promised, what was sold and what has been clocked. And it speaks up before the promise is broken, not after.

The figures and the verdict are worked out by the same code the job page uses, when the page is generated. The flow runs against the real product in a browser – read the test. Registrations, cars, customers and names are examples.

The customer decides, with the photograph in front of them

The technician photographs what is worn. The customer gets a link, sees the photograph on their phone and answers yes or no – no account, no app, and nobody describing brake pads down the telephone. A yes shows on the board at once, and becomes a line on the job in one step. The price is put to them separately, and their yes is to exactly the price they saw.

The flow runs against the real product in a browser: the photograph is uploaded, the link is opened without signing in, and the customer’s yes becomes a line on the job – read the test. The brake pad is a drawing. Registrations, cars, the link and names are examples.

One job, two screens

The same job, opened by the technician and by the front desk. The technician is given the car and the job. The customer’s name and phone number are only at the desk – not hidden from the technician, never fetched.

Which role is given the customer’s details is decided by the product’s own permission code, and the page is not generated if the scene says otherwise. The flow runs against the real product in a browser, which also checks that the name is not even in the technician’s page source – read the test. Registrations, cars, customers and names are examples.

The planner knows who is in

A booking holds a slot without inventing a job. The planner treats people and lifts as different limits, and says so – it moves nothing by itself. Who takes the car is a person’s decision.

The words come from the product’s catalogue when the page is generated. The flow runs against the real product in a browser: the lifts are set, the cars booked, Erik marked away, the day shut – and a booking on the shut day refused – read the test. Registrations and names are examples.

What is waiting for you, and only that

Each person sees what is theirs to do – not a feed of everything that happened. A thing reaches the right person by itself, and leaves when somebody has dealt with it. Nobody ticks anything off by hand, and two people at the counter see the same list.

The words come from the product’s catalogue when the page is generated. The flow runs against the real product in three browsers, one per role, and the test checks that no page was reloaded – read the test. Registrations and names are examples.

The rota, and who may know what

Whoever plans staff sets the week and moves a day. The law’s rest is warned about, not enforced – collective agreements differ. The person it concerns is told their schedule changed. Colleagues see that somebody is away, not why: sickness is health data.

The words and the rest are worked out by the product’s own code when the page is generated. The flow runs against the real product in three browsers: the rota is set, Thursday moved, the warning shown, Erik told and reading it, and the desk seeing “away” where Erik sees “off sick” – read the test. Names are examples.

The customer is told, and you can see that they were

Where the workshop has a provider, the front desk sends the link straight from the job: email through the workshop’s own mail, or a text. The first message to a new address is confirmed. Nothing goes between eight in the evening and eight in the morning, nothing goes twice, and replies are not read – the number to ring is in the message.

The words come from the product’s catalogue when the page is generated. The flow runs against the real product in a browser: the email goes over SMTP to a real mail server, and the test reads what arrived and opens the link in it as the customer would – read the test. Texts through 46elks, the delivery report and quiet hours are tested by the server’s own tests. Registrations, addresses and names are examples.

The price before the car arrives

A customer asks what the brakes would cost, before there is a car here. The front desk puts a price to them with its terms. They read every amount on their own link and say yes to part of it, and what they accepted is booked and carried onto the job – at the price they were shown, with nothing typed twice.

The words come from the product's language catalogue and the amounts from its money code when the page is generated. The flow runs against the real product in a browser – read the test. Registrations, cars and names are examples.

When somebody is off sick

Erik rings in sick, and he has a job planned for today. The front desk sees it straight away, hands the job to Tina with a reason, and Erik stays in the history. The time he already clocked is his. A job that takes two days is moved without anything being booked again.

The words come from the product’s language catalogue when the page is generated. The flow runs against the real product in a browser: Erik is marked sick, the clash shows, the job is handed over, Tina sees it in her list, a two-day plan is carried over and a car waiting for a part gives up its lift – read the test. Registrations and names are examples.

When a line is wrong

A line has the right words and the wrong price, or was never meant to be there. The front desk corrects it on the page and sees what it comes to first. A dearer line needs a new yes; the old yes stays as it was. A mistaken line is withdrawn with a reason and stays in the history.

The words come from the product's own language catalogue and the amounts from its money code when the page is generated. The flow runs against the real product in a browser: the price is corrected, the agreement falls, the other line keeps its own, two people correct the same line and one line is withdrawn – read the test. Registration numbers, names and amounts are examples.

When a car has several jobs

The brakes are done, the exhaust is waiting for a part and the road test is dropped. The technician ticks off and says what is in the way, with no price on the screen. The counter sees what holds the car up, and a car with work left cannot be marked ready.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: the list is made from the agreed work, the technician ticks off and says a part is in the way, the counter leaves a job out with a reason and a customer decision, and the car cannot be marked ready until everything is done – read the test. Registration numbers and names are examples.

The same customer, once

The number changes, the car gets a new plate and the customer suddenly exists twice. The desk corrects the card and sees what changed, who did it and when. A duplicate is asked about before it is made, and two records that are one are joined after a page that says what moves – issued invoices stay as they were issued.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: the number is corrected, two people editing at once are told, a mistyped plate is rewritten while a new one is added, the car is sold, the duplicate is asked about and the records are merged – read the test. Names and numbers are examples.

When the shift changes

Whoever takes over a job should not have to ask whoever left. What happened is in one list, read from the records that already exist: state, price and approval, steps, parts, inspection. Notes and conversations that no other record held are added to it. A corrected note keeps its old wording, and the technician never sees the customer or the prices.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: the technician leaves and corrects a note, the counter writes down an earlier call, and the technician never sees the call – read the test. Names and notes are examples.

Ordered somewhere else

Parts are ordered from the wholesaler, not in the system. The parts desk notes what was ordered, from whom and when it is expected, and ties the order to the job's request. The day can move, the delivery can come in two parts and the same delivery note counts once. A wrong part goes back, the job asks again for the right one, and the credit is a step of its own that can come before or after.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: the technician asks for a part, the parts desk notes the order and moves the day, the delivery comes in two parts, one is sent back and credited – read the test. Names and orders are examples.

When the car is collected

The customer gets more than an invoice. The workshop hands over what was actually done, what the customer said no to, what is left and what the workshop wants them to know. It is built from what was recorded as done, never from a quote, and it does not claim the car is safe. It is handed to whoever collects, frozen, and a correction is the next version.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: the brakes are done, the technician suggests something for later, the counter hands over to the customer's brother and then a corrected version – read the test. Names and work are examples.

The invoice arrives

The counter confirms who the invoice is for and where it goes, and sends a link that opens that one document. The provider taking the message is not the customer reading it: only an opened link or a handover says that. Sent again, the first link closes, and what failed lands on a list to follow up.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser, against a real mail server: the invoice is sent, the customer opens the link, the counter sees it was opened, sends again, and the first link stops working – read the test. Names and addresses are examples.

When the invoice is wrong

An issued invoice is not changed. A part billed wrongly is credited on its own, after the counter has seen what that comes to and what is left to credit, and more than was billed can never be credited. If the wrong person was billed, all of it is credited and the right customer is billed on a correction order. Every step says why and by whom, and nothing puts a part back on the shelf by itself.

The words come from the product's own language catalogue and the amounts from its money code when the page is generated. The flow is run against the real product in a browser: a part is credited after a preview, too much is refused, the rest is credited and the right customer is billed – read the test. Names and amounts are examples.

When the invoice is not paid

Unpaid invoices are not just listed, they are followed up: someone has them, a conversation and a promise are written down, and a dispute holds the reminder without touching the balance. The reminder carries what is owed when it goes, and one paid in the meantime is never sent. Money owed back becomes a task, and a refund is not the same as reversing a mistaken payment.

The words come from the product's own language catalogue and the amounts from its money code when the page is generated. The flow is run against the real product in a browser, against a real mail server: the invoice is taken, a conversation and a promise are written down, a dispute holds and is lifted, the reminder goes with the right amount, and a part is credited and paid back – read the test. Names and amounts are examples.

The day adds up

At closing time the day shows what was invoiced and credited, apart from what was recorded as arrived and paid out, and every total is a link to the document or entry it is made of. The owner compares with the bank statement, and if the figures differ a reason is needed. If the day is signed off and something changes after, a payment entered late for instance, the day says it has changed. Everything that should be put right first is a list.

The words come from the product's own language catalogue and the amounts from its money code when the page is generated. The flow is run against the real product in a browser: a day with a part payment and a credit is compared with the bank, signed off, and changed by a refund – read the test. Names and amounts are examples.

Before the car comes

A booking exists before a job does, and the customer should know when to come. The confirmation is shown first so the counter sees exactly what is sent, with the time on the workshop's clock and how to reach a person. It goes through the same queue as everything else. A reminder waiting is stopped if the booking moves, is cancelled or the car has already come, and what did not get through lands in the counter's queue – or is told by hand.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser, against a real mail server: the confirmation is previewed and lands in a mailbox, a reminder is stopped by a move, and the customer is told by hand – read the test. Names and times are examples.

When the car comes back

A customer coming back is not the same as the repair being wrong. A return visit opens a job of its own on the same car and writes down what the customer says, but decides nothing about whose fault it was. The shop's position – warranty, goodwill, unrelated – is a row with a reason, and can change without the earlier ones disappearing. A claim on the supplier needs the case called warranty, and can be rejected and argued.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: a return visit is opened from an invoiced job, a position needs its reason, a supplier claim is rejected and argued, and a technician sees what was reported but no money – read the test. Names and amounts are examples.

When the work is done somewhere else

A sublet job is a line on the invoice, but the turbocharger that left on Tuesday and was promised for Friday shows up nowhere. Here it is a record of its own: what was sent, to whom, when it is expected, who is chasing it. Where it is is kept apart from the job's state and from whether the car is on a lift. Coming back is not being accepted – the shop says that itself, and only then can the job be ready.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: a turbocharger is sent, runs late, comes back, is accepted by the shop and not before, and the invoice is handed on – read the test. Names and amounts are examples.

Start from what you already have

The workshop already has a customer list, a vehicle register and a shelf of parts. An import writes nothing until you have seen it: the file is read (semicolons, decimal commas, åäö, older Windows files too), every row is shown with what it would do, and a row that may be somebody already here needs your answer. The same file twice is the same upload, and opening stock is a dated ledger entry that is never added twice.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser with Swedish files: customers, parts and opening stock are previewed and applied, a possible duplicate needs an answer and the same file is the same upload – read the test. Names and quantities are examples.

From the first sign-in to the first customer

The owner who has just made the workshop gets a list, not an empty board. It is read from the workshop's own settings: the address is there or it is not, the technician exists or does not. What cannot be read – that the invoice has been looked at, who owns the backups, that “no final check” is a choice – is said by a person and kept with who and when. A one-person workshop is spared the staff questions, and a provider for texts or plate lookup is never a requirement.

The words come from the product's own language catalogue when the page is generated. The flow is run against the real product in a browser: the owner fills in the details through the forms the list links to, looks at an example invoice and sees the list become ready – read the test. Names and numbers are examples.

In Swedish all the way, on a phone, with a keyboard

Every sentence a reader can be shown has a Swedish translation, and a test walks the pages of an ordinary day in Swedish and fails if an English sentence is left. A refusal speaks Swedish and is read out by a screen reader. A keyboard gets past the menu with one press, always sees where it is, and the screen works at 360 pixels without scrolling sideways. What the workshop wrote itself – a part description, a note – is never translated.

The words come from the product's own language catalogue when the page is generated. The test is run against the real product in a browser: an automatic accessibility check in light and dark, in Swedish and English, a keyboard, a phone width and a refusal in Swedish – read the test. Names and numbers are examples.

Scan the shelf, don't copy it down

Every part has a label that prints on an ordinary printer, with the number in plain text under the bars. A handheld scanner is a keyboard that types the code and presses Enter, so the scan screen has a single field. The technician takes the part out to the job with the same code. Each arrival, take-out and count is a row in the stock ledger: what is on the shelf is the sum of them, never a number typed over another.

The words come from the product's own language catalogue and the bars are drawn by its own Code 128, when the page is generated. The flow is run against the real product in a browser: the label is printed, a code finds the part, an unknown code is refused, the technician takes the part out and the balance drops by one – read the test. Parts, codes and names are examples.

Clear a person, keep the invoice

A customer who asks to be erased is entitled to it, and the workshop must still keep the invoice for seven years. FreeSMS does both: name, telephone, email and address are cleared, issued invoices keep the name they went out with, and what was cleared and what was kept, with the reason, is written down. Before that the person can have a copy of everything held about them. An employee who can sign in is not erased; the account is switched off first.

The labels and sentences come from the product's own language catalogue; the list of what is cleared and kept is shortened here, the full text is on the Personal data page. The flow is run against the real product in a browser: a copy is downloaded, the person is erased, the invoice keeps the name, it cannot be done twice and not from the shop floor – read the test. Names and details are examples.

The whole workshop in one file, without us

The owner can take the whole workshop away at any time: customers, vehicles and their history, jobs, invoices as issued, inspections with their photographs, stock and clocked time. It is a zip with a CSV per table, a README that says how to read it and a manifest with the row counts, readable without FreeSMS. Passwords and sign-ins never go along, and every export is listed so you can see who took the workshop out and when.

The words come from the product's own language catalogue; the file listing is a selection of what the zip holds. The flow is run against the real product in a browser: the owner takes the workshop out, the file is built, it is a real zip with a manifest and a README, and neither the counter nor anybody else can get at it – read the test. Names and times are examples.

Built to be relied on

0 krin licence fees. AGPL-3.0.
1 serveryour own. One binary and one Postgres.
SIE 4the standard format for Swedish bookkeeping.
2 languagesEnglish and Svenska, with more to come.

Questions

What does it cost?

Nothing. FreeSMS is open source under AGPL-3.0. There is no hosted service to pay for: the workshop runs it on its own server, and anybody who wants help with that can hire whoever they like.

Where are our customers’ details kept?

With you. The database is on the workshop’s own server, not ours. And inside the system only the roles that need a customer’s name and phone number see them – the technician’s screen never fetches them.

Does it work with our accounts package, or our accountant?

FreeSMS hands over the month’s invoices and payments as an SIE 4 file – the standard format Swedish bookkeeping programs read, Fortnox and Visma among them. No integration to pay for or wait to be approved. The file is checked against an independent SIE reader on every change to the code; it has not yet been tried against a commercial program, and we would rather say so than pretend. Outside Sweden there is no export yet.

Do we need a certified cash register?

FreeSMS is built for invoiced sales and has no till. In Sweden, invoiced sales are not covered by the certified cash register requirement, but how that applies to your business is a question for your accountant.

What happens when the connection drops?

What is written is kept in the phone and sent, exactly once, when the connection is back. That is the first of the closer scenes on this page, and it runs as a test on every change.

Is it ready to use?

It is early. A car can go all the way from the door to the books, but there are things left – they are open as issues in the source code, with what is missing and why.

Run it on your own server

Docker, one password and nothing else. Behind HTTPS the whole workshop reaches it.

cp .env.example .env
# set POSTGRES_PASSWORD in .env
docker compose up
Getting started