Jun 14, 2026

Designing the post repository before the posts

Why a content-source abstraction is worth its weight even when the only source is the filesystem.

This is a placeholder post that exists so the scaffold has a styled article to render. It demonstrates the prose layout, headings, code blocks, blockquotes, and lists that the future MDX renderer will reuse.

Why a repository

The post repository is an interface, not a class. The filesystem implementation reads markdown off disk; a future implementation might read from a database, a CMS, or a Git provider's content API. The pages don't care.

If you can't describe a module's job in one sentence, the module is probably doing too much.

A sketch

Here's the shape it'll take in TypeScript, give or take a Zod schema or two:

interface PostRepository {
  list(): Promise<PostSummary[]>;
  get(slug: string): Promise<Post | null>;
}

Open questions

  • How aggressive should the cache be at the page level?
  • Does generateStaticParams belong in the route or the repository?
  • What does a draft post look like to the build?

None of these are urgent. The point of this post is to make the scaffold real before any of them need answers.