Events In use

Party Invite App#

Self-hosted invitations and RSVPs, with no corporate platform in the middle.

A web app for running private events end to end. Create a party with a poster, invite guests privately by passcode-protected link (or open registration to let them sign themselves up), then collect RSVPs with adult and child head counts, guest lists, and notes, all managed from an admin console.

Wrap Up records who actually showed up (whether or not check-in was ever switched on), logs presents against the guests who brought them, and turns each invite page into a thank-you: one shared message, plus a personal note per guest that follows it or replaces it. The photo album and activity wall stay open afterwards, which is what keeps people coming back to the page.

Built security-first, because event data is personal: argon2id-hashed passcodes, signed httpOnly sessions, a CSRF token on every mutation, RSVP responses encrypted at rest, login lockout after repeated failures, and a full admin audit log. Role-based admin accounts with granular permissions. Admins can sign in with a passkey through my self-hosted Pocket ID, and a small read-only MCP server lets Claude answer “how many are coming?” for a linked admin. Ships as a Docker Compose stack with encrypted backups.

NodeFastifySQLiteTypeScriptAngularMaterialTailwindMCPOIDCPocket IDDocker
  • Private passcode invites & open self-registration
  • RSVP with adult/child counts & guest lists
  • Poster upload — portrait & landscape
  • Granular admin roles & permissions
  • Encrypted-at-rest guest data
  • Email / SMS invite sharing
  • Wrap Up: who showed up, presents, thank-yous
  • A personal thank-you note per guest
  • See who opened the invite or the thank-you
  • Passkey SSO for admins via Pocket ID
  • Read-only MCP server for RSVP totals
Household In use

Family Status Board#

A shared kanban board for the whole household.

A self-hosted task board for family and personal work: shared kanban columns, recurring and scheduled tasks with rotation between family members, per-user accounts and roles, and an installable, mobile-first PWA so it lives on everyone's phone. Points, rewards, approval flows, and streaks turn chores into something the kids actually engage with.

It has also moved onto the kitchen wall. A parent can turn any tablet into a shared display: the family's day for whoever walks past, with nobody signed in, and view-only until someone taps Edit, picks their name and enters their own PIN or draws their own 9-dot pattern. For the next minute the tablet acts as that person: a kid ticks off their chores, a parent's tick approves and pays out the points — and then it locks itself. Left alone it settles into an ambient view: a clock and the next eight hours, as large as fits. Subscribed calendars feed the same picture — paste a private iCal address from Google, iCloud or Outlook and its events appear in a schedule band on My Day, Family Day and the wall, with tomorrow previewed alongside.

The wall is its own principal, not a parent left logged in: enrolling a display replaces the parent's session on that browser, and the device can read only an allowlisted, kid-safe view — parent-only tasks never reach it, even while a parent is editing. A PIN or pattern is not a password. One route accepts it, only from an enrolled display, and what it buys is an elevation the server times — sixty idle seconds, ten minutes at most — with waits that double after three wrong tries. Change the enrolling parent's password and their displays disconnect. Calendar addresses are handled as secrets: encrypted at rest, write-only after save, fetched server-side behind SSRF checks, with private events dropped at parse time and a per-calendar switch that keeps one off shared displays.

It now talks to Claude. A remote MCP server lets Claude Code and Claude on the web, desktop and phone read and update the board as a linked parent (tasks, recurring chores, approvals, points), and four MCP App cards render inside the conversation itself: the family's day at a glance, a one-tap confirm, and new-task and edit forms the model fills in and a parent finishes by hand. The model drafts; the person taps.

The server is an OAuth 2.1 resource server, never an authorization server: access tokens come from a self-hosted Pocket ID identity provider and are checked on every request — signature, audience, lifetime, scope — then mapped to a board user only through an explicit account link, never by email. Parents only, decided by the board's own role on every call; separate read and write scopes; every change audited with the client and tool that made it. The same Pocket ID backs Sign in with synchala — passkey single sign-on over OIDC with PKCE, bound to the browser that started it — offered alongside the password login, never instead of it, so the kids' tablets carry on as they were.

A sibling to the party app, sharing the same conventions — cookie-session plus CSRF auth, encrypted-at-rest PII, in-code forward-only migrations, encrypted SQLite backups, and Gitea CI/CD. Tags, email notifications, and per-user themes round it out. Runs on the Bun runtime end to end.

BunFastifybun:sqliteAngularSignalsMaterialTailwindPWAiCal feedsMCPMCP AppsOAuth 2.1OIDCPocket IDDocker
  • Shared kanban for family & personal tasks
  • Recurring / scheduled tasks with rotation
  • Points, rewards & approval flows
  • Per-user accounts, roles & themes
  • Streaks, tags & email notifications
  • Installable mobile-first PWA
  • Remote MCP server for Claude, parents only
  • Interactive MCP App cards in the chat
  • Passkey SSO via self-hosted Pocket ID
  • Subscribed iCal calendars in the day view
  • Shared wall display for the family tablet
  • Per-person PIN or pattern to edit on the wall
  • Ambient clock with the next eight hours
Learning In use

Family Music Recaps#

Turning weekly lesson notes into practice exercises.

Live and in use at home. A single-family app that turns a kid's weekly music-lesson notes into AI-generated practice exercises, complete with real notation, guitar tab, chord diagrams, and audio playback (all via abcjs), across violin, piano, and guitar. Parents administer student profiles and lesson logs; kids log each lesson in their own words and ask for something to practice.

