Leaderbrock Case Study: A Sales Team App for the Agenda, the Route and Receipts

Case studies · Oct 26, 2026 · 11 min read

Leaderbrock Sports is a sports marketing agency from Valencia with a sales team spread across Europe and America. We built the app that team works with: the agenda, the day's route and expenses from a photo of the receipt, and the web panel from which the office plans, supervises and approves. We built all of it, the backend, the web and the app, from a clickable demo in May 2026 to the release of 26 October 2026.

Three processes that lived in a spreadsheet and an envelope

Before the app, the team planned its week in a shared spreadsheet, kept its receipts in an envelope and wrote them down by hand, and nobody in the office knew where each rep was on a trip. The app replaces those three processes, and each role sees its own part of them.

  • Sales reps carry the mobile app: their agenda, their receipts and their route.
  • Finance reviews and approves expenses, exports them for the accounts and receives the reports.
  • Managers see their part of the org chart, with its agenda, its expenses and its people on the map, but they do not approve expenses.
  • Admins see everything, grant roles and approve access requests. Nobody signs up on their own.
screens in the mobile app
55
roles: admin, manager, finance and sales rep
4
codebases: the backend and a monorepo with the web and the app
2
commits since May 2026
1,200+

The architecture

As in Boathous, the backend is reactive Java. The web and the app share one API client and one domain package, so a rule such as how an amount is formatted or which role can open which screen is written once and holds on both.

The field app and the office panel talk to one Spring Boot backend, which stores data in PostgreSQL, keeps receipts encrypted in S3-compatible storage, sends receipts to the AI to be read and sends push and email notices.

How the app, the office panel and the backend fit together
What Leaderbrock runs on
PartTechnologyWhy
BackendJava 25, Spring Boot 4.1 with WebFlux, PostgreSQL through R2DBC, FlywayReactive end to end: the live map, notifications and receipt reading share one service
Office panelReact 19, Vite 8, Tailwind 4, FullCalendar, MapLibrePlanning, expense review and the team's map on a large screen
AppExpo SDK 57, React Native 0.85, Expo RouterOne codebase for iPhone and Android, with camera, background GPS, Face ID and push
Shared codeA Bun monorepo: API client, domain, stores and design tokensThe logic of both apps lives in one place and is tested once
AISpring AI with Anthropic or OpenAIReading receipts and an assistant; the provider is a setting, not a rewrite
FilesS3-compatible storage, encrypted by the applicationReceipts and photos only come out through an authenticated endpoint
NotificationsFCM, Resend and WebSocketPush, email and in-app messages with one contract

Backend and web run as Docker images on one server, with a staging copy next to production. A deploy goes to staging first, and the previous version is not retired until the new one reports healthy. iPhones install the app through TestFlight and Android phones download an APK the admin publishes from the panel; at startup the app asks whether there is a newer version and whether updating is mandatory. An internal app does not need a public store.

An expense from a photo of the receipt

A rep pays for lunch with a client, takes a photo of the receipt and moves on. The app has its own camera with a framing guide and flash, and also takes a photo from the gallery or a PDF from Files: JPEG, PNG, WebP, HEIC or PDF, up to 15 MB.

  • The AI reads the merchant, the base, the VAT and the total, the currency, the date and time of purchase, the city and country and the category. Its instructions say to leave empty what the document does not show and never to guess the total.
  • The server then checks the arithmetic itself: base plus VAT must give the total to within two cents, and a missing figure is worked out from the other two.
  • The result is a draft, never a filed expense. The rep sees how sure the reading was, corrects what is wrong and only then presents it.
  • The photo uploads and is read in the background, so the rep can close the app and gets a notification when it is ready. Without coverage it waits in a queue, and one idempotency key per receipt means a double tap or a retry never creates two expenses.
  • If a receipt looks like one the same person already filed, with the same date, amount and currency, the app warns before it goes in twice.
  • The app asks where the receipt is from, here or somewhere else, because a lunch receipt uploaded at night used to land on the hotel. Somewhere else opens a map with that day's route and stops to pick the place.

From the receipt to the accounts

An expense goes through four states: draft, pending, approved or rejected. Finance and admins review the whole organisation. Each verdict reaches the rep by push, by email and inside the app, and is written to an audit trail.

  • Each amount keeps its currency. The panel and the reports give a total per currency and never add euros to dollars.
  • The CSV export is made for Excel in Spanish: semicolons, a decimal comma, dates as day, month and year, and readable labels instead of codes.
  • Approved expenses come out as accounting entries, with the expense account of each category (defaults from the Spanish chart of accounts, all configurable), the base, the VAT and its rate.
  • When the company connects Holded, an approved expense is sent there as a purchase document, once: a second send is refused.
  • Finance can receive a weekly or monthly PDF report, and download one at any time.

An agenda for a team in several countries

The agenda looks like Google Calendar on purpose: it is what the team already knew. Every event takes the colour of its owner's country, the same on the web and on the phone. A rep sees the agenda of their country and the meetings they are invited to; the other roles see the whole organisation.

  • A meeting invites colleagues, who answer inside the app, and outside guests by email, with a link that expires.
  • Closing a meeting asks how it went: closed sale, interested, follow-up or no interest, with a note of up to 2,000 characters and photos of the visit. Without coverage the closing waits in a queue with what was written, and the photos upload on their own afterwards.
  • A receipt added from a meeting is placed on that meeting's place, day and route, without reading the GPS.
  • The agenda refreshes every minute while it is on screen and whenever the app comes back, because the team told us they sometimes had to leave and come back to see a meeting they had just created.

