# abiolr/aeterna-rag architecture

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

- Interactive diagram: https://gitdiagram.com/abiolr/aeterna-rag
- Repository: https://github.com/abiolr/aeterna-rag

## Overview

Aeterna is a FastAPI service that accepts files and returns explainable, citation-backed survivability scores. The main workflow authenticates and rate-limits a request, checks for a cached result, extracts file metadata, gathers PRONOM/LoC facts and semantic context, then asks an LLM for evidence-based sub-scores. Python computes the final weighted score before the response is cached and returned. The README documents capabilities beyond the sampled code; those links are shown where documented, while uncertain internal wiring is omitted.

Main entry points: [`app.py`](https://github.com/abiolr/aeterna-rag/blob/main/app.py) (FastAPI routes), [`services/llm_inference.py`](https://github.com/abiolr/aeterna-rag/blob/main/services/llm_inference.py) (LLM inference), [`services/data_pipeline.py`](https://github.com/abiolr/aeterna-rag/blob/main/services/data_pipeline.py) (Context assembly), [`services/auth.py`](https://github.com/abiolr/aeterna-rag/blob/main/services/auth.py) (API key auth)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_api["API and access"]
  node_api["FastAPI routes<br/>[app.py]"]
  node_auth["API key auth<br/>[auth.py]"]
  node_limiter["Rate limiting<br/>[cache.py]"]
  node_upload["Temporary upload<br/>[app.py]"]
end

subgraph group_context["Evidence gathering"]
  node_metadata["Metadata extraction<br/>[file_extraction.py]"]
  node_gather["Context assembly<br/>[data_pipeline.py]"]
  node_lookup["Format lookup<br/>[build_lookup_db.py]"]
  node_vector["Similar formats<br/>[vector_db_setup.py]"]
end

subgraph group_scoring["Scoring"]
  node_prompt["Scoring prompt<br/>[system_prompt.py]"]
  node_inference["LLM inference<br/>[llm_inference.py]"]
  node_score["Weighted score<br/>[llm_inference.py]"]
end

subgraph group_state["Data and state"]
  node_cache["Score cache<br/>[cache.py]"]
  node_postgres[("PostgreSQL")]
  node_redis[("Redis")]
  node_vectorstore[("Chroma store")]
  node_registrydata["PRONOM and LoC data"]
  node_locdocs["LoC vector documents"]
end

node_client(("API client"))
node_anthropic{{"Anthropic API"}}

node_client -->|"submits file"| node_api
node_api -->|"validates key"| node_auth
node_auth -->|"checks key hash"| node_postgres
node_api -->|"checks limits"| node_limiter
node_limiter -->|"increments counter"| node_redis
node_client -->|"requests key"| node_api
node_api -->|"generates key"| node_auth
node_auth -->|"stores key hash"| node_postgres
node_api -->|"saves upload"| node_upload
node_api -->|"checks result"| node_cache
node_cache -->|"reads cache"| node_redis
node_api -->|"runs scoring"| node_inference
node_inference -->|"requests context"| node_gather
node_gather -->|"extracts metadata"| node_metadata
node_gather -->|"looks up extension"| node_lookup
node_lookup -->|"queries formats"| node_postgres
node_registrydata -.->|"seeds lookup data"| node_postgres
node_gather -->|"searches context"| node_vector
node_vector -->|"queries documents"| node_vectorstore
node_locdocs -.->|"seeds documents"| node_vectorstore
node_inference -->|"builds prompt"| node_prompt
node_inference -->|"requests analysis"| node_anthropic
node_inference -->|"computes from subscores"| node_score
node_inference -->|"returns result"| node_api
node_api -->|"stores result"| node_cache
node_cache -->|"writes cached result"| node_redis
node_api -->|"returns score"| node_client

click node_api "https://github.com/abiolr/aeterna-rag/blob/main/app.py"
click node_auth "https://github.com/abiolr/aeterna-rag/blob/main/services/auth.py"
click node_limiter "https://github.com/abiolr/aeterna-rag/blob/main/services/cache.py"
click node_upload "https://github.com/abiolr/aeterna-rag/blob/main/app.py"
click node_metadata "https://github.com/abiolr/aeterna-rag/blob/main/services/file_extraction.py"
click node_gather "https://github.com/abiolr/aeterna-rag/blob/main/services/data_pipeline.py"
click node_lookup "https://github.com/abiolr/aeterna-rag/blob/main/services/build_lookup_db.py"
click node_vector "https://github.com/abiolr/aeterna-rag/blob/main/services/vector_db_setup.py"
click node_prompt "https://github.com/abiolr/aeterna-rag/blob/main/services/system_prompt.py"
click node_inference "https://github.com/abiolr/aeterna-rag/blob/main/services/llm_inference.py"
click node_score "https://github.com/abiolr/aeterna-rag/blob/main/services/llm_inference.py"
click node_cache "https://github.com/abiolr/aeterna-rag/blob/main/services/cache.py"
click node_vectorstore "https://github.com/abiolr/aeterna-rag/tree/main/db/aeterna_vector_db"
click node_registrydata "https://github.com/abiolr/aeterna-rag/tree/main/data"
click node_locdocs "https://github.com/abiolr/aeterna-rag/blob/main/data/loc_vector_docs.json"

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_auth,node_limiter,node_upload,node_client toneBlue
class node_metadata,node_gather,node_lookup,node_vector toneAmber
class node_prompt,node_inference,node_score,node_anthropic toneMint
class node_cache,node_postgres,node_redis,node_vectorstore,node_registrydata,node_locdocs toneRose
```

## Components

### API and access

- [FastAPI routes](https://github.com/abiolr/aeterna-rag/blob/main/app.py): `app.py`
- [API key auth](https://github.com/abiolr/aeterna-rag/blob/main/services/auth.py): `services/auth.py`
- [Rate limiting](https://github.com/abiolr/aeterna-rag/blob/main/services/cache.py): `services/cache.py`
- [Temporary upload](https://github.com/abiolr/aeterna-rag/blob/main/app.py): `app.py`

### Evidence gathering

- [Metadata extraction](https://github.com/abiolr/aeterna-rag/blob/main/services/file_extraction.py): `services/file_extraction.py`
- [Context assembly](https://github.com/abiolr/aeterna-rag/blob/main/services/data_pipeline.py): `services/data_pipeline.py`
- [Format lookup](https://github.com/abiolr/aeterna-rag/blob/main/services/build_lookup_db.py): `services/build_lookup_db.py`
- [Similar formats](https://github.com/abiolr/aeterna-rag/blob/main/services/vector_db_setup.py): `services/vector_db_setup.py`

### Scoring

- [Scoring prompt](https://github.com/abiolr/aeterna-rag/blob/main/services/system_prompt.py): `services/system_prompt.py`
- [LLM inference](https://github.com/abiolr/aeterna-rag/blob/main/services/llm_inference.py): `services/llm_inference.py`
- [Weighted score](https://github.com/abiolr/aeterna-rag/blob/main/services/llm_inference.py): `services/llm_inference.py`

### Data and state

- [Score cache](https://github.com/abiolr/aeterna-rag/blob/main/services/cache.py): `services/cache.py`
- **PostgreSQL**
- **Redis**
- [Chroma store](https://github.com/abiolr/aeterna-rag/tree/main/db/aeterna_vector_db): `db/aeterna_vector_db`
- [PRONOM and LoC data](https://github.com/abiolr/aeterna-rag/tree/main/data): `data`
- [LoC vector documents](https://github.com/abiolr/aeterna-rag/blob/main/data/loc_vector_docs.json): `data/loc_vector_docs.json`

### Other components

- **API client**
- **Anthropic API**

## Connections

- API client → FastAPI routes: submits file
- FastAPI routes → API key auth: validates key
- API key auth → PostgreSQL: checks key hash
- FastAPI routes → Rate limiting: checks limits
- Rate limiting → Redis: increments counter
- API client → FastAPI routes: requests key
- FastAPI routes → API key auth: generates key
- API key auth → PostgreSQL: stores key hash
- FastAPI routes → Temporary upload: saves upload
- FastAPI routes → Score cache: checks result
- Score cache → Redis: reads cache
- FastAPI routes → LLM inference: runs scoring
- LLM inference → Context assembly: requests context
- Context assembly → Metadata extraction: extracts metadata
- Context assembly → Format lookup: looks up extension
- Format lookup → PostgreSQL: queries formats
- PRONOM and LoC data → PostgreSQL: seeds lookup data
- Context assembly → Similar formats: searches context
- Similar formats → Chroma store: queries documents
- LoC vector documents → Chroma store: seeds documents
- LLM inference → Scoring prompt: builds prompt
- LLM inference → Anthropic API: requests analysis
- LLM inference → Weighted score: computes from subscores
- LLM inference → FastAPI routes: returns result
- FastAPI routes → Score cache: stores result
- Score cache → Redis: writes cached result
- FastAPI routes → API client: returns score
