# lpuigo/trombi architecture

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

- Interactive diagram: https://gitdiagram.com/lpuigo/trombi
- Repository: https://github.com/lpuigo/trombi

## Overview

Trombi is a command-line tool that turns image files into portrait PDFs. Its main workflow expands file or directory inputs, loads and orients each image, detects and selects a face, computes and bounds a portrait crop, then exports either a single-image diagnostic PDF or a paginated batch grid. Batch processing isolates failures per image; the service layer coordinates loading, detection, framing, and cropping. The source excerpts establish these runtime links; the tree supports the image-listing and crop modules, but their implementations were not sampled.

Main entry points: [`cmd/trombi/main.go`](https://github.com/lpuigo/trombi/blob/master/cmd/trombi/main.go) (Command entry), [`service/process.go`](https://github.com/lpuigo/trombi/blob/master/service/process.go) (Image workflow), [`service/batch.go`](https://github.com/lpuigo/trombi/blob/master/service/batch.go) (Batch workflow), [`infra/imageio/loader.go`](https://github.com/lpuigo/trombi/blob/master/infra/imageio/loader.go) (Image loading)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_entry["CLI"]
  node_cli["Command entry<br/>[main.go]"]
end

subgraph group_orchestration["Service"]
  node_service_image["Image workflow<br/>[process.go]"]
  node_service_batch["Batch workflow<br/>[batch.go]"]
end

subgraph group_portrait_domain["Portrait domain"]
  node_portrait_batch["Batch items<br/>[batch.go]"]
  node_portrait_item["Portrait item<br/>[item.go]"]
  node_face_selection["Face selection<br/>[selection.go]"]
  node_framing["Crop geometry<br/>[framing.go]"]
  node_bounds["Crop bounds<br/>[clamp.go]"]
  node_results["Processing results<br/>[result.go]"]
  node_detector_contract["Face detector<br/>[detector.go]"]
end

subgraph group_adapters["Image and PDF adapters"]
  node_file_list["Directory listing<br/>[list.go]"]
  node_image_loader["Image loading<br/>[loader.go]"]
  node_image_decode["Decode and orient<br/>[decode.go]"]
  node_exif["EXIF orientation<br/>[exif.go]"]
  node_cropper["Crop and resize<br/>[crop.go]"]
  node_pigo["Pigo detection<br/>[detector.go]"]
  node_diagnostic_pdf["Diagnostic PDF<br/>[diagnostic.go]"]
  node_grid_pdf["Grid PDF<br/>[grid.go]"]
end

node_operator(("CLI user"))
node_input_images["Image files"]
node_pdf_output["PDF output"]

node_operator -->|"provides inputs"| node_cli
node_cli -->|"lists directories"| node_file_list
node_cli -->|"creates batch"| node_portrait_batch
node_cli -->|"processes image"| node_service_image
node_cli -->|"processes batch"| node_service_batch
node_cli -->|"initializes detector"| node_pigo
node_cli -->|"exports diagnostic"| node_diagnostic_pdf
node_cli -->|"exports grid"| node_grid_pdf
node_input_images -->|"reads files"| node_image_loader
node_file_list -->|"returns paths"| node_cli
node_service_batch -->|"processes items"| node_portrait_item
node_service_batch -->|"loads images"| node_image_loader
node_service_batch -->|"invokes per image"| node_service_image
node_service_image -->|"detects faces"| node_detector_contract
node_pigo -->|"implements"| node_detector_contract
node_service_image -->|"selects face"| node_face_selection
node_service_image -->|"computes crop"| node_framing
node_service_image -->|"fits crop"| node_bounds
node_service_image -->|"crops and resizes"| node_cropper
node_service_image -->|"assembles result"| node_results
node_image_loader -->|"decodes image"| node_image_decode
node_image_decode -->|"reads orientation"| node_exif
node_service_batch -->|"returns updated batch"| node_portrait_batch
node_cli -->|"writes PDF"| node_pdf_output
node_diagnostic_pdf -->|"writes diagnostic"| node_pdf_output
node_grid_pdf -->|"writes grid"| node_pdf_output

click node_cli "https://github.com/lpuigo/trombi/blob/master/cmd/trombi/main.go"
click node_service_image "https://github.com/lpuigo/trombi/blob/master/service/process.go"
click node_service_batch "https://github.com/lpuigo/trombi/blob/master/service/batch.go"
click node_portrait_batch "https://github.com/lpuigo/trombi/blob/master/domain/portrait/batch.go"
click node_portrait_item "https://github.com/lpuigo/trombi/blob/master/domain/portrait/item.go"
click node_face_selection "https://github.com/lpuigo/trombi/blob/master/domain/portrait/selection.go"
click node_framing "https://github.com/lpuigo/trombi/blob/master/domain/portrait/framing.go"
click node_bounds "https://github.com/lpuigo/trombi/blob/master/domain/portrait/clamp.go"
click node_results "https://github.com/lpuigo/trombi/blob/master/domain/portrait/result.go"
click node_detector_contract "https://github.com/lpuigo/trombi/blob/master/domain/portrait/detector.go"
click node_file_list "https://github.com/lpuigo/trombi/blob/master/infra/imageio/list.go"
click node_image_loader "https://github.com/lpuigo/trombi/blob/master/infra/imageio/loader.go"
click node_image_decode "https://github.com/lpuigo/trombi/blob/master/infra/imageio/decode.go"
click node_exif "https://github.com/lpuigo/trombi/blob/master/infra/imageio/exif.go"
click node_cropper "https://github.com/lpuigo/trombi/blob/master/infra/imageio/crop.go"
click node_pigo "https://github.com/lpuigo/trombi/blob/master/infra/facedetect/pigodetect/detector.go"
click node_diagnostic_pdf "https://github.com/lpuigo/trombi/blob/master/infra/pdfexport/diagnostic.go"
click node_grid_pdf "https://github.com/lpuigo/trombi/blob/master/infra/pdfexport/grid.go"

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_cli,node_operator toneBlue
class node_service_image,node_service_batch toneAmber
class node_portrait_batch,node_portrait_item,node_face_selection,node_framing,node_bounds,node_results,node_detector_contract toneMint
class node_file_list,node_image_loader,node_image_decode,node_exif,node_cropper,node_pigo,node_diagnostic_pdf,node_grid_pdf toneRose
class node_input_images,node_pdf_output toneIndigo
```

## Components

### CLI

- [Command entry](https://github.com/lpuigo/trombi/blob/master/cmd/trombi/main.go): `cmd/trombi/main.go`

### Service

- [Image workflow](https://github.com/lpuigo/trombi/blob/master/service/process.go): `service/process.go`
- [Batch workflow](https://github.com/lpuigo/trombi/blob/master/service/batch.go): `service/batch.go`

### Portrait domain

- [Batch items](https://github.com/lpuigo/trombi/blob/master/domain/portrait/batch.go): `domain/portrait/batch.go`
- [Portrait item](https://github.com/lpuigo/trombi/blob/master/domain/portrait/item.go): `domain/portrait/item.go`
- [Face selection](https://github.com/lpuigo/trombi/blob/master/domain/portrait/selection.go): `domain/portrait/selection.go`
- [Crop geometry](https://github.com/lpuigo/trombi/blob/master/domain/portrait/framing.go): `domain/portrait/framing.go`
- [Crop bounds](https://github.com/lpuigo/trombi/blob/master/domain/portrait/clamp.go): `domain/portrait/clamp.go`
- [Processing results](https://github.com/lpuigo/trombi/blob/master/domain/portrait/result.go): `domain/portrait/result.go`
- [Face detector](https://github.com/lpuigo/trombi/blob/master/domain/portrait/detector.go): `domain/portrait/detector.go`

### Image and PDF adapters

- [Directory listing](https://github.com/lpuigo/trombi/blob/master/infra/imageio/list.go): `infra/imageio/list.go`
- [Image loading](https://github.com/lpuigo/trombi/blob/master/infra/imageio/loader.go): `infra/imageio/loader.go`
- [Decode and orient](https://github.com/lpuigo/trombi/blob/master/infra/imageio/decode.go): `infra/imageio/decode.go`
- [EXIF orientation](https://github.com/lpuigo/trombi/blob/master/infra/imageio/exif.go): `infra/imageio/exif.go`
- [Crop and resize](https://github.com/lpuigo/trombi/blob/master/infra/imageio/crop.go): `infra/imageio/crop.go`
- [Pigo detection](https://github.com/lpuigo/trombi/blob/master/infra/facedetect/pigodetect/detector.go): `infra/facedetect/pigodetect/detector.go`
- [Diagnostic PDF](https://github.com/lpuigo/trombi/blob/master/infra/pdfexport/diagnostic.go): `infra/pdfexport/diagnostic.go`
- [Grid PDF](https://github.com/lpuigo/trombi/blob/master/infra/pdfexport/grid.go): `infra/pdfexport/grid.go`

### Other components

- **CLI user**
- **Image files**
- **PDF output**

## Connections

- CLI user → Command entry: provides inputs
- Command entry → Directory listing: lists directories
- Command entry → Batch items: creates batch
- Command entry → Image workflow: processes image
- Command entry → Batch workflow: processes batch
- Command entry → Pigo detection: initializes detector
- Command entry → Diagnostic PDF: exports diagnostic
- Command entry → Grid PDF: exports grid
- Image files → Image loading: reads files
- Directory listing → Command entry: returns paths
- Batch workflow → Portrait item: processes items
- Batch workflow → Image loading: loads images
- Batch workflow → Image workflow: invokes per image
- Image workflow → Face detector: detects faces
- Pigo detection → Face detector: implements
- Image workflow → Face selection: selects face
- Image workflow → Crop geometry: computes crop
- Image workflow → Crop bounds: fits crop
- Image workflow → Crop and resize: crops and resizes
- Image workflow → Processing results: assembles result
- Image loading → Decode and orient: decodes image
- Decode and orient → EXIF orientation: reads orientation
- Batch workflow → Batch items: returns updated batch
- Command entry → PDF output: writes PDF
- Diagnostic PDF → PDF output: writes diagnostic
- Grid PDF → PDF output: writes grid
