Summary
The Knowledge Base / Database section is accessible in the UI but completely non-functional. A full database infrastructure was designed and coded (PostgreSQL, Redis, Qdrant, ORM models, repositories, cache layer, RAG pipeline) — but none of it was ever connected to the running application. The /api/v1/knowledge/search endpoint fakes results by calling the generic LLM and returning a single hardcoded result with score 0.95.
Root Causes
1. BLOCKER — metadata reserved attribute name (src/medex/db/models.py L367)
The Message ORM model uses metadata as a column name, which is reserved by SQLAlchemy's DeclarativeBase. This causes an immediate InvalidRequestError on import, making the entire src/medex/db/ package unimportable:
sqlalchemy.exc.InvalidRequestError: Attribute name 'metadata' is reserved when using the Declarative API.
2. BLOCKER — Alembic migration never run
The migration file exists at alembic/versions/001_initial_schema.py but was never applied. The PostgreSQL database only has the app_config table (from init-db.sql). The ORM tables (users, conversations, messages, patient_contexts, tool_executions, kb_index) do not exist.
3. BLOCKER — No DB/Redis/Qdrant initialization in startup
MedeXApplication.startup() in src/medex/main.py only initializes LLM, Tools, and Agent services. No database connection, no Redis connection, no Qdrant client is created. The ServiceContainer never receives db, cache, or rag registrations.
4. BLOCKER — RAG explicitly disabled
The agent config at main.py L232 sets enable_rag=False. Even if everything else were fixed, RAG would still be off.
5. Fake endpoint — /api/v1/knowledge/search
# run_api.py L781-807 — What it actually does:
response = await medex_app.query(query=request.query, user_type="professional")
return {"results": [{"id": "kb_1", "title": "MedeX Knowledge Response",
"content": response.get("response", "..."),
"source": "MedeX RAG", "score": 0.95, "category": "medical"}]}
Always returns exactly 1 result with hardcoded score 0.95. No actual database query occurs.
6. Stub endpoint — /api/v1/search
MedeXApplication.search() always returns {"results": [], "total": 0}.
7. Zero Qdrant collections
The Qdrant container is running but has zero collections. No embeddings have ever been indexed. The collections referenced in .env.example (medex_conditions, medex_medications) were never created.
8. Legacy KB data never indexed
medical_knowledge_base.py (916 lines) and pharmaceutical_database.py (582 lines) at the project root contain rich in-memory medical data (conditions, medications, procedures, protocols, lab values, drug monographs, interactions). This data was never embedded or indexed into Qdrant.
Infrastructure Status
| Component |
Status |
PostgreSQL 16 (medex-postgres) |
✅ Container running, only app_config table |
Redis 7 (medex-redis) |
✅ Container running, not connected by app |
Qdrant 1.12.1 (medex-qdrant) |
⚠️ Running but unhealthy, 0 collections |
src/medex/db/models.py |
❌ Cannot import (reserved name bug) |
src/medex/db/connection.py |
❌ Cannot import (depends on models.py) |
src/medex/db/repositories.py |
❌ Cannot import (depends on models.py) |
src/medex/db/cache.py |
⚪ Code complete, never instantiated |
src/medex/rag/ |
⚪ Code complete, never used (enable_rag=False) |
Technical Tasks
A. Fix Database Layer
B. Wire DB/Redis/Qdrant into Application Startup
C. Knowledge Base Indexing Pipeline
D. Implement Real Search Endpoints
E. Tests
Files Affected
| File |
Change |
src/medex/db/models.py L367 |
Rename metadata → message_metadata |
src/medex/main.py |
Add DB/Redis/Qdrant init to startup(), set enable_rag=True |
run_api.py L768-816 |
Replace fake endpoints with real search |
.env |
Add database configuration vars |
New: scripts/index_knowledge_base.py |
Indexing pipeline |
Makefile |
Add index-kb target |
tests/ |
New DB + RAG integration tests |
Summary
The Knowledge Base / Database section is accessible in the UI but completely non-functional. A full database infrastructure was designed and coded (PostgreSQL, Redis, Qdrant, ORM models, repositories, cache layer, RAG pipeline) — but none of it was ever connected to the running application. The
/api/v1/knowledge/searchendpoint fakes results by calling the generic LLM and returning a single hardcoded result with score 0.95.Root Causes
1. BLOCKER —
metadatareserved attribute name (src/medex/db/models.pyL367)The
MessageORM model usesmetadataas a column name, which is reserved by SQLAlchemy's DeclarativeBase. This causes an immediateInvalidRequestErroron import, making the entiresrc/medex/db/package unimportable:2. BLOCKER — Alembic migration never run
The migration file exists at
alembic/versions/001_initial_schema.pybut was never applied. The PostgreSQL database only has theapp_configtable (frominit-db.sql). The ORM tables (users,conversations,messages,patient_contexts,tool_executions,kb_index) do not exist.3. BLOCKER — No DB/Redis/Qdrant initialization in startup
MedeXApplication.startup()insrc/medex/main.pyonly initializes LLM, Tools, and Agent services. No database connection, no Redis connection, no Qdrant client is created. TheServiceContainernever receivesdb,cache, orragregistrations.4. BLOCKER — RAG explicitly disabled
The agent config at
main.pyL232 setsenable_rag=False. Even if everything else were fixed, RAG would still be off.5. Fake endpoint —
/api/v1/knowledge/searchAlways returns exactly 1 result with hardcoded score 0.95. No actual database query occurs.
6. Stub endpoint —
/api/v1/searchMedeXApplication.search()always returns{"results": [], "total": 0}.7. Zero Qdrant collections
The Qdrant container is running but has zero collections. No embeddings have ever been indexed. The collections referenced in
.env.example(medex_conditions,medex_medications) were never created.8. Legacy KB data never indexed
medical_knowledge_base.py(916 lines) andpharmaceutical_database.py(582 lines) at the project root contain rich in-memory medical data (conditions, medications, procedures, protocols, lab values, drug monographs, interactions). This data was never embedded or indexed into Qdrant.Infrastructure Status
medex-postgres)app_configtablemedex-redis)medex-qdrant)src/medex/db/models.pysrc/medex/db/connection.pysrc/medex/db/repositories.pysrc/medex/db/cache.pysrc/medex/rag/enable_rag=False)Technical Tasks
A. Fix Database Layer
metadata→message_metadatainsrc/medex/db/models.pyMessage classsrc/medex/db/package imports successfullyalembic upgrade headto create ORM tablesusers,conversations,messages,patient_contexts,tool_executions,kb_indexB. Wire DB/Redis/Qdrant into Application Startup
MedeXApplication.startup()usingsrc/medex/db/connection.pysrc/medex/db/cache.pydb,cache,ragservices inServiceContainer.envwith database configuration from.env.exampletemplateC. Knowledge Base Indexing Pipeline
medical_knowledge_base.pyandpharmaceutical_database.pyall-MiniLM-L6-v2(or configured model)medex_conditions,medex_medications)make index-kbcommand to MakefileD. Implement Real Search Endpoints
/api/v1/knowledge/searchwith actual Qdrant vector search via RAG serviceMedeXApplication.search()method (currently stub returning empty)/api/v1/knowledge/statsto return real counts from DB/Qdrantenable_rag=Truein agent configE. Tests
Files Affected
src/medex/db/models.pyL367metadata→message_metadatasrc/medex/main.pyenable_rag=Truerun_api.pyL768-816.envscripts/index_knowledge_base.pyMakefileindex-kbtargettests/