# grabjke/petfamily architecture

> Architecture diagram of the GitHub repository grabjke/petfamily, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-03). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/grabjke/petfamily
- Repository: https://github.com/grabjke/petfamily

## Overview

#### Purpose and runtime
PetFamily is a modular .NET backend for managing animal-care volunteers, their pets, species/breeds, volunteer applications, user accounts, discussions, and files. The executable API host is `backend/src/PetFamily.Web/Program.cs`; solution-level build orchestration is `backend/backend.sln`. Container deployment is defined by `backend/src/PetFamily.Web/Dockerfile` and `backend/compose.yaml`, with Nginx configuration at `backend/nginx.conf`.

#### Modular architecture and request boundary
Each business module follows layered boundaries: Presentation controllers map HTTP requests to application commands/queries; Application owns use cases and repository interfaces; Domain owns aggregates/rules; Infrastructure implements persistence and external integrations. Module registrations are composed through dependency injection, e.g. `backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/DependencyInjection.cs` and `backend/src/Accounts/PetFamily.Accounts.Application/DependencyInjection.cs`. Shared command/query abstractions are in `backend/src/Shared/PetFamily.Core/Abstractions/ICommand.cs` and `backend/src/Shared/PetFamily.Core/Abstractions/IQuery.cs`. API errors are centralized through `backend/src/PetFamily.Web/Middlewares/ExceptionMiddlware.cs`.

#### Accounts, identity, and authorization
Accounts manage registration, login, logout, refresh sessions, JWT issuance, roles, permissions, and account types (participant, volunteer, admin). HTTP entry is `backend/src/Accounts/PetFamily.Accounts.Presentation/AccountController.cs`; authentication workflows reside in `backend/src/Accounts/PetFamily.Accounts.Application/AccountsManagement/Commands/LoginUser/LoginHandler.cs` and `backend/src/Accounts/PetFamily.Accounts.Application/AccountsManagement/Commands/RefreshTokens/RefreshTokensHandler.cs`. Infrastructure persists identity entities through `backend/src/Accounts/PetFamily.Accounts.Infrastructure/AccountDbContext.cs`, creates JWTs via `backend/src/Accounts/PetFamily.Accounts.Infrastructure/JwtTokenProvider.cs`, and enforces dynamic permission policies through `backend/src/Accounts/PetFamily.Accounts.Infrastructure/PermissionPolicyProvider.cs`.

#### Volunteer and animal management
The Volunteers module is the core operational catalog: volunteers own pets, with lifecycle, profile, status, ordering, and photo operations. Its API boundary is `backend/src/Volunteers/PetFamily.Volunteers.Presentation/VolunteersController.cs`; domain aggregates are `backend/src/Volunteers/PetFamily.Volunteers.Domain/PetManagement/Volunteer.cs` and `backend/src/Volunteers/PetFamily.Volunteers.Domain/PetManagement/Pet.cs`. Commands mutate the write model, such as `backend/src/Volunteers/PetFamily.Volunteers.Application/Volunteers/Commands/AddPet/AddPetHandler.cs`; paginated reads use handlers such as `backend/src/Volunteers/PetFamily.Volunteers.Application/Volunteers/Queries/GetPetsWithPagination/GetPetsWithPaginationHandler.cs`.

#### Species and discussions
Species/breeds are a separate reference-data module, exposed by `backend/src/Species/PetFamily.Species.Presentation/Species/SpeciesController.cs` and stored through distinct read/write contexts at `backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/SpeciesReadDbContext.cs` and `backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/WriteSpeciesDbContext.cs`. Discussions provide relation-scoped conversations with message editing/deletion and close operations; API entry is `backend/src/Discussions/PetFamily.Discussions.Presentation/DiscussionsController.cs`, domain state is `backend/src/Discussions/PetFamily.Discussions.Domain/DiscussionManagement/Discussion.cs`, and persistence likewise separates reads and writes.

