C.W.K.
Stream
Lesson 03 of 04 · published

The Multi-Year Layer

~9 min · multi-year, five-year-diary, on-this-day, near-free

Level 0Cold Hearth
0 XP0/34 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"The older the journal grows, the deeper the strata. Writing today's layer with last year's layer in view is the point."

An Analog Diary, Generalized

Dad keeps an analog five-year diary: a page for each calendar day, split into five bands, so this year's July 24 sits right above last year's July 24 and the three before it. You write in today's band with the previous years visible above it. Vesta generalizes that into the multi-year layer view: the same month-day stacked vertically across years, one layer per year, each holding that year's crumbs and draft for that date. Except it isn't capped at five — the window is configurable, and the older the journal grows, the deeper the strata get. Ten years in, July 24 is ten layers deep.

The value is the same one the paper diary discovered: writing today's entry with last year's in view changes what you write. You see the pattern, the anniversary, the way the same date rhymes across years. It's not nostalgia bolted on — it's a native shape of a journal organized by an open date axis, where 'the same day across time' is a natural query.

When the model is right, the rich feature is a query, not a subsystem. The multi-year view isn't a feature you build so much as a question you ask the store: 'give me every year's layer for this month-day'. Because crumbs live on an open date axis with a derived month-day index, that question is near-free. A good data model turns what would be a whole feature in a worse design into a one-line read.

Near-Free by Construction

Here's why it costs almost nothing. The projection model already keeps a derived SQLite mirror with a month-day index. The multi-year layer is just a query against that index: select every crumb whose month-day matches, group by year. There's no new store, no background job precomputing anniversaries, no denormalized 'on this day' table to keep in sync — it's a read over the same canonical crumbs every other view reads. This is the payoff of the previous two lessons compounding: because there's one store and a derived index, a feature that would be a real project elsewhere is a query here. (February 29 simply shows the years that have it — the query naturally returns fewer layers, no special case needed.)

A View Shape, Not a Notification

Note what Vesta deliberately does not do: it doesn't push you an 'On This Day' notification. Day One resurfaces old entries by interrupting you; Vesta delivers the same thing as a view shape you open when you choose to. On This Day is just a subset of the multi-year layer — one prior year instead of all of them — and it's pull, not push. That's the same journal-not-reminder-app boundary from the open-timeline track: the memory is there, deep in the strata, waiting for you to look. Vesta shows you the depth when you arrive; it never taps you on the shoulder to perform remembering.

Code

The multi-year layer is one indexed query·sql
-- derived SQLite mirror carries a month-day index (mm-dd)
-- the whole 'multi-year layer' feature: select by month-day, group by year

SELECT strftime('%Y', target_date) AS year, id, text
FROM crumbs
WHERE strftime('%m-%d', target_date) = '07-24'   -- same month-day
  AND journal_id = :journal
ORDER BY year DESC;                               -- newest layer on top

-- no 'on this day' table, no anniversary cron, no denormalized copy
-- Feb 29 just returns fewer rows — the leap years that have it

External links

Exercise

Think of an 'anniversary' or 'this time last year' feature you've seen. Would it, on a well-modeled store, be a background job with its own table — or just an indexed query grouped by year? Sketch the query version. Then decide whether it should reach the user as a push notification or as a view they open, and justify the choice for the product you have in mind.
Hint
If your data is on a clean date axis with an index, 'this day across years' is a group-by-year query, not a subsystem — the model does the work. And the push-vs-pull call is a product-personality decision: interrupt-to-resurface (push) suits an engagement app; wait-in-the-strata (pull) suits a journal you return to on your own terms.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.