Files
InvoiceShelf/docs/architecture/0001-modular-monolith.md
T
Darko Gjorgjijoski 5ef7804e60 refactor: adopt modular domain architecture (#747)
* refactor: stabilize model identities for domain migration

* refactor: extract module platform context

* refactor: assign models to domain contexts

* refactor: extract ai platform context

* refactor: extract storage platform context

* refactor: extract mail platform context

* refactor: extract pdf platform context

* refactor: extract operations platform context

* refactor: move installation into operations platform

* refactor: extract money domain context

* refactor: extract taxation domain context

* refactor: extract catalog domain context

* refactor: extract metadata domain context

* refactor: extract reporting domain context

* refactor: extract purchases domain context

* refactor: extract receivables domain context

* refactor: extract accounts domain context

* refactor: complete reporting statement boundary

* refactor: extract contacts domain context

* refactor: extract sales domain context

* refactor: remove legacy application layers

* fix: migrate legacy bouncer role identities
2026-08-05 17:40:03 +02:00

64 lines
2.7 KiB
Markdown

# ADR 0001: Laravel-native modular monolith
Date: 2026-08-05
Status: Accepted
## Context
InvoiceShelf 3.x is still in alpha and may break PHP namespaces and internal
extension contracts. Existing installations must retain their database data,
document links, and public `/api/v1` behavior. The current layer-first layout
mixes sales, receivables, purchases, reporting, and infrastructure in global
model, controller, and service directories.
## Decision
The backend is organized as a modular monolith under `app/Domains` and
`app/Platform`.
Business contexts are Accounts, Contacts, Catalog, Taxation, Money, Metadata,
Sales, Receivables, Purchases, and Reporting. Platform capabilities are
Modules, AI, Mail, PDF, Storage, and Operations.
Each context owns its models, actions, queries, policies, events, jobs, and HTTP
adapters. Large contexts may contain feature subdirectories. Every context is
registered explicitly through a service provider; root route files are
composition roots for context-owned route fragments.
Direct Eloquent relationships across contexts are permitted for read
navigation when declared by the architecture dependency map. Cross-context
writes and workflows use contracts and application actions. Reporting may
query shared tables through read-only query objects. Infrastructure is reached
through platform contracts. No repository abstraction is required around
Eloquent by default.
All first-party models use stable morph aliases. Model namespaces, Hashids
connection names, and public API discriminators are separate identities. The
database stores aliases, Hashids retain their historical salt inputs, and v1
resources retain their existing discriminator strings.
Modules depend on the versioned `invoiceshelf/modules` SDK and must not import
domain internals.
## Migration rules
- Contexts move in independently green pull requests.
- A moved class has one canonical namespace; class aliases are forbidden.
- Temporary adapters may connect migrated and unmigrated contexts, but must be
deleted when the counterpart context moves.
- Existing table and column names remain unchanged and moved models declare
their table explicitly.
- HTTP methods, paths, middleware, payloads, status codes, and OpenAPI schemas
remain stable.
- Queue workers are drained and restarted for the namespace cutover; serialized
legacy jobs are not supported.
## Consequences
Feature ownership and cross-domain writes become explicit, while Eloquent
remains usable without a framework-independent persistence layer. Namespace
changes require coordinated imports across application code, factories,
seeders, configuration, tests, and historical migrations, but no persisted
record depends on those namespaces after the alias migration.