#### Volunteer application workflow and asynchronous integration
Volunteer applications model submission, assignment/take, revision, approval, and rejection. The public boundary is `backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Presentation/VolunteersApplicationsController.cs`; approval behavior is in `backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Application/VolunteersApplications/Commands/Approve/ApproveApplicationHandler.cs`. Approval emits `ApprovedApplicationEvent` via a transactional outbox represented by `backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Infrastructure/Outbox/OutboxMessage.cs` and processed by `backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Infrastructure/Outbox/ProcessOutboxMessagesJob.cs`. Accounts consumes volunteer-registration events at `backend/src/Accounts/PetFamily.Accounts.Infrastructure/Consumers/RegisterVolunteerConsumer.cs`.

#### Persistence, files, and services
Entity Framework-style write/read persistence is evident across module-specific DbContexts, repositories, UnitOfWork implementations, and migrations. File APIs are exposed at `backend/src/Files/PetFamily.Files.Presentation/FileController.cs`; uploads, removal, and presigned access flow through `backend/src/Files/PetFamily.Files.Application/Files/Upload/UploadFilesHandler.cs` and `backend/src/Files/PetFamily.Files.Application/Files/Presigned/PresignedFileHandler.cs`. Object storage is abstracted by `backend/src/Shared/PetFamily.Core/IFileProvider.cs` and implemented with MinIO at `backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/Providers/MinioProvider.cs`. A background cleaner (`backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/BackgroundServices/FilesCleanerBackgroundService.cs`) removes queued obsolete files using an in-memory message queue.

