S19 refinement
All checks were successful
Build, test and publish / verify (push) Successful in 8m15s
All checks were successful
Build, test and publish / verify (push) Successful in 8m15s
This commit is contained in:
215
adr/approved/ADR1_application-size.md
Normal file
215
adr/approved/ADR1_application-size.md
Normal file
@@ -0,0 +1,215 @@
|
||||
**ID:** ADR1 \
|
||||
**Title:** Application size \
|
||||
**Supersedes:** - \
|
||||
**Status:** APPROVED \
|
||||
**Expiration Date:** Six months after approval; record the calendar date upon manual approval.
|
||||
|
||||
## Context
|
||||
|
||||
Agile Dancers currently keeps its frontend, backend, CI pipeline, skills,
|
||||
specifications, ADRs, and other documentation in one repository. As the application
|
||||
grows, humans and agents need more context to understand individual tasks.
|
||||
Functional dependencies can become entangled, making changes and reuse harder.
|
||||
|
||||
The primary goal is to reduce the context required for a task. Supporting goals
|
||||
are preventing uncontrolled coupling and enabling reuse and replacement of
|
||||
capabilities. Repository organization, module boundaries, and deployment
|
||||
boundaries are separate architectural choices.
|
||||
|
||||
Business capabilities stand on their own, while an application system may support
|
||||
multiple capabilities. Loosely coupled capability boundaries allow implementations
|
||||
to change between custom software, libraries, and externally supplied components.
|
||||
Scheduling and school administration are candidate areas to examine; their exact
|
||||
system boundaries have not yet been decided.
|
||||
|
||||
Code-level modularity alone is insufficient when shared tables, materialized
|
||||
views, SQL scripts, or other database access bypass module boundaries. Separate
|
||||
services would have the same weakness without enforced data ownership.
|
||||
|
||||
Systems can initially run on the same physical server. Independent workload
|
||||
placement is nevertheless useful: computational work, such as runners and future
|
||||
scheduling calculations, may run on a mini-PC rather than the Synology. Independent
|
||||
scaling and release cycles are future possibilities rather than universal current
|
||||
requirements. Colocation reduces network exposure but process restarts, timeouts,
|
||||
and resource contention still require defined failure behavior.
|
||||
|
||||
Reusable engineering resources should also support other projects. Specifications
|
||||
can affect several projects, and ADRs apply across the application landscape.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Capabilities and systems
|
||||
|
||||
Organize the landscape into independently deployable systems. Group capabilities
|
||||
into systems according to cohesion, data ownership, replacement needs, and
|
||||
operational requirements, including workload placement. Capability size alone does
|
||||
not justify a separate system.
|
||||
|
||||
Each system has its own repository and independent deployment lifecycle. Within a
|
||||
system, use modules to keep its capabilities loosely coupled. A capability does
|
||||
not automatically require its own service or deployment. Compute workers may be
|
||||
deployed separately from the business system that delegates work to them.
|
||||
|
||||
Capability contracts should allow implementations to be replaced by custom code,
|
||||
libraries, or external products, using adapters where necessary.
|
||||
|
||||
### Data ownership
|
||||
|
||||
Each system exclusively owns its data. Other systems access that data through
|
||||
explicit contracts, never through direct access to its storage. This restriction
|
||||
also applies to reporting queries, views, migrations, and maintenance scripts.
|
||||
Cross-system reporting requires explicit contracts or a separately owned
|
||||
projection.
|
||||
|
||||
PostgreSQL-backed systems initially share one PostgreSQL server/container, with
|
||||
separate databases or schemas and separate credentials whose permissions enforce
|
||||
ownership. Sharing physical infrastructure does not permit sharing storage access.
|
||||
Systems may choose other storage technologies when justified. This permits future
|
||||
CQRS designs without adopting CQRS through this ADR.
|
||||
|
||||
### Contracts and communication
|
||||
|
||||
Systems communicate through explicit, versioned contracts. Internal domain models
|
||||
and persistence entities remain private to their owning system and are not shared
|
||||
through common libraries. Contract definitions and generated clients may be shared.
|
||||
|
||||
Choose synchronous APIs or asynchronous messaging for each interaction according
|
||||
to its needs. Define failure behavior for each interaction. This ADR mandates
|
||||
neither a landscape-wide communication mechanism nor a message broker.
|
||||
|
||||
### Landscape and engineering resources
|
||||
|
||||
Maintain a landscape repository containing ADRs, specifications, and the capability
|
||||
and system map. Specifications identify the projects they affect and may span
|
||||
multiple systems. ADRs govern the application landscape according to their scope.
|
||||
Each system retains a README describing its implementation and operation.
|
||||
|
||||
Maintain reusable engineering resources, including pipeline components, skills,
|
||||
and general engineering documentation, separately from the landscape repository
|
||||
and individual systems. Group these resources according to maintenance and release
|
||||
needs; a separate repository per resource type is not required. Version shared
|
||||
resources so consuming projects can adopt updates deliberately.
|
||||
|
||||
### Adoption and review
|
||||
|
||||
Use this ADR as guidance and the starting point for follow-up specifications.
|
||||
Detailed system boundaries, contracts, and migration designs are follow-up work.
|
||||
Migrate incrementally, keeping the application working after each extraction.
|
||||
|
||||
Perform an initial review six months after approval. Review earlier if contract
|
||||
coordination, operational overhead, or persistent cross-system coupling becomes a
|
||||
significant burden. The expiration date triggers reevaluation and does not
|
||||
automatically invalidate the decision.
|
||||
|
||||
## Options considered
|
||||
|
||||
### 1. Improve navigation within the current structure
|
||||
|
||||
Keep the existing projects and deployment structure, improving focused
|
||||
documentation, task guidance, and file organization.
|
||||
|
||||
Pros:
|
||||
|
||||
- Requires little disruption or migration work.
|
||||
- Makes relevant context easier to find.
|
||||
- Retains simple local development and coordinated changes.
|
||||
|
||||
Cons:
|
||||
|
||||
- Offers limited protection against functional entanglement.
|
||||
- Does not enforce data ownership or support independent workload placement.
|
||||
- Leaves reuse and replacement dependent on existing application boundaries.
|
||||
|
||||
Not chosen because navigation improvements alone do not establish the ownership
|
||||
and replacement boundaries needed as the landscape grows.
|
||||
|
||||
### 2. Modular monolith in one repository
|
||||
|
||||
Organize capabilities into modules with explicit interfaces and dependency rules,
|
||||
while retaining coordinated deployment and one repository.
|
||||
|
||||
Pros:
|
||||
|
||||
- Reduces the code area needed to understand a capability.
|
||||
- Enables dependency checks and straightforward changes across modules.
|
||||
- Keeps deployment and in-process communication simple.
|
||||
|
||||
Cons:
|
||||
|
||||
- Shared database access can bypass code-level boundaries through tables, views,
|
||||
and scripts unless storage ownership is separately enforced.
|
||||
- Workload placement and deployment remain coupled.
|
||||
- Independent replacement and reuse may require later extraction.
|
||||
|
||||
Not chosen as the landscape-wide approach because independently enforced ownership
|
||||
and deployment boundaries are desired. Modular design remains part of the chosen
|
||||
approach inside each system.
|
||||
|
||||
### 3. Separate projects and repositories with coordinated deployment
|
||||
|
||||
Extract capabilities into separately built libraries or applications with
|
||||
versioned contracts, while retaining a coordinated deployment lifecycle.
|
||||
|
||||
Pros:
|
||||
|
||||
- Separates source and build context.
|
||||
- Gives reusable components their own versioned releases.
|
||||
- Retains a coordinated operational release process.
|
||||
|
||||
Cons:
|
||||
|
||||
- Changes spanning repositories require dependency release coordination.
|
||||
- Deployment remains coupled despite repository separation.
|
||||
- Repository separation alone does not enforce storage ownership or runtime
|
||||
independence.
|
||||
|
||||
Not chosen because it incurs repository coordination costs while retaining a
|
||||
deployment constraint that would limit workload placement and replacement.
|
||||
|
||||
### 4. Independently deployable systems with internal capability modules — chosen
|
||||
|
||||
Give systems their own repositories, deployment lifecycles, contracts, and enforced
|
||||
data ownership. Keep capabilities loosely coupled through modules within a system.
|
||||
Place compute workers independently where useful.
|
||||
|
||||
Pros:
|
||||
|
||||
- Supports focused development context and independent system evolution.
|
||||
- Enforces data ownership beyond code dependency rules through storage permissions.
|
||||
- Allows workloads to move between the Synology and mini-PC.
|
||||
- Supports capability replacement and reuse through explicit contracts.
|
||||
- Allows storage technology choices per system.
|
||||
|
||||
Cons:
|
||||
|
||||
- Requires contract compatibility and coordination for changes spanning systems.
|
||||
- Adds deployment, configuration, and operational maintenance for multiple processes.
|
||||
- Requires explicit failure handling and cross-system consistency decisions.
|
||||
- Sharing one server or PostgreSQL instance retains common infrastructure failure
|
||||
points despite logical isolation.
|
||||
|
||||
Chosen because ownership, replaceability, focused context, and independent workload
|
||||
placement outweigh the additional operational and contract coordination work.
|
||||
|
||||
## Consequences
|
||||
|
||||
- Write follow-up specifications to map capabilities and dependencies, choose
|
||||
initial system boundaries, define contracts and data ownership, and plan
|
||||
extraction. This ADR does not itself settle those boundaries or implement them.
|
||||
- Establish the landscape repository and the repositories and versioning needed
|
||||
for reusable engineering resources. Preserve links between specifications and
|
||||
affected projects, and between system READMEs and landscape guidance.
|
||||
- Extract systems one at a time, establishing contracts and enforcing storage
|
||||
ownership as part of each extraction. Moving tables into separate schemas is
|
||||
insufficient while cross-system SQL access remains possible.
|
||||
- Adapt build and deployment pipelines to release systems independently and
|
||||
consume versioned shared engineering resources.
|
||||
- Add appropriate checks for module dependencies, contract compatibility, and
|
||||
storage isolation. Include views and scripts in boundary enforcement.
|
||||
- Specify how systems exchange information, handle failed interactions, and keep
|
||||
derived information consistent. These choices belong to the relevant follow-up
|
||||
specifications rather than a universal messaging requirement.
|
||||
- Keep one PostgreSQL container initially. Detailed backup and failover design is
|
||||
future work; logical data separation does not provide infrastructure failover.
|
||||
- Record the calendar review date when a maintainer manually approves this ADR.
|
||||
REFINED records the agreed proposal; approval remains a separate manual step.
|
||||
Reference in New Issue
Block a user