CAWLabel

Labels that keep printing when the network doesn’t.

CAWLabel manages articles, packaging, label layouts and scales — then uploads everything to the shop-floor scales so they run on their own. A Delphi / VCL application, built from the first line with AI assistance.

Etiketten, die weiterlaufen, wenn das Netz ausfällt.

CAWLabel verwaltet Artikel, Verpackungen, Etikettenlayouts und Waagen — und lädt alles auf die Waagen in der Produktion, damit sie eigenständig arbeiten. Eine Delphi-/VCL-Anwendung, von der ersten Zeile an mit KI-Unterstützung entwickelt.

74,000 lines of Delphi in 179 units Zeilen Delphi in 179 Units
1,927 automated tests, run on every change automatische Tests, bei jeder Änderung
54 screens and frames Bildschirme und Frames
40 pages of user documentation Seiten Benutzerdokumentation

What it does

A labelling system for production environments where scales print the labels — not the PC.

Was es tut

Ein Etikettiersystem für Produktionsumgebungen, in denen die Waage das Etikett druckt — nicht der PC.

Article master data with live label preview
Article master data. The label preview on the right updates as you type.
Artikelstammdaten. Die Etikettenvorschau rechts aktualisiert sich während der Eingabe.

Article master data with live preview

Every article carries its weights, packaging, VAT rate, best-before rules and nutrition values. Free-form additional fields let each installation define what else an article needs — ingredient lists, origin declarations, storage advice — without touching the program.

The preview on the right renders the actual label for the selected article and scale, including the keyword highlighting and barcode structure described below. What you see is what the scale will print.

Artikelstammdaten mit Live-Vorschau

Zu jedem Artikel gehören Gewichte, Verpackung, Umsatzsteuersatz, Mindesthaltbarkeits-Regeln und Nährwerte. Über frei definierbare Zusatzfelder legt jede Installation fest, was ein Artikel sonst noch braucht — Zutatenlisten, Herkunftsangaben, Lagerhinweise — ohne Eingriff ins Programm.

Die Vorschau rechts rendert das tatsächliche Etikett für den gewählten Artikel und die gewählte Waage, samt Hervorhebungen und Codeaufbau. Was dort steht, druckt später die Waage.

Label layout designer
The FastReport designer, embedded in the application.
Der FastReport-Designer, in die Anwendung eingebettet.

Label design without a developer

Layouts are built in an embedded FastReport designer. Fields from articles, packaging, scale configuration and the additional fields are offered as a data tree — drag one onto the label and it prints.

A validation pass checks every layout against the physical label size and reports elements that would fall outside the printable area, before anything reaches a scale.

Etikettengestaltung ohne Entwickler

Layouts entstehen in einem eingebetteten FastReport-Designer. Felder aus Artikeln, Verpackungen, Waagenkonfiguration und den Zusatzfeldern stehen als Datenbaum bereit — hineinziehen genügt.

Eine Prüffunktion vergleicht jedes Layout mit der physischen Etikettengröße und meldet Elemente außerhalb des Druckbereichs, bevor irgendetwas auf einer Waage landet.

Working with the scales

The part that shaped every design decision: once the data is uploaded, the scales must keep working on their own.

Zusammenspiel mit den Waagen

Der Punkt, der jede Entwurfsentscheidung geprägt hat: Nach dem Upload müssen die Waagen eigenständig weiterarbeiten.

Transfer screen with progress log
Transfer screen. Every step is logged, warnings and errors are colour-coded.
Übertragungsbildschirm. Jeder Schritt wird protokolliert, Warnungen und Fehler farblich abgesetzt.

Upload, then autonomy

The scales sit on the shop floor with a Zebra printer attached. CAWLabel renders each layout into ZPL — the printer’s own command language — and transfers it together with the article data over FTP.

From that moment the scales are independent. An operator selects an article, places the goods, and the scale composes and prints the label itself: the weight, the price, the best-before date, the barcode. No network, no server, no PC involved. A cable pulled out during a shift does not stop production.

This is why the data has to be complete and correct before it leaves the PC. There is no second chance to fix a typo remotely.

