Fabio SteyerDE

DATA ANALYTICS · AUTOMATION · APPLIED AI

Three thousand invoices.Nobody checks themby hand.

So I made the checking verifiable.

I’m Fabio. At a construction company, I automated the reconciliation of around 3,000 invoices and quotes. Now I’m looking for the next challenge between data and day-to-day operations.

Berlin / remote · permanent full-time role

≈ 3,000
documents reconciled in practiceWork experience · not public
4 / 4
planted deviations detectedPublicly reproducible
104
tests across five Python projectsPublicly reproducible

01 / APPROACH

From a real-world workflowto a result you can check.

First, understand where a process gets stuck. Then decide which step needs a script, which needs a language model, and which should stay in human hands.

  1. 01

    Understand

    Read the documents, exceptions and handovers. Not just the intended workflow.

  2. 02

    Choose

    Check fixed number formats with rules. Use language models where language is the task.

  3. 03

    Verify

    Plant known errors, compare results and make the limitations explicit.

  4. 04

    Operate

    A solution matters when it works in daily operations. At Cavator, that meant around 3,000 documents.

02 / PUBLIC PROJECTS

More than a description.Try the logic.

Five Python projects on invented data, and this site itself. The first two examples are simplified and run directly in your browser; the others show measured runs.

PYTHON · PDFPLUMBER · PYTEST

Reconciling invoices against quotes

A supplier sends a quote and later invoices against it. Whether the invoice matches what was agreed is something nobody checks line by line once a document runs to three digits of positions.

4 / 4Deviations detected. No false alarms.
Decisions, result and limitations

The approach

Both documents are read out of PDF, positions are matched, and every deviation is reported with its effect in euro. A generator writes the test documents itself and records which deviations it planted, which makes detection measurable rather than merely plausible.

The measured result

4 of 4 planted deviations detected, 0 false alarms, 20 tests. Three of the seven cases contain no deviation on purpose: a change of unit and a partial delivery across two invoices are not errors. A checker that reports them stops being read after two weeks.

What this does not show

No real supplier documents. The generated PDFs are tidier than reality. No OCR for scans, no proprietary wholesaler formats, no ERP integration.

Code and measurements on GitHub
01 / DOCUMENT RECONCILIATIONSynthetic data
QuoteA-001

Mounting bracket · Item 01

120 × €2.00
Agreed€240.00
InvoiceR-001

Mounting bracket · Item 01

120 × €2.20
Invoiced€264.00
€24.00 overcharged

120 pieces × €0.20 price difference. The same item, a different price.

Simplified calculation. No PDFs are processed or data transmitted here.

PYTHON · STANDARD LIBRARY

Coordinating concurrent writes without a server

Several processes work on the same file tree. There is no database server handing out locks. There are only files. Without an agreement, the slower process silently overwrites what the faster one just saved.

14 → 0Lost entries in the documented comparison run.
Decisions, result and limitations

The approach

Before writing, a process declares the files it intends to change together with the hashes it saw, and acquires a global lease. After the write the coordinator verifies that only declared files changed and appends the before and after hash to a journal. A gap in that chain proves somebody wrote outside the protocol.

The measured result

Same work, four processes, twenty writes expected: without coordination 14 lost and 18 chain gaps, with coordination 0 and 0. Neither run reports an error. That is exactly what makes this class of bug expensive. 18 tests.

What this does not show

Not a distributed system: one machine, one filesystem. Not a lock manager: a single global lease serialises everything, which is right when writes are rare and wrong when they are not. Detecting undeclared changes hashes the whole tree and does not scale to hundreds of thousands of files.

Code and measurements on GitHub
02 / CONCURRENT WRITESFour processes
Awritten
Bwritten
Cwritten
Dwritten
data.jsonSaved entries
1 of 4 entries survives.

All read the same old state. Each overwrites the other processes’ entries.

Simplified schedule: four processes, one entry each. Not a real multiprocess run in the browser.

PYTHON · REGEX · STANDARD LIBRARY

Checking any text for stock phrasing and having it rewritten