Main entry points: [`backend/src/PetFamily.Web/Program.cs`](https://github.com/grabjke/petfamily/blob/main/backend/src/PetFamily.Web/Program.cs) (Web API host), [`backend/src/Accounts/PetFamily.Accounts.Application/AccountsManagement/Commands/LoginUser/LoginHandler.cs`](https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Application/AccountsManagement/Commands/LoginUser/LoginHandler.cs) (Account authentication), [`backend/src/Volunteers/PetFamily.Volunteers.Application/Volunteers/Commands/AddPet/AddPetHandler.cs`](https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Application/Volunteers/Commands/AddPet/AddPetHandler.cs) (Volunteer and pet use cases), [`backend/src/Species/PetFamily.Species.Presentation/Species/SpeciesController.cs`](https://github.com/grabjke/petfamily/blob/main/backend/src/Species/PetFamily.Species.Presentation/Species/SpeciesController.cs) (Species API)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["API Runtime"]
  node_solution["Solution build<br/>[backend.sln]"]
  node_deployment{{"Container deployment<br/>[compose.yaml]"}}
  node_nginx{{"Nginx<br/>reverse proxy<br/>[nginx.conf]"}}
  node_api_host["Web API host<br/>ASP.NET host<br/>[Program.cs]"]
  node_exception_middleware["Exception middleware<br/>HTTP middleware"]
  node_cqrs_abstractions["Command/query contracts<br/>shared abstraction<br/>[ICommand.cs]"]
end

subgraph group_modules["Business Modules"]
  node_accounts_api["Accounts API<br/>controller"]
  node_accounts_auth["Account authentication<br/>application handler<br/>[LoginHandler.cs]"]
  node_accounts_identity[("Identity and authorization<br/>identity infrastructure")]
  node_volunteers_api["Volunteers API<br/>controller"]
  node_volunteers_usecases["Volunteer and pet use cases<br/>application handlers<br/>[AddPetHandler.cs]"]
  node_volunteer_domain["Volunteer and pet model<br/>domain aggregate<br/>[Volunteer.cs]"]
  node_species_api["Species API<br/>controller"]
  node_discussions_api["Discussions API<br/>controller"]
  node_discussion_domain["Discussion model<br/>domain aggregate<br/>[Discussion.cs]"]
  node_applications_api["Applications API<br/>controller"]
  node_approval_workflow["Application approval<br/>application handler"]
  node_files_api["Files API<br/>controller<br/>[FileController.cs]"]
  node_file_usecases["File upload and access<br/>application handler"]
end

subgraph group_integration["Persistence &amp; Integration"]
  node_species_read_store[("Species read store<br/>read DbContext")]
  node_species_write_store[("Species write store<br/>write DbContext")]
  node_outbox["Transactional outbox<br/>outbox processor"]
  node_volunteer_registration_consumer["Volunteer registration consumer<br/>event consumer"]
  node_object_storage[("MinIO object storage<br/>file provider<br/>[MinioProvider.cs]")]
  node_file_cleaner["Obsolete file cleaner<br/>background service"]
end

node_solution -->|"builds"| node_api_host
node_deployment -->|"deploys"| node_nginx
node_nginx -->|"proxies requests"| node_api_host
node_api_host -->|"uses"| node_exception_middleware
node_api_host -->|"routes"| node_accounts_api
node_api_host -->|"routes"| node_volunteers_api
node_api_host -->|"routes"| node_species_api
node_api_host -->|"routes"| node_discussions_api
node_api_host -->|"routes"| node_applications_api
node_api_host -->|"routes"| node_files_api
node_accounts_api -->|"invokes"| node_accounts_auth
node_accounts_auth -->|"implements"| node_cqrs_abstractions
node_accounts_auth -->|"uses"| node_accounts_identity
node_volunteers_api -->|"invokes"| node_volunteers_usecases
node_volunteers_usecases -->|"implements"| node_cqrs_abstractions
node_volunteers_usecases -->|"applies rules"| node_volunteer_domain
node_species_api -->|"queries"| node_species_read_store
node_species_api -->|"updates"| node_species_write_store
node_discussions_api -->|"manages"| node_discussion_domain
node_applications_api -->|"invokes"| node_approval_workflow
node_approval_workflow -->|"writes event"| node_outbox
node_outbox -.->|"publishes registration event"| node_volunteer_registration_consumer
node_volunteer_registration_consumer -->|"creates volunteer account"| node_accounts_identity
node_files_api -->|"invokes"| node_file_usecases
node_file_usecases -->|"stores and signs files"| node_object_storage
node_file_cleaner -->|"deletes obsolete files"| node_object_storage

click node_solution "https://github.com/grabjke/petfamily/blob/main/backend/backend.sln"
click node_deployment "https://github.com/grabjke/petfamily/blob/main/backend/compose.yaml"
click node_nginx "https://github.com/grabjke/petfamily/blob/main/backend/nginx.conf"
click node_api_host "https://github.com/grabjke/petfamily/blob/main/backend/src/PetFamily.Web/Program.cs"
click node_exception_middleware "https://github.com/grabjke/petfamily/blob/main/backend/src/PetFamily.Web/Middlewares/ExceptionMiddlware.cs"
click node_cqrs_abstractions "https://github.com/grabjke/petfamily/blob/main/backend/src/Shared/PetFamily.Core/Abstractions/ICommand.cs"
click node_accounts_api "https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Presentation/AccountController.cs"
click node_accounts_auth "https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Application/AccountsManagement/Commands/LoginUser/LoginHandler.cs"
click node_accounts_identity "https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Infrastructure/AccountDbContext.cs"
click node_volunteers_api "https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Presentation/VolunteersController.cs"
click node_volunteers_usecases "https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Application/Volunteers/Commands/AddPet/AddPetHandler.cs"
click node_volunteer_domain "https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Domain/PetManagement/Volunteer.cs"
click node_species_api "https://github.com/grabjke/petfamily/blob/main/backend/src/Species/PetFamily.Species.Presentation/Species/SpeciesController.cs"
click node_species_read_store "https://github.com/grabjke/petfamily/blob/main/backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/SpeciesReadDbContext.cs"
click node_species_write_store "https://github.com/grabjke/petfamily/blob/main/backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/WriteSpeciesDbContext.cs"
click node_discussions_api "https://github.com/grabjke/petfamily/blob/main/backend/src/Discussions/PetFamily.Discussions.Presentation/DiscussionsController.cs"
click node_discussion_domain "https://github.com/grabjke/petfamily/blob/main/backend/src/Discussions/PetFamily.Discussions.Domain/DiscussionManagement/Discussion.cs"
click node_applications_api "https://github.com/grabjke/petfamily/blob/main/backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Presentation/VolunteersApplicationsController.cs"
click node_approval_workflow "https://github.com/grabjke/petfamily/blob/main/backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Application/VolunteersApplications/Commands/Approve/ApproveApplicationHandler.cs"
click node_outbox "https://github.com/grabjke/petfamily/blob/main/backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Infrastructure/Outbox/ProcessOutboxMessagesJob.cs"
click node_volunteer_registration_consumer "https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Infrastructure/Consumers/RegisterVolunteerConsumer.cs"
click node_files_api "https://github.com/grabjke/petfamily/blob/main/backend/src/Files/PetFamily.Files.Presentation/FileController.cs"
click node_file_usecases "https://github.com/grabjke/petfamily/blob/main/backend/src/Files/PetFamily.Files.Application/Files/Upload/UploadFilesHandler.cs"
click node_object_storage "https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/Providers/MinioProvider.cs"
click node_file_cleaner "https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/BackgroundServices/FilesCleanerBackgroundService.cs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_solution,node_deployment,node_nginx,node_api_host,node_exception_middleware,node_cqrs_abstractions toneBlue
class node_accounts_api,node_accounts_auth,node_accounts_identity,node_volunteers_api,node_volunteers_usecases,node_volunteer_domain,node_species_api,node_discussions_api,node_discussion_domain,node_applications_api,node_approval_workflow,node_files_api,node_file_usecases toneAmber
class node_species_read_store,node_species_write_store,node_outbox,node_volunteer_registration_consumer,node_object_storage,node_file_cleaner toneMint
```

## Components

### API Runtime

- [Solution build](https://github.com/grabjke/petfamily/blob/main/backend/backend.sln): solution · `backend/backend.sln`
- [Container deployment](https://github.com/grabjke/petfamily/blob/main/backend/compose.yaml): deployment · Compose deploys the API behind Nginx. · `backend/compose.yaml`
- [Nginx](https://github.com/grabjke/petfamily/blob/main/backend/nginx.conf): reverse proxy · `backend/nginx.conf`
- [Web API host](https://github.com/grabjke/petfamily/blob/main/backend/src/PetFamily.Web/Program.cs): ASP.NET host · Composes module dependency injection registrations. · `backend/src/PetFamily.Web/Program.cs`
- [Exception middleware](https://github.com/grabjke/petfamily/blob/main/backend/src/PetFamily.Web/Middlewares/ExceptionMiddlware.cs): HTTP middleware · `backend/src/PetFamily.Web/Middlewares/ExceptionMiddlware.cs`
- [Command/query contracts](https://github.com/grabjke/petfamily/blob/main/backend/src/Shared/PetFamily.Core/Abstractions/ICommand.cs): shared abstraction · `backend/src/Shared/PetFamily.Core/Abstractions/ICommand.cs`

### Business Modules

- [Accounts API](https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Presentation/AccountController.cs): controller · `backend/src/Accounts/PetFamily.Accounts.Presentation/AccountController.cs`
- [Account authentication](https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Application/AccountsManagement/Commands/LoginUser/LoginHandler.cs): application handler · Login and refresh-session workflows. · `backend/src/Accounts/PetFamily.Accounts.Application/AccountsManagement/Commands/LoginUser/LoginHandler.cs`
- [Identity and authorization](https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Infrastructure/AccountDbContext.cs): identity infrastructure · Persists accounts and supplies JWTs and dynamic permission policies. · `backend/src/Accounts/PetFamily.Accounts.Infrastructure/AccountDbContext.cs`
- [Volunteers API](https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Presentation/VolunteersController.cs): controller · `backend/src/Volunteers/PetFamily.Volunteers.Presentation/VolunteersController.cs`
- [Volunteer and pet use cases](https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Application/Volunteers/Commands/AddPet/AddPetHandler.cs): application handlers · Commands update pets; queries provide paginated reads. · `backend/src/Volunteers/PetFamily.Volunteers.Application/Volunteers/Commands/AddPet/AddPetHandler.cs`
- [Volunteer and pet model](https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Domain/PetManagement/Volunteer.cs): domain aggregate · Volunteers own pets and their lifecycle data. · `backend/src/Volunteers/PetFamily.Volunteers.Domain/PetManagement/Volunteer.cs`
- [Species API](https://github.com/grabjke/petfamily/blob/main/backend/src/Species/PetFamily.Species.Presentation/Species/SpeciesController.cs): controller · `backend/src/Species/PetFamily.Species.Presentation/Species/SpeciesController.cs`
- [Discussions API](https://github.com/grabjke/petfamily/blob/main/backend/src/Discussions/PetFamily.Discussions.Presentation/DiscussionsController.cs): controller · `backend/src/Discussions/PetFamily.Discussions.Presentation/DiscussionsController.cs`
- [Discussion model](https://github.com/grabjke/petfamily/blob/main/backend/src/Discussions/PetFamily.Discussions.Domain/DiscussionManagement/Discussion.cs): domain aggregate · Relation-scoped conversations support edits, deletion, and closure. · `backend/src/Discussions/PetFamily.Discussions.Domain/DiscussionManagement/Discussion.cs`
- [Applications API](https://github.com/grabjke/petfamily/blob/main/backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Presentation/VolunteersApplicationsController.cs): controller · `backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Presentation/VolunteersApplicationsController.cs`
- [Application approval](https://github.com/grabjke/petfamily/blob/main/backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Application/VolunteersApplications/Commands/Approve/ApproveApplicationHandler.cs): application handler · Approves applications and emits registration events. · `backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Application/VolunteersApplications/Commands/Approve/ApproveApplicationHandler.cs`
- [Files API](https://github.com/grabjke/petfamily/blob/main/backend/src/Files/PetFamily.Files.Presentation/FileController.cs): controller · `backend/src/Files/PetFamily.Files.Presentation/FileController.cs`
- [File upload and access](https://github.com/grabjke/petfamily/blob/main/backend/src/Files/PetFamily.Files.Application/Files/Upload/UploadFilesHandler.cs): application handler · Uploads, removal, and presigned-file access. · `backend/src/Files/PetFamily.Files.Application/Files/Upload/UploadFilesHandler.cs`

### Persistence & Integration

- [Species read store](https://github.com/grabjke/petfamily/blob/main/backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/SpeciesReadDbContext.cs): read DbContext · `backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/SpeciesReadDbContext.cs`
- [Species write store](https://github.com/grabjke/petfamily/blob/main/backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/WriteSpeciesDbContext.cs): write DbContext · `backend/src/Species/PetFamily.Species.Infrastructure/DbContexts/WriteSpeciesDbContext.cs`
- [Transactional outbox](https://github.com/grabjke/petfamily/blob/main/backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Infrastructure/Outbox/ProcessOutboxMessagesJob.cs): outbox processor · Background job publishes approved-application events reliably. · `backend/src/VolunteersApplications/PetFamily.VolunteersApplications.Infrastructure/Outbox/ProcessOutboxMessagesJob.cs`
- [Volunteer registration consumer](https://github.com/grabjke/petfamily/blob/main/backend/src/Accounts/PetFamily.Accounts.Infrastructure/Consumers/RegisterVolunteerConsumer.cs): event consumer · `backend/src/Accounts/PetFamily.Accounts.Infrastructure/Consumers/RegisterVolunteerConsumer.cs`
- [MinIO object storage](https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/Providers/MinioProvider.cs): file provider · `backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/Providers/MinioProvider.cs`
- [Obsolete file cleaner](https://github.com/grabjke/petfamily/blob/main/backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/BackgroundServices/FilesCleanerBackgroundService.cs): background service · Removes queued obsolete files. · `backend/src/Volunteers/PetFamily.Volunteers.Infrastructure/BackgroundServices/FilesCleanerBackgroundService.cs`

## Connections

- Solution build → Web API host: builds
- Container deployment → Nginx: deploys
- Nginx → Web API host: proxies requests
- Web API host → Exception middleware: uses
- Web API host → Accounts API: routes
- Web API host → Volunteers API: routes
- Web API host → Species API: routes
- Web API host → Discussions API: routes
- Web API host → Applications API: routes
- Web API host → Files API: routes
- Accounts API → Account authentication: invokes
- Account authentication → Command/query contracts: implements
- Account authentication → Identity and authorization: uses
- Volunteers API → Volunteer and pet use cases: invokes
- Volunteer and pet use cases → Command/query contracts: implements
- Volunteer and pet use cases → Volunteer and pet model: applies rules
- Species API → Species read store: queries
- Species API → Species write store: updates
- Discussions API → Discussion model: manages
- Applications API → Application approval: invokes
- Application approval → Transactional outbox: writes event
- Transactional outbox → Volunteer registration consumer: publishes registration event
- Volunteer registration consumer → Identity and authorization: creates volunteer account
- Files API → File upload and access: invokes
- File upload and access → MinIO object storage: stores and signs files
- Obsolete file cleaner → MinIO object storage: deletes obsolete files
