Contacts
Building a 3PL System From Scratch With Claude Code - Picture №1
01

Building a 3PL System From Scratch With Claude Code

Content:
Rate this article
Thank you for feedback!
5.0
Views: 13

When our team set out to build a third-party logistics (3PL) system for U.S. warehouse operations, we made Claude Code the main coding agent from day one and wanted to see how far a spec-driven workflow could take a project built from scratch. About 3 months later, the system is running in production, while a project of this size written by hand would normally take us around 6 months.


Most of that gain came from spec-driven development (SDD), where every task reached the agent together with the verified project context and clear rules for implementation and acceptance. The faster pace also changed the developer's role, moving attention toward architecture and review and leaving a shallower personal understanding of the generated code, a trade-off we look at closely later in the article.


Below, we share how we prepared the context and organized the work, how testing went, where the process broke down, and which practices we plan to keep on future projects.


Project 3PL system for U.S. warehouse operations, built from scratch
Main tools Claude Code for implementation, a second AI model for independent review of documents and task breakdown
Approach Spec-driven development with task cards stored in the repository
Timeline About 3 months from architecture to production
Status Launched in production

What the 3PL system includes

The system covers the client’s work with the warehouse from the first stock delivery to invoicing and payment. It consists of 13 modules:


Module What it covers
Dashboard An overview of the client’s account and current activity
Products The client’s product catalog
Inbound Shipments Stock deliveries sent to the warehouse
Inventory Current stock levels in the warehouse
Product report Reports on the client’s products
Orders Customer orders fulfilled from the warehouse
Stores Connected third-party stores
Import orders Orders that arrive by API from other platforms, such as Shopify
Returns Items sent back to the warehouse
Disposal Disposal of stock the client no longer needs
Invoices Invoices for warehouse services
Payments Payment of invoices directly in the system
Balance The client’s account balance

Why we needed a different approach

AI code generation has become standard practice in software development. Few teams write every line by hand anymore, and a growing share of code comes from AI agents working under an engineer's direction. For us, the open question was how to use AI well on a large project.


A new system needs dozens of consistent decisions across modules that don't exist yet, such as the layer structure, data model, API format, and testing rules. An agent that sees only the current task makes choices that look reasonable locally and clash later.


Our main challenge was giving the agent a complete, stable picture of the system. Spec-driven development handled this: the project's rules live in files the agent reads at the start of every session, and its work doesn't depend on any earlier chat.


Building the context the agent needs

Before writing any code, we gathered the material the agent needed to understand the client's business and our technical standards. It came from three sources:


  1. Business requirements. The technical specification for the 3PL system, with the business logic and functional scenarios behind the warehouse processes it must support.
  2. Our proven components. Ready-made modules and packages we rely on for specific functions, from layering conventions to standard features.
  3. Project documentation. The agent had access to project sources, including Confluence documentation, which enriched its context with extra detail on requirements and decisions.

From these sources, we produced two core documents that every later agent session relies on:


  • architecture.md: layers, classes, testing rules, API response format, and the overall project skeleton.
  • spec_db.md: the complete database structure.

Each AI tool had a clear role:


Tool Role in the project
Claude Code Studied our components and packages, then implemented the tasks
A second model with high reasoning (ChatGPT) Helped align the documentation and checked the task breakdown against the specification

Two days that set the direction

Initial architecture design and task planning took about 1 to 2 days. We clarified and manually reviewed every important output before moving on.


architecture.md

Working from the specification and our components, the agent described the layers, classes, testing rules, API response format, and overall skeleton. The first version contained a design mistake: it proposed a separate manager class for almost every controller method. We fixed this and other inaccuracies over several review iterations.


spec_db.md

In a separate chat, we built the complete database structure from the source materials and the approved architecture. The schema went through several generations and refinements before implementation started.


Large task cards

We split the full scope into about 24 to 25 domain or functional tasks, each with 5 to 7 subtasks. The first version was too detailed, so we revised the plan several times, adjusting the prompt and reworking the structure and content of the cards until we reached the final version.


We paid special attention to whether the tasks matched the specification. A second model with high reasoning reviewed the cards and subtasks independently.


By the end of this stage, we wrote down the architecture agreements, and the agent had a plan to follow for the rest of the project.


A task model that lives in the repository

We moved the plan straight into the repository. Backlog, active, and completed folders tracked the state of both large tasks and their subtasks. A large task card described the scope of work, while detailed subtask cards described how to implement it and how to accept the result.


