|
15 | 15 | from app.services.whisper import call_whisper_asr |
16 | 16 | from app.core.errors.base import AppError |
17 | 17 | from app.db.repositories import create_form, get_template, get_form_submission, delete_form_submission |
18 | | -from app.models import FormSubmission |
| 18 | +from app.models import FormSubmission, Template |
19 | 19 | from app.services.controller import Controller |
20 | 20 |
|
21 | 21 | PROJECT_ROOT = BASE_DIR |
@@ -149,3 +149,80 @@ def purge_submissions_endpoint(days: int = Query(default=None), db: Session = De |
149 | 149 |
|
150 | 150 | return {"status": "success", "purged_count": purged_count, "retention_days_used": retention_days} |
151 | 151 |
|
| 152 | + |
| 153 | + |
| 154 | +@router.get("/submissions") |
| 155 | +def get_submissions(db: Session = Depends(get_db)): |
| 156 | + from sqlmodel import select |
| 157 | + statement = ( |
| 158 | + select(FormSubmission, Template.name) |
| 159 | + .join(Template, FormSubmission.template_id == Template.id, isouter=True) |
| 160 | + .order_by(FormSubmission.created_at.desc(), FormSubmission.id.desc()) |
| 161 | + ) |
| 162 | + results = db.exec(statement).all() |
| 163 | + return [ |
| 164 | + { |
| 165 | + "id": sub.id, |
| 166 | + "template_id": sub.template_id, |
| 167 | + "template_name": name or "Unknown Template", |
| 168 | + "input_text": sub.input_text, |
| 169 | + "output_pdf_path": sub.output_pdf_path, |
| 170 | + "created_at": sub.created_at.isoformat() if sub.created_at else None, |
| 171 | + } |
| 172 | + for sub, name in results |
| 173 | + ] |
| 174 | + |
| 175 | + |
| 176 | +@router.get("/submissions/analytics") |
| 177 | +def get_submissions_analytics(db: Session = Depends(get_db)): |
| 178 | + from collections import Counter |
| 179 | + import re |
| 180 | + from sqlmodel import select |
| 181 | + |
| 182 | + statement = select(FormSubmission, Template.name).join( |
| 183 | + Template, FormSubmission.template_id == Template.id, isouter=True |
| 184 | + ) |
| 185 | + results = db.exec(statement).all() |
| 186 | + |
| 187 | + total_submissions = len(results) |
| 188 | + |
| 189 | + template_counts = Counter() |
| 190 | + daily_counts = Counter() |
| 191 | + words = [] |
| 192 | + |
| 193 | + stopwords = { |
| 194 | + "the", "and", "a", "of", "to", "in", "is", "that", "it", "was", "for", "on", |
| 195 | + "as", "with", "by", "at", "an", "be", "this", "are", "from", "or", "have", |
| 196 | + "has", "had", "but", "not", "he", "she", "they", "we", "i", "you", "my", "his", |
| 197 | + "her", "their", "our", "me", "him", "them", "us", "about", "there", "their", |
| 198 | + "were", "been", "would", "could", "should", "will", "can", "no", "yes", "any", |
| 199 | + "so", "very", "patient", "presents", "with", "reported", "history", "shows", |
| 200 | + "left", "right", "pain", "due", "after", "before", "emergency", "department", |
| 201 | + "medical", "clinical" |
| 202 | + } |
| 203 | + |
| 204 | + for sub, name in results: |
| 205 | + template_name = name or "Unknown Template" |
| 206 | + template_counts[template_name] += 1 |
| 207 | + |
| 208 | + if sub.created_at: |
| 209 | + date_str = sub.created_at.strftime("%Y-%m-%d") |
| 210 | + daily_counts[date_str] += 1 |
| 211 | + |
| 212 | + if sub.input_text: |
| 213 | + found_words = re.findall(r"\b[a-zA-Z]{3,15}\b", sub.input_text.lower()) |
| 214 | + for w in found_words: |
| 215 | + if w not in stopwords: |
| 216 | + words.append(w) |
| 217 | + |
| 218 | + sorted_daily = [{"date": k, "count": v} for k, v in sorted(daily_counts.items())] |
| 219 | + sorted_templates = [{"template_name": k, "count": v} for k, v in template_counts.most_common()] |
| 220 | + common_terms = [{"word": k, "count": v} for k, v in Counter(words).most_common(12)] |
| 221 | + |
| 222 | + return { |
| 223 | + "total_submissions": total_submissions, |
| 224 | + "by_template": sorted_templates, |
| 225 | + "by_date": sorted_daily, |
| 226 | + "common_terms": common_terms, |
| 227 | + } |
| 228 | + |
0 commit comments