This article is protected. Printing and print-to-PDF are disabled.Read the original at https://arincortex.hashnode.dev
Arin/ tech blogs

Chapter 20 of 20 · 4 min · 100% through

What I would tell you

Contents

If you are thinking about building one

A shorter chapter, and the one I would actually want to read.

Do not build this to save money. A hosted platform is cheaper than your time by an enormous margin. Build it because you want a shape a platform does not offer, or because the building is itself the interesting part. Both are good reasons. “It’s cheaper” is not one.

Decide where the wall goes, first. The single most valuable decision here was that the public front end has no editing surface, no login and no database connection, and meets the editor only at a folder of content files. Everything good that followed — deploying to a CDN, rewriting the editor without touching a page, content that outlives both — followed from that one line.

Make the content boring. Plain files, plain Markdown, a small metadata block. The most valuable property of this system is that if every piece of software in it disappeared, the writing would be completely intact and readable. Anything that makes content harder to read without your tooling is a mistake you will discover slowly.

Let each content type have its own shape. Articles are files. Books are folders with ordered chapters. Decks are folders with an ordered list of images. Forcing one shape onto all three would have made two of them awkward, and awkwardness in the content model shows up as friction in every module built on top.

Fail closed, everywhere. Anything not exactly “published” is a draft. New content is always created as a draft. Six independent layers enforce that one rule. It sounds excessive right up until you picture unfinished writing live under your name.

Write the guard so it can fail. The most useful thing I learned building this: a check that has quietly stopped being able to fail is worse than no check at all, because it reports success. One of mine did exactly that after an architectural change — the code it scanned no longer existed — and it went on passing for weeks. Now the guards check structure and source as well as output, and every important assertion is proven by breaking the thing it protects.

Verify the outcome, not the command. A deploy that prints nothing alarming has not necessarily deployed. A domain that resolves has not necessarily moved. Check the artefact — the deployed page, the live tag, the actual redirect — not the exit code of the thing that claimed to produce it.

Put the expensive work at build time. Diagrams are rendered once on my machine, not in every reader’s browser. Slides are images, not re-flowed components. Image dimensions are measured on upload, not calculated on render. Every one of those moves work away from the reader.

Be honest about the ceiling. The protection module cannot stop a determined copy and its own documentation says so. A feature that overstates itself is worse than one that does not exist, because it produces confidence that is not earned.

What I would do differently

Not much, structurally — which surprises me, because the system grew module by module rather than from a plan.

I would have built the deck module earlier. I spent a year turning material that wanted to be slides into articles with a lot of headings.

I would have written the outside-in verification before the first deploy rather than after the first mistake. Every operational failure in this system’s history was invisible from the inside and obvious from the outside.

And I would have started the tests at the interface tier rather than working up to it. The unit tests found real bugs; the tests that click things at real coordinates found the ones that would have embarrassed me.

The thing underneath

If there is one idea holding all twenty chapters together, it is the one on the cover.

The publication is mine — the words, the addresses, the history, the shape of it. The things that assist — the hosting platform, the rendering framework, the model on the other end of a connected interface — are rented, scoped, and replaceable. Each of them could be swapped for a competitor without the writing noticing.

That is not an argument against using any of them. It is an argument for knowing which half is which.

Own the context. Rent the intelligence.