A text that reads like a template gets skimmed, whether it is a cover letter, a quote, a report or product copy. The patterns that create that impression are few and can be named. The contrast "not X, but Y", the dash in the middle of a sentence, stock phrases, five sentences of the same length in a row.

36 / 36Planted patterns in test sentences caught. No false alarms.
Decisions, result and limitations

The approach

A fixed set of 17 rules finds those patterns reliably and always in the same way. For the rewrite, the tool collects suggestions from two AI models by different vendors, one with no history of the text, the second as a cross-check. Each suggestion is applied on its own and kept only if the rules afterwards count no more findings than before. The models propose, the rules decide.

The measured result

Checked against 50 invented test sentences, 18 of them clean ones no tool may flag: 36 of 36 planted patterns found, 0 false alarms, 29 automated tests. An English example text goes through the procedure from 6 findings to 0. The German one keeps one warning because the rewrites made every sentence the same length, and the tool says so.

What this does not show

Not a detector for AI-written text, and inverting it does not make one. The rule list rests on my own observation rather than on literature. The shipped model answers are labelled placeholders; real runs need two API keys.

Code and measurements on GitHub
03 / TEXT CHECKInvented example text
  1. 1Rule check17 rules, always the same
  2. 2Suggestion 1AI model with no prior context
  3. 3Suggestion 2model by a different vendor
  4. 4Rule checkkeeps only what improves
beforeFAIL 6 · WARN 4

I am not applying for any operations role, but for one where the process is still being built.

Found: contrast "not X, but Y"
afterFAIL 0 · WARN 0

I am applying for an operations role where the process is still being built.

Suggestion 1, confirmed by the rule check

One sentence from the example text. The counters come from the measured run over the whole text. Two rounds, five suggestions applied, none rejected.

PYTHON · STANDARD LIBRARY · THREADS

Work that keeps going by itself, with nobody having to start it

In a small organisation a lot stays undone because somebody would have to start it: working through lists, gathering figures, writing down results. If scheduled runs are to do that at night by themselves while people work on the same files during the day, three things are needed. A rule for who may work on what right now. A handover, so that the next morning it is visible what happened. And a line for what a run must never do without a person.

12 / 12Tasks worked through or put forward, with nobody attending a run.
Decisions, result and limitations

The approach

Each run takes one project at a time, locks it briefly for itself and works through the open tasks; a project somebody is sitting at is skipped and done on the next run. At the end a closing step sums up what all runs did and found, as a handover for the next person. Anything irreversible, such as sending, publishing, deleting or paying, a run only puts forward; a person decides, a later run carries it out and records who approved.

The measured result

Two scheduled runs and one person at the same moment on the same example with 12 tasks in three projects, once without and once with the protocol, then counted from the files. With the protocol: all 12 tasks worked through or put forward for a decision, none twice, 8 findings in the handover, the person's edit kept, 0 irreversible actions without approval. Without: tasks done twice, the person's edit overwritten, no handover, 8 irreversible actions without approval. 16 automated tests.

What this does not show

The tasks are dummies; doing one means appending a line. When a run starts is up to a scheduler outside, which is not included. One machine, no network, no language model. Two design mistakes that only the comparison run made visible are stated openly in the README.

Code and measurements on GitHub
04 / WORK THAT RUNS ITSELFInvented example organisation
Two runs and one person, at the same timewithout protocolwith protocol
Tasks worked through or put forward1212
Findings in the handover08
Person’s edit keptnoyes
Tasks done twice7–120
Irreversible actions without approval80

The sequence above re-enacts the comparison run in the repository, tasks and projects as there. The table is counted from the files; how many tasks get done twice without the protocol depends on timing.

ASTRO · GSAP · NODE TEST

This website, built with AI tools in six working days

A site like this would have taken weeks a few years ago: design, two languages, motion, legal pages, tests. With AI tools as collaborators it takes days, provided you know what you want, make the decisions yourself and check every result. This site is the evidence, commit history included.

6Working days from an empty repository to this page with six projects.
Decisions, result and limitations

The approach

A written design first, then the code, written by AI tools and reviewed by me. Three design variants built in one day on one codebase, compared in the browser, one chosen. Automated tests run against the finished site and check, among other things, that the privacy statement describes what the site actually does. Served statically, without tracking and without outside services; no request leaves this address when you visit.

