01 — The Problem
The same checks, on every content type
A corporate CMS grows content types faster than it grows anything else. Each new one needs its payload validated, its editor authorised and its change recorded — and written per type, those become dozens of nearly identical blocks that drift apart quietly.
- Many content types, one set of rules about writing.
- A change record that no route is allowed to skip.
- The same behaviour on a laptop as on the server.
02 — What I Built
Two layers everything passes through
Validation and audit were pulled out into middleware that every route mounts. A content module is then only the logic that makes it different, and the whole service is described in Compose so the environment stops being a variable.
- Reusable validation middleware, applied before any handler runs.
- Reusable audit middleware, recording who changed what on every mutation.
- Express modules per content type over Mongoose models with a shared base.
- Docker Compose, from local development through to the deployed server.
03 — What Changed
A new content type is a route file
The rules arrive with the mounting rather than with the author's memory. And because the container is the unit of delivery, works-on-my-machine stopped being a category of bug.
- New modules inherit validation and audit by being mounted.
- Change history has the same shape across every content type.
- Local and production run the same image.