Hochladen, dann eigenständig

Die Waagen stehen in der Produktion, mit angeschlossenem Zebra-Drucker. CAWLabel rendert jedes Layout nach ZPL — der eigenen Befehlssprache des Druckers — und überträgt es zusammen mit den Artikeldaten per FTP.

Ab diesem Moment sind die Waagen unabhängig. Eine Bedienkraft wählt einen Artikel, legt die Ware auf, und die Waage setzt das Etikett selbst zusammen und druckt es: Gewicht, Preis, Mindesthaltbarkeitsdatum, Barcode. Ohne Netzwerk, ohne Server, ohne PC. Ein herausgezogenes Kabel hält die Produktion nicht an.

Deshalb müssen die Daten vollständig und richtig sein, bevor sie den PC verlassen. Einen Tippfehler kann niemand aus der Ferne nachbessern.

Reachability check

Before a transfer starts, each selected scale is probed over FTP. If none answers, the transfer never begins; if only some do, the operator decides whether to continue.

Erreichbarkeitsprüfung

Vor jeder Übertragung wird jede gewählte Waage per FTP angesprochen. Antwortet keine, startet die Übertragung gar nicht; antworten nur einige, entscheidet die Bedienkraft.

Weighing records come back

What the scales recorded during the shift is collected in the same run — which article, which weight, when. The transfer screen can upload, download, or only validate.

Wiegungen kommen zurück

Was die Waagen während der Schicht protokolliert haben, wird im selben Lauf abgeholt — welcher Artikel, welches Gewicht, wann. Der Bildschirm kann hochladen, abrufen oder nur prüfen.

Unattended runs

The same transfer runs from the command line with an exit code and a log file, so a scheduled task can refresh the scales overnight.

Unbeaufsichtigte Läufe

Dieselbe Übertragung läuft auch von der Kommandozeile, mit Rückgabewert und Protokolldatei — eine geplante Aufgabe kann die Waagen nachts auffrischen.

More of what it handles

Was es sonst noch kann

Keyword highlighting

Keyword highlighting

Words that have to stand out on a label — allergens, for instance — are maintained in one place and highlighted automatically wherever they appear, in bold, italic or colour.

Hervorhebungen

Wörter, die auf dem Etikett auffallen müssen — etwa Allergene — werden an einer Stelle gepflegt und überall automatisch hervorgehoben: fett, kursiv oder farbig.

Barcode structure editor

Barcode structures

Which digits carry the article number, which the weight, which the price — defined per structure and reused across articles, so a new barcode scheme does not require a code change.

Codeaufbau

Welche Stellen die Artikelnummer tragen, welche das Gewicht, welche den Preis — je Struktur definiert und artikelübergreifend wiederverwendet. Ein neues Barcode-Schema braucht keine Programmänderung.

Additional field definitions

Additional fields

Text, numbers, dates, checkboxes, lists, rich text, images — each installation defines the fields its articles need, and they appear in the article screen and the layout designer alike.

Zusatzfelder

Text, Zahlen, Datum, Ankreuzfelder, Listen, Formattext, Grafiken — jede Installation legt die Felder fest, die ihre Artikel brauchen. Sie erscheinen im Artikelbildschirm und im Layout-Designer.

Data import dialog

Import and migration

Articles, packaging, scales and VAT rates import from CSV, up to 100,000 rows per run, with a dry run that reports what would change before anything is written.

Import und Migration

Artikel, Verpackungen, Waagen und Steuersätze lassen sich aus CSV importieren, bis zu 100.000 Zeilen je Lauf — mit Probelauf, der vorher meldet, was sich ändern würde.

How this was built

Three phases, three ways of working with AI — and a different result each time.

Wie das entstanden ist

Drei Phasen, drei Arten mit KI zu arbeiten — und jedes Mal ein anderes Ergebnis.

Phase 1 — ChatGPT and the clipboard

The project started with a browser window next to the IDE. Describe a problem, read the answer, copy the code across, adjust it by hand. It worked, and for isolated questions it worked well: a parsing routine, a regular expression, the outline of a class.

