Vince Altavilla

GroovyBaby

A baby log shared by everyone who looks after the child, which turns the feeds, sleeps and diapers already logged into a forecast of the next nap, feed and bedtime.

Flutter, Material 3, Riverpod, GoRouter, Firebase Auth, Cloud Firestore

Mobile app In development

What it solves

Most baby trackers answer “what happened?”: the last feed, the last sleep, today's diaper count. The question a tired caregiver actually has is “what's next?” A nap that started at 1:15 means a wake-up around 2:45 and a feed soon after, and that arithmetic should not live in anyone's head. The log is also rarely one person's: parents, grandparents and a nanny all write to it, sometimes from different time zones.

How it is built

Events live in one flat Firestore collection scoped to a family, with owner, caregiver and viewer roles enforced in security rules, and every event stores the IANA time zone it was logged in. The forecast engine is pure Dart: an architecture test fails the build if it imports Flutter or Firebase, so every prediction is unit-tested against synthetic event lists and an injected clock.

Each prediction blends population age norms with the baby's own history. Personal statistics are an exponentially weighted mean with a seven-day half-life, because babies change fast and a nap from five weeks ago is weaker evidence than one from this morning. The weight on that personal estimate grows with the number of samples, w = n / (n + 5), so a newborn gets clean age norms and a well-tracked six-month-old gets a forecast that is essentially their own pattern, with no threshold and no visible switch.

Weight on the baby's own data rises with samples logged: 50% at 5, 67% at 10, 80% at 20, 91% at 50. 100%50%0% 01020 304050 50%67% 80%91%
Share of each forecast drawn from the baby's own history, by number of logged samples. The rest comes from age norms.

The hard decision

Naps and night sleep are separated before any statistic is computed, and the split is never stored.

Mix them and the forecast quietly breaks: one ten-hour night dropped into the nap samples drags a 75-minute nap prediction toward four hours. A sleep counts as night if it starts between 18:00 and 05:00 in the time zone it was logged in, not the viewer's, so a grandparent three zones away does not turn bedtime into a nap. The label is derived on read rather than written to the database, so when the rule turns out to be wrong for some family, it can be corrected without a data migration.

What it taught me

“Builds clean” and “runs” are different claims. The first phase was signed off on a web build that compiled with zero analyzer errors, and the app still threw on launch on every platform, because Firebase had never been configured. The same lesson runs through the forecast design: every prediction carries its basis and sample count, so the screen can say “based on her last 12 naps” instead of asserting a time. A prediction a caregiver cannot interrogate is one they will not trust.

Back to all projects