1. Work
  2. Web and product engineering

Self-running daily reading and reflection app (two versions)

A daily reading and reflection app that assembles each day before anyone wakes, never shows half-built content, degrades visibly on failure, is designed around free-tier allowances, and was rebuilt when the first platform could no longer carry it.

Problem

A small private group of readers wanted a short daily reading, a written reflection and an audio version waiting every morning, with nobody paying for hosting or doing anything by hand. The site that publishes each day's reading schedule has no data API, and on some mornings a plain request is refused. Partway through, the preferred hosted AI provider began refusing requests without warning. With a single failure path, any of this meant a blank day.

Goal

Assemble the day automatically before anyone wakes, never show wrong or half-built content, degrade visibly when something fails, design around free-tier compute, AI and storage allowances, and decide honestly when the first platform could no longer carry the app.

My role

Product owner and builder of version one, working with an AI coding assistant, including independent model reviews of the codebase and the decision record that led to the rebuild. Sole designer and engineer of version two: architecture, fetching and parsing, AI integration, audio pipeline, security model, test suite and gated deployment.

Solution

Version one ran on a serverless script platform with a spreadsheet as its data store, a custom signed-token login and routed question answering. Version two is a serverless edge application whose scheduled jobs build the day in stages, with a separate fallback chain at every fragile point (fetching, AI generation and audio), strict all-or-nothing rules for the essentials, and a private front end behind a shared access code.

How it works

Version one. A nightly job fetched the day's schedule page with a browser-like client and backoff, fell back to the publisher's feed when a request was refused, parsed irregular multi-part reference strings into structured references, fetched the texts from an open API, and asked a language model for a short reflection under strict length and tone rules while avoiding recently used stories. Every external call was counted against configured limits. The written decision record compared staying put against four families of platforms, using two independent AI reviews of the real code, and chose an edge worker with a small SQL database for real local testing, one-step deploys and scheduled triggers.

Version two.

A few scheduled runs fire each day. The first builds the day; later runs are cheap retries that fill in only what failed.

The schedule is found through three isolated routes in order: a plain request, a headless-browser fetch that renders the publisher's public daily page, and a syndication feed that publishes later. A route succeeds only if its output parses into a valid structure. Parsers are pure functions tested against saved real pages.

The reflection comes from a model ladder for provider redundancy: the preferred hosted model, then a second provider, then an open-weights model hosted on the edge platform itself, so one provider's outage never leaves the day without a reflection. A rung without credentials is skipped, and a refusal that a retry cannot change is not retried.

The essentials are all-or-nothing. If any of them fails, no record is written, and the page shows the most recent complete day under a clear notice.

Everything else degrades on its own: secondary readings, a curated short story matched to the day's theme, a screened current-events link threaded across the week, and audio synthesised at the edge within a character budget sized to the free daily allowance, stored as a real audio track that plays from a lock screen.

Access is a shared code that mints a signed bearer token, with constant-time comparisons and brute-force limits that group IPv6 addresses by their routed prefix, so one network cannot spread attempts across many addresses.

Technical challenges

Fetching from a source with no API that intermittently refuses plain requests, without ever showing wrong content.

Redesigning the AI step around a ladder that depends on no single provider after the preferred provider began refusing requests.

A locale-data quirk in month abbreviations that would silently have disabled the feed fallback for a whole month.

HTML entity edge cases that silently dropped a section of the page.

Fitting text-to-speech into a free daily budget by measuring real content lengths.

Stopping a model from inventing plausible but unsupported details.

In version one: no local testing on the platform, and deployed code that had drifted from the repository because deploys bypassed version control, which became evidence for the migration.

Capabilities

  • Automated daily content pipeline
  • Three-route fetching with a last-known-good fallback
  • Multi-provider language model ladder
  • Structured reference parsing
  • Screened, threaded current-events links
  • Curated story matching
  • Edge text-to-speech with a budget cap
  • Grounded question answering from an approved reference set
  • Private access-code login
  • Usage view against free allowances
  • Light and dark themes
  • No third-party requests on page load
  • A documented, reviewed platform migration

Technology

  • Serverless script platform with time-driven triggers
  • Spreadsheet data store
  • Free-tier language model API
  • Open text API
  • Signed session tokens
  • JavaScript on a serverless edge platform
  • Versioned migrations on serverless SQLite
  • Key-value storage
  • Headless browser rendering and scheduled triggers
  • Web Crypto
  • Hosted language model APIs
  • Edge-hosted open-weights model
  • Edge text-to-speech
  • Vitest
  • CI deploys gated on the full test suite

Impact

Version one ran daily at zero hosting cost and produced the evidence and written reasoning for the rebuild. Version two delivers the day unattended, survives refused requests and provider outages without showing wrong content.

Skills demonstrated

  • End-to-end product delivery
  • Resilience engineering and graceful degradation
  • Robust parsing of irregular markup
  • Failover across language model providers
  • Prompt governance
  • Serverless edge architecture
  • Fixture-based parser testing
  • Security hardening
  • Designing around quotas
  • CI/CD with test gates
  • Architecture decision records
  • Knowing when to re-platform

All work