Splitting into services enforces nothing if they share a database; splitting into modules with a checked dependency rule enforces more.
# deptrac.yaml
layers:
- name: Orders
collectors: [{ type: directory, value: app/Modules/Orders/.* }]
- name: Catalogue
collectors: [{ type: directory, value: app/Modules/Catalogue/.* }]
- name: Shared
collectors: [{ type: directory, value: app/Shared/.* }]
ruleset:
Orders: [Shared] # NOT Catalogue
Catalogue: [Shared]
Shared: ~
A build failure on a cross-module import is a stricter guarantee than a network call between two services that both connect to the same schema. It also fails at the moment the coupling is introduced rather than eighteen months later, which is the difference between a five-minute conversation and a refactor.