The day's route

A rep starts the day's route with one button. It ends on its own after eight hours at most and can be started again. Admins and finance see the whole team on a live map over WebSocket, a manager only their part of the org chart, and anyone without a signal for more than five minutes is marked as out of touch.

  • A GPS fix less precise than 100 metres is kept, but it is neither drawn nor measured.
  • A fix that implies up to 160 km/h from the last good one goes in. A faster one waits until the next two precise fixes confirm it at no more than 1,200 km/h, so a high-speed train or a flight is drawn and an isolated jump never is. We added that second speed in October, after a person who had flown kept appearing at the origin for hours.
  • A stop is more than 10 minutes within 100 metres. The team's map shows each person's stops, the start and end of their route, their meetings of the day and their expenses, in that person's colour.
  • The filter runs when the data is read, not when it is saved, so changing the rule corrects the past too. It is written twice, in Java and in TypeScript, with the same test cases, so the live map and the history never disagree.

A noisy GPS fix is not a trip. We keep it, but we do not draw it.

Positions are deleted after 90 days. Locating employees has its own rule in Spain, article 90 of the data protection law (LOPDGDD), and before using the app each person reads to the end and accepts the prior information written by the company's lawyer, with a record that cannot be altered and a receipt.

Personal data, encrypted from the start

The app holds the names, emails and phones of a team in several countries, photos of their receipts and their positions. We designed it so that a copy of the database or of the files does not tell anyone who is who.

  • Every personal field is encrypted in the database with AES-256-GCM, with keys that can be rotated, and found through a blind index (an HMAC), so looking someone up by email works without storing the email in clear.
  • Receipts, photos and avatars are encrypted by the application before they reach storage, and there are no public links to them: they come out only through an authenticated endpoint that decrypts them.
  • Nobody signs up on their own. An account comes from an access request an admin approves or from an invitation, and the admin role is never offered in a public form.
  • Sign-in with a password, Google, Apple or a passkey; short sessions with rotating refresh tokens; Face ID or a fingerprint to unlock the app; and each person can see and close their sessions on every device.
  • GDPR rights are self-service: each person can download their data and delete their account. Expenses are kept pseudonymised for as long as tax law requires, and the rest is deleted.

How it was built

Leaderbrock, from the demo to version 1.62
WhenWhat arrived
May 2026A clickable demo of the web and the app, with a simulated receipt reader, to agree on the screens
Jun 2026The backend for the agenda, expenses and routes, the AI that reads receipts, and both apps on real data
Jul 2026The live map, push notifications, background GPS, passkeys, the accounting export and Holded, access requests and the timesheet
Aug 2026Production on the company's own domain, and the app on TestFlight and as an APK with update notices
Sep 2026Closing a meeting with its outcome, each expense on the day's route, the duplicate warning, the live team and the prior information
Oct 2026Release channels, flights and trains confirmed on the map, the whole team's stops and meetings, and uploads in the background

The backend carries 714 test classes, 48 of them against a database, with a floor of 78% of lines covered, and the monorepo 685 test files. Of the more than 1,200 commits, about 120 come from AI agents and the rest are ours, the two of us. Many of the recent changes answer something the team asked for, and the docs record each one with its date.

What we take from it

  1. Let AI fill in a draft, never file it. Reading a receipt saves typing; checking the sums and asking a person to confirm is what makes it safe.
  2. Every amount with its currency, and never add two currencies together.
  3. Store the time on the wall with its zone, and show it in the zone of the person reading.
  4. A rule that two sides apply, like the GPS filter, gets the same test cases on both, or the live map and the history end up telling different stories.

If your team still plans in a spreadsheet and keeps its receipts in an envelope, this is the kind of custom software we build, with a mobile app for the people out in the field.

Questions

What does the Leaderbrock app do?

It gives a sales team spread across several countries its agenda, the day's route and expenses from a photo of the receipt on the phone, and gives the office a web panel to plan, follow the team on a live map and review and approve expenses.

How does the app read a receipt?

The photo or PDF goes to the backend, where an AI model reads the merchant, amounts, VAT, currency, date and category. The server checks that base plus VAT gives the total and creates a draft that the rep reviews, corrects if needed and then presents.

Can the AI approve an expense by itself?

No. The AI only fills in a draft. The rep confirms it and finance or an admin approves or rejects it, and each verdict is written to an audit trail.

Is the app on the App Store and Google Play?

No, it is an internal app. iPhones install it through TestFlight and Android phones from an APK the admin publishes, and the app warns at startup when there is a new version.

How does it handle employees' location data?

Each person reads and accepts the prior information written by the company's lawyer before using the app, as article 90 of Spain's LOPDGDD requires, positions are deleted after 90 days and every personal field is encrypted.

Sources

  1. Spring Boot
  2. Spring AI
  3. Expo documentation
  4. MapLibre
  5. Organic Law 3/2018 on data protection (LOPDGDD), BOE

Keep reading

Blog