# t-teieki/onaka-log architecture

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

- Interactive diagram: https://gitdiagram.com/t-teieki/onaka-log
- Repository: https://github.com/t-teieki/onaka-log

## Overview

onaka-log is a food nutrition estimation and meal-logging backend for a planned mobile app. The principal workflow accepts label or meal-photo images for estimation, or a barcode for product lookup; it converts results into food-item candidates, then supports creating and updating meals and retrieving day summaries. The API also validates requests against shared contracts and persists meals through configurable repositories. The graph follows the sampled API and bootstrap code; unsampled API routes and client internals are represented only where documented or explicitly wired.

Main entry points: [`apps/api/src/onaka_api/api/app.py`](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py) (HTTP API), [`apps/api/src/onaka_api/main.py`](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/main.py) (App bootstrap), [`apps/api/src/onaka_api/estimation/drafts.py`](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/estimation/drafts.py) (Candidate conversion), [`apps/api/src/onaka_api/repository/__init__.py`](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/repository/__init__.py) (Meal repository)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["API and workflow"]
  node_api["HTTP API<br/>[app.py]"]
  node_api_contracts["API contracts<br/>[openapi.yaml]"]
  node_bootstrap["App bootstrap<br/>[main.py]"]
  node_settings["Runtime settings<br/>[settings.py]"]
end

subgraph group_estimation["Estimation and lookup"]
  node_llm_contracts["LLM contracts"]
  node_label_estimation["Label estimation<br/>[app.py]"]
  node_photo_estimation["Photo estimation<br/>[app.py]"]
  node_barcode_lookup["Barcode lookup<br/>[app.py]"]
  node_draft_conversion["Candidate conversion<br/>[drafts.py]"]
end

subgraph group_domain["Meal domain and storage"]
  node_meal_domain["Meal rules<br/>[meal.py]"]
  node_repository_contract["Meal repository<br/>[__init__.py]"]
  node_dynamodb_repo[("DynamoDB store<br/>[dynamodb.py]")]
  node_memory_repo[("Memory store<br/>[memory.py]")]
end

subgraph group_integrations["External integrations"]
  node_claude_estimator["Claude estimator<br/>[claude.py]"]
  node_off_client["OFF client<br/>[off.py]"]
end

node_mobile(("Mobile app"))
node_claude_service{{"Anthropic Claude"}}
node_off_service{{"Open Food Facts"}}

node_mobile -->|"sends requests"| node_api
node_api -->|"validates requests"| node_api_contracts
node_api -->|"routes label requests"| node_label_estimation
node_api -->|"routes photo requests"| node_photo_estimation
node_api -->|"routes product lookups"| node_barcode_lookup
node_label_estimation -->|"validates image input"| node_llm_contracts
node_photo_estimation -->|"validates image input"| node_llm_contracts
node_label_estimation -->|"converts results"| node_draft_conversion
node_photo_estimation -->|"converts results"| node_draft_conversion
node_barcode_lookup -->|"converts product data"| node_draft_conversion
node_bootstrap -->|"assembles app"| node_api
node_bootstrap -->|"loads configuration"| node_settings
node_bootstrap -->|"configures estimator"| node_claude_estimator
node_bootstrap -->|"configures client"| node_off_client
node_bootstrap -->|"selects store"| node_dynamodb_repo
node_bootstrap -->|"selects store"| node_memory_repo
node_claude_estimator -.->|"calls model"| node_claude_service
node_off_client -.->|"fetches products"| node_off_service
node_api -->|"creates and updates meals"| node_meal_domain
node_api -->|"reads and writes meals"| node_repository_contract
node_dynamodb_repo -->|"implements"| node_repository_contract
node_memory_repo -->|"implements"| node_repository_contract

