A broker CRM for construction brokerage between Poland and Germany
A broker connects German clients with Polish contractors and earns on the margin. The whole arrangement rests on one thing: neither side may learn who the other is. I moved it off WhatsApp and a spreadsheet into a system where anonymisation is enforced by code rather than by the operator's memory.
Industry: Construction brokerage, Polish and German market
In short
- The contractor never learns the end client, and the person sourcing the lead never learns the contractor
- The client's phone number sits in a separate encrypted table; the panel shows only the last four digits
- Contractor matching is deterministic, driven by rules in the database, at most three firms per job
- Phone numbers are retained for 90 days, then purged automatically
About the project
The brand facing the German market is Angebot aus Polen. Jobs cover stairs, fencing, terraces, balustrades, carports, conservatories, paving and steel structures. Somebody sources the lead, the broker picks contractors, the contractors send back a price, and the client receives an offer with a markup on top. Until now all of it ran through WhatsApp and a single spreadsheet.
The challenge
The model earns money because the two sides do not know each other. If the person sourcing the lead meets the contractor, or the contractor meets the client, the broker is no longer needed. Manual discipline holds up at a few jobs a day and stops holding up at a dozen. On top of that, clients' phone numbers sat in a spreadsheet with no protection at all.
Goals
- Enforce the separation of the two sides in software, not in someone's memory
- Get phone numbers out of the spreadsheet and under encryption and retention
- Turn contractor selection from instinct into repeatable rules
- Build a panel that works on a phone, because that is where the operator works
Technical challenges
Anonymisation enforced by code
Data leaves the system through mappers with an allowlist of fields, separate ones for the lead sourcer and for the contractor. Nobody can forget to hide something, because by default nothing goes out unless it is explicitly permitted. The contractor's name, its internal codename, its price and the margin never reach the other side.
The client's phone physically separated
The job table has no phone column. The number is created separately, only once a client shows interest, encrypted with a key held outside the database, access narrowed to the owner and the person who brought the lead, and every view written to its own audit log. The interface shows the last four digits.
Contractor matching without a language model
The rules live in the database as data: service type, postcode prefix, region, whether structural calculations are required, daily caps per firm, priority and weight. The same inputs always produce the same list, at most three firms. The system suggests; a human decides.
Messenger content never drives the system
Messages from contractors and lead sourcers are treated as untrusted content. Parsing is deterministic; a language model is used at most to break down a free-form message, after personal data has been stripped, and it never assigns identifiers.
Solution and implementation
An operator panel instead of a spreadsheet
Jobs with their own code and barcode, statuses in Polish, a per-firm quote register that flags what is missing, a contractor suggestion, and offer PDF generation under the Angebot aus Polen brand. The panel is designed for a phone: cards rather than tables.
Sign-in by phone number, not by email
The operator signs in with a phone number and password; the owner adds a second factor. Password reset goes by SMS code to the account's number. On top of that, a login attempt limit, account lockout after repeated failures, and generic error messages.
A bridge for the transition off WhatsApp
Instead of forcing everyone to change habits at once, the panel accepts a pasted message and fills in the form itself, then hands back ready text to copy: one for the contractor with the job code, one back to the lead sourcer with no company name in it.
Results
Leaks no longer depend on vigilance
Separating the two sides is a property of the system. Even an operator's slip will not send a contractor's name where it does not belong.
Personal data has left the spreadsheet
Phone numbers are encrypted, access is narrowed and logged, and after ninety days the number disappears automatically.
Contractor matching can be reproduced
Instead of remembering who had spare capacity last, the system derives it from rules and daily caps, the same way every time.
Takeaways
A business model can be written into a database schema
If a company earns money because two parties do not know each other, splitting the tables and allowlisting the fields matters more than any feature in the interface.
Automation does not have to start with a revolution
Pasting a messenger message into a panel looks primitive, but it lets the system be used in the first week without everyone changing habits at once.
Scope
- Analysis and architecture
- System from scratch
- Anonymisation and GDPR
- Mobile-first panel
Technologies
- Express
- TypeScript
- React
- Prisma
- PostgreSQL
- Docker
Frequently asked questions
Why so much attention to anonymisation?
Because the whole model rests on it. Once the lead sourcer meets the contractor, or the contractor meets the client, the broker is no longer part of the arrangement.
How does the system protect the client's phone number?
The number sits in a separate encrypted table, the key is held outside the database, access is limited to the owner and the person who brought the lead, every view is logged, and after ninety days the number is deleted.
Does artificial intelligence pick the contractors?
No. Matching is derived from rules stored in the database and is fully repeatable. The system suggests at most three firms; a human makes the decision.
Is automated WhatsApp handling already live?
No. That is the designed next stage, today a skeleton outside the deployment. The working version relies on pasting messages into the panel.
Why sign in with a phone number rather than an email?
Because that is how people in this chain work. The number is what they already have to hand, and password reset goes by SMS to the same number.