Management system

Pigeon Manager

Breeding records for pigeon lofts — Arabic-first, mobile-first, and strict about the rules that keep the records trustworthy.

Pigeon Manager — the dashboard, showing farm and bird counts, upcoming breeding rounds and a chart of the year's top pairs

In development — designed and built in-house

  • Ruby 3.3
  • Rails 8
  • PostgreSQL
  • Hotwire
  • Pundit
  • Chartkick

The problem

Breeders keep their records on paper or in a notes app, and the records they most need — which pair produced which bird, how many rounds a nest box has run, what a bird's ancestry looks like — are the ones a flat list cannot answer. The data also arrives in Arabic, on a phone, from people who are not going to tolerate a form that argues with them.

Modelled the way a loft works

A farm holds barns, a barn holds nest boxes, a nest box holds a pair, and a pair runs breeding rounds that move through laying, inspection, hatching and banding. Birds exist independently of pairs, because a bird is bought, sold and recorded long before it is matched with anything. Ancestry is held on the bird itself, so a pedigree is a walk up the records that are already there rather than a separate document to maintain.

Arabic search that actually matches

Arabic names are typed inconsistently by nature: three spellings of alef, two endings that sound the same, optional diacritics, decorative letter stretching. A plain search misses most of what the user meant. Both the stored value and the typed query are normalised inside PostgreSQL before they are compared, so a name entered one way is found when it is typed another.

Rules enforced twice

Every invariant that matters is stated in the application and again in the database. A nest box can hold one male at a time, held as a partial unique index rather than a check-then-write that two requests can both pass. A pedigree cannot loop back on itself, checked by walking the ancestry with a bounded depth so a corrupt record cannot turn a page load into an infinite climb. Validations catch these early and give a usable error on the right field; the constraints make sure they are true regardless.

Built for the phone

The interface is right-to-left throughout and laid out for a narrow screen first — the records are entered in the barn, standing up, not at a desk afterwards. Charts summarise hatch rates and activity per farm. Access is scoped to the farms a user owns, and an unauthorised request is answered as not-found rather than forbidden, so the application does not confirm that someone else's record exists.

What is not done

Stated plainly because it is part of the picture: the automated test suite has not been written yet, and the deployment configuration is still the generated default. The data model, the constraints and the interface are the finished parts.