What it could not do was know the project. Every question had to carry its own context, and every answer arrived without knowing what the rest of the code looked like. Names drifted apart, patterns were reinvented, and the copy-and-paste step itself introduced its own mistakes — a missing line, a stale variable name, an indentation that hid a scoping bug.

Phase 2 — Kai inside the IDE

Kai moved the assistant into RAD Studio itself. The difference was immediate: no more copying. Kai reads the editor buffer, so unsaved changes are part of the picture, and it writes back into the same buffer. Compiling, opening a unit, adding a file to the project — all of that became something to ask for rather than something to do by hand.

For debugging, the practical lesson was to stay short. Kai can set breakpoints and read the call stack, but long live-debugging sessions proved fragile. The habit that emerged: read the code first, form a hypothesis, and reach for the debugger only to confirm it — one breakpoint, one look, terminate.

Phase 3 — Claude Code alongside

Claude Code added the thing the other two lacked: it can run the whole loop. Build the project, run the tests, read the output, fix what broke, run them again. A session is not a conversation about code but a sequence of verified steps.

A project file (CLAUDE.md) carries the knowledge that is not visible in the source: which of three installed Delphi versions this project needs, why a cached frame must restore its state in Reactivate rather than Initialize, which build output directory actually receives the test executable. Every hard-won insight goes in there, so the next session starts where the last one ended instead of rediscovering the same trap.

Phase 1 — ChatGPT und die Zwischenablage

Angefangen hat es mit einem Browserfenster neben der IDE. Problem beschreiben, Antwort lesen, Code herüberkopieren, von Hand anpassen. Das ging, und für abgegrenzte Fragen ging es gut: eine Parsing-Routine, ein regulärer Ausdruck, das Gerüst einer Klasse.

Was nicht ging: das Projekt kennen. Jede Frage musste ihren Kontext selbst mitbringen, und jede Antwort kam, ohne den übrigen Code zu kennen. Namen liefen auseinander, Muster wurden neu erfunden, und das Kopieren selbst brachte eigene Fehler mit — eine fehlende Zeile, ein alter Variablenname, eine Einrückung, die einen Gültigkeitsfehler verdeckte.

Phase 2 — Kai in der IDE

Kai holte den Assistenten in RAD Studio selbst. Der Unterschied war sofort spürbar: kein Kopieren mehr. Kai liest den Editorpuffer, also gehören auch ungespeicherte Änderungen zum Bild, und schreibt in denselben Puffer zurück. Kompilieren, eine Unit öffnen, eine Datei ins Projekt aufnehmen — all das wurde zu etwas, das man erbittet, statt es von Hand zu tun.

Beim Debuggen war die praktische Lehre: kurz bleiben. Kai kann Haltepunkte setzen und den Aufrufstapel lesen, aber lange Live-Sitzungen erwiesen sich als störanfällig. Daraus wurde eine Gewohnheit: erst den Code lesen, eine Vermutung bilden, und den Debugger nur zur Bestätigung bemühen — ein Haltepunkt, ein Blick, beenden.

Phase 3 — Claude Code daneben

Claude Code brachte, was den beiden anderen fehlte: Es kann den ganzen Kreis laufen. Projekt bauen, Tests ausführen, Ausgabe lesen, Gebrochenes reparieren, erneut ausführen. Eine Sitzung ist kein Gespräch über Code, sondern eine Folge nachgeprüfter Schritte.

Eine Projektdatei (CLAUDE.md) trägt das Wissen, das im Quelltext nicht sichtbar ist: welche von drei installierten Delphi-Versionen dieses Projekt braucht, warum ein gecachtes Frame seinen Zustand in Reactivate wiederherstellen muss und nicht in Initialize, welches Ausgabeverzeichnis die Test-Exe tatsächlich bekommt. Jede teuer erkaufte Erkenntnis landet dort, damit die nächste Sitzung dort beginnt, wo die letzte aufhörte, statt in dieselbe Falle zu laufen.

What changed in practice

Was sich praktisch geändert hat

Tests, every single time