click node_api "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py"
click node_api_contracts "https://github.com/t-teieki/onaka-log/blob/main/contracts/api/openapi.yaml"
click node_llm_contracts "https://github.com/t-teieki/onaka-log/tree/main/contracts/llm"
click node_label_estimation "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py"
click node_photo_estimation "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py"
click node_barcode_lookup "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py"
click node_draft_conversion "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/estimation/drafts.py"
click node_claude_estimator "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/clients/claude.py"
click node_off_client "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/clients/off.py"
click node_meal_domain "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/domain/meal.py"
click node_repository_contract "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/repository/__init__.py"
click node_dynamodb_repo "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/repository/dynamodb.py"
click node_memory_repo "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/repository/memory.py"
click node_bootstrap "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/main.py"
click node_settings "https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/settings.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_api,node_api_contracts,node_bootstrap,node_settings toneBlue
class node_llm_contracts,node_label_estimation,node_photo_estimation,node_barcode_lookup,node_draft_conversion toneAmber
class node_meal_domain,node_repository_contract,node_dynamodb_repo,node_memory_repo toneMint
class node_claude_estimator,node_off_client toneRose
class node_mobile,node_claude_service,node_off_service toneIndigo
```

## Components

### API and workflow

- [HTTP API](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py): `apps/api/src/onaka_api/api/app.py`
- [API contracts](https://github.com/t-teieki/onaka-log/blob/main/contracts/api/openapi.yaml): `contracts/api/openapi.yaml`
- [App bootstrap](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/main.py): `apps/api/src/onaka_api/main.py`
- [Runtime settings](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/settings.py): `apps/api/src/onaka_api/settings.py`

### Estimation and lookup

- [LLM contracts](https://github.com/t-teieki/onaka-log/tree/main/contracts/llm): `contracts/llm`
- [Label estimation](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py): `apps/api/src/onaka_api/api/app.py`
- [Photo estimation](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py): `apps/api/src/onaka_api/api/app.py`
- [Barcode lookup](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/api/app.py): `apps/api/src/onaka_api/api/app.py`
- [Candidate conversion](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/estimation/drafts.py): `apps/api/src/onaka_api/estimation/drafts.py`

### Meal domain and storage

- [Meal rules](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/domain/meal.py): `apps/api/src/onaka_api/domain/meal.py`
- [Meal repository](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/repository/__init__.py): `apps/api/src/onaka_api/repository/__init__.py`
- [DynamoDB store](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/repository/dynamodb.py): `apps/api/src/onaka_api/repository/dynamodb.py`
- [Memory store](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/repository/memory.py): `apps/api/src/onaka_api/repository/memory.py`

### External integrations

- [Claude estimator](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/clients/claude.py): `apps/api/src/onaka_api/clients/claude.py`
- [OFF client](https://github.com/t-teieki/onaka-log/blob/main/apps/api/src/onaka_api/clients/off.py): `apps/api/src/onaka_api/clients/off.py`

### Other components

- **Mobile app**
- **Anthropic Claude**
- **Open Food Facts**

## Connections

- Mobile app → HTTP API: sends requests (evidence: `README.md`)
- HTTP API → API contracts: validates requests (evidence: `apps/api/src/onaka_api/api/app.py`)
- HTTP API → Label estimation: routes label requests (evidence: `apps/api/src/onaka_api/api/app.py`)
- HTTP API → Photo estimation: routes photo requests (evidence: `apps/api/src/onaka_api/api/app.py`)
- HTTP API → Barcode lookup: routes product lookups (evidence: `apps/api/src/onaka_api/api/app.py`)
- Label estimation → LLM contracts: validates image input (evidence: `apps/api/src/onaka_api/api/app.py`)
- Photo estimation → LLM contracts: validates image input (evidence: `apps/api/src/onaka_api/api/app.py`)
- Label estimation → Candidate conversion: converts results (evidence: `apps/api/src/onaka_api/api/app.py`)
- Photo estimation → Candidate conversion: converts results (evidence: `apps/api/src/onaka_api/api/app.py`)
- Barcode lookup → Candidate conversion: converts product data (evidence: `apps/api/src/onaka_api/estimation/drafts.py`)
- App bootstrap → HTTP API: assembles app (evidence: `apps/api/src/onaka_api/main.py`)
- App bootstrap → Runtime settings: loads configuration (evidence: `apps/api/src/onaka_api/main.py`)
- App bootstrap → Claude estimator: configures estimator (evidence: `apps/api/src/onaka_api/main.py`)
- App bootstrap → OFF client: configures client (evidence: `apps/api/src/onaka_api/main.py`)
- App bootstrap → DynamoDB store: selects store (evidence: `apps/api/src/onaka_api/main.py`)
- App bootstrap → Memory store: selects store (evidence: `apps/api/src/onaka_api/main.py`)
- Claude estimator → Anthropic Claude: calls model
- OFF client → Open Food Facts: fetches products
- HTTP API → Meal rules: creates and updates meals (evidence: `apps/api/src/onaka_api/api/app.py`)
- HTTP API → Meal repository: reads and writes meals (evidence: `apps/api/src/onaka_api/api/app.py`)
- DynamoDB store → Meal repository: implements (evidence: `apps/api/src/onaka_api/repository/dynamodb.py`)
- Memory store → Meal repository: implements (evidence: `apps/api/src/onaka_api/repository/memory.py`)
