# vitordan/herbariumback architecture

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

- Interactive diagram: https://gitdiagram.com/vitordan/herbariumback
- Repository: https://github.com/vitordan/herbariumback

## Overview

This is a Flask API for managing herbarium specimen (“exsiccate”) records, including taxonomy, collection locations, collectors, and associated images, plus user signup and login. The primary workflow accepts specimen data and uploaded images, dispatches record and image-metadata work to Celery tasks, stores structured records in the SQLAlchemy database and image files under the configured upload folder, and returns serialized results. The graph includes the API setup and authentication branches. Source excerpts show task dispatch and database operations; image-file persistence is visible, but broader storage and deployment details are not established.

Main entry points: [`app/api/exsiccate/tasks.py`](https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/tasks.py) (Record tasks), [`app/api/exsiccate/urls.py`](https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/urls.py) (Specimen routes), [`app/api/factory.py`](https://github.com/vitordan/herbariumback/blob/main/app/api/factory.py) (App factory), [`app/api/users/account.py`](https://github.com/vitordan/herbariumback/blob/main/app/api/users/account.py) (Account routes)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["API and routing"]
  node_app_factory["App factory<br/>[factory.py]"]
  node_specimen_routes["Specimen routes<br/>[urls.py]"]
  node_config["App configuration<br/>[config.py]"]
end

subgraph group_specimens["Specimen records"]
  node_record_tasks["Record tasks<br/>[tasks.py]"]
  node_serializers["Serializers<br/>[serializers.py]"]
  node_domain_models["Domain models<br/>[models.py]"]
end

subgraph group_identity["User identity"]
  node_account_routes["Account routes<br/>[account.py]"]
  node_token_auth["Token auth<br/>[auth.py]"]
  node_user_tasks["User tasks<br/>[tasks.py]"]
end

subgraph group_async["Async and images"]
  node_image_routes["Image access<br/>[path.py]"]
  node_celery_setup["Celery setup<br/>[__init__.py]"]
  node_celery_config["Task configuration<br/>[celery_config.py]"]
  node_task_context["Task context<br/>[cutils.py]"]
  node_task_broker["Task broker"]
end

subgraph group_persistence["Persistence"]
  node_sql_database[("SQL database<br/>[models.py]")]
  node_image_files["Image files<br/>[tasks.py]"]
end

node_client(("API client"))

node_client -->|"submits requests"| node_specimen_routes
node_client -.->|"uses account API"| node_account_routes
node_app_factory -->|"registers route"| node_specimen_routes
node_app_factory -->|"loads routes"| node_account_routes
node_app_factory -->|"loads settings"| node_config
node_app_factory -->|"initializes Celery"| node_task_context
node_specimen_routes -->|"dispatches tasks"| node_record_tasks
node_specimen_routes -->|"parses and formats"| node_serializers
node_record_tasks -->|"queries and updates"| node_domain_models
node_record_tasks -->|"serializes results"| node_serializers
node_serializers -->|"maps model data"| node_domain_models
node_domain_models -->|"defines mapped tables"| node_sql_database
node_specimen_routes -->|"requests image access"| node_image_routes
node_record_tasks -->|"creates image paths"| node_image_files
node_account_routes -->|"dispatches login tasks"| node_user_tasks
node_account_routes -->|"guards user route"| node_token_auth
node_user_tasks -->|"reads and saves users"| node_domain_models
node_user_tasks -.->|"imports serializers"| node_serializers
node_celery_setup -->|"reads broker settings"| node_celery_config
node_celery_config -->|"configures broker"| node_task_broker
node_task_context -->|"wraps task execution"| node_celery_setup
node_record_tasks -.->|"runs asynchronously"| node_task_broker

click node_app_factory "https://github.com/vitordan/herbariumback/blob/main/app/api/factory.py"
click node_specimen_routes "https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/urls.py"
click node_account_routes "https://github.com/vitordan/herbariumback/blob/main/app/api/users/account.py"
click node_token_auth "https://github.com/vitordan/herbariumback/blob/main/app/api/auth.py"
click node_user_tasks "https://github.com/vitordan/herbariumback/blob/main/app/api/users/tasks.py"
click node_record_tasks "https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/tasks.py"
click node_serializers "https://github.com/vitordan/herbariumback/blob/main/app/api/serializers.py"
click node_domain_models "https://github.com/vitordan/herbariumback/blob/main/app/api/models.py"
click node_sql_database "https://github.com/vitordan/herbariumback/blob/main/app/api/models.py"
click node_image_routes "https://github.com/vitordan/herbariumback/blob/main/app/api/images/path.py"
click node_celery_setup "https://github.com/vitordan/herbariumback/blob/main/app/api/__init__.py"
click node_celery_config "https://github.com/vitordan/herbariumback/blob/main/app/celery_config.py"
click node_task_context "https://github.com/vitordan/herbariumback/blob/main/app/api/cutils.py"
click node_image_files "https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/tasks.py"
click node_config "https://github.com/vitordan/herbariumback/blob/main/app/config.py"

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_app_factory,node_specimen_routes,node_config,node_client toneBlue
class node_record_tasks,node_serializers,node_domain_models toneAmber
class node_account_routes,node_token_auth,node_user_tasks toneMint
class node_image_routes,node_celery_setup,node_celery_config,node_task_context,node_task_broker toneRose
class node_sql_database,node_image_files toneIndigo
```

## Components

### API and routing

- [App factory](https://github.com/vitordan/herbariumback/blob/main/app/api/factory.py): `app/api/factory.py`
- [Specimen routes](https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/urls.py): `app/api/exsiccate/urls.py`
- [App configuration](https://github.com/vitordan/herbariumback/blob/main/app/config.py): `app/config.py`

### Specimen records

- [Record tasks](https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/tasks.py): `app/api/exsiccate/tasks.py`
- [Serializers](https://github.com/vitordan/herbariumback/blob/main/app/api/serializers.py): `app/api/serializers.py`
- [Domain models](https://github.com/vitordan/herbariumback/blob/main/app/api/models.py): `app/api/models.py`

### User identity

- [Account routes](https://github.com/vitordan/herbariumback/blob/main/app/api/users/account.py): `app/api/users/account.py`
- [Token auth](https://github.com/vitordan/herbariumback/blob/main/app/api/auth.py): `app/api/auth.py`
- [User tasks](https://github.com/vitordan/herbariumback/blob/main/app/api/users/tasks.py): `app/api/users/tasks.py`

### Async and images

- [Image access](https://github.com/vitordan/herbariumback/blob/main/app/api/images/path.py): `app/api/images/path.py`
- [Celery setup](https://github.com/vitordan/herbariumback/blob/main/app/api/__init__.py): `app/api/__init__.py`
- [Task configuration](https://github.com/vitordan/herbariumback/blob/main/app/celery_config.py): `app/celery_config.py`
- [Task context](https://github.com/vitordan/herbariumback/blob/main/app/api/cutils.py): `app/api/cutils.py`
- **Task broker**

### Persistence

- [SQL database](https://github.com/vitordan/herbariumback/blob/main/app/api/models.py): `app/api/models.py`
- [Image files](https://github.com/vitordan/herbariumback/blob/main/app/api/exsiccate/tasks.py): `app/api/exsiccate/tasks.py`

### Other components

- **API client**

## Connections

- API client → Specimen routes: submits requests
- API client → Account routes: uses account API
- App factory → Specimen routes: registers route (evidence: `app/api/factory.py`)
- App factory → Account routes: loads routes (evidence: `app/api/factory.py`)
- App factory → App configuration: loads settings (evidence: `app/api/factory.py`)
- App factory → Task context: initializes Celery (evidence: `app/api/factory.py`)
- Specimen routes → Record tasks: dispatches tasks (evidence: `app/api/exsiccate/urls.py`)
- Specimen routes → Serializers: parses and formats (evidence: `app/api/exsiccate/urls.py`)
- Record tasks → Domain models: queries and updates (evidence: `app/api/exsiccate/tasks.py`)
- Record tasks → Serializers: serializes results (evidence: `app/api/exsiccate/tasks.py`)
- Serializers → Domain models: maps model data (evidence: `app/api/serializers.py`)
- Domain models → SQL database: defines mapped tables (evidence: `app/api/models.py`)
- Specimen routes → Image access: requests image access (evidence: `app/api/exsiccate/urls.py`)
- Record tasks → Image files: creates image paths (evidence: `app/api/exsiccate/tasks.py`)
- Account routes → User tasks: dispatches login tasks (evidence: `app/api/users/account.py`)
- Account routes → Token auth: guards user route (evidence: `app/api/users/account.py`)
- User tasks → Domain models: reads and saves users (evidence: `app/api/users/tasks.py`)
- User tasks → Serializers: imports serializers (evidence: `app/api/users/tasks.py`)
- Celery setup → Task configuration: reads broker settings (evidence: `app/api/__init__.py`)
- Task configuration → Task broker: configures broker (evidence: `app/celery_config.py`)
- Task context → Celery setup: wraps task execution (evidence: `app/api/cutils.py`)
- Record tasks → Task broker: runs asynchronously