tasks/
├── backlog/
├── active/
│   ├── domain-task/
│   │   ├── task-card.md
│   │   ├── backlog/
│   │   │   ├── 01-....md
│   │   │   └── 02-....md
│   │   ├── active/
│   │   └── completed/
│   └── quicktasks/
│       ├── fix-a.md
│       └── fix-b.md
└── completed/


The structure is illustrative, and file names are placeholders.


We worked with three types of cards:


Card type What it holds
Large task A domain or major functional block. The card at its root describes the expected result and lists the planned subtasks.
Subtask Created with a separate prompt. Has a defined scope, dependencies, implementation rules, and acceptance criteria.
Quick task A small business-logic fix kept as a standalone card, with no decomposition. Moves to completed after acceptance.

Each subtask card stated the goal and linked the relevant parts of architecture.md, spec_db.md, and the specification. Its acceptance criteria listed the required tests, API checks, and documentation.


A task changed state only after we verified its result in practice. This kept a long development process consistent and easy to resume between sessions.


The full cycle of one task

Every large task went through the same four steps, and each subtask was executed separately against its specification and acceptance criteria.


  1. Decomposition. The first prompt combined the task card, architecture.md, and spec_db.md and turned the large card into ready-to-run subtask cards.
  2. Implementation. Each subtask was moved to active in turn. The agent wrote the code along with unit and feature tests, and checked new API endpoints with cURL.
  3. The "-99" control step. A final subtask numbered "-99" ran an end-to-end check of the whole task and produced two reports.
  4. Review and completion. After checking the API contracts and business logic, we moved the task to completed and handed it over to the frontend team.
The full cycle of one task: decomposition, implementation, the -99 check, and review, with a fix loop back to implementation

The "-99" step produced two artifacts:


  • Frontend documentation: API contracts and expected responses, plus a description of the business logic in its final form.
  • A cURL check log: concrete requests to the local environment, with payloads, HTTP responses, and results.

When the review found an issue, the fix followed the same path: a new subtask card, implementation, a repeat check, and updated documentation.


Checks focused mainly on API contracts and business scenarios. This kept the results reliable, but the developer's full understanding of the generated implementation became a separate risk, which we cover below.


Automated testing: where it helps and where it stops

Claude Code generated unit and feature tests on its own and ran HTTP checks with cURL. This cut manual API work, and in many scenarios we needed Postman far less. The cost showed up later, when the growing test suite had to run.


We ran checks at three levels:


Level What runs
Subtask Relevant automated tests and API requests
Task ("-99" step) A final end-to-end check and the cURL report
Full regression The complete test suite

Full regression became the bottleneck, with a complete run taking several hours.


Incidents along the way

  • Disk overflow. Tests generated so many PDF files that the disk filled up and Claude Code stopped.
  • Local database loss. During some test runs, the agent deleted the local database.
  • Agent conflicts. Several agents running in parallel interfered with a shared environment and got in each other's way.

We found no serious errors in the business logic itself. The most visible failures involved the test infrastructure and the way agents interacted with shared state.


Why specifications are critical

An agent is limited by its working context and doesn't retain a full understanding of the system between sessions. Documentation became our way to restore the project's intent without rereading the whole codebase each time. However, outdated specifications can do more harm than having none at all.


Small early mistakes get expensive

At the start, the difference between two decisions looks minimal. Once dependent modules are built on top, fixing a field type or a layer boundary can require significant rework. Two practices helped:


  • Keep specs in sync with the code. Any client change that touches the structure or business rules updates architecture.md and spec_db.md together with the code.
  • Record why decisions were made. Explanatory comments in the code can capture why a non-obvious solution was chosen and which mistake future agent sessions should avoid. We haven't measured the effect yet.

Technical debt to watch

Even with the early design mistake fixed, the manager layer grew too large. It is a candidate for architectural review and possible refactoring.


Models and the limits of autonomy

The whole approach ran on standard prompts and file-based specifications, with no custom tooling.


Period Main mode How it was used
First 2 months Sonnet, medium reasoning Main implementation. Opus handled decomposition, complex decisions, and periodic code analysis.
Last month Sonnet, low reasoning Main code generation in a more economical mode to stay within weekly usage limits.

A clear line for Git and the server

The agent The developer
Read the Git state Created branches
Generated and changed code Committed and pushed to the repository
Ran local checks Connected to the server and ran git pull

