Skip to content

Commit

Permalink
allergies and dialysis cache
Browse files Browse the repository at this point in the history
  • Loading branch information
marceloarocha committed Jan 2, 2025
1 parent 0e0d0ea commit 55ffe5e
Show file tree
Hide file tree
Showing 5 changed files with 266 additions and 81 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,56 @@
from models.main import db, User
from models.notes import ClinicalNotes
from services import cache_service, clinical_notes_service
from decorators.timed_decorator import timed


def get_dialysis_cache(admission_number: int):
return (
db.session.query(
ClinicalNotes.id, ClinicalNotes.annotations, ClinicalNotes.date
)
.filter(ClinicalNotes.admissionNumber == admission_number)
.filter(ClinicalNotes.dialysisText != "")
.filter(ClinicalNotes.dialysisText != None)
.filter(ClinicalNotes.date > func.current_date() - 3)
.order_by(desc(ClinicalNotes.date))
.all()
)


def get_allergies_cache(admission_number: int):
return (
db.session.query(
ClinicalNotes.id, ClinicalNotes.annotations, ClinicalNotes.date
)
.filter(ClinicalNotes.admissionNumber == admission_number)
.filter(ClinicalNotes.allergyText != "")
.filter(ClinicalNotes.allergyText != None)
.filter(ClinicalNotes.date > func.current_date() - 120)
.order_by(desc(ClinicalNotes.date))
.all()
)


@timed()
def get_signs(admission_number: int, user_context: User, cache=True):
signs = {}
if cache:
result = cache_service.get_by_key(
f"""{user_context.schema}:{admission_number}:sinais"""
)

