# jinbriden/asyncflow architecture

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

- Interactive diagram: https://gitdiagram.com/jinbriden/asyncflow
- Repository: https://github.com/jinbriden/asyncflow
- Video tour (about a minute): https://gitdiagram.com/jinbriden/asyncflow/video

## Overview

AsyncFlow accepts sales-report tasks over REST, deduplicates submissions, and processes accepted work asynchronously into downloadable regional-sales CSV reports. Its main path is task submission and transactional persistence, Outbox publication, RabbitMQ consumption, report generation and storage, then status/result queries. Separate API capabilities support task listing, event history, cancellation, dead-task replay and compensation; scheduled recovery and retry behavior are represented at the subsystem level. The README documents these paths, but several implementation classes were not sampled, so their internal calls are not expanded.

Main entry points: [`src/main/java/io/github/asyncflow/repository/TaskRepository.java`](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/repository/TaskRepository.java) (Task repository), [`src/main/java/io/github/asyncflow/api/TaskController.java`](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/api/TaskController.java) (Task endpoints), [`src/main/java/io/github/asyncflow/service/TaskProcessor.java`](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskProcessor.java) (Task processor), [`src/main/java/io/github/asyncflow/service/TaskSubmissionService.java`](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskSubmissionService.java) (Task submission)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["Task API"]
  node_task_api["Task endpoints"]
  node_internal_api["Recovery endpoints"]
end

subgraph group_execution["Async execution"]
  node_submission["Task submission"]
  node_creation_tx["Creation transaction"]
  node_listener["Task listener<br/>[TaskListener.java]"]
  node_processor["Task processor<br/>[TaskProcessor.java]"]
end

subgraph group_reports["Report lifecycle"]
  node_payload_parser["Payload validation"]
  node_report_generator["Sales report generator"]
  node_report_storage["CSV storage<br/>[ReportStorage.java]"]
  node_report_query["Result query"]
end

subgraph group_state["State and recovery"]
  node_idempotency["Idempotency store"]
  node_task_domain["Task state model"]
  node_task_events["Event recording"]
  node_recovery["Replay and compensation"]
  node_cancellation["Task cancellation"]
  node_stale_scanner["Stale-task scanner"]
end

subgraph group_infrastructure["Persistence and messaging"]
  node_outbox["Outbox scheduling"]
  node_outbox_publisher["Outbox publisher"]
  node_rabbit["RabbitMQ"]
  node_task_repo["Task repository"]
  node_event_repo["Event repository"]
  node_outbox_repo["Outbox repository"]
  node_result_repo["Report-result repository"]
  node_mysql[("MySQL")]
  node_redis_store["Redis idempotency"]
  node_redis[("Redis")]
  node_filesystem[("Report files")]
end

node_client(("API client"))

node_client -->|"submits and queries"| node_task_api
node_task_api -->|"submits task"| node_submission
node_submission -->|"validates report"| node_payload_parser
node_submission -->|"checks and reserves"| node_idempotency
node_submission -->|"looks up task"| node_task_repo
node_submission -->|"creates task"| node_creation_tx
node_creation_tx -->|"persists task"| node_task_repo
node_creation_tx -->|"records creation"| node_task_events
node_creation_tx -->|"writes outbox event"| node_outbox_repo
node_task_events -->|"persists event"| node_event_repo
node_outbox -->|"reads pending events"| node_outbox_repo
node_outbox -->|"dispatches events"| node_outbox_publisher
node_outbox_publisher -->|"publishes task"| node_rabbit
node_rabbit -->|"delivers message"| node_listener
node_listener -->|"dispatches task"| node_processor
node_processor -->|"generates CSV"| node_report_generator
node_processor -->|"stores report"| node_report_storage
node_report_storage -->|"writes and loads files"| node_filesystem
node_processor -->|"updates task"| node_task_repo
node_processor -->|"records progress"| node_task_events
node_processor -->|"stores result metadata"| node_result_repo
node_task_api -->|"requests download"| node_report_query
node_report_query -->|"checks task status"| node_task_repo
node_report_query -->|"reads result metadata"| node_result_repo
node_report_query -->|"loads report"| node_report_storage
node_task_api -->|"lists tasks"| node_task_repo
node_task_api -->|"reads event history"| node_event_repo
node_task_api -->|"cancels task"| node_cancellation
node_cancellation -->|"loads and updates task"| node_task_repo
node_cancellation -->|"records cancellation"| node_task_events
node_internal_api -->|"replays or compensates"| node_recovery
node_recovery -->|"loads and updates task"| node_task_repo
node_recovery -->|"records recovery"| node_task_events
node_recovery -->|"requeues replay"| node_rabbit
node_stale_scanner -->|"finds stale tasks"| node_task_repo
node_task_repo -->|"reads and writes"| node_mysql
node_event_repo -->|"reads and writes"| node_mysql
node_outbox_repo -->|"reads and writes"| node_mysql
node_result_repo -->|"reads and writes"| node_mysql
node_idempotency -.->|"uses configured store"| node_redis_store
node_redis_store -.->|"stores short-lived mappings"| node_redis
node_task_domain -->|"state persisted with task"| node_task_repo

