Rebuilding a Church Site: An Engineering Exercise in Patience
Not to ship it, and not to make money from it. Just to build one old thing properly, start to finish, with my own hands.
I have a side project: a full-stack rewrite of swedenborgwork.cn. The original was .NET 6 + Furion + SQL Server on a Windows box. I changed no requirements — I just rewrote it in React / NestJS / PostgreSQL and moved it to Linux.
The motivation is plain
Not for performance. Not to have one more line on a résumé.
It's to find out whether I can see one three-year-long thing through to completion on my own — from data-model migration and a full API rewrite, through deployment, monitoring and bug fixes.
Every decision in this project was mine to make, and the only person accountable for it was me. That feeling is hard to get inside a job.
Nothing here is technically impressive
The rewrite itself has no hard parts: SQL Server → PostgreSQL, reimplementing every endpoint, nginx deployment, moving an entire site off Windows Server. Each item is solved technology.
What actually ate the time was the detail nobody writes into a résumé:
- A daily cache-clearing cron job silently did nothing for three months because a Windows line-ending mismatch made
cmdskip it - Uploading a file with Chinese characters produced mojibake in the article body because
busboyparsedfilenameas latin1 - An unbounded fetch cache on the magnet tier exhausted file handles (EMFILE) and turned the entire site into unstyled raw HTML
That last bug took me a long time. The symptom was "the website suddenly broke"; the cause was a cache-design problem. The feeling was: production teaches you more than any book does.
What I took away
- Observability is not optional. How fast you can localize a problem depends entirely on how many traces you left behind. I now preserve "invalidated inferences" alongside every fix — it's invaluable later.
- Silent failure is scarier than crashing. The cache-clearing script ran for three months without error, which is exactly why nobody noticed.
- Performance problems are usually architecture problems. The handle leak was not fixable with an extra
close(); the cache boundary itself was wrong.
Why it lives under "Hobby"
Because it should not be considered work.
No KPI, no deadline, nobody chasing it. The only measure of success is whether I still want to maintain it next month.
I keep it here to remind myself that part of engineering ability comes from the things nobody asked you to do, that will never appear on a résumé, and that you still wanted to do properly.