# Architecture Overview
This document details the architecture of the `book-translator` plugin.
## Architecture decisions
The indexed [architecture decision records](../decisions/README.md) preserve
the security, release, cache and deployment rationale, including superseded
decisions.
## Overview
The plugin operates as a decoupled overlay in front of a stock reader. Reader
connectors isolate upstream-specific routes, DOM and authentication from the
translation/cache/provider core. There are three deployment profiles:
1. **Universal hub (`btctl`, recommended).** One non-root container runs a
distinct Gunicorn API process per enabled reader plus one namespaced nginx
listener per reader. APIs bind only to loopback and use separate databases,
session keys, connector IDs and cookies. `BT_ENABLE_CWA` and
`BT_ENABLE_KAVITA` enable either or both without changing the image. Any
child exit stops the complete container. This simplifies deployment at the
cost of one shared compromise and restart boundary. See
[ADR-015](../decisions/ADR-015-universal-reader-hub.md).
2. **Decoupled reverse proxy architecture (SWAG / master proxy).** The master
reverse proxy fronts stock reader instances (CWA, Kavita) directly on their
native ports and injects `` via
HTTP `sub_filter`. The translation hub operates in pure API mode
(`BT_ROLE=api`, `CWA_UPSTREAM=""`) serving `/bt-api/` and static assets under
`/bt-static/`. This fully isolates reader uptime from translator lifecycle
and eliminates redundant internal proxy worker overhead. See
[ADR-018](../decisions/ADR-018-decoupled-reverse-proxy-and-draggable-controls.md).
3. **Managed split profile (`btctl`, advanced isolation).** Two isolated non-root
containers run the same release image with `BT_ROLE=proxy` and
`BT_ROLE=api`. nginx sits in front of a **stock** CWA or pinned Kavita
instance (`BT_READER_UPSTREAM`). HTML responses get a
single `