Writing the .NET record DTO first, then the matching TypeScript
interface, felt like double work at the start. It paid off fast.
Because both sides use camelCase JSON (JsonNamingPolicy.CamelCase +
JsonStringEnumConverter), there's zero mapping glue — and when a shape
drifts, the TS compiler catches it the moment I touch the frontend. The
discipline of "DTO before UI" kept the API honest.
This one burned an afternoon. A hidden input holding a derived JSON blob
kept reverting after a Server Action re-render. The fix: never trust
defaultValue for derived state — use a controlled value=.
Uncontrolled hidden fields are not safe across action round-trips in
React 19.
The Resend key and a placeholder JWT signing key ended up committed
before the security pass. Lesson: wire up .env.example + a real secrets
story on day one, not as a hardening afterthought. Rotating a leaked key
is always more annoying than never committing it.
The first version just minted a JWT and called it done. A real login needs lockout on repeated failures, 2FA at the API layer (not just the UI), and security-stamp revocation so a password change actually kills existing sessions. Each of these is small on its own; skipping them quietly leaves the door open.
The robots.txt route broke because it exported both revalidate and
force-dynamic — incompatible directives that Next.js won't let you
combine. The error message wasn't obvious. Takeaway: route segment config
isn't a free-for-all; pick one caching strategy per route and read the
constraints.
Creating a non-root user in the backend image needed actual
groupadd/useradd, not a hand-waved USER line. Containers still want
a valid uid/gid that owns the app files, or the process can't read its
own working directory.
Getting Next.js to trust the ASP.NET dev cert (via NODE_EXTRA_CA_CERTS)
is fiddly and machine-specific — the path is hardcoded per dev. If I
started over I'd script the cert export so onboarding isn't "edit this
path in package.json."
Shipping v1 meant naming these out loud rather than pretending they didn't exist.