click node_task_api "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/api/TaskController.java"
click node_internal_api "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/api/InternalTaskController.java"
click node_submission "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskSubmissionService.java"
click node_payload_parser "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportPayloadParser.java"
click node_idempotency "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/idempotency/IdempotencyStore.java"
click node_creation_tx "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskCreationTransaction.java"
click node_task_domain "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/domain/TaskStateMachine.java"
click node_task_events "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskEventRecorder.java"
click node_outbox "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/messaging/OutboxScheduler.java"
click node_outbox_publisher "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/messaging/OutboxPublisher.java"
click node_listener "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/messaging/TaskListener.java"
click node_processor "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskProcessor.java"
click node_report_generator "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/SalesReportGenerator.java"
click node_report_storage "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportStorage.java"
click node_report_query "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportQueryService.java"
click node_recovery "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/RecoveryService.java"
click node_cancellation "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskCancellationService.java"
click node_stale_scanner "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/StaleTaskScanner.java"
click node_task_repo "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/repository/TaskRepository.java"
click node_event_repo "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/repository/TaskEventRepository.java"
click node_outbox_repo "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/repository/OutboxEventRepository.java"
click node_result_repo "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportResultRepository.java"
click node_redis_store "https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/idempotency/RedisIdempotencyStore.java"

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_task_api,node_internal_api,node_client toneBlue
class node_submission,node_creation_tx,node_listener,node_processor toneAmber
class node_payload_parser,node_report_generator,node_report_storage,node_report_query toneMint
class node_idempotency,node_task_domain,node_task_events,node_recovery,node_cancellation,node_stale_scanner toneRose
class node_outbox,node_outbox_publisher,node_rabbit,node_task_repo,node_event_repo,node_outbox_repo,node_result_repo,node_mysql,node_redis_store,node_redis,node_filesystem toneIndigo
```

## Components

### Task API

- [Task endpoints](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/api/TaskController.java): `src/main/java/io/github/asyncflow/api/TaskController.java`
- [Recovery endpoints](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/api/InternalTaskController.java): `src/main/java/io/github/asyncflow/api/InternalTaskController.java`

### Async execution

- [Task submission](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskSubmissionService.java): `src/main/java/io/github/asyncflow/service/TaskSubmissionService.java`
- [Creation transaction](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskCreationTransaction.java): `src/main/java/io/github/asyncflow/service/TaskCreationTransaction.java`
- [Task listener](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/messaging/TaskListener.java): `src/main/java/io/github/asyncflow/messaging/TaskListener.java`
- [Task processor](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskProcessor.java): `src/main/java/io/github/asyncflow/service/TaskProcessor.java`

### Report lifecycle

- [Payload validation](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportPayloadParser.java): `src/main/java/io/github/asyncflow/report/ReportPayloadParser.java`
- [Sales report generator](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/SalesReportGenerator.java): `src/main/java/io/github/asyncflow/report/SalesReportGenerator.java`
- [CSV storage](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportStorage.java): `src/main/java/io/github/asyncflow/report/ReportStorage.java`
- [Result query](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportQueryService.java): `src/main/java/io/github/asyncflow/report/ReportQueryService.java`

### State and recovery

- [Idempotency store](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/idempotency/IdempotencyStore.java): `src/main/java/io/github/asyncflow/idempotency/IdempotencyStore.java`
- [Task state model](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/domain/TaskStateMachine.java): `src/main/java/io/github/asyncflow/domain/TaskStateMachine.java`
- [Event recording](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskEventRecorder.java): `src/main/java/io/github/asyncflow/service/TaskEventRecorder.java`
- [Replay and compensation](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/RecoveryService.java): `src/main/java/io/github/asyncflow/service/RecoveryService.java`
- [Task cancellation](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/TaskCancellationService.java): `src/main/java/io/github/asyncflow/service/TaskCancellationService.java`
- [Stale-task scanner](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/service/StaleTaskScanner.java): `src/main/java/io/github/asyncflow/service/StaleTaskScanner.java`

### Persistence and messaging

- [Outbox scheduling](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/messaging/OutboxScheduler.java): `src/main/java/io/github/asyncflow/messaging/OutboxScheduler.java`
- [Outbox publisher](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/messaging/OutboxPublisher.java): `src/main/java/io/github/asyncflow/messaging/OutboxPublisher.java`
- **RabbitMQ**
- [Task repository](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/repository/TaskRepository.java): `src/main/java/io/github/asyncflow/repository/TaskRepository.java`
- [Event repository](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/repository/TaskEventRepository.java): `src/main/java/io/github/asyncflow/repository/TaskEventRepository.java`
- [Outbox repository](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/repository/OutboxEventRepository.java): `src/main/java/io/github/asyncflow/repository/OutboxEventRepository.java`
- [Report-result repository](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/report/ReportResultRepository.java): `src/main/java/io/github/asyncflow/report/ReportResultRepository.java`
- **MySQL**
- [Redis idempotency](https://github.com/jinbriden/asyncflow/blob/main/src/main/java/io/github/asyncflow/idempotency/RedisIdempotencyStore.java): `src/main/java/io/github/asyncflow/idempotency/RedisIdempotencyStore.java`
- **Redis**
- **Report files**

### Other components

- **API client**

## Connections

- API client → Task endpoints: submits and queries
- Task endpoints → Task submission: submits task
- Task submission → Payload validation: validates report
- Task submission → Idempotency store: checks and reserves
- Task submission → Task repository: looks up task
- Task submission → Creation transaction: creates task
- Creation transaction → Task repository: persists task
- Creation transaction → Event recording: records creation
- Creation transaction → Outbox repository: writes outbox event
- Event recording → Event repository: persists event
- Outbox scheduling → Outbox repository: reads pending events
- Outbox scheduling → Outbox publisher: dispatches events
- Outbox publisher → RabbitMQ: publishes task
- RabbitMQ → Task listener: delivers message
- Task listener → Task processor: dispatches task
- Task processor → Sales report generator: generates CSV
- Task processor → CSV storage: stores report
- CSV storage → Report files: writes and loads files
- Task processor → Task repository: updates task
- Task processor → Event recording: records progress
- Task processor → Report-result repository: stores result metadata
- Task endpoints → Result query: requests download
- Result query → Task repository: checks task status
- Result query → Report-result repository: reads result metadata
- Result query → CSV storage: loads report
- Task endpoints → Task repository: lists tasks
- Task endpoints → Event repository: reads event history
- Task endpoints → Task cancellation: cancels task
- Task cancellation → Task repository: loads and updates task
- Task cancellation → Event recording: records cancellation
- Recovery endpoints → Replay and compensation: replays or compensates
- Replay and compensation → Task repository: loads and updates task
- Replay and compensation → Event recording: records recovery
- Replay and compensation → RabbitMQ: requeues replay
- Stale-task scanner → Task repository: finds stale tasks
- Task repository → MySQL: reads and writes
- Event repository → MySQL: reads and writes
- Outbox repository → MySQL: reads and writes
- Report-result repository → MySQL: reads and writes
- Idempotency store → Redis idempotency: uses configured store
- Redis idempotency → Redis: stores short-lived mappings
- Task state model → Task repository: state persisted with task
