Skip to main content

112. Artifact Service for Report Storage

Status: Accepted Date: 2025-07-06

Context

The Atlas module generates report files (e.g., Markdown files). These files need to be stored somewhere persistent and then delivered to their destinations (e.g., uploaded to a GitHub release, sent as a file to Telegram). If we put the logic for file storage and delivery (which involves interacting with external APIs like GitHub's) directly inside the Atlas module, we would be mixing the responsibilities of data aggregation and report delivery.

Decision

The Atlas module will not handle report storage or delivery directly. Instead, it will delegate this responsibility to a dedicated, generic ArtifactsService.

The workflow will be:

  1. The AtlasService will generate the report content (e.g., a Markdown string).
  2. It will then call a method on the ArtifactsService, such as artifactsService.upload({ content: reportString, fileName: 'report.md', destination: 'github' }).
  3. The ArtifactsService will be responsible for all the low-level logic of interacting with the external APIs (like GitHub or Telegram) to upload the file, handle authentication, and manage API-specific errors.

This creates a clean separation of concerns. Atlas is responsible for what is in the report; ArtifactsService is responsible for where and how it gets delivered.

Consequences

Positive:

  • Separation of Concerns: This design cleanly separates the business logic of report generation from the infrastructure logic of file delivery. This makes both modules simpler and easier to maintain.
  • Reusability: The ArtifactsService is generic. It can be reused by any other part of the application that needs to store or deliver a file. For example, a different module could use it to upload a CSV file or a PDF.
  • Centralized API Logic: All the complex logic for interacting with external file storage APIs (like GitHub) is centralized in one place, which is easier to manage, test, and update.

Negative:

  • Adds an Extra Layer: Introduces an extra service call (an "indirection") into the process.

Mitigation:

  • A Necessary Abstraction: This is a beneficial abstraction that significantly improves the overall architecture. The cost of one extra internal function call is negligible compared to the benefits of improved modularity and reusability. The ArtifactsService will likely be a simple wrapper around our existing github-integration (adr://github-integration) and kaido-telegram libraries, composing existing functionality into a clean, high-level API.