Public
Longitudinal indoor-garden tracker; embeddable snapshots
Val Town is a collaborative website to build and scale JavaScript apps.
Deploy APIs, crons, & store data – all from the browser, and deployed in milliseconds.

farm-log

A longitudinal tracker for my indoor Kratky garden. Each phone-call check-in becomes a dated snapshot file — old snapshots are never edited, so the record builds up over time instead of getting overwritten. Posts on my site embed a snapshot via <iframe>.

Routes

  • / — timeline of all snapshots + the latest one inline
  • /s/:date — one snapshot, with "what changed since last time" once there's history
  • /embed/:date — chrome-less view for embedding in a blog post
  • /api/snapshots, /api/s/:date — JSON
  • /source — this code

Embedding in a post

The personal-site renders an iframe code-fence. In a blog post:

```iframe height=560
https://charlies-farm-log.val.run/embed/2026-06-14
```

Older posts embed the default deployment URL (https://dcm31--6ac4f166685411f1858c1607ee4eb77e.web.val.run/embed/<date>). That URL still resolves — adding the custom domain didn't disable it — so existing embeds keep working. New posts should use the charlies-farm-log.val.run form.

Logging a new snapshot (the call-in flow)

When I get back on the phone and describe the garden, the AI:

  1. adds data/<YYYY-MM-DD>.json (a new file — never edits the old ones), and
  2. adds that date to SNAPSHOT_DATES in data/loader.ts.

Plant keys are stable across snapshots, so the same plant can be followed over time and diff() can show what changed. Snapshot schema:

{ "date": "2026-06-14", "title": "Pre-trip inventory", "note": "…", "plants": [ { "key": "tiny-tim-40l", "name": "\"Tiny Tim\" dwarf tomato", "type": "Fruit", "vessel": "The prize pot", "volL": 40, "status": "About to flower", "flags": ["star"] } ] }

flags: "star" (highlight) and "attention" (needs care — shown with ⚠). volL may be null.

Files

  • main.tsx — Hono server + all views
  • data/loader.ts — reads snapshot files, sorts newest-first, computes diffs
  • data/<date>.json — one snapshot per file

Not here yet (on purpose)

Crons/reminders, photos, succession scheduling, and any multi-user/login stuff — this is just for me, kept deliberately small.