Health Data on a Public Page

Blog post #67


A year ago one of the kids had a symptom that came and went for a while and then stopped. At the time I wanted a record of when it came and what the day had looked like, and I did not have one. The health wiki I wrote about in post #64 is where that record should live. On Tuesday I asked Claude to build the diary part.

What shipped

A symptom log in the wiki. One markdown table, one row per person, track and day: date, who, track, a level from 0 to 3, a note. A track is anything worth following over time, and each of us has a few. Zero days get logged too, because a pattern needs the quiet days as much as the bad ones.

I dictate in the chat, one sentence per person. Claude writes the raw file, adds the rows, updates the article for that track, commits, opens a pull request and merges it. The rules went into the project’s instructions file, so any session can do it.

A scheduled task that asks. Every evening at half past eight, Claude Code opens a session, reads the day’s log, sends a notification and asks one question: how was today, for you and for everyone else. When I answer it logs, commits and republishes the page. It has run twice. The first evening gave me a row of zeros, which is the first real baseline I have.

A private page. The log is compiled into a small calendar: a month grid with one chip per person and track, coloured by level, eight weeks of track rows underneath, and the whole log as a table. It is published as a Claude artifact, which is private by default and can be shared with one person. That is the right shape for something two parents look at.

What’s unclear or broken

My first idea was the family calendar we already have on Vercel, a static page with our events and the kids’ weekly schedules. I asked Claude to show the symptom rows there as a health layer, one chip per day, coloured by severity. It took one session. It looked good. It was deployed to production before I remembered that the calendar has no login. Anyone with the address could open it. The family’s health notes were on the open web, next to the children’s weekly schedule.

I noticed a few messages later and asked for it to come down. The layer is still in the code with an empty data list. The export script no longer writes to the calendar repository, and the wiki’s instructions now say the health data never goes there, so a future session does not repeat the mistake. But I had asked for it, watched it happen, and read the summary that said “deployed”, and the problem did not register until the next message.

The second thing I found out that evening was that the calendar had no GitHub remote. Every commit was on my laptop only. I was sure it had been set up. It had not. It is a private repository now.

Decisions made

The calendar gets a login. That should have been true from the beginning, and the health scare made it unavoidable.

Google sign-in, with an allowlist of two email addresses. The site stays static. A small edge middleware checks a signed cookie on every request and sends everything else to a login page, and three serverless functions handle the round trip to Google. The OAuth app stays in Google’s testing mode, which means only the listed test users can sign in at all. For a family of two adults that is exactly the restriction I want.

The health data stays out of the calendar even now that it is locked. The calendar is logistics. The diary is medical. They have different readers and different consequences if they leak.

Tooling & process

The Google Cloud console is a wall of buttons, and I got as far as the consent screen before handing over. Claude drove the rest in my Chrome: test users, client, redirect address. When the client was created the console showed the secret once, in a dialog, and I did not copy it before the next navigation closed it. Google no longer lets you view a secret after that. Adding a new one is two clicks, and this time I copied it.

The plan was to keep the secret in 1Password and let the CLI read it into Vercel. The CLI integration timed out on authorization twice, so I pasted it into Vercel’s dashboard myself. The secret never went through the chat.

The test was Claude clicking through the login in my own browser: account chooser, consent, calendar. It works. Caroline opens the same address as before and picks her account.

Two loose ends. The Google console still shows a warning that the OAuth configuration is incomplete, while every field I can find is filled in. And the evening question only fires while the Claude desktop app is open; if it is closed at half past eight, it runs on next launch. So far that has been fine. I will find out whether it stays fine.


— Stefan