Benjamin Shado

Shipped 2026

Poultry farm operations

Role
Product designer and engineer, sole builder
Timeline
In daily use since Oct 2026
Stack
FastAPI, PostgreSQL, React, Redis, Docker

Overview

A 10,000-bird egg farm, run on WhatsApp and spreadsheets.

The farm is a commercial egg operation with three pens and more than 30 staff. Every day, it moves eggs, feed, fuel and money. Every one of those figures travelled as a text message and ended up in a spreadsheet.

How a day was recorded before. Sample data.

I replaced it with one operations system.

I designed and built it end to end: research, data model, backend, frontend and deployment. Since October 2026, it has held every daily record the farm produces.

The whole operation on one screen. Sample data.

The problem

The records existed. The structure didn't.

Daily figures arrived as messages from the pens, the store and the wider farm, and were keyed into a set of spreadsheets that had grown without a common structure. Each sheet served its own purpose, but together they offered no single view of the operation. Reading across them took effort, and reconciling them took days.

Pens
Store
Rest of farm
WhatsApp messages
One person
Types it all in
Eggs sheet
Feed sheet
Fuel sheet
Sales sheet
Payroll sheet

No checks at any step.

Many sources, one inbox, no validation

Errors entered silently and stayed hidden.

Nothing validated the data on the way in. A mistyped figure, a missing report or a store count that didn't reconcile went undetected until month-end, when compiling a single report took around two days.

The most valuable data was never captured.

Eggs are sold in five grades, each at its own price. Sales were recorded by grade, but collection was recorded as a single total. The farm could see 40 crates of large eggs leave the store, but could never confirm that 40 crates had come in. Any shortfall disappeared into the total.

Sales
Large
✓ Recorded
Big
✓ Recorded
Medium
✓ Recorded
Pullet
✓ Recorded
Cracked
✓ Recorded
Collection
Total eggs
✓ Recorded, as one number
Large
Not recorded
Big
Not recorded
Medium
Not recorded
Pullet
Not recorded
Cracked
Not recorded
A gap no spreadsheet formula could close

The result: decisions made on figures no one could verify.

Stock on hand, the cost of feeding each pen, whether the store balanced: the farm had no dependable answer to any of them. That matters most for feed, which is the largest single cost in egg production, typically 60–70% of the total.

My approach

I started with the operation, not the software.

Before designing anything, I mapped how the farm actually works. I traced how eggs move from pen to store to customer, how feed is ordered, delivered and consumed, how staff are paid, and what the owner needs to see at the end of each month.

Mapping the flow exposed what was missing.

Egg grades were one gap. Feed type was another: pens reported how many bags they used, but not which feed, so per-pen feed cost was impossible to calculate. I worked with the farm to add both to daily reporting, giving the system complete and consistent inputs.

Pen A, daily reportExample figures
Eggs collected1,240
Feed6 bags
Daily pen reporting, before and after
Exploration

Where should the store balance come from?

Option 1 · Not chosen
Record a daily balance

This mirrors the spreadsheets and inherits their weakness: one wrong entry and the balance drifts from reality, with no trail explaining why.

Option 2 · Chosen
Derive it from every movement

Each stock movement is recorded once, at the moment it happens: collections, sales, deliveries, daily feed use, and fuel purchases and usage. The balance is calculated from that ledger, so it can be reproduced for any date. When a physical count disagrees, an adjustment resolves it, and every adjustment requires a reason.

Comes in
Store
Balance on any date, added up from records

Goes out
Both ways
Adjustments and egg conversions
Each with a reason

Tap or hover a movement to trace it.

Every movement recorded once; the balance follows
Exploration

How should feedings be recorded?

Option 1 · Not chosen
Fixed morning and evening fields

This fits today's routine but hard-codes it. Adding a third daily feeding would mean changing the software.

Option 2 · Chosen
Daily total per feed, feeding times separate

Bags are logged once a day, as a total for each feed. Feeding times are logged on their own, as many as the day needs. The routine can change without the software changing.

Adding a third feeding, both ways. Sample data.
Exploration

