Topic
Delivery & Evolution
Deployment, migration, maintenance, and reversible ways to evolve real systems.
One Project, Many Deployables: Drawing Boundaries by Runtime Role
Separate public, admin, batch, and operations workloads into runnable applications without splitting the whole codebase into separate projects too early.
Track Database Changes with the Work That Ships Them
Collect database changes with the issue and PR that need them, test them in development, and hand off the final release set before code deployment.
Software Is Not Done Until It Is Deployed
Stale pull requests and delayed releases make changes harder to review, deploy, diagnose, and roll back. Keep the path to production short and observable.
Rebuild First, Migrate Second
Design a replacement system around the problems it must solve, then handle legacy data through explicit migration mappings and retirement conditions.
Put Logic Where Change Is Cheapest: Client vs. Server
Place display-only work near the UI, but centralize meaningful or changing values when multiple clients and shipped app versions make updates expensive.
Don't Distort Production Code Just to Make Tests Easier
Change production code when its behavior becomes clearer or legacy code needs a testing seam—not merely to expose values or methods that only tests use.
Modernize Legacy Systems Gradually—and Treat Caches as Operations
Choose legacy boundaries carefully, change them in small steps, and add a shared cache only after DB work and deployment failure modes are understood.
Git History Is a Team Asset, Not a Work Diary
Split work before polishing commits, shape pull requests for reviewers, and leave a history that helps the next engineer understand changes and recover a release.
Upgrade Dependencies Before the Gap Becomes a Project
Frequent, prioritized dependency upgrades keep change small, expose compatibility problems early, and prevent a maintained service from quietly accumulating debt.