The agent was not allowed to perform any Git action that changes state. Deployment and repository management stayed fully manual.


Results

All core features of the 3PL system are live in production. The project took about 3 months from architecture to release. Based on our experience with similar systems, building it by hand would have taken about 6 months, so the agentic approach cut development time roughly in half.


Large tasks also moved much faster:


Scenario Typical duration of a complex task
Before the agentic approach A week or more
3PL project with Claude Code 1 to 3 days

Most of the effort shifted from writing code to shaping the project: designing the architecture, refining specifications, preparing task cards, and reviewing results.


Where the approach worked best

  • New projects: maximum effect. A system built from scratch, with the architecture and database described up front and large tasks broken into subtasks.
  • Existing projects: a more modest effect. Fixes and small features based on standalone spec cards. The agent studied the code while working, without a new set of architecture documents.

These figures come from one project and our team's own assessment, without a controlled benchmark.


The trade-off: faster delivery, shallower understanding

Faster development came with a cost that matters more than any timeline figure: the developer understood the code less deeply.


The developer stayed in control the whole time, from writing prompts to accepting each task. Reviewing code, however, works differently from writing it. Writing code yourself builds cause-and-effect links in your head, such as why a class exists and what breaks if it changes. A review leaves a more surface-level familiarity, and some details or connections can slip past.


A developer who reads generated classes understands each piece but may struggle to explain every link and the full execution path. We treat this loss of end-to-end code ownership as a real risk and keep it in check with regular walkthroughs and architectural reviews.


Practical rules for agentic development

These rules sum up what we would carry into the next agentic project. Most of them concern the work around code generation, where this project's quality was decided.


  1. Design the system carefully. Documentation, architecture, the database schema, and task cards all need a thorough review. A mistake made at the start costs far more after dozens of tasks are built on it.
  2. Control tests and split test runs. Check which tests the agent creates. Use fast smoke tests and targeted checks for frequent runs, and schedule deep verification as a separate, less frequent run.
  3. Spot the need for refactoring early. Review generated code and layer boundaries regularly. A weak decision is easier to fix right away than after ten related tasks.
  4. Keep your understanding of critical code. After each major stage, walk through the key scenarios and keep the specifications in sync with every change.
  5. Protect the test environment. Isolate the test database and limit the files tests create. Give parallel agents separate environments to keep checks from damaging shared state.

Conclusion

The quality of agentic development depends first of all on decisions made before any code is generated. On this project, the agentic approach cut delivery time from an estimated 6 months to about 3 and helped us launch a production 3PL system. The price was a shallower personal understanding of the code, which we now manage deliberately.


Design carries the most responsibility. Current specifications and regular code review let a team use the agent's speed without piling up mistakes that become expensive to fix later.

Previous article Website Technical Support: What It Is, Why It Matters, and What It Includes
Let's discuss your project
By clicking the ‘Send’ button, you consent to the processing of personal data. Learn more.
Blog
#0000

Read more articles in our blog

What is PWA: Comprehensive Guide with Code Samples
26 Feb, 2024
Progressive Web Apps are web applications that bring best web and mobile features. PWAs are similar to native apps in functionality and can be used on any device with a web browser.
VIEW ARTICLE
Building a 3PL System From Scratch With Claude Code - Picture №11
Outsourcing and outstaff: difference and features
20 Jul, 2023
Modern companies often have a need for fast and efficient development of software and other IT projects.
VIEW ARTICLE
Building a 3PL System From Scratch With Claude Code - Picture №12
Website Development Costs: What to Expect
08 Jan, 2025
Are you curious about the cost of creating a website? Discover how design intricacies, advanced functionality, and the type of site you envision can impact your budget.
VIEW ARTICLE
YII vs Laravel: What is the Best Option for Your Project?
02 Jan, 2024
Thanks to technological development, it is no longer necessary to write PHP code from scratch: there are many frameworks — ready-made models, "templates" for software platforms, among which Yii2 and Laravel became the most popular. In what their difference and which of the frameworks to choose for creating a product? We tell and compare the structures in this material.
VIEW ARTICLE
 
Contact us
#0000

Got a question?

Please fill out the form below, and our specialists will contact you as soon as possible!
By clicking the ‘Send’ button, you agree to the processing of personal data. Click to learn more.
consultant
Tetiana
IT Consultant at Asabix