The measured result

Over 30 commits across 6 working days, live since day two. 8 pages in two languages, 0 requests to third parties, 10 tests against the finished build, accessibility 100 in the Lighthouse run against the live address. The texts on this site went through the tool from the third project.

What this does not show

Six working days does not mean six full days in a row; they are spread over two weeks. No backend, no form, no user data. The repository contains application texts and a photo and therefore carries no open licence. The site is deliberately not findable through search engines; it is reachable only through the shared link.

Code and measurements on GitHub
05 / THIS WEBSITEBuilt with AI, signed off by me
  1. 11.09.scaffold and design
  2. 12.09.live, legal pages, Lighthouse
  3. 14.09.delivery via Actions
  4. 15.09.polish
  5. 16.09.three variants, motion
  6. 22.09.six projects
6
working days, spread over two weeks
30+
commits, live since day two
3
design variants in one day
10
tests against the finished build
0
requests to third parties on a visit
100
accessibility in the Lighthouse run
tests/site-build.test.mjs10 / 10
  • same header and footer on every page
  • exactly one main heading per page
  • privacy statement describes what the site does
  • no placeholders, no replacement characters in the build

Every number comes from this site’s repository, the working days from the commit dates. Both can be checked there.

PYTHON · CSV · STANDARD LIBRARY

Order proposal from the numbers the till already has

A bar books every sale in its point-of-sale system and counts the shelves once a week. Ordering still happens with a notepad in the cellar. How much of what will last until the next delivery, and in how many cases? Four suppliers, four forms, every week.

10 / 10Planted shortages ordered, pack counts exact. No unnecessary order.
Decisions, result and limitations

The approach

The tool takes what the system already knows, sales per day and the last count, and works out per article the stock today, the daily consumption of the last two weeks and the stock on delivery day. If that falls below the minimum, it orders whole packs up to the target. Articles without sales go on a list instead of an order; a supplier below its minimum order value gets a flag, and nobody pads the order for it. Plus a count list in shelf order for the next inventory.

The measured result

An invented bar with 33 articles and 4 suppliers. A generator builds four weeks of sales and records what it plants. Result: 10 of 10 shortages ordered, pack count exact in 10 of 10, 0 unnecessary orders, 3 of 3 boundary cases left alone, 2 of 2 articles without consumption listed, 1 supplier flagged below its minimum. 21 tests, one of which shows that the check can fail.

What this does not show

No real POS export; the files are only shaped like one. No sending, the order ends as a file per supplier because the sending script at the bar was started and never finished. No forecast, a two-week average flattens weekends and events. No SQL, neither then nor here.

Code and measurements on GitHub
06 / REORDER PROPOSALInvented bar
  1. 1Countlast count minus sales since
  2. 2Ratesales of the last 14 days
  3. 3Projectionstock on delivery day
  4. 4Packswhole cases up to the target
Cola 0.33 · cellar A2order
stock today
40
6 a day × 2 days
− 12
on delivery day
28
minimum
48
short of target 144
116
cases of 24
5
Order per supplier4 × CSV + TXT
  • Getraenke Nord3 lines268,80 €
  • Brauerei Falkenau3 lines767,20 €
  • Spirituosen Hensel3 lines564,00 €
  • Bar Bedarf Kruse1 lines112,00 €below minimum order 150 €

Numbers from the run over the shipped example data: 10 of 10 shortages ordered, 0 unnecessary, 1 supplier flagged. Nothing is sent; the order ends as a file.

03 / BACKGROUND

Physics taught meto look more closely.

I hold a B.Sc. in physics and am writing my master’s thesis at TU Berlin alongside work. Scientific data analysis taught me to check a claim against the data.

In practice, I learned that a good prototype is not yet a good handover. At Cavator, the work involved real documents, exceptions and people who needed to use the result.

Background, photo and evidence

04 / CONTACT

Which workflow deservesa closer look?

I’m looking for a permanent full-time role in data analysis, process automation or customer-facing technical work. Berlin or remote.

steyerfabio@gmail.com