Personal Life Operating System — an AI-powered backend that turns natural-language journal entries into structured life data, manages a personal knowledge base with hybrid search and RAG chat, and exposes everything through a multi-service API.
Write a journal entry in plain English. PLOS extracts your sleep, mood, calories, activities, social interactions, locations, and health symptoms — stores them relationally — and lets you query them with natural language. Upload any document or URL and it lives in a searchable knowledge base with a knowledge graph, RAG chat, and AI-powered organisation.
Quick Start · API · Knowledge Base · Docs · Coming Next
- Journal AI pipeline — 5-stage extraction (preprocess → context retrieval → Gemini extraction → gap resolution → normalised storage), 9 data types, 80+ activity vocabulary, interactive gap-resolution loop
- 11 report types — sleep, mood, calories, nutrition, social, health, work, activity, water, steps, and custom date ranges
- Knowledge Base — ingest text, PDF, images, Office files, and social URLs (Reddit, Twitter/X, LinkedIn, Instagram, YouTube) into a personal knowledge base
- Hybrid search — 3-tier RRF fusion: Qdrant semantic (768-dim) + PostgreSQL full-text + Meilisearch typo-tolerant, with cross-encoder reranking and MMR diversity
- RAG chat — Gemini-powered conversational search with source attribution over your own documents
- Knowledge graph — NER entity extraction, disambiguation, path finding, co-occurrence, centrality analysis, and timeline
- AI bucket organisation — documents auto-routed to buckets; hierarchical tree, bulk moves, route preview
- Resilient Gemini client — multi-key rotation, per-key quota tracking, task-type model dispatch
- Multi-tenancy — all data scoped by JWT user; anonymous graceful degradation
- Observability — Prometheus
/metrics, structured logging, DLQ monitoring on every service
graph TD
subgraph Client
C[Client Request]
end
C --> G["Kong API Gateway - Port 8000 - Reverse proxy, rate limiting, routing"]
subgraph Services
G --> CB["Context Broker - Port 8001 - User state, context windows, session cache"]
G --> JP["Journal Parser - Port 8002 - 5-stage Gemini AI extraction, auth, JWT"]
G --> KB["Knowledge Base - Port 8003 - Document ingestion, hybrid search, RAG chat, knowledge graph"]
end
subgraph "Journal AI Pipeline"
JP --> P1["Stage 1: Preprocessing - Text cleanup, spell correction, time normalization"]
P1 --> P2["Stage 2: Context Retrieval - User baseline, patterns, relationship state"]
P2 --> P3["Stage 3: Gemini Extraction - AI-powered extraction, gap detection"]
P3 --> P4["Stage 4: Storage - Normalized relational storage"]
P3 --> Gap["Gap Resolution Loop - Interactive clarification"]
Gap --> P3
end
subgraph "Hybrid Search"
KB --> S1["Tier 1: Semantic - Qdrant HNSW 60%"]
KB --> S2["Tier 2: Full-Text - PostgreSQL tsvector 30%"]
KB --> S3["Tier 3: Typo-Tolerant - Meilisearch fuzzy 10%"]
S1 --> F["RRF Fusion k=60"]
S2 --> F
S3 --> F
F --> R["Cross-Encoder Reranking + MMR Diversity"]
end
subgraph "RAG Chat"
KB --> RC["Gemini-powered conversational search - Source attribution"]
end
subgraph "Knowledge Graph"
KB --> E["NER Entity Extraction - Disambiguation, co-occurrence"]
E --> P["Path Finding - Centrality analysis, timeline"]
end
subgraph Infrastructure
CB --> DB["PostgreSQL - Primary data store"]
JP --> DB
KB --> DB
CB --> R["Redis - Cache, session store"]
JP --> R
KB --> R
CB --> K["Kafka - Async event streaming"]
JP --> K
KB --> K
KB --> Q["Qdrant - Vector embeddings 768-dim"]
KB --> M["Meilisearch - Typo-tolerant search"]
KB --> Min["MinIO - Object storage"]
end
| Service | Port | Responsibility |
|---|---|---|
api-gateway |
8000 | Kong DB-less reverse proxy, rate limiting, routing |
context-broker |
8001 | User context state, Redis caching, context window management |
journal-parser |
8002 | Journal ingestion, 5-stage Gemini AI extraction, 11 report types |
knowledge-base |
8003 | Document ingestion, hybrid search, RAG chat, knowledge graph, bucket organisation |
| Component | Image | Purpose |
|---|---|---|
| PostgreSQL | supabase/postgres:15.8.1.060 |
Primary data store |
| Redis | redis:7-alpine |
Cache, session store, search L2 cache |
| Qdrant | qdrant/qdrant:v1.12.0 |
Vector embeddings (768-dim) |
| Meilisearch | getmeili/meilisearch:v1.11 |
Typo-tolerant full-text search |
| MinIO | minio/minio |
Object storage for raw documents |
| Kafka + Zookeeper | confluentinc/cp-kafka:7.5.0 |
Async event streaming |
- Docker Engine >= 24 with Compose plugin >= 2.x
- 8 GB RAM available to Docker
- A Google Gemini API key
git clone https://github.com/Sathish111j/PLOS-backend.git
cd PLOS-backend
# First-time setup: checks prerequisites, creates .env
./scripts/setup/setup.sh
# Edit .env and set GEMINI_API_KEY (required)
# Then start the full stack
./scripts/start/dev.shdev.sh handles: infrastructure startup → DB readiness wait → schema migrations → seed → application services → health checks.
Verify everything is healthy:
./scripts/verify/verify-infrastructure.sh
./scripts/verify/smoke-e2e.sh # end-to-end API smoke testCopy .env.example to .env. Minimum required variables:
# Gemini — supports multi-key rotation (pipe-delimited, name optional)
GEMINI_API_KEYS=AIzaSy...key1|primary,AIzaSy...key2|backup-1
# Database
POSTGRES_USER=postgres
POSTGRES_PASSWORD=plos_db_secure_2025
POSTGRES_DB=plos
# Redis
REDIS_PASSWORD=plos_redis_secure_2025
# Meilisearch
MEILISEARCH_MASTER_KEY=plos_meili_secure_2025Optional: MINIO_ENABLED, USE_GEMINI_CACHING, LOG_LEVEL, GEMINI_API_KEY_ROTATION_ENABLED, GEMINI_API_KEY_ROTATION_BACKOFF_SECONDS.
Core services start by default. Optional services require explicit profiles:
docker compose --profile studio up -d # Supabase Studio UI :3000
docker compose --profile monitoring up -d # Prometheus + Grafana :9090 / :3333
docker compose --profile ui up -d # Kafka UI :18080
docker compose --profile bi up -d # Metabase BI :3001
docker compose --profile test up -d # Isolated test environmentAll traffic goes through the gateway at :8000. Interactive docs at each service's /docs path.
POST /auth/register — register · POST /auth/login — obtain JWT · GET /auth/me — current user
POST /journal/process — submit a journal entry (plain English); pass require_complete: true to enforce gap filling before storage.
POST /journal/resolve-gap · POST /journal/resolve-paragraph · GET /journal/pending-gaps — interactive gap-resolution loop when the AI needs clarification on missing data.
/reports/overview · /reports/calories · /reports/sleep · /reports/mood · /reports/water · /reports/steps · /reports/activity · /reports/nutrition · /reports/social · /reports/health · /reports/work
GET /context/{user_id} · POST /context/update · GET /context/{user_id}/summary · POST /context/{user_id}/invalidate
Buckets — GET /kb/buckets · POST /kb/buckets · GET /kb/buckets/tree · POST /kb/buckets/{id}/move · DELETE /kb/buckets/{id} · POST /kb/buckets/bulk-move-documents · POST /kb/buckets/route-preview
Knowledge graph — GET /kb/graph/entity/search · GET /kb/graph/entity/{id} · GET /kb/graph/document/{doc_id}/entities · GET /kb/graph/related/{entity_id} · GET /kb/graph/path · GET /kb/graph/cooccurring · GET /kb/graph/centrality · GET /kb/graph/timeline · GET /kb/graph/stats
Operations — GET /kb/ops/embedding-dlq/stats · POST /kb/ops/embedding-dlq/reprocess-unreplayable · POST /kb/ops/embedding-dlq/purge-unreplayable
Full endpoint reference: docs/API_REFERENCE.md
The most feature-rich service. Details: docs/KB_FEATURES_AND_FLOWS.md
Ingestion pipeline — base64 or URL → checksum deduplication → semantic chunking → 768-dim Gemini embeddings → Qdrant + Meilisearch + PostgreSQL → NER entity extraction → AI bucket routing → 4-stage integrity chain.
Supported formats: plain text, PDF, images, Office (docx/xlsx/pptx), web URLs, and social media URLs — Reddit, Twitter/X, LinkedIn, Instagram, YouTube.
Hybrid search — 3-tier RRF fusion across Qdrant (semantic, 60%), PostgreSQL tsvector (full-text, 30%), and Meilisearch (typo-tolerant, 10%). Dynamic intent weights auto-adjust per query type (conceptual / exact phrase / navigational / typo-heavy / filter-heavy). Cross-encoder reranking blends relevance, recency, engagement, and bucket context. Post-rerank MMR diversity. Two-layer cache: in-process LRU (5 min) + Redis (1 hr).
RAG chat — Gemini-powered, retrieves from your documents via hybrid search, returns answers with source attribution and session continuity.
Knowledge graph — NER entity extraction → disambiguation → Kuzu graph store. Query entity relations, find paths, rank by centrality, view co-occurrence clusters, and explore timelines.
Bucket organisation — four default buckets (Research and Reference / Work and Projects / Web and Media Saves / Needs Classification) created automatically. Hierarchical tree, AI auto-routing on ingest, bulk moves, route preview endpoint, protected defaults.
4-stage integrity chain — each document tracks chain_hash + verified flag across: ingestion / chunking / embedding / entity extraction.
Error format — {"detail": "...", "error_code": "AUTHENTICATION_FAILED|VALIDATION_ERROR|NOT_FOUND|RATE_LIMITED|INTERNAL_ERROR"}
Migrations are tracked in infrastructure/database/migrations/ and applied incrementally via schema_migrations table.
# Apply pending migrations
./scripts/setup/migrate.sh
# Seed initial data
./scripts/setup/seed.shThe migration runner is idempotent — safe to run against an existing database.
PLOS-backend/
├── services/
│ ├── api-gateway/ Kong configuration (kong.yml, kong.conf)
│ ├── context-broker/ FastAPI service + Dockerfile
│ ├── journal-parser/ FastAPI service + Dockerfile
│ └── knowledge-base/ FastAPI service + Dockerfile + split requirements/
├── shared/
│ ├── auth/ JWT validation, user models, auth middleware
│ ├── gemini/ Resilient Gemini client with key rotation
│ ├── kafka/ Producer abstraction, topic definitions
│ ├── models/ Shared Pydantic models
│ └── utils/ Config, logging, metrics helpers
├── infrastructure/
│ ├── database/ init.sql, migrations/, seed.sql
│ ├── kafka/ init-topics.sh
│ ├── monitoring/ prometheus.yml, alerts.yml, Grafana provisioning
│ └── redis/ redis.conf
├── scripts/
│ ├── lint/lint.sh
│ ├── setup/{setup,migrate,seed}.sh
│ ├── start/dev.sh
│ ├── stop/stop.sh
│ ├── verify/{verify-infrastructure,smoke-e2e}.sh
│ └── dev-tools/ Local debugging scripts (not for CI)
├── tests/ pytest integration and E2E tests
├── docs/ Architecture, API reference, setup guides
├── docker-compose.yml
├── docker-compose.dev.yml Volume mounts for hot reload
└── pyproject.toml Linter config (black, ruff, isort)
./scripts/lint/lint.sh # check
./scripts/lint/lint.sh --fix # auto-fixRuns black, ruff, and isort against services/ and shared/.
pytest services/ shared/ tests/ -vdocker-compose.dev.yml mounts local source into containers. Services restart on code change:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d./scripts/stop/stop.sh # stop, keep volumes
./scripts/stop/stop.sh --clean # stop and delete all data| Doc | Contents |
|---|---|
| docs/QUICKSTART.md | Step-by-step local setup |
| docs/API_REFERENCE.md | Full API reference for all services |
| docs/ARCHITECTURE_STANDARDS.md | Service design conventions |
| docs/JOURNAL_PROCESSING_FLOW.md | Journal → AI extraction → storage pipeline |
| docs/KB_FEATURES_AND_FLOWS.md | Knowledge base ingestion and search |
| docs/HYBRID_SEARCH_ARCHITECTURE.md | Qdrant + Meilisearch hybrid search design |
| shared/gemini/DOCUMENTATION.md | Gemini client configuration and key rotation |
Telegram AI Integration — natural-language journal input and knowledge base queries directly from Telegram. Send a message like "I ran 5 km and had oatmeal for breakfast" or "find my notes on machine learning" — the same Gemini pipeline processes it and responds in-chat, no app needed.
See CONTRIBUTING.md.
License: GPL-3.0-or-later