System architecture
DebtDrone CLI has two consumers of one reusable scanner: the local CLI/TUI and
the DebtDrone SaaS. The public scanner packages are the stable boundary; the
internal packages are implementation details and cannot be imported by other
Go modules.
Read Scanner ownership and contribution boundary before making a change that also affects the SaaS.
Dependency direction
Section titled “Dependency direction”cmd/debtdrone ──> internal/service ──> scannerinternal/tui ──> internal/service ──> scannerdebtdrone SaaS adapter ──────────────> scanner (version pinned in SaaS go.mod)
scanner ──> internal/scancore + internal analyzers/file policyscanner -X-> CLI, TUI, SaaS, database, Redis, queues, billing, integrationsThe final arrow is enforced by external-consumer and dependency-boundary tests. Consumers configure a scan through neutral options and receive a neutral, deterministically ordered report.
Public scanner packages
Section titled “Public scanner packages”| Package | Responsibility |
|---|---|
scanner |
Scan entry point, scope, analyzer options, progress, failures, report contract |
scanner/coverage |
Coverage artifact types, parsers, and optional execution interface |
scanner/repostructure |
Repository layout, build-root, and build-enrichment detection |
scanner.Scan accepts a context, repository path, and scanner.Options.
Callers choose full, incremental, or explicit no-change scope. Cancellation and
partial analyzer failures are part of the public contract; callers must not
infer them from logs.
Internal implementation
Section titled “Internal implementation”internal/analysis/analyzerscontains complexity, line-count, and Trivy implementations registered with the scanner runner.internal/filepolicycentralizes safe file inclusion/exclusion behavior.internal/scancorecontains internal analyzer contracts shared by the public runner and implementations.internal/serviceadapts public scanner reports for local CLI/TUI history and presentation.internal/store/memoryprovides local ephemeral persistence.internal/git,internal/config, andinternal/updateare CLI support code.internal/tuiis the Bubble Tea presentation adapter.
Internal types may change without a module API promise. Types needed by an
external consumer must be deliberately modeled in scanner, documented, and
covered by compatibility tests.
SaaS integration
Section titled “SaaS integration”The SaaS imports an immutable debtdrone-cli/v2 module version and adapts the
report to its own database models. It owns queueing, hosted cloning, isolated
Docker execution, persistence, reconciliation, history, and commercial
features. The scanner remains unaware of those systems.
Scanner changes land and are released here first. The SaaS then receives a reviewable dependency-only pull request and runs Linux, macOS, and Windows boundary tests before adoption. A SaaS rollback restores its previous application revision and scanner pin; it never switches to a copied engine.