On The 8 Spot

From inherited code to a documented, tested, load-tuned system in about five weeks

A case study in using Claude Code on a legacy web application

At a glance

Situation One engineer inherits two legacy PHP web applications for a client, with no handoff, no documentation and no automated tests
Approach Claude Code, directed in plain conversation, operating the environment, reading the code and verifying findings live
Window About five weeks from first to last session: 2 sessions over 5 active days, about 8 hours of active session time in total
Effort from the engineer 33 typed messages, about 600 words in total
Output About 26,000 words of documentation, 44 passing end-to-end tests, a load-tuned runtime configuration and a ranked review of risks

The situation

An engineer took over support of a long-running web application used by many external users to submit documents and by staff to review them. A second, sibling application handled a related workflow and shared the same database design. Both were built on an older PHP framework, both ran against a large database, and neither came with a handover pack. There was no runnable local environment, no written description of the roles and screens, and no test suite beyond the framework's own harness.

The goal was modest and urgent: understand the systems well enough to support them.

How the work was run

The engineer set one working rule from the start: stay in the conversation. No separate terminal sessions, no copy-pasting commands. Claude Code was asked to do the work directly, and to prove it.

  1. Read and map. Claude Code read the codebase and wrote a project guide describing the request flow, the domain model and the places where behavior branches by user role.
  2. Make it run. It built a containerized local stack and imported an authorized copy of the database, all from the chat.
  3. Look at it as users do. It logged into the running application in a real browser as each kind of user in turn (an administrator, staff, an external user), clicking through the main pages. Several behaviors that are hard to see in code turned up only this way, such as permissions that behave differently depending on a user's role.
  4. Write it down. From those walkthroughs came a user manual and a developer guide, each with screenshots, then a comparison against the client's existing manuals that listed the gaps.
  5. Review risks. A structured review produced findings ranked by severity. The details are deliberately not published here.
  6. Test it. A test plan was organized in tiers so the team could choose what to run by the time available, backed by a pytest and Playwright suite.
  7. Make it hold up. Production slowness was traced to configuration, not code, and the fixes were measured.

Timeline

When What happened Typed messages Claude responses
Day 1 Code read, project guide written, local stack running, database imported 2 38
Day 2 Role walkthroughs, manuals, comparison, risk review, test plan 18 488
Days 16 to 19 Sibling system brought up and documented, test suites built, slowness diagnosed and load tested 11 683
Day 36 Short handoff review 2 5

The numbers

Counted from the saved session transcripts, through the end of the engagement window:

Measure Value
Messages typed by the engineer 33 (about 100 characters each)
Claude Code responses 1,214
Tool actions (commands, reads, edits, browser steps) 1,363
Active session time about 7 h 55 m
Responses per typed message about 37
Words of documentation produced about 26,000, against about 600 typed

The densest session was the one that stood up the sibling application and tuned both: 8 typed messages produced 664 responses.

The slowness: three defaults

Under heavy load, both applications dropped requests. The causes were three configuration defaults, not application code:

After the fixes, dropped requests in the load tests fell to zero and median response times fell several-fold. The pool settings were made configurable per environment, and worker counts were sized from measured per-worker memory against the production hardware profile.

A caveat the team put in writing: these measurements came from a development machine, not production hardware. They show the cause and the direction of the fix, not a guarantee, and a repeat on the real target was listed as an open item.

Where it was wrong, and how that was caught

The most useful part of the process was how often a first answer was checked and changed:

Each correction was recorded, and the lessons were saved to the project's memory so that later sessions started from them.

What was left open

Takeaways

  1. Operate, don't just advise. The biggest gain came from Claude Code running the environment itself, which made every later step verifiable.
  2. Verify live before you write it down. Findings tested against the running system were more accurate than findings inferred from code, and the corrections were cheap to make early.
  3. Documentation is a by-product of the work. The manuals, guides and test plan came out of the walkthroughs rather than after them.
  4. Write the caveats down. The open items and the hardware caveat made the results more credible, not less.
  5. Keep the thread. Saved project memory meant a status check weeks later could report what had changed and what was still open without re-reading everything.

About these numbers

Message, response and tool-action counts come from the session transcripts and cover the engagement window only. "Active session time" adds up gaps between events of 30 minutes or less. Performance figures are from a single development machine and should not be read as production results.