1,927 tests across three DUnitX projects, in 87 test units. They are not run occasionally — they run after every change, and a commit without a green run does not happen.

Writing them stopped being the expensive part. A new value editor arrives with its tests; a bug fix arrives with the test that would have caught it.

Tests, jedes Mal

1.927 Tests in drei DUnitX-Projekten, verteilt auf 87 Test-Units. Sie laufen nicht gelegentlich — sie laufen nach jeder Änderung, und ohne grünen Lauf gibt es kein Einchecken.

Sie zu schreiben ist nicht mehr der teure Teil. Ein neuer Wert-Editor kommt mit seinen Tests; eine Fehlerbehebung kommt mit dem Test, der den Fehler gefunden hätte.

Counter-checking a green test

A test that passes proves nothing until you have seen it fail. The habit: remove the fix, confirm that exactly the intended test goes red, put the fix back.

It has caught tests that asserted nothing, and it has saved a bug report that turned out to be wrong — the code path looked broken, the measurement said otherwise.

Gegenprobe zum grünen Test

Ein bestandener Test beweist nichts, solange man ihn nicht hat fallen sehen. Die Gewohnheit: die Korrektur ausbauen, prüfen, dass genau der gemeinte Test rot wird, die Korrektur wieder einbauen.

Das hat Tests entlarvt, die nichts prüften — und eine Fehlermeldung verhindert, die falsch gewesen wäre: Der Codepfad sah kaputt aus, die Messung sagte etwas anderes.

Measure, don’t assume

Performance work is verified against the database’s own execution counters, not against intuition. One caching change looked like a clear win on paper; the first measurement showed the effect drowning in noise, and the real fix turned out to be somewhere else entirely.

Messen statt vermuten

Leistungsarbeit wird an den Ausführungszählern der Datenbank geprüft, nicht am Bauchgefühl. Eine Cache-Änderung sah auf dem Papier nach klarem Gewinn aus; die erste Messung zeigte den Effekt im Rauschen untergehen, und die eigentliche Ursache lag ganz woanders.

Reviews that leave a trail

Twenty documented review rounds in a log that records what was checked, what was found, and which revision fixed it — so the next review can start from the last one instead of re-reading everything.

Reviews mit Spur

Zwanzig dokumentierte Review-Durchläufe in einem Protokoll, das festhält, was geprüft wurde, was gefunden wurde und welche Revision es behoben hat — damit das nächste Review beim letzten ansetzen kann.

Documentation as it happens

40 pages of user documentation in Markdown, generated into HTML help with screenshots. It is written alongside the feature, not months later — which is the only reason it still matches the program.

Dokumentation nebenher

40 Seiten Benutzerdokumentation in Markdown, daraus erzeugte HTML-Hilfe mit Bildschirmfotos. Sie entsteht mit der Funktion, nicht Monate später — nur deshalb passt sie noch zum Programm.

Testing the UI from outside

A small HTTP component was built into the application so an automated run can ask which controls exist, read their properties, trigger actions and wait for a screen to settle — instead of guessing pixel coordinates.

Die Oberfläche von außen prüfen

Eine kleine HTTP-Komponente in der Anwendung erlaubt es einem automatisierten Lauf, nach vorhandenen Steuerelementen zu fragen, Eigenschaften zu lesen, Aktionen auszulösen und auf einen Bildschirmzustand zu warten — statt Pixelkoordinaten zu raten.

Built with

Verwendete Technik

Language and UI
Sprache und Oberfläche
Delphi / RAD Studio, VCL
Grids and controls
Grids und Bedienelemente
DevExpress VCL, Konopka Signature VCL Controls
Labels and printing
Etiketten und Druck
FastReport VCL, ZPL output for Zebra printers
FastReport VCL, ZPL-Ausgabe für Zebra-Drucker
Database
Datenbank
Microsoft SQL Server via ADO / OLE DB
Microsoft SQL Server über ADO / OLE DB
Tests and logging
Tests und Protokollierung
DUnitX, SmartInspect
Scale transfer
Waagenübertragung
FTP, with reachability probing
FTP, mit Erreichbarkeitsprüfung