GitHub Actions commited on
Commit
a066e5a
·
1 Parent(s): edbfac1

Deploy from GitHub Actions (2026-03-12 11:50 UTC)

Browse files
.gitignore CHANGED
@@ -200,6 +200,7 @@ PROJECT.md
200
  # Everything inside `archive` except `daily_log.md`
201
  archive/*
202
  !archive/daily_log.md
 
203
 
204
  # Microservice credentials (sensitive)
205
  services/credentials/*.json
 
200
  # Everything inside `archive` except `daily_log.md`
201
  archive/*
202
  !archive/daily_log.md
203
+ !archive/development_notes/
204
 
205
  # Microservice credentials (sensitive)
206
  services/credentials/*.json
app/main.py CHANGED
@@ -17,6 +17,7 @@ from app.models.conversation_manager import ConversationManager
17
  from app.models.database import init_database, get_database, User, Conversation, Message
18
  from app.models.smart_models import UserPreference, UserInsight, ConversationTopic
19
  from app.data.training_data import TRAINING_DATA
 
20
 
21
  # Load configuration (this sets up logging automatically)
22
  config = get_config()
@@ -54,6 +55,7 @@ async def lifespan(fastapi_app: FastAPI): # pylint: disable=unused-argument
54
 
55
 
56
  app = FastAPI(title=config.api.title, debug=config.api.debug, lifespan=lifespan)
 
57
 
58
  # Enable CORS
59
  app.add_middleware(
@@ -247,4 +249,6 @@ async def get_user_stats(session_id: str):
247
  # Must be mounted LAST so API routes above take precedence
248
  _frontend_dir = Path(__file__).parent.parent / "frontend"
249
  if _frontend_dir.exists():
250
- app.mount("/", StaticFiles(directory=str(_frontend_dir), html=True), name="frontend")
 
 
 
17
  from app.models.database import init_database, get_database, User, Conversation, Message
18
  from app.models.smart_models import UserPreference, UserInsight, ConversationTopic
19
  from app.data.training_data import TRAINING_DATA
20
+ from app.routers import knowledge_base
21
 
22
  # Load configuration (this sets up logging automatically)
23
  config = get_config()
 
55
 
56
 
57
  app = FastAPI(title=config.api.title, debug=config.api.debug, lifespan=lifespan)
58
+ app.include_router(knowledge_base.router)
59
 
60
  # Enable CORS
61
  app.add_middleware(
 
249
  # Must be mounted LAST so API routes above take precedence
250
  _frontend_dir = Path(__file__).parent.parent / "frontend"
251
  if _frontend_dir.exists():
252
+ app.mount(
253
+ "/", StaticFiles(directory=str(_frontend_dir), html=True), name="frontend"
254
+ )
app/models/database.py CHANGED
@@ -185,3 +185,11 @@ def get_database() -> DatabaseManager:
185
  def init_database():
186
  """Initialize the global database manager instance and create tables"""
187
  return db_manager.init_database()
 
 
 
 
 
 
 
 
 
185
  def init_database():
186
  """Initialize the global database manager instance and create tables"""
187
  return db_manager.init_database()
188
+
189
+
190
+ def get_db():
191
+ db = get_database().get_session()
192
+ try:
193
+ yield db
194
+ finally:
195
+ db.close()
app/models/smart_models.py CHANGED
@@ -107,3 +107,20 @@ class UserInsight(Base):
107
 
108
  def __repr__(self):
109
  return f"<UserInsight(id={self.id} user_id={self.user_id}, {self.insight_key}={self.insight_value})>"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
107
 
108
  def __repr__(self):
109
  return f"<UserInsight(id={self.id} user_id={self.user_id}, {self.insight_key}={self.insight_value})>"
110
+
111
+
112
+ class KnowledgeBase(Base):
113
+ __tablename__ = "knowledge_base"
114
+
115
+ id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
116
+ created_at = Column(DateTime, default=lambda: datetime.now(timezone.utc))
117
+ updated_at = Column(
118
+ DateTime,
119
+ default=lambda: datetime.now(timezone.utc),
120
+ onupdate=lambda: datetime.now(timezone.utc),
121
+ )
122
+ tenant_id = Column(UUID(as_uuid=True), nullable=False)
123
+ entry = Column(Text, nullable=False)
124
+
125
+ def __repr__(self):
126
+ return f"<KnowledgeBase(id={self.id} tenant_id={self.tenant_id})>"
app/routers/knowledge_base.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import uuid
2
+
3
+ from fastapi import APIRouter, Depends, HTTPException
4
+ from sqlalchemy import select
5
+ from sqlalchemy.orm import Session
6
+
7
+ from app.models.smart_models import KnowledgeBase
8
+ from app.schemas.knowledge_base import KBEntryCreate, KBEntryResponse, KBEntryUpdate
9
+ from app.models.database import get_db
10
+
11
+ router = APIRouter()
12
+
13
+
14
+ @router.post("/kb/entries", status_code=201, response_model=KBEntryResponse)
15
+ def create_entry(
16
+ entry: KBEntryCreate, db: Session = Depends(get_db)
17
+ ) -> KBEntryResponse:
18
+
19
+ knowledge_base = KnowledgeBase()
20
+ knowledge_base.tenant_id = uuid.uuid4()
21
+ knowledge_base.entry = entry.entry
22
+ db.add(knowledge_base)
23
+ db.commit()
24
+ db.refresh(knowledge_base)
25
+
26
+ return knowledge_base
27
+
28
+
29
+ @router.get("/kb/entries/{entry_id}", status_code=200, response_model=KBEntryResponse)
30
+ def read_entry(entry_id: uuid.UUID, db: Session = Depends(get_db)) -> KBEntryResponse:
31
+
32
+ kb = db.get(KnowledgeBase, entry_id)
33
+
34
+ if kb is None:
35
+ raise HTTPException(status_code=404, detail="Entry not found")
36
+
37
+ return kb
38
+
39
+
40
+ @router.get("/kb/entries", status_code=200, response_model=list[KBEntryResponse])
41
+ def read_entries(db: Session = Depends(get_db)) -> list[KBEntryResponse]:
42
+
43
+ kb_entries = db.scalars(select(KnowledgeBase)).all()
44
+
45
+ return kb_entries
46
+
47
+
48
+ @router.put("/kb/entries/{entry_id}", status_code=200, response_model=KBEntryResponse)
49
+ def update_entry(
50
+ entry_id: uuid.UUID, entry: KBEntryUpdate, db: Session = Depends(get_db)
51
+ ) -> KBEntryResponse:
52
+
53
+ kb = db.get(KnowledgeBase, entry_id)
54
+
55
+ if kb is None:
56
+ raise HTTPException(status_code=404, detail="Entry not found")
57
+ kb.entry = entry.entry
58
+ db.commit()
59
+ db.refresh(kb)
60
+
61
+ return kb
62
+
63
+
64
+ @router.delete("/kb/entries/{entry_id}", status_code=204)
65
+ def delete_entry(entry_id: uuid.UUID, db: Session = Depends(get_db)) -> None:
66
+
67
+ kb = db.get(KnowledgeBase, entry_id)
68
+
69
+ if kb is None:
70
+ raise HTTPException(status_code=404, detail="Entry not found")
71
+
72
+ db.delete(kb)
73
+ db.commit()
74
+
75
+ return
app/schemas/knowledge_base.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from datetime import datetime
2
+ import uuid
3
+ from pydantic import BaseModel
4
+
5
+
6
+ class KBEntryCreate(BaseModel):
7
+ entry: str
8
+
9
+
10
+ class KBEntryResponse(BaseModel):
11
+ id: uuid.UUID
12
+ created_at: datetime
13
+ updated_at: datetime
14
+ tenant_id: uuid.UUID
15
+ entry: str
16
+
17
+
18
+ class KBEntryUpdate(BaseModel):
19
+ entry: str