I was assigned to extend (and eventually maintain) a legacy system (mostly procedural, semi-ball of mud) without MVC. Any tips or suggestions for me going forward? :S
Start writing test for the code now, before you make changes. This gives you a baseline of the current functionality. You are going to have a hard enough time figuring out how to add in new features, you don't want to be spending time figuring out how what you did broke something. And that is if you find out you broke it.
The automated test will give you some semblance of confidence with the current state of things. It may even indicate a few things that don't work as expected now. But most importantly, it will tell you immediately when you did something that breaks something else. If a test fails after you check in a change, you will know where you changed things and where to look for issues.
Beyond that, get as much historical information as possible. If the last person who owned the code is still there, get as much information out of their head as possible. Hopefully the code is commented and there is documentation.
You should read the following book:
I heard Michael speek at a conference and bought his book for my whole team. It boils down to writing tests, but not your normal tests. You write tests that pass regardless as to whether they are right or not. What you are trying to do is create a verification that you didn't break any existing functionality whether that functionality is right or not is a decision for the support manager.
In the book he goes into details about how to modify existing code so it's testable. Creating mocks etc. It can be a long process, but after you have a set of tests that verifies existing functionality you can start refactoring the worst code.
I was able to improve an existing product that was a big mess like this. Home brewed controller that was more Model-View than MVC. In the end we had a far more stable product and was able to really improve the reliability of the system.
There are a few recommended practices depending on the rough shape of the ball of bandaids and the goals of the system.
If there is a database behind it all we have had some success with keeping the existing systems running in what ever mess they are in and doing the follwoing.
Minor tweak or correction. Fix it in the current mess.
As new larger scale (individual processes or subsystems) come along you can use these as the excuse to start migrating the system to a better world.
Create a new database and a stored view / stored proecedure layer to transform the OLD view of the world into the new view of the world (which you then program against) and a BUS to go back again. If you use the BUS to describe the intent of the users rather than the change of the data you can usually work out how to transfer the data backwards easily enough.
This allows you to build the new subsystems in your shiny new platform of choice. If its web/silverlight whatever you can, in most cases provide "launch points" from the old system that does something like
ShellExecute("NewApp;ParametersToDirectAppToNewFunction") or open in the browser to the correct URL (same concept different tech).
The old database remains the "single source of truth" for a while longer and you translate the data "Forward" into the new system automatically on triggers or pull from in when populating the new system (through an API layer in SQL or in Code).
Eventually you can eat away at more and more of the system until the old system isn't doing that much anymore and you can turn the old database and legacy system off.
NB. All of your reports should be made off the new API layer and never go directly.
This approach does require a good deal of both Business Domain knowledge and SQL / Data modelling work upfront and you need to be pretty good at performance tuning in order to make it viable ... if you good with all that, this works quite well.
If you have some say over the development schedule picking first "satellite" then "less core" screens / processes to remodel and replace, say 1 in every 3 "development sprints" will help you clear the backlog of the legacy and give you "Clients" the chance to revisit and improve the processes.