From 08eb9f20ce0afdd59a0bc0091a23ccd0a7b3fb93 Mon Sep 17 00:00:00 2001 From: marcvergees Date: Tue, 23 Jun 2026 11:23:58 -0700 Subject: [PATCH 1/2] feat: :sparkles: introducing analytics and form submission history --- app/api/routes/forms.py | 79 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 78 insertions(+), 1 deletion(-) diff --git a/app/api/routes/forms.py b/app/api/routes/forms.py index 9ecb46c..63366f4 100644 --- a/app/api/routes/forms.py +++ b/app/api/routes/forms.py @@ -12,7 +12,7 @@ from app.core.config import OLLAMA_HOST, OLLAMA_MODEL, WHISPER_HOST from app.core.errors.base import AppError from app.db.repositories import create_form, get_template -from app.models import FormSubmission +from app.models import FormSubmission, Template from app.services.controller import Controller router = APIRouter(prefix="/forms", tags=["forms"]) @@ -104,3 +104,80 @@ def transcribe(audio: UploadFile = File(...)): text = response.text.strip() return TranscriptionResponse(text=text) + + +@router.get("/submissions") +def get_submissions(db: Session = Depends(get_db)): + from sqlmodel import select + statement = ( + select(FormSubmission, Template.name) + .join(Template, FormSubmission.template_id == Template.id, isouter=True) + .order_by(FormSubmission.created_at.desc(), FormSubmission.id.desc()) + ) + results = db.exec(statement).all() + return [ + { + "id": sub.id, + "template_id": sub.template_id, + "template_name": name or "Unknown Template", + "input_text": sub.input_text, + "output_pdf_path": sub.output_pdf_path, + "created_at": sub.created_at.isoformat() if sub.created_at else None, + } + for sub, name in results + ] + + +@router.get("/submissions/analytics") +def get_submissions_analytics(db: Session = Depends(get_db)): + from collections import Counter + import re + from sqlmodel import select + + statement = select(FormSubmission, Template.name).join( + Template, FormSubmission.template_id == Template.id, isouter=True + ) + results = db.exec(statement).all() + + total_submissions = len(results) + + template_counts = Counter() + daily_counts = Counter() + words = [] + + stopwords = { + "the", "and", "a", "of", "to", "in", "is", "that", "it", "was", "for", "on", + "as", "with", "by", "at", "an", "be", "this", "are", "from", "or", "have", + "has", "had", "but", "not", "he", "she", "they", "we", "i", "you", "my", "his", + "her", "their", "our", "me", "him", "them", "us", "about", "there", "their", + "were", "been", "would", "could", "should", "will", "can", "no", "yes", "any", + "so", "very", "patient", "presents", "with", "reported", "history", "shows", + "left", "right", "pain", "due", "after", "before", "emergency", "department", + "medical", "clinical" + } + + for sub, name in results: + template_name = name or "Unknown Template" + template_counts[template_name] += 1 + + if sub.created_at: + date_str = sub.created_at.strftime("%Y-%m-%d") + daily_counts[date_str] += 1 + + if sub.input_text: + found_words = re.findall(r"\b[a-zA-Z]{3,15}\b", sub.input_text.lower()) + for w in found_words: + if w not in stopwords: + words.append(w) + + sorted_daily = [{"date": k, "count": v} for k, v in sorted(daily_counts.items())] + sorted_templates = [{"template_name": k, "count": v} for k, v in template_counts.most_common()] + common_terms = [{"word": k, "count": v} for k, v in Counter(words).most_common(12)] + + return { + "total_submissions": total_submissions, + "by_template": sorted_templates, + "by_date": sorted_daily, + "common_terms": common_terms, + } + From b01e316a8cb0f44d45b8f8530ebbda6501a14233 Mon Sep 17 00:00:00 2001 From: marcvergees Date: Wed, 24 Jun 2026 17:40:34 -0400 Subject: [PATCH 2/2] fix: :bug: missing import --- app/api/routes/forms.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/api/routes/forms.py b/app/api/routes/forms.py index 3c1769b..a0a1091 100644 --- a/app/api/routes/forms.py +++ b/app/api/routes/forms.py @@ -14,7 +14,7 @@ from app.core.config import OLLAMA_HOST, OLLAMA_MODEL, WHISPER_HOST, BASE_DIR, RETENTION_PERIOD_DAYS from app.core.errors.base import AppError from app.db.repositories import create_form, get_template, get_form_submission, delete_form_submission -from app.models import FormSubmission +from app.models import FormSubmission, Template from app.services.controller import Controller PROJECT_ROOT = BASE_DIR