TDK CLI in Practice: Dependencies and Debugging Across 20 Services in the ERP Sales Stack

TDK CLI manages 20 sales microservices, emphasizing dependency order and end-to-end flow testing.
This article introduces the composition and operation of the sales stack in the tdk-erp-system sample. The sales stack contains 20 resources, covering the full sales cycle: leads, opportunities, quotes, pricing, orders, payments, and forecasting. Use `tdk up sales` to start the stack, and preferably preview the startup plan with `--dry-run` first. Services declare dependencies via `dependsOn`, and TDK starts them in topological order to avoid request failures caused by incorrect startup order. The core principle is to test complete cross-service flows rather than isolated services—for example, starting from crm-api on port 4300 and verifying steps such as creating a lead, converting it, and requesting a quote in sequence. Use `tdk status --json` to check readiness and `tdk logs --json --service` to view logs. Finally, use `tdk down` to stop the stack and free ports.
In an ERP system, sales is one of the busiest domains: leads turn into opportunities, opportunities turn into quotes, quotes turn into orders, and orders involve pricing and payment. The sales stack in the tdk-erp-system sample contains 20 resources. This article explains how these services relate to one another and how to use TDK CLI to inspect a complete flow.

What Makes Up the Sales Stack
The sales stack is organized around the sales cycle, with core services each handling a specific job:
- lead-management-api: tracks leads
- crm-api: manages customer relationships, running on port 4300
- opportunity-api: tracks the deal pipeline
- quoting-api: generates quotes
- pricing-api: manages prices
- order-management-api: handles orders
- sales-forecasting-api: sales forecasting
The remaining services include payment-processing-api (payment processing), territory-management-api (territory management), and sales-portal-api (customer portal), collectively covering payments, territories, and customer-facing entry points. This microservices architecture, split by business capability, lets each service evolve independently—but it also introduces complexity in the dependencies between services.
Starting the Sales Stack
Run the following from the repository root:
tdk up sales
If you've modified a service.json, it's a good idea to add --dry-run first to preview the startup plan:
tdk up sales --dry-run
This habit helps you catch configuration errors early and avoid services failing halfway through startup. For a stack with 20 resources, a dry-run is almost mandatory.
Dependency Order Is Key
There are clear dependencies among the sales services: quoting needs pricing, and orders need customers. Each service declares its dependencies via dependsOn, and TDK starts services in that order.
If the quoting service starts before pricing is ready, its first request will fail in a confusing way. So whenever you add a service, be sure to check its dependency list—this is the most easily overlooked detail when maintaining the sales stack. Dependency declarations are not only a guarantee of startup order but also part of the service contract.
dependsOn is the field in TDK that declares service startup dependencies, defined in a service's service.json configuration. When starting a stack, TDK parses the dependsOn of all services, builds a directed acyclic graph (DAG), and determines startup order via topological sort. If there is a circular dependency between two services, TDK reports an error and aborts startup. dependsOn only guarantees startup order; it does not wait for the dependent service to be fully ready (health check passing). Therefore, services still need to implement retry or wait logic internally. In addition, dependsOn is also used to stop services in reverse order when stopping the stack, ensuring that dependents are stopped before the services they depend on. Using dependsOn correctly is the foundation for consistent startup in a microservices architecture.
Inspecting a Flow End to End
Don't test a single service in isolation; instead, pick a complete path—for example, "create lead → convert → request quote"—and check each step along the way.
First call the health check route, then call the endpoint that actually performs the business logic. Since other services look up customers through crm-api, it's best to start with crm-api on port 4300.
When something fails, read the logs of the corresponding service:
tdk logs --json --service quoting-api --tail 200
Before running a flow, use tdk status --json to confirm readiness. A service that is still in a pending state will cause the flow to fail even if the code is correct.
A health check route is typically a lightweight HTTP endpoint (such as /health or /ready) used to quickly determine whether a service process is alive and ready to receive traffic. It does not involve business logic, nor does it verify that downstream dependencies are available. Therefore, a passing health check only means the service itself is running normally; it does not guarantee that the services it depends on (such as databases, message queues, or other microservices) are available, and certainly does not guarantee that business contracts (such as API parameter formats and data models) match. In a microservices architecture, health checks are commonly used for container orchestration liveness and readiness probes, but end-to-end testing must go beyond health checks by directly calling business endpoints and verifying cross-service interaction results.
Test the Flow, Not the Service
This is the core principle emphasized in the original article: a sales service can pass its health check yet fail when a quote requests a price. The real integration points you need to focus on are between services, so deliberately exercise cross-service paths.
A health check can only prove the process is alive; it cannot prove the business contract holds. By focusing testing on cross-service business flows, you can expose deeper issues such as misconfigured dependencies and inconsistent data contracts.
A business contract refers to the interface agreement followed when services interact, including API request/response formats, error codes, meanings of data fields, timeout behavior, and so on. In a microservices architecture, each service evolves independently, and contracts can be broken inadvertently. For example, if pricing-api changes the response structure of price queries but quoting-api still parses it in the old format, quote generation will fail. Health checks cannot catch this kind of problem because the service itself is healthy. End-to-end testing simulates real business flows and verifies contract consistency across multiple services, thereby exposing integration defects such as missing fields, type mismatches, and incorrect status codes. Maintaining explicit contract documentation (such as OpenAPI) and performing regular contract testing are effective ways to reduce these problems.
Wrapping Up: Stopping the Stack
When you're done, run tdk down. A stack that isn't stopped will occupy ports and affect the next startup. This simple cleanup step helps you avoid low-level failures like "port already in use."
Summary
The sales stack consists of 20 resources arranged along the sales cycle. Start it with tdk up sales, check dependencies before adding a new service, and test a flow end to end starting from crm-api on port 4300. The value of TDK CLI lies in making dependency management and flow verification actionable, giving complex ERP sales stack debugging a clear process to follow.
Related articles

Qwen 4 First Test Leaks: Performance Rivals Opus 5.5, DeepSeek V4 Series Surfaces
Early Qwen 4 test outputs leak, with front-end generation said to rival Opus 5.5; DeepSeek V4 Mini, Flash, and Pro names appear in a code repo; Ant Group's Ling-3.1-flash surfaces too. Here's the latest on model tiering and on-device lightweight models.

OpenCode Makes DeepSeek V4.1 Flash Free, AI Daily Roundup
AI daily roundup: OpenCode makes DeepSeek V4.1 Flash free, StepFun Step5 Preview and Ling 3.1 Flash open-sourced, Grok Voice 3.0 tops speech leaderboard, Matrix Game 4.0 open-sourced, and the EU opens its first AI Act enforcement probe into OpenAI and Anthropic.

DeepSeek V4.1 Flash 1017 Released: Reasoning and Coding Upgrades, Search and Fetch API Now Available
DeepSeek releases V4.1 Flash 1017 with major gains in reasoning, coding, and agentic tasks, plus web search and fetch APIs at 5 yuan per 1,000 requests. Tencent Hunyuan open-sources High Memory 2.0, Perplexity open-sources multimodal decision models, and MOFCOM seeks comments on AI export catalog.