During the weekends in July and August, provided there was ample sunshine and not too much wind, I've been running a small, outdoor pop-up pizzeria in my orchard. Simple, no-nonsense, good food & drinks and relaxing tunes. The months leading up to that I'd been doing a lot of research, obtaining the necessary permits, getting insurance, taking care of food and fire safety, selecting a provider such that I could accept electronic payments, finding suppliers for food and drinks, etc ...
Given the small size of this endeavour, I could probably have used pen and paper to take orders, but honestly, what kind of software developer would I be, if I didn't crave a little bit of technology and automation 😉. Aware of the limited time I had, "buy" was obviously preferred over "build". I started looking for affordable, existing solutions that met my list of requirements:
Guess what, the solutions were neither affordable, aligned with temporary businesses such as pop-ups, or anywhere near meeting the requirements set out. After looking at the 5th solution, I either gave up or was fed up or both - my recollection is fuzzy. Either I had to let go of requirements, take on a yearly plan of something I only needed for a couple of months, reconsider the "build" option, or go old skool with pen and paper. Trade offs are unavoidable, but I quickly had to eliminate most options on the basis of being too expensive for what was bound to be a roll of the dice in terms of revenue, or my wife, who was doing most of the order taking and payment handling, being very adamant about the fact she was not going to be doing additions and tax classification by hand on top of all the serving and cleaning, the chance of human error pissing off customers (which is always there to a certain degree, don't get me wrong) and the apologies that would have to go with that. All that and more led to "I'll quickly build this" ... famous words I uttered a few months ago.
Still, I did what had to be done and started working on it. I used it as an excuse to evaluate Anthropic's Claude Code. I had been tinkering with tools in the AI space, you know, like most people, to see what all the fuss is about, but not in anger. Whatever your position is on the subject of AI, my intent is not to convince you of anything. My experience is not transferable nor is it an endorsement of any kind. Just one of many aspects that stood out on this journey.
In my career, I've been predominantly using the .NET stack, so I picked familiarity (e.g. F#, Event Sourcing, EventStoreDB, Postgres) and an ecosystem of dependencies (e.g. Giraffe, NodaTime, Serilog) I already knew, just to eliminate as much learning curve as I could. Still, there were plenty of areas where some level of learning or exploration was necessary. Notably, I had not used QuestPDF before to create a printable PDF version of the menu. In fact, Claude did most of the authoring there. Good, because frankly, I did not feel like learning the ins and outs of such a reasonably sized object model. A risk in that I did not fully "own" the associated code? For sure, but one I was willing to take if it meant concentrating on more important parts. Claude's initial interaction with the Epson TM-T20III I bought was not at a level that pleased me, so I dug in, learned the ropes of the ESC/POS protocol, and came up with a "better" version Claude could extend. While I was at it, I used .NET Aspire, a new kid on the block when it comes to building distributed applications, thereby replacing the manual approach to composing the main application with various databases. Always be learning ...
Claude was the main author of all the views, following my instructions. I deemed UI yet another piece I'd be willing to redo if Claude made a mess of things. I used server-side-rendered html, the output of a view function combined with a model, where the model was hydrated from handcrafted database tables, and plain javascript when needed. Claude "understood" both the view engine I was using and how to combine it with TailwindCSS. Annoyingly, Claude seemed to be very happy when it came to repeating itself, something I learned to live with up to a certain degree, and, honestly, it may as well be my failure to instruct it properly. The constant inlining of either javascript (in html) or html (in javascript) rubbed the wrong way, and while I managed to rectify the situation, I was not quite prepared to deal with the toddler with amnesia. What surprised me was the fact that Claude picked up on the fact that the view literals were in Dutch. It kept using Dutch in appropriate places. You win some, you lose some. Visually, it wasn't the most original design, but it was fully functional in Safari on an Apple iPad, which was the main device used for order taking.
When it came to defining the behavior and rules that govern each behavior, I used tests to drive the implementation, after an initial round of REPL-based exploration. Behaviors would be things such as publishing a menu, opening a ticket, taking an order, sending it to the kitchen, receiving a payment in cash or by card, printing a receipt, closing a ticket, and many more ... After I'd done a few behaviors by hand, I started to focus on writing tests and delegating the task of making the tests pass to Claude. I got mixed results and often had to rework the changes it had made to the internals. Sometimes the output wasn't idiomatic, too complicated for what needed to be achieved, or generally lacked the insight that a lot of rework would be needed when adding the next behavior. I did not always have the patience to ask it to redo or simplify its work and simply took over. The "thinking" time it takes to get something done the way I want it, versus me doing it manually, when it's already clear in my head, is a source of frustration, I confess. I kept a tight leash on the schema in use ... I owned that bit and would rather die than let Claude take the bastion of describing the messages and the properties that travel with them. This turned out to be a wise move. My use of Claude was in select areas where reverting the blast radius of changes was only a checkout away. That gave me a comfortable feeling to be honest. Being the sole developers, me and Claude, on this codebase, I doubt this exact experience is going to scale very well. Granted, I've got no evidence - just a gut feeling at this point.
It may appear as if I developed all the functionality in one go before going to production. That wasn't the case though. This wasn't Moses taking a shower under a waterfall after handing me the tablets with requirements. Instead, by the time we got to opening for the first time, I had hard-coded the menu and table layout. The supported table ticket behaviors were opening a table ticket, taking an order, change an order, sending it to the kitchen, print customer and tax receipts, receiving cash or card payments, and closing a table ticket. That and printing the menu. I can tell you, I'm glad we'd not made any big announcements just yet at that point. Why? Well, bugs, obviously. The kind I had to fix in between baking pizza's. Yeah, not exactly a place you wanna be - nothing makes you feel more like an amateur and a sensation of "Building your own, what were you thinking, how is that even relevant? You should be focused on the real aspects of running this, like making sure that each pizza is at the same level of quality". Humbling lessons shape us. By the next week, I had more testing in place, and added the ability to edit the menu. As an aside, table layout remained hard coded because there's not been a need to make that editable - I'm neither adding or removing tables nor changing the overall layout. The stability improved over time, I got into a habit of running "smoke test" tickets through the system before each opening, catching any regressions before they made it into production. By the third week, I had the cashbook and daily receipts book done. This went on week after week. There was a perpetual and incremental motion to this experience. Small improvements were based on a usage feedback loop, such as making the font bold on printed tickets for readability purposes - I kept forgetting where I put my glasses, while bigger features were driven by lack of functionality or visibility. At times, I veered off into various directions, just to see where they would take me. Numerous dead branches in the GIT repository are a testimony to that. This too happened.
Meanwhile, I practiced scaling my production capacity from one, to two, to now three pizza's at a time, cutting my food prepping time by a third by learning how to work faster and more efficient, building a routine for dough preparation, following a daily checklist of what needed to be done by what time, operating multiple ovens at the same time, getting to grips with each oven's temperature drop, etc... for a short stint I got to work another profession and I enjoyed it. Technology was fairly distant and merely used in a supporting capacity. At times there was stress involved, things not going your way as you're prepping before service in the morning, being creative when problems needed to be solved quickly, dealing with the food safety inspector, etc ... This stood in stark contrast to the customer's experience. Chill, relaxed, no rush, time on their hands, it's holiday season. I made sure I maintained a level of quality I would expect myself, not to rush myself when more orders piled up, and it paid off in terms of customer feedback. "By far the best pizza I had since I visited Naples" was probably the ultimate form of flattery I could receive. Plates were always empty, so that must count for something. I remain humble enough to realize that my perception of things might be very different if I had to do this day in and out. If anything, it reaffirmed my deep respect for pizzaiolo's and other people working in the hospitality sector for most of their career.
As the summer is rapidly coming to an end, I'm already contemplating how I'm going to change the system to support take-away and scheduling order pick-up time slots that align with my productivity, add basic menu engineering. I've made strides towards inventory tracking and using it for food cost calculation, allergen detection, recipe composition. Technically, I'm playing with changing the UI to a mobile form factor, as well as feeding recorded events - translated into sentences - to an LLM and see how I can start asking questions about my data, for extra fun, obviously, but also because I'm simply giving in to the current fad. All overkill for the size I'm at, but there's joy to be had in maturing a software solution like that, plus there's bound to be more things I learn along the way.
Can't wait to repeat this experience next year 😃