if result != None:
result_list = result.get("lista", [])
return {
signs = {
"id": str(result.get("fkevolucao", None)),
"data": " ".join(result_list),
"date": result.get("dtevolucao", None),
"cache": True,
}

return signs

result = (
db.session.query(ClinicalNotes.signsText, ClinicalNotes.date, ClinicalNotes.id)
.select_from(ClinicalNotes)
Expand All @@ -33,31 +66,35 @@ def get_signs(admission_number: int, user_context: User, cache=True):
)

if result != None:
return {
signs = {
"id": str(result[2]),
"data": result[0],
"date": result[1].isoformat(),
"cache": False,
}

return {}
return signs


@timed()
def get_infos(admission_number, user_context: User, cache=True):
infos = {}
if cache:
result = cache_service.get_by_key(
f"""{user_context.schema}:{admission_number}:dados"""
)

if result != None:
result_list = result.get("lista", [])
return {
infos = {
"id": str(result.get("fkevolucao", None)),
"data": " ".join(result_list),
"date": result.get("dtevolucao", None),
"cache": True,
}

return infos

result = (
db.session.query(ClinicalNotes.infoText, ClinicalNotes.date, ClinicalNotes.id)
.select_from(ClinicalNotes)
Expand All @@ -70,24 +107,58 @@ def get_infos(admission_number, user_context: User, cache=True):
)

if result != None:
return {
infos = {
"id": str(result[2]),
"data": result[0],
"date": result[1].isoformat(),
"cache": False,
}

return {}
return infos


@timed()
def get_allergies(
admission_number, user_context: User, admission_date=None, cache=True
):
allergies = []

if cache:
results = cache_service.get_range(
key=f"""{user_context.schema}:{admission_number}:alergia""", days_ago=120
)

if results:
texts = []
for a in sorted(
results,
key=lambda d: d["dtevolucao"],
reverse=True,
):
text = " ".join(a.get("lista", []))
if text in texts:
continue

texts.append(text)
allergies.append(
{
"id": str(a.get("fkevolucao", None)),
"text": text,
"date": a.get("dtevolucao", None),
"cache": True,
"source": "care",
}
)

return allergies

def get_allergies(admission_number, admission_date=None):
cutoff_date = (
datetime.today() - timedelta(days=120)
if admission_date == None
else admission_date
) - timedelta(days=1)

return (
results = (
db.session.query(
ClinicalNotes.allergyText,
func.max(ClinicalNotes.date).label("maxdate"),
Expand All @@ -104,9 +175,52 @@ def get_allergies(admission_number, admission_date=None):
.all()
)

allergies = []
for a in results:
allergies.append(
{
"date": a[1].isoformat(),
"text": a[0],
"source": "care",
"id": str(a[2]),
"cache": False,
}
)
return allergies

def get_dialysis(admission_number):
return (

@timed()
def get_dialysis(admission_number: int, user_context: User, cache=True):
dialysis_data = []

if cache:
results = cache_service.get_range(
key=f"""{user_context.schema}:{admission_number}:dialise""", days_ago=3
)

if results:
texts = []
for d in sorted(
results,
key=lambda d: d["dtevolucao"] if d["dtevolucao"] != None else "",
reverse=True,
):
text = " ".join(d.get("lista", []))
if text in texts:
continue

dialysis_data.append(
{
"id": str(d.get("fkevolucao", None)),
"text": " ".join(d.get("lista", [])),
"date": d.get("dtevolucao", None),
"cache": True,
}
)

return dialysis_data

results = (
db.session.query(
func.first_value(ClinicalNotes.dialysisText).over(
partition_by=func.date(ClinicalNotes.date),
Expand All @@ -131,7 +245,15 @@ def get_dialysis(admission_number):
.all()
)

for d in results:
dialysis_data.append(
{"date": d[1].isoformat(), "text": d[0], "id": str(d[3]), "cache": False}
)

return dialysis_data


@timed()
def get_admission_stats(admission_number: int, user_context: User, cache=True):
tags = clinical_notes_service.get_tags()
stats = {}
Expand Down
89 changes: 88 additions & 1 deletion services/clinical_notes_service.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import json
import time
from datetime import datetime, timedelta
from sqlalchemy import text, Integer, func, desc, or_
from sqlalchemy.orm import undefer

from models.main import db, User
from models.main import db, User, redis_client
from models.notes import ClinicalNotes
from models.prescription import Prescription, Patient
from models.enums import UserAuditTypeEnum
from services import memory_service, exams_service, user_service
from repository import clinical_notes_repository
from decorators.has_permission_decorator import has_permission, Permission
from exception.validation_error import ValidationError
from utils import status
Expand Down Expand Up @@ -94,11 +97,19 @@ def remove_annotation(id_clinical_notes: int, annotation_type: str, user_context
clinical_notes.allergy = 0
clinical_notes.allergyText = None
db.session.flush()

refresh_allergies_cache(
admission_number=clinical_notes.admissionNumber, user_context=user_context
)
elif annotation_type == "dialysis":
old_note = clinical_notes.dialysisText
clinical_notes.dialysis = 0
clinical_notes.dialysisText = None
db.session.flush()

refresh_dialysis_cache(
admission_number=clinical_notes.admissionNumber, user_context=user_context
)
else:
raise ValidationError(
"Tipo inválido", "errors.businessRules", status.HTTP_400_BAD_REQUEST
Expand Down Expand Up @@ -377,3 +388,79 @@ def update_note_text(id: int, data: dict, user_context: User):
n.form = data.get("form")

return n


@has_permission(Permission.WRITE_PRESCRIPTION, Permission.MAINTAINER)
def refresh_clinical_notes_stats_cache(admission_number: int, user_context: User):
def _add_cache(key: str, data: dict, expire_in: int):
if data.get("data", None) != None:
cache_data = {
"dtevolucao": data.get("date", None),
"fkevolucao": data.get("id", None),
"lista": [data.get("data", None)],
}

redis_client.json().set(key, "$", cache_data)
redis_client.expire(key, expire_in)

# signs (expires in 30 days)
signs = clinical_notes_repository.get_signs(
admission_number=admission_number, user_context=user_context, cache=False
)
key = f"{user_context.schema}:{admission_number}:sinais"
_add_cache(key=key, data=signs, expire_in=(30 * 24 * 60 * 60))

# infos (expires in 30 days)
infos = clinical_notes_repository.get_infos(
admission_number=admission_number, user_context=user_context, cache=False
)
key = f"{user_context.schema}:{admission_number}:dados"
_add_cache(key=key, data=infos, expire_in=(30 * 24 * 60 * 60))


@has_permission(Permission.WRITE_PRESCRIPTION, Permission.MAINTAINER)
def refresh_dialysis_cache(admission_number: int, user_context: User):
dialysis = clinical_notes_repository.get_dialysis_cache(
admission_number=admission_number
)
key = f"{user_context.schema}:{admission_number}:dialise"
now = int(time.time())
ten_days_ago = now - (10 * 24 * 60 * 60)

redis_client.delete(key)

for d in dialysis:
data = {
"dtevolucao": d.date.isoformat(),
"fkevolucao": d.id,
"lista": d.annotations.get("dialise", []),
}
data_json = json.dumps(data)
timestamp = int(
time.mktime(time.strptime(data["dtevolucao"], "%Y-%m-%dT%H:%M:%S"))
)
redis_client.zadd(key, {data_json: timestamp})
redis_client.zremrangebyscore(key, min=0, max=ten_days_ago)
redis_client.expire(key, (10 * 24 * 60 * 60)) # 10 days


@has_permission(Permission.WRITE_PRESCRIPTION, Permission.MAINTAINER)
def refresh_allergies_cache(admission_number: int, user_context: User):
allergies = clinical_notes_repository.get_allergies_cache(
admission_number=admission_number
)
key = f"{user_context.schema}:{admission_number}:alergia"
redis_client.delete(key)

for a in allergies:
data = {
"dtevolucao": a.date.isoformat(),
"fkevolucao": a.id,
"lista": a.annotations.get("allergiesComposed", []),
}
data_json = json.dumps(data)
timestamp = int(
time.mktime(time.strptime(data["dtevolucao"], "%Y-%m-%dT%H:%M:%S"))
)
redis_client.zadd(key, {data_json: timestamp})
redis_client.expire(key, (120 * 24 * 60 * 60)) # 120 days
18 changes: 17 additions & 1 deletion services/exams_service.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import copy
import json
from sqlalchemy import text, desc, and_
from datetime import datetime, timedelta, date

from models.main import db
from models.main import db, redis_client, User
from models.prescription import Patient
from models.segment import Exams, SegmentExam
from models.notes import ClinicalNotes
Expand Down Expand Up @@ -507,3 +508,18 @@ def find_latest_exams(
)

return dict(exams, **examsExtra)


@has_permission(Permission.WRITE_PRESCRIPTION, Permission.MAINTAINER)
def refresh_exams_cache(id_patient: int, user_context: User):
exams = get_exams_current_results(
id_patient=id_patient,
add_previous_exams=True,
cache=False,
schema=user_context.schema,
lower_key=False,
)

key = f"{user_context.schema}:{id_patient}:exames"
for type_exam, exam in exams.items():
redis_client.hset(key, type_exam, json.dumps(exam))
Loading

0 comments on commit 55ffe5e

Please sign in to comment.