Extending the base repository would have kept an unscoped findMany callable, and TypeScript cannot hide an inherited public method. Making the tenant id the first argument of every method turns a data leak into a compile error.
Eleven NestJS APIs, and the guard stack grew the same way in each: two guards, then three, then seven. What that progression teaches about ordering, and the fail-open bug hiding where row-level security met a permissive default.
Every endpoint returning the same envelope, success or failure — the response shape worth settling on, and the global interceptor and exception filter that enforce it in NestJS.
Why the default flat src/ falls apart once a project has real features, and the module-driven layout that replaces it — one directory per feature, with common, config and database kept alongside.
From an empty terminal to a working custom endpoint: installing the Nest CLI, reading the generated project, and how the controller and service split the work between them.