Before I offered legacy code documentation to anyone, I ran the method on a database I could show in public: Microsoft's AdventureWorks sample. One install script, about 6,600 lines of T-SQL, 71 tables, and 32 triggers, stored procedures, and functions. It produced a dependency map, eight findings tied to line numbers, and one catch that explains why the slowest step in the process is the one I will not skip.
I am Matt Shepard, a licensed general contractor in Colorado and the owner of Shepard Consulting. Every system I sell is one I run on my own work first. If you want this done on your system, here is the service. What follows is the practice run.
Why a sample database
AdventureWorks is a fictional company Microsoft publishes for learning SQL Server. Using it means nobody's private code is on display, and anyone can check my line numbers against the same install script on GitHub. Everything below describes the sample code, not any real company's systems.
One order line quietly writes to five other tables
Insert, change, or delete a single sales order line and a chain of triggers fires. The first trigger writes inventory history, updates the customer's lifetime spend, and recalculates the order total. That recalculation fires a second trigger, which bumps the order's revision number and updates year-to-date sales for the salesperson and the territory.
None of that is visible from the application. A migration that moves the tables but drops or rewrites those triggers changes totals and customer data without throwing a single error. That is the kind of thing a dependency map exists to catch before the move, not after.
Eight findings, each tied to a line number
| Finding | What the code does | Type |
|---|---|---|
| Year-to-date sales never update | The totals only count orders between July 2003 and June 2004, hardcoded in two functions. Every order in the sample data is dated 2022 to 2025. | Bug risk |
| Duplicate history rows | Editing one purchase order line writes one history row per line on the whole order. | Bug risk |
| Stale order totals after a delete | Removing a line does not recalculate the order SubTotal. | Bug risk |
| Customer spend drifts down | Any edit to a line, even a tracking number, subtracts the old total but only adds it back when product, quantity, price, or discount change. | Data drift |
| Silent failures | Two HR procedures log their errors and stop, so the calling application sees success. | Silent failure |
| A NULL check that never fires | A language parameter is compared with "= NULL", which is never true in SQL Server. | Bug risk |
| Rules that live only in code | Dealer price is fixed at 60 percent of list, and stock counts one storage location. Neither is in a table a business user can see. | Business rule |
| Status codes in three places | The meaning of "shipped" is defined in a display function and again as a bare number inside a trigger. | Business rule |
Reading code is not proof. Each finding in the report comes with the test that confirms or clears it, such as editing one line on a multi-line order and counting the history rows it writes. On a sample, the reading is the exercise. On a client system, those tests run against real data before anything goes into the deliverable.
The catch: 17 "unused" objects, one of them load-bearing
The first automated pass looked for code that nothing else in the database calls. It flagged 17 objects as possibly unused, which is exactly the list a migration team would love to skip.
Checking each name against the full script found that one of them, a small function that pads numbers with leading zeros, builds the AccountNumber column on every customer record. Delete it during a migration and every customer account number breaks.
That left 16. Those are still not cleared, because applications and reports call procedures from outside the database. Nothing calling it from inside is a lead, not a verdict. The last check is the database's own execution history. On the jobsite the rule is the same: you do not pull a wall until you know what it is holding up.
What a documented object looks like
Every object in scope gets the same one-page write-up, drafted with AI from the code, checked by a person, and signed off by whoever owns the business process:
- Purpose in one plain sentence
- Runs when, for triggers and scheduled jobs
- Reads and writes, table by table
- Business rules buried in the logic
- Depends on, so nothing moves out of order
- Known issues, linked to the findings
- Migration note, for example: move it as-is first, prove the totals match, then fix the bug as a separate change
- Verified by, with the test and the date, or marked pending
If you are planning a migration
- Inventory everything first: procedures, triggers, functions, scheduled jobs, and scripts outside the database
- Map what fires what, because triggers hide behavior the application never shows
- Pull business rules out of the code and confirm them with the people who own them
- Treat "unused" as a lead, and confirm it against execution history before deleting anything
- Move it as-is and prove the numbers match, then fix bugs as separate, tested changes
AI makes the first read fast. It does not make it right. The value is in reading fast and then proving each finding before anyone builds a migration plan on top of it.
Have a system nobody can fully explain anymore?
Tell me what you run and what is driving the move. Everything happens by email, and replies come within 24 hours from matt@shepardconsulting.ai.
Email matt@shepardconsulting.ai →Frequently Asked Questions
What is legacy code documentation?
It is the work of figuring out and writing down what an old system actually does: its stored procedures, triggers, scheduled jobs, scripts, and the business rules inside them. It is usually the first step of a migration, because nobody can plan a move for a system they cannot describe.
Can AI document legacy code on its own?
AI reads code quickly and is often right, and sometimes wrong in ways that sound sure. In this example the first pass flagged a function as unused that builds every customer account number. Every finding needs to be checked against the source and against how the system actually runs.
Is AdventureWorks a real company?
No. AdventureWorks is a fictional sample database Microsoft publishes for learning SQL Server. The findings describe the sample code, not any real company systems, and anyone can check the line numbers against the public install script.
Do you do the migration itself?
No. I document and map the system so whoever does the migration, your own team or a migration firm, starts from facts. I also work as a subcontractor for migration firms that need extra hands on the assessment phase.