Claude enriches the raw notes into concept tags and kid-friendly memory aids, then writes exercises that build on lesson history instead of repeating it. Music teachers get their own read-mostly accounts by one-time invite link; they see only the students a parent assigned them, and may suggest a rewording rather than edit a child's own words. Anything a child asks that touches pain, posture or instrument setup is routed to a parent instead of answered by a model.

BunFastifybun:sqliteAngularMaterialTailwindabcjsClaude APIDocker
  • Lesson logs in the kid's own words
  • AI exercises with notation, tab & playback
  • Multi-student, multi-instrument profiles
  • Invited teacher accounts, scoped & read-mostly
  • Safety triage routes to a parent, not a model
  • Printable practice packets
Agriculture Live · in use on the farm

Dairy Repro Analytics#

Herd reproduction, rebuilt from the raw exports because the spreadsheet was broken.

Live since September 2026, running on the herd's real data. Reproduction analytics for a working dairy: it ingests the herd software's raw exports (every dated event, plus the whole-herd inventory going back sixteen years), reconstructs each animal's breeding history from them, and reports heat detection, conception and pregnancy rate over time and across cohorts. It replaces a quarterly workbook whose formulas had drifted: whole rows of #REF!, a quarter of #DIV/0!, and a herd pregnancy rate counting heifer pregnancies against cow-only eligibility.

The arithmetic was never the hard part; the definitions were. Every rate is computed on the 21-day estrus cycle, the actual unit of breeding opportunity, so a month and a quarter answer the same question at different resolutions. Truncated periods are clipped and labeled, recent cycles are marked provisional and refused as a headline, overlapping imports layer rather than double-count, and every figure carries the derivation run and ruleset that produced it. Where the data can't support a number, it says so.

Since going live it has grown past the dashboard. A breeders report gives conception rate by the person who did the insemination, each on a one-page printable sheet with the herd's figures for the same dates beside it, so a small or unlucky run is not read as a verdict on anyone — under twenty resolved services is shown but not judged. A breeder can have an account that sees only their own results. The dashboard can set any period against the one before it or the same dates a year earlier, and says so when the baseline is too weak to lean on. Sign-in is by passkey through my self-hosted Pocket ID, alongside the password.

Node 24pnpmFastifybetter-sqlite3ZodAngularSignalsSVG chartsTabulatorTailwindOIDCPocket IDDocker
  • Every rate on the 21-day cycle basis
  • Event replay from the raw herd exports
  • Data-quality queue, held-back findings explained
  • Cell-by-cell workbook reconciliation
  • Per-animal file: events, services, outcomes
  • Printable & CSV reports, stamped with their basis
  • Conception rate by breeder, one printable sheet each
  • Breeder accounts that see only their own results
  • Compare a period with the previous one or a year earlier
  • Passkey SSO via self-hosted Pocket ID
Schoolwork Live · in use at home

little by little#

Weekly practice flashcards for math facts, spelling and vocabulary, at a kid's own pace.

The newest one. Weekly practice flashcards for my kids: math facts, spelling words and vocabulary, one set per kid per week. A parent decides which kinds of practice each kid has and builds the week; kids sign in, see only their own published week, and turn cards over. It started as a static prototype, and the real app keeps the prototype's card: think it through, then tap to reveal. There is deliberately no score, no timer and no streak: a kid presses I practised when they are done, and a parent sees when, and which cards were turned over.

Since launch it has learned to talk and to show its working. With listen and type on, a spelling card keeps the word off the front: the kid presses Play, hears it (in its sentence, when the teacher gave one) and types it, and the card turns over to show the word beside what they typed. A missed word comes back later in the sitting. The words are recorded ahead of time by a small self-hosted text-to-speech service, so they sound the same on every tablet, with the device's own voice as the fallback. A parent picks the voice — each listed with its recording-quality grade, with a sample to hear first — and the speed, per kid or for one week, and can respell a word that comes out wrong (“skrimble”, said as “skrim bull”). Work it out turns a math card into a small worksheet: the problem stands in columns, the kid types one digit per box on an on-screen keypad, with room for carries, borrows, partial products and guided long division, then checks the answer digit by digit. Hint points at the next step without giving it away. Only the final answer leaves the device, and a parent sees which words and facts need work — never a score.

Spelling and vocabulary words live in a library and are linked into weeks, so a word is entered once and reused. Or not typed at all: a parent can photograph the teacher's sheet and Claude reads it into draft cards, transcribed as printed, never paraphrased or filled in. Anything it could not read, was not sure of, or suggested on its own is flagged, and nothing reaches a kid until a parent has checked the draft against the sheet and accepted it. Math facts are never stored: each sitting deals fresh cards from the ranges and operations set for that kid, or for that week. Sign-in is a local password, with passkey single sign-on through the same self-hosted Pocket ID as the family board.

Node 24pnpmFastifybetter-sqlite3ZodAngularClaude APIKokoro TTSOIDCPocket IDVitestPlaywrightDocker
  • Math facts, spelling & vocabulary, switched on per kid
  • A week per kid: draft, published, archived
  • A photo of the teacher's sheet becomes draft cards
  • Every AI draft checked by a parent before a kid sees it
  • Highlighted letters and named patterns on spelling cards
  • Math cards dealt fresh from per-kid ranges
  • Listen and type: hear the word, spell it
  • Words pre-recorded in a chosen voice and speed
  • “Say it as” for words the voice gets wrong
  • Work it out: column math on an on-screen keypad
  • Self-reported practice log: no scores, timers or streaks
  • Passkey SSO via Pocket ID; a password always works

These are personal projects, built and self-hosted on my own infrastructure.