Homeowners
Upkeep
The reminder that carries the part number you used last time.
Home maintenance on intervals, with the record of what was actually done. Pick a house type and get a proposed schedule, mark a job done in one hand under a sink, and print the whole history for a buyer's surveyor.
- Next.js 16
- TypeScript
- Supabase
- PostgreSQL
- Row-level security
- Private file storage
- Resend
- Scheduled jobs
- React PDF
- Magic-link sign-in
- Getting started
- A proposed schedule
- Every reminder
- Carries the part
- Overdue
- Stays overdue
by house type, then edited
from the last time you did it
no silent reschedule, ever
What was going wrong
Everything in a house has an interval, and none of them are written down anywhere. The boiler service is remembered because it is annual and invoiced; the gutters, the smoke alarms, the water filter and the drain rods are remembered the day after they mattered. And when the reminder does arrive, it says "replace the water filter" without saying which one, so the job gets postponed to a day with a hardware shop in it.
What we built
Start from a schedule rather than an empty list — nobody wants to enumerate their own house. Then make the completion record carry the detail: what was done, when, what it cost, which part, with a photo. That record is what turns the next reminder into something actionable, and four years of it into a document a surveyor will read. Overdue is a state the app refuses to soften, because softening it is exactly how the six-year gutter happens.
What it looks like
Every screen shown on a desktop and on a phone, because half of these are used standing up.
The house, today
What is overdue, what is due, and what is coming — with the part number on the row rather than one level down.
/house
Desktop capture
1440 × 900
Mobile capture
390 × 844
One job, and its history
Mark it done in one hand under a sink. Everything past the date is optional, which is why the history is not empty.
/house/t/[id]
Desktop capture
1440 × 900
Mobile capture
390 × 844
The schedule
Every job and how often, including the seasonal ones that anchor to a month rather than to a count of days.
/house/schedule
Desktop capture
1440 × 900
Mobile capture
390 × 844
The record
Four years of maintenance as a document, with photographs and part numbers. The thing you hand a surveyor.
/house/record
Desktop capture
1440 × 900
Mobile capture
390 × 844
What it does
A schedule you start from
Pick a house type and get a proposed set of jobs and intervals, then cut the ones that do not apply.
Reminders worth reading
The nudge carries the filter size or part number you used last time. That is the part a calendar cannot do.
Seasonal jobs
"Before the first frost" anchors to a month with a window and fires early in it, rather than being month arithmetic.
One-handed completion
Everything past the date is optional. A required field is how you end up with a house whose history is empty.
Before and after photos
Compressed in the browser before they are uploaded, which also strips the location data off them.
The record, as a document
Every job, date, part and photo as a PDF — the thing a surveyor or a buyer actually asks for.
Who reaches for it, and when
A new owner in month one
Picks the house type, gets a schedule, and finds out the boiler service is already four months late.
Under the sink on a Saturday
Marks the filter changed and types the part number, one-handed, in about fifteen seconds.
Selling four years later
Hands over a document of everything that was done, with dates and photographs, instead of a shrug.
What makes this one different
An overdue task stays overdue
It does not roll forward and it does not go quiet. The gutters that were skipped for six years were skipped one quiet reschedule at a time, and any change that lets a due date move without a completion is wrong.
The interval counts from when it was done
Servicing a boiler two months late must not compress the next gap. Counting from the due date is how a schedule quietly drifts into being wrong.
You cannot mark your own boiler fine
A task's state is derived, and a nightly job is the only thing allowed to write it — the database grant revokes that column from ordinary users. The screens recompute live state at read time rather than trusting the stored value.
One reminder per job, per due date
Enforced by a unique constraint, not by hoping. An overdue task keeps its due date, so the second night produces nothing, and an app that mails you every morning about the same gutters gets filtered to a folder.
Built with
What each piece is doing here — the people who read this section are usually the ones who would have to maintain it after us.
Next.js 16
The application framework. Pages render on the server by default.
TypeScript
Strict mode everywhere. A field renamed in one place fails to compile in the others.
Supabase
Postgres, authentication, file storage and realtime in one managed service.
PostgreSQL
The database. Constraints and permissions live here, not in the interface.
Row-level security
Who can read which row is decided by Postgres. A UI bug cannot leak data.
Private file storage
Photos and receipts behind signed URLs, namespaced so policies can check them.
Resend
Transactional email — invitations, reminders and sign-in links.
Scheduled jobs
Nightly work — reminders, recomputed state, and the demo reset.
React PDF
Documents generated on the server, identical every time they are made.
Magic-link sign-in
An emailed link instead of a password nobody can remember.
Want something like Upkeep?
It does not have to be your industry — the underlying problem is nearly always the same. Tell us how the work moves through your business and we will tell you what it would take.
Every project is quoted on its own. Turnaround starts at two weeks.