What should happen when an entry looks wrong?

Option 1 · Not chosen
Reject it

Clean in theory, but farm data rarely arrives in order, and feed is sometimes used before its delivery is logged. Hard blocks would stall data entry and push staff back to workarounds.

Option 2 · Chosen
Accept it and flag it

Records always save, and anomalies surface as warnings. Missing pen logs, unreconciled stock and over-delivered orders are flagged on the dashboard and summarised in the monthly report.

Flag, don't block. Sample data.

The solution

Every egg is traced by grade, from pen to customer.

Pens log collection by grade, in crates and pieces. When an egg's grade changes after collection, for example when it cracks in transit, a conversion records the change with a reason. Totals stay intact, and every egg is accounted for.

Logging a day's collection by grade. Sample data.

Feed cost is visible at the pen level.

A moving-average cost for each feed, based on actual purchase prices, is applied to every bag consumed. The result is a daily feed cost for every pen, the farm's largest expense made measurable for the first time.

Daily feed cost, per pen. Sample data.

Designed for high-volume entry.

Dozens of reports go in every day, so the interface is built to stay out of the way.

  • Quiet by default. A monochrome palette and a single typeface, with nothing on screen that doesn't serve the task.
  • Colour carries meaning. Amber signals a warning, red a loss, green completion. Exceptions stand out at a glance.
  • The farm's vocabulary. Eggs are counted in crates and pieces, and payroll prints in the farm's existing salary-sheet format.
  • Absence is visible. A pen without a log still appears, marked "Not logged".
  • Laptop and phone. Tables reflow into stacked rows on mobile, and forms open as bottom sheets.
A pen log open in the real app, with its checks, feeding times and feed
A pen log in the real app, with test data.
One responsive app. Sample data.

Under the hood

For technical readers.

Business logic lives on the server. The client only renders.

Farm staff, on a laptop or phone
Managers record; the owner only reads
React app
One responsive app; shows only what the server returns
HTTPS /api
FastAPI backend
Sign-in and roles
Rotating tokens, rate limits, owner can't change data
Business rules
Stock, feed cost, payroll, reports and warnings
Audit log
Before and after of every change
PostgreSQL
All farm records, rules enforced by constraints
Redis
Report cache for 10 minutes, cleared when farm data changes
All rules enforced server-side
  • Ledger-based inventory. Balances are never stored. They are computed from stock movements, so they are reproducible for any date.
  • Exact arithmetic. Money and quantities use decimals throughout, never floating point. Eggs are stored as units and displayed as crates of 30.
  • Integrity at the database layer. Constraints such as "one log per pen per day" are enforced by PostgreSQL, independent of the UI.
  • Full traceability. Soft deletes, plus an audit log capturing the before and after state of every change.
  • Server-enforced roles. The owner's account is read-only at the API level, not just hidden in the interface.
  • Resilient and tested. Report summaries are cached in Redis and degrade gracefully without it. More than 200 automated tests cover the business rules.
An audit log entry showing a pen log's eggs before and after a change
One change in the real audit log, with test data.

Outcome

The farm now runs on figures it can trust.

Month-end reporting, generated on demand. Sample data.
  • Stock by grade, on demand. In its first week, the system recorded 3,382 crates and 22 pieces collected, fully broken down by grade. Before, that figure could only be estimated.
  • Month-end reporting: from two days to instant. Reports are generated on demand from the daily records.
  • One view of the operation. Stock levels, unreconciled items, missing logs and month-to-date performance all sit on a single dashboard.
The dashboard in the real app, showing stock, warnings, pen logs and the laying rate
The dashboard in the real app, with test data.

Reflection

The most valuable work happened before any code. Mapping the operation revealed data that had never been captured. No amount of automation would have fixed that.

Real operations are messy, and good systems accommodate that. Late data, human error and changing routines are normal. Warnings instead of blocks, a full audit trail and flexible records were designed around that reality, not against it.

Next: moving data entry to the source. Letting staff log reports directly would remove the retyping step, and the errors that come with it.