- Implemented a new bottom bar feature in `bottom-bar.js` that fetches and displays various notifications and statuses in real-time. - Added functions for handling visibility, state updates, and user interactions within the bottom bar. - Introduced WebSocket connection for real-time updates and fallback polling mechanism. - Created a manual testing script `test_manual.py` to validate API endpoints for the manual module. - Included tests for various paths to ensure expected responses from the server.
96 lines
3.5 KiB
Python
96 lines
3.5 KiB
Python
import re
|
|
|
|
with open("app/modules/manual/backend/router.py", "r") as f:
|
|
text = f.read()
|
|
|
|
# Make sure to import cache
|
|
if "from app.modules.manual.backend.cache import manual_cache" not in text:
|
|
text = text.replace("from app.core.database import", "from app.modules.manual.backend.cache import manual_cache\nfrom app.core.database import")
|
|
|
|
# Patch GET list:
|
|
# It has def get_manual_articles( ... ) -> Dict[str, Any]:
|
|
# Need to inject at the top of that function.
|
|
patch_list = """async def get_manual_articles(
|
|
module: Optional[str] = Query(None, description="Filtrer på modul"),
|
|
difficulty: Optional[DifficultyType] = Query(None, description="Filtrer på sværhedsgrad"),
|
|
tag: Optional[str] = Query(None, description="Filtrer på et bestemt tag"),
|
|
search: Optional[str] = Query(None, description="Søg i titel, summary og content"),
|
|
limit: int = Query(50, ge=1, le=100),
|
|
offset: int = Query(0, ge=0),
|
|
) -> Dict[str, Any]:
|
|
cache_key = f"list:{module}:{difficulty}:{tag}:{search}:{limit}:{offset}"
|
|
cached = manual_cache.get(cache_key)
|
|
if cached:
|
|
return cached"""
|
|
|
|
text = re.sub(
|
|
r'async def get_manual_articles\([^)]*\)\s*->\s*Dict\[str, Any\]:',
|
|
patch_list,
|
|
text
|
|
)
|
|
|
|
# And at the end of get_manual_articles:
|
|
# return {"items": rows, "total": total}
|
|
# Replace with setting cache
|
|
text = text.replace(
|
|
'return {"items": rows, "total": total}',
|
|
'result = {"items": rows, "total": total}\n manual_cache.set(cache_key, result)\n return result'
|
|
)
|
|
|
|
# Patch Context:
|
|
patch_context = """async def contextual_manual_suggestions(
|
|
module: str = Query(..., description="Modulet der søges hjælp ud fra, fx 'Sag'"),
|
|
tag: Optional[str] = Query(None, description="Kategori eller tag fra konteksten"),
|
|
limit: int = Query(5, ge=1, le=10)
|
|
):
|
|
cache_key = f"context:{module}:{tag}:{limit}"
|
|
cached = manual_cache.get(cache_key)
|
|
if cached:
|
|
return cached"""
|
|
|
|
text = re.sub(
|
|
r'async def contextual_manual_suggestions\([^)]*\):',
|
|
patch_context,
|
|
text
|
|
)
|
|
# return {"results": rows}
|
|
text = text.replace(
|
|
'return {"results": rows}',
|
|
'result = {"results": rows}\n manual_cache.set(cache_key, result)\n return result'
|
|
)
|
|
|
|
# Patch Get Slug:
|
|
patch_slug = """async def get_manual_article(slug: str, background_tasks: BackgroundTasks):
|
|
cache_key = f"slug:{slug}"
|
|
cached = manual_cache.get(cache_key)
|
|
|
|
if cached:
|
|
background_tasks.add_task(_increment_use_count, cached["id"])
|
|
return cached"""
|
|
|
|
text = re.sub(
|
|
r'async def get_manual_article\(slug: str.*?BackgroundTasks[^)]*\):',
|
|
patch_slug,
|
|
text
|
|
)
|
|
|
|
text = re.sub(
|
|
r'return \{\s*"article": article,\s*"steps": steps,\s*"relations": related\s*\}',
|
|
'result = {"article": article, "steps": steps, "relations": related}\n manual_cache.set(cache_key, result)\n return result',
|
|
text
|
|
)
|
|
|
|
# Invalidation:
|
|
mutations = ['async def create_manual_article', 'async def update_manual_article', 'async def delete_manual_article']
|
|
for m in mutations:
|
|
text = text.replace(m, "@manual_cache.clear\n" + m)
|
|
|
|
# Actually, the python decorator is not made in cache.py, let me just add manual_cache.clear() inside them instead.
|
|
text = text.replace('@manual_cache.clear\n', '')
|
|
text = text.replace('return {"status": "success"', 'manual_cache.clear()\n return {"status": "success"')
|
|
text = text.replace('return {"status": "created"', 'manual_cache.clear()\n return {"status": "created"')
|
|
|
|
with open("app/modules/manual/backend/router.py", "w") as f:
|
|
f.write(text)
|
|
|