This repository contains a distributed Document Management System built as a microservices-based lab project. It combines a React frontend, several Spring Boot backend services, a Python translation worker, and Kubernetes deployment manifests for running the full platform locally.
The platform supports document upload and management, authentication, comments, service orchestration, and asynchronous translation workflows.
- JWT-based authentication and role-aware access
- Document upload, listing, details, and file storage
- Comments managed by a dedicated service
- Asynchronous translation pipeline using Kafka and a Python worker
- Local deployment with Minikube and Kubernetes manifests
flowchart LR
UI[Frontend UI]
GW[Gateway Service]
AUTH[Auth Service]
DOCS[Documents Service]
COMM[Comments Service]
ORCH[Orchestration Service]
TRANS[Translator Service]
AUTHDB[(Auth PostgreSQL)]
DOCSDB[(Documents PostgreSQL)]
CASS[(Comments Cassandra)]
REDIS[(Redis)]
MINIO[(MinIO)]
KAFKA[[Kafka]]
LLM((OpenRouter or Gemini API))
UI --> GW
GW --> AUTH
GW --> DOCS
GW --> COMM
GW --> ORCH
AUTH --> AUTHDB
DOCS --> DOCSDB
DOCS --> REDIS
DOCS --> MINIO
DOCS --> COMM
COMM --> CASS
ORCH --> DOCS
ORCH --> COMM
DOCS --> KAFKA
KAFKA --> TRANS
TRANS --> MINIO
TRANS --> LLM
.
├── backend/
│ ├── authentication/ # authentication service
│ ├── documents/ # documents service
│ ├── orchestration/ # orchestration service
│ ├── gateway/ # gateway service
│ ├── comments/ # comments service
│ ├── s3/ # additional service assets / experiments
│ └── translation/ # translator worker (Python)
├── frontend/
│ └── ui/ # React + Vite frontend
├── infra/
│ ├── Compose/
│ ├── benchmark/
│ └── k8s/ # Kubernetes manifests and helper scripts
├── architecture.mmd
└── README.md
| Service | Stack | Responsibility |
|---|---|---|
| Gateway | Spring Cloud Gateway | Single entry point for client API requests |
| Authentication | Spring Boot + PostgreSQL | Login, identity, roles, JWT issuance |
| Documents | Spring Boot + PostgreSQL + MinIO + Redis | Document metadata, storage integration, and translation event publishing |
| Comments | Spring Boot + Cassandra | Comment creation and retrieval |
| Orchestration | Spring Boot | Cross-service workflow aggregation |
| Translation | Python worker + Kafka | Consumes translation events and calls the LLM provider |
| Frontend | React + Vite | User and admin web interface |
Prerequisites:
- Docker
- Minikube
- kubectl
- fish shell
- jq
- An API key stored in
openrouter_key.txtat the repository root
Start the backend platform:
cd infra/k8s
fish build-and-load.fish minikube
fish deploy.fish
kubectl -n dms port-forward svc/gateway-service 8090:8080Then start the frontend in another terminal:
cd frontend/ui
npm install
npm run devOpen http://localhost:5173.
cd frontend/ui
npm install
npm run db
npm run devThis runs the React app with the local mock backend used for UI development and testing.
This section is the complete setup flow for running the full platform on Kubernetes.
- Docker installed and running
- Minikube installed
- kubectl installed
- fish shell installed
- jq installed
- API key stored in openrouter_key.txt at the repository root
On Debian/Ubuntu, example package install:
sudo apt update
sudo apt install -y fish jqminikube start
kubectl cluster-infocd infra/k8s
fish build-and-load.fish minikubeThis builds and prepares these images:
- dms/documents-service:latest
- dms/comments-service:latest
- dms/gateway-service:latest
- dms/auth-service:latest
- dms/orchestration-service:latest
- dms/translator:latest
cd infra/k8s
fish deploy.fishDeployment includes:
- Namespace and secrets
- PostgreSQL (documents and auth)
- Cassandra
- MinIO
- Redis
- Kafka
- Auth, Documents, Comments, Orchestration, Translator, Gateway services
kubectl -n dms get podsAll pods should be Running and ready.
If a service is failing:
kubectl -n dms logs deploy/<service-name> --tail=120Keep these running in dedicated terminals.
Gateway:
kubectl -n dms port-forward svc/gateway-service 8090:8080MinIO console (optional):
kubectl -n dms port-forward svc/minio-service 9000:9000 9001:9001MinIO console URL: http://localhost:9001 Default local credentials: admin / ensia2026
Login test:
curl -s -X POST http://localhost:8090/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","password":"password123"}' | jq .Use token for authenticated calls:
TOKEN=$(curl -s -X POST http://localhost:8090/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","password":"password123"}' | jq -r .token)
curl -s http://localhost:8090/api/documents/list \
-H "Authorization: Bearer $TOKEN" | jq .cd frontend/ui
npm install
npm run devOpen: http://localhost:5173
- Log in from the frontend.
- Upload a document.
- Open document details.
- Click Translate.
- Wait a few seconds and refresh to confirm translated fields.
Optional logs:
kubectl -n dms logs deploy/translator -f
kubectl -n dms logs deploy/documents-service -fIf Docker is stopped:
sudo systemctl start docker
systemctl is-active dockerThen recover cluster:
minikube start
kubectl cluster-info
kubectl get ns dms
kubectl -n dms get podsWait for core infra:
kubectl -n dms rollout status statefulset/docs-postgres --timeout=240s || true
kubectl -n dms rollout status statefulset/auth-postgres --timeout=240s || true
kubectl -n dms rollout status statefulset/cassandra --timeout=240s || true
kubectl -n dms rollout status deployment/minio --timeout=240s || true
kubectl -n dms rollout status deployment/redis --timeout=240s || true
kubectl -n dms rollout status deployment/kafka --timeout=300s || trueRestart app deployments in order:
kubectl -n dms rollout restart deployment/auth-service
kubectl -n dms rollout status deployment/auth-service --timeout=240s
kubectl -n dms rollout restart deployment/documents-service
kubectl -n dms rollout status deployment/documents-service --timeout=240s
kubectl -n dms rollout restart deployment/comments-service
kubectl -n dms rollout status deployment/comments-service --timeout=240s
kubectl -n dms rollout restart deployment/translator
kubectl -n dms rollout status deployment/translator --timeout=240s
kubectl -n dms rollout restart deployment/orchestration-service
kubectl -n dms rollout status deployment/orchestration-service --timeout=240s
kubectl -n dms rollout restart deployment/gateway-service
kubectl -n dms rollout status deployment/gateway-service --timeout=240sExample for auth service:
docker build -t dms/auth-service:latest backend/authentication
minikube image load dms/auth-service:latest
kubectl -n dms rollout restart deployment/auth-service
kubectl -n dms rollout status deployment/auth-service --timeout=180sExample for documents service:
docker build -t dms/documents-service:latest backend/documents
minikube image load dms/documents-service:latest
kubectl -n dms rollout restart deployment/documents-service
kubectl -n dms rollout status deployment/documents-service --timeout=180skubectl -n dms exec statefulset/docs-postgres -- \
psql -U dmsuser -d documentsdb -c \
"TRUNCATE TABLE document, app_user, department, category RESTART IDENTITY CASCADE;"
kubectl -n dms rollout restart deployment/documents-service
kubectl -n dms rollout status deployment/documents-service --timeout=180sComments service keyspace issue:
kubectl -n dms exec statefulset/cassandra -- cqlsh -e \
"CREATE KEYSPACE IF NOT EXISTS dms WITH replication = {'class':'SimpleStrategy','replication_factor':1};"
kubectl -n dms rollout restart deployment/comments-serviceTranslator secret/key issue:
kubectl -n dms create secret generic openrouter-secret \
--from-literal=gemini-api-key="$(cat openrouter_key.txt)" \
--dry-run=client -o yaml | kubectl apply -f -
kubectl -n dms rollout restart deployment/translatorGateway not reachable from UI:
kubectl -n dms port-forward svc/gateway-service 8090:8080kubectl delete namespace dms- Full Kubernetes deployment guide: infra/k8s/README.md
- Frontend guide and scripts: frontend/ui/README.md
- Documents service notes: backend/documents/C2_README.md
- Auth service decisions: backend/authentication/DECISIONS.md
- Built with React 19 and Vite
- Includes Cypress and Playwright configuration
- Supports user and admin flows
- Java services are structured as separate Maven projects
- Dockerfiles are provided per service
- Kubernetes manifests are maintained under
infra/k8s/
- A document-related event is published by the Documents service.
- Kafka delivers the event to the Translator worker.
- The Translator calls the external LLM provider.
- The translated output is stored and surfaced back through the platform.
Useful checks after deployment:
kubectl -n dms get pods
curl -s -X POST http://localhost:8090/api/auth/login \
-H 'Content-Type: application/json' \
-d '{"email":"user@example.com","password":"password123"}'If you are only validating the frontend locally:
cd frontend/ui
npm run cy:run- React, Vite, Cypress, Playwright
- Spring Boot, Spring Cloud Gateway, Maven
- PostgreSQL, Cassandra, Redis, MinIO
- Kafka
- Python
- Docker, Kubernetes, Minikube
This repository was created for academic and lab use. Add a project license here if you plan to publish it more broadly.