Solution Architecture
DeskDox EDMS is delivered as a containerized application stack with clearly separated presentation, API, data, conversion, preview, indexing, and integration responsibilities.
Verified Production Services
The current production compose files define the following runtime services:
| Service | Role | Repository evidence |
|---|---|---|
frontend | NGINX-served React application and same-origin /api/ reverse proxy to backend. | docker-compose.prod.yml, deploy-kit/compose/docker-compose.production.yml, frontend/nginx.conf |
backend | FastAPI application, REST API, authentication, RBAC, workflows, document operations, settings, backup APIs, and startup orchestration. | Production Compose files and backend service entry point |
postgres | PostgreSQL database for application state, metadata, users, roles, workflows, audit records, jobs, and settings. | Production Compose files |
gotenberg | Document conversion service used for Office/PDF preview workflows. | Production Compose files |
preview-worker | Dedicated worker process for preview generation jobs. | Production Compose files and preview worker entry point |
index-worker | Dedicated worker process for OCR, search indexing, and retrieval/index artifacts. | Production Compose files and index worker entry point |
Redis and Celery are not deployed as services in the current production compose baseline. The application code contains optional REDIS_URL support for limited AI rate-limiting and WhatsApp state paths, but this is not a required production service in the current packaged deployment. Celery is not part of the active production runtime topology.
Logical Service Groups
| Service group | DeskDox implementation | Planning note |
|---|---|---|
| Presentation layer | frontend container running NGINX and static React assets. | Public user access should terminate at HTTPS before reaching this layer. |
| Application/API layer | backend container running Uvicorn/FastAPI on port 8000 inside the stack. | Direct public exposure should be avoided unless a reviewed deployment model requires it. |
| PostgreSQL data layer | postgres service on internal port 5432. | Must remain internal-only. |
| Document storage layer | Mounted filesystem paths for /app/files and related data directories. | Requires durable storage and backup coverage. |
| Preview/conversion layer | gotenberg service and preview-worker. | Converter must remain internal-only. |
| OCR/indexing/search layer | index-worker, Tesseract configuration, FAISS/index directories. | Sizing depends heavily on scanned documents and OCR percentage. |
| Integration layer | SMTP, WhatsApp Cloud API, OpenAI/Azure/Ollama, or local LLM endpoints when enabled. | Outbound access and secrets are customer-controlled. |
Logical Architecture Diagram
flowchart LR
U[User browser] --> RP[Customer DNS / TLS / reverse proxy]
RP --> FE[frontend - NGINX / React]
FE -->|/api/ proxy| API[backend - FastAPI]
API --> DB[(postgres)]
API --> FS[(uploaded documents)]
API --> BK[(backup storage)]
API --> GW[gotenberg]
PW[preview-worker] --> FS
PW --> PREV[(preview artifacts)]
PW --> GW
IW[index-worker] --> FS
IW --> IDX[(FAISS / index data)]
API --> SMTP[SMTP relay]
API --> WA[WhatsApp Cloud API]
API --> AI[OpenAI / Azure / Ollama when enabled]Single-Server Docker Compose Topology
flowchart TB
subgraph Host["Single production host"]
Proxy["Customer reverse proxy or host binding"]
subgraph Net["Docker network"]
FE["frontend"]
API["backend"]
PG["postgres"]
GO["gotenberg"]
PW["preview-worker"]
IW["index-worker"]
end
subgraph Volumes["Persistent volumes"]
PGDATA[("PostgreSQL data")]
UPLOADS[("Uploaded documents")]
PREVIEWS[("Preview artifacts")]
INDEX[("FAISS and index data")]
BACKUPS[("Backup directory")]
LICENSE[("Licensing state")]
end
end
Proxy --> FE
FE --> API
API --> PG
API --> UPLOADS
API --> BACKUPS
API --> LICENSE
PW --> UPLOADS
PW --> PREVIEWS
PW --> GO
IW --> UPLOADS
IW --> INDEX
PG --> PGDATABrowser-to-Application Flow
- The user accesses the approved public DeskDox URL.
- DNS resolves the FQDN to the customer-controlled host or reverse proxy.
- TLS is terminated at the customer-approved edge, reverse proxy, or equivalent network layer.
- The request reaches the
frontendservice. - Static application assets are served by NGINX.
- API requests under
/api/are proxied by NGINX to thebackendservice on internal port8000. - The backend validates authentication, authorization, request limits, and business rules before reading or writing database and file storage.
Document Upload Flow
sequenceDiagram
participant B as Browser
participant F as Frontend
participant A as Backend API
participant D as PostgreSQL
participant S as Document storage
participant P as Preview worker
participant I as Index worker
participant G as Gotenberg
B->>F: Upload document
F->>A: POST /api/v1 documents
A->>S: Store uploaded binary
A->>D: Store metadata, version, permissions, audit events
A->>D: Queue preview/index work
P->>D: Claim preview job
P->>S: Read source file
P->>G: Convert if required
P->>S: Write preview artifact
I->>D: Claim indexing work
I->>S: Read source file
I->>D: Update search/OCR statusPreview Generation Flow
Preview generation is handled by the preview-worker. The worker reads source documents from mounted file storage, calls Gotenberg for supported conversion workflows, and writes preview artifacts to the preview data path. In the deploy-kit compose file, CONVERTER_URL is set to http://gotenberg:3000; in root production compose, Gotenberg is also the configured converter endpoint.
Preview workload is CPU and I/O sensitive. Office-document conversion can be materially heavier than simple PDF preview handling.
OCR, Indexing, and Search Flow
The index-worker handles indexing work. OCR is controlled by environment settings such as OCR_ENABLED, TESSERACT_CMD, TESSERACT_LANG, OCR_MAX_PAGES, and OCR_MIN_TEXT_THRESHOLD. Index and retrieval artifacts are stored under the configured FAISS/data directory, mounted in production as /app/data/faiss.
Sizing must account for the percentage of scanned documents, average page count, language coverage, OCR page limits, and expected search freshness.
flowchart LR
Upload["Uploaded document"] --> Job["Indexing job record"]
Job --> Worker["index-worker"]
Worker --> Extract["Text extraction"]
Worker --> OCR["OCR when text is insufficient"]
Extract --> Index[("FAISS and search index data")]
OCR --> Index
Index --> Search["Search results"]
Index --> Emii["Emii retrieval when enabled"]Public Link and Email Flow
Document sharing, public document links, file requests, password reset, and notification emails depend on correct FRONTEND_URL or PUBLIC_URL configuration and SMTP readiness. The application embeds the public URL in outbound links, so production deployments must not use local-only URLs when DEBUG=false.
Outbound SMTP uses customer-provided settings. Email delivery quality, relay rate limits, mailbox reputation, and external spam controls remain customer or SMTP-provider responsibilities.
sequenceDiagram
participant U as Authenticated user
participant F as Frontend
participant A as Backend API
participant M as SMTP relay
participant R as Recipient
participant S as Document storage
U->>F: Share document or send email
F->>A: Request controlled link
A->>A: Validate permission and create token
A->>M: Send email with public link
M->>R: Deliver message
R->>A: Open public link
A->>A: Validate token, expiry, and policy
A->>S: Read permitted file
A->>R: Serve allowed document responseBackup Flow
Production backup coverage must include:
- PostgreSQL database dump or equivalent database backup.
- Uploaded document binaries.
- Preview artifacts where required for operational continuity.
- FAISS/search/index data where required to avoid reprocessing.
- Licensing data.
- Backup metadata and retention evidence.
The Windows deploy-kit backup.ps1 script creates a database dump and copies uploads, faiss, and previews from DATA_ROOT. Application backup services are also configured through BACKUP_ROOT and BACKUP_ENCRYPTION_KEY. Restore handling should be validated against the selected deployment model before go-live.
