Skip to content

Entrega 2: implementación completa de AEnEA (backend IA, app Expo, despliegue) - #294

Open
jialvarez wants to merge 6 commits into
LIDR-academy:mainfrom
jialvarez:feature-entrega2-jiar
Open

Entrega 2: implementación completa de AEnEA (backend IA, app Expo, despliegue)#294
jialvarez wants to merge 6 commits into
LIDR-academy:mainfrom
jialvarez:feature-entrega2-jiar

Conversation

@jialvarez

@jialvarez jialvarez commented Jul 30, 2026

Copy link
Copy Markdown

Resumen

Implementa de extremo a extremo la plataforma AEnEA documentada en la Entrega 1 (que era solo
diseño/documentación) más la funcionalidad de onboarding (US-00) detectada como hueco tras la
revisión inicial:

  • Backend (FastAPI + SQLAlchemy + Alembic + Postgres): modelos con tipo GUID agnóstico de
    Postgres/SQLite, AIOrchestratorService con cliente OpenAI inyectable (Whisper STT + GPT-4o-mini
    para clasificación estructurada BASELINE/TIMELINE/IRRELEVANT y detección de banderas rojas
    cruzando el historial longitudinal), endpoints POST/GET /api/v1/patients y
    /patients/{id}/process-voice|process-document|passport.
  • Frontend (Expo Router + TypeScript): onboarding sin login (US-00), timeline con chips de
    baseline, banner de bandera roja, grabación de voz (expo-audio), captura de documentos
    (expo-image-picker) y exportación a PDF (expo-print/expo-sharing) fiel al diseño de
    pasaporte_medico_inteligente.pdf.
  • Despliegue: render.yaml + Dockerfile (backend en Render, Postgres gestionado) y
    eas.json (build de Android vía EAS) — ya desplegado y verificado en producción.
  • Documentación: readme.md actualizado (modelo de datos, API, US-00, tickets/PRs de
    Entrega 2) con convención de nombres en inglés para el código y español para el contenido.

Test plan

  • pytest backend: 23 tests en verde (unitarios + integración; E2E real opcional con
    OPENAI_API_KEY)
  • npx tsc --noEmit sin errores en el frontend
  • npx expo export bundlea sin fallos (1156 módulos)
  • Backend desplegado en Render, /health y /docs verificados en producción
  • Build de Android generado con EAS e instalado en dispositivo real
  • Flujo completo probado en producción: onboarding → nota de voz → timeline → exportar PDF

Summary by CodeRabbit

  • New Features

    • Added patient onboarding and profile management.
    • Added voice-note and medical-document processing with AI-assisted classification.
    • Added medical passport view with baseline history, timeline events, and critical-alert indicators.
    • Added event details, document capture, voice recording, and PDF export in the mobile app.
    • Added API health monitoring and deployment support.
  • Documentation

    • Added setup, deployment, API, architecture, and security guidance.
  • Tests

    • Added unit, integration, and opt-in end-to-end coverage for core workflows.

jialvarez and others added 6 commits June 12, 2026 17:33
Entrega 1: Documentación Técnica, Arquitectura y Registro de Prompts (AEnEA)
…file

- AIOrchestratorService now supports a third routing value (IRRELEVANT)
  so off-topic voice notes/photos are acknowledged (200, status=ignored)
  instead of being forced into a fabricated clinical record.
- Fix frontend/package-lock.json desync and add .npmrc (legacy-peer-deps)
  so `npm ci` — what EAS Build actually runs — succeeds; this was causing
  EAS builds to fail during dependency install.
- Wire up real EAS/Render deployment values (projectId, package name,
  permissions, backend URL) and correct render CLI usage in DEPLOY.md.
- Update readme.md API spec to document the IRRELEVANT routing contract.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

AEnEA adds a FastAPI backend with PostgreSQL persistence and AI-based clinical extraction, an Expo mobile frontend for onboarding and health timelines, PDF export, deployment configuration, automated tests, and expanded project documentation.

Changes

AEnEA medical passport platform

Layer / File(s) Summary
Backend persistence and runtime foundation
backend/app/models/*, backend/app/repositories/*, backend/app/core/*, backend/migrations/*, backend/Dockerfile, backend/docker-compose.yml
Adds patient, baseline, and medical-event models; repository operations; UUID handling; database configuration; Docker services; and Alembic migrations.
AI extraction and API flow
backend/app/services/*, backend/app/schemas/*, backend/app/api/v1/*, backend/app/main.py
Adds OpenAI transcription/classification, structured routing contracts, prompt templates, orchestration, patient endpoints, voice/document processing, passport retrieval, and HTTP error handling.
Backend integration and orchestration validation
backend/tests/*, backend/pytest.ini, backend/requirements*.txt
Adds SQLite test fixtures and coverage for repositories, API routes, AI routing, parsing failures, provider errors, red flags, and the opt-in real voice path.
Frontend data and navigation flow
frontend/app/*, frontend/services/*, frontend/types/*
Adds patient persistence, API mappers, audio recording, onboarding, timeline loading, voice/document processing, and PDF export actions.
Frontend health presentation and export
frontend/components/*, frontend/services/pdfExportService.ts
Adds baseline chips, timeline cards, category badges, red-flag presentation, event details, upload controls, loading overlays, and escaped HTML-based PDF generation and sharing.
Deployment, tooling, and project documentation
render.yaml, DEPLOY.md, readme.md, frontend/app.json, frontend/eas.json, .serena/*, backend/.env.example, frontend/.env.example, *gitignore, frontend/package.json
Adds Render and EAS deployment configuration, environment templates, project tooling settings, dependency configuration, ignore rules, and detailed architecture, API, data-model, testing, and deployment documentation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.92% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed El título describe correctamente la entrega completa de backend IA, app Expo y despliegue, que coincide con el alcance principal del PR.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Due to the large number of review comments, Critical severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
render.yaml (1)

22-24: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Replace wildcard CORS for the medical API.

CORS_ORIGINS: "*" permits every browser origin to call the API. Combined with the documented no-auth patient routes, arbitrary sites can invoke medical endpoints if they obtain a patient_id. Restrict CORS to trusted origins or disable it for native-only clients.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@render.yaml` around lines 22 - 24, Update the CORS_ORIGINS configuration for
the medical API to remove the wildcard value. Restrict it to the project’s
trusted browser origins, or disable CORS when the API is intended only for
native clients.
🟠 Major comments (23)
backend/app/core/config.py-12-12 (1)

12-12: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Remove wildcard CORS defaults for the health-data API. The runtime default and copied environment template both permit every browser origin; require explicit frontend origins for each deployment.

  • backend/app/core/config.py#L12-L12: replace the wildcard fallback with a safe development-only origin or require CORS_ORIGINS at startup.
  • backend/.env.example#L6-L6: show explicit local frontend origin(s), not *.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/core/config.py` at line 12, Remove the wildcard CORS default from
cors_origins in backend/app/core/config.py:12-12 by requiring CORS_ORIGINS at
startup or using an explicit development-only frontend origin. Update
backend/.env.example:6-6 to list explicit local frontend origin(s) instead of
"*", keeping both configuration sources aligned.
backend/app/services/ai_orchestrator.py-64-82 (1)

64-82: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Do not discard red flags returned with baseline extractions.

Line 64 persists a BASELINE while dropping result.red_flag, even though the prompt requests red-flag analysis for all new content. Persist alerts independently of event routing (or reject baseline red flags until that storage/UI path exists); otherwise valid safety signals disappear.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/services/ai_orchestrator.py` around lines 64 - 82, Update the
BASELINE handling in the orchestrator method around result.routing and add
persistence for result.red_flag independently of baseline event creation, or
explicitly reject baseline red flags until supported storage/UI exists. Ensure
valid red flags are never silently discarded while preserving the existing
baseline item response.
backend/app/schemas/ai_contracts.py-51-57 (1)

51-57: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Enforce mutually exclusive routing payloads.

This validator still accepts BASELINE with an event, TIMELINE with a baseline, and IRRELEVANT with either payload. The orchestrator persists only the field matching its routing branch, so malformed AI outputs can silently ignore clinical data. Make the schema match the documented contract: each routing path gets exactly the required payload, and IRRELEVANT gets none.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/schemas/ai_contracts.py` around lines 51 - 57, The
_check_routing_payload validator must enforce exact payload matching: BASELINE
requires baseline and rejects event, TIMELINE requires event and rejects
baseline, and IRRELEVANT rejects both payloads. Update the existing routing
checks while preserving the current validation errors for missing required
payloads.
backend/app/main.py-11-17 (1)

11-17: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Reject wildcard origins when credentials are enabled.

cors_origin_list can return ["*"], while this middleware enables credentials and wildcard methods/headers. Require an explicit frontend-origin allowlist and enumerate the required methods/headers before enabling credentials; otherwise an arbitrary origin can make credentialed cross-origin requests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/main.py` around lines 11 - 17, Update the CORSMiddleware
configuration in the application setup to reject or fail fast when
settings.cors_origin_list contains the wildcard origin while allow_credentials
is enabled. Require explicit frontend origins and replace wildcard methods and
headers with the specific methods and headers the API needs before allowing
credentialed requests.

Source: Linters/SAST tools

backend/app/api/v1/health.py-36-38 (1)

36-38: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Enforce a shared maximum request size before buffering ingestion payloads. Both endpoints accept client-controlled content without a size limit, risking memory exhaustion and excessive downstream AI usage.

  • backend/app/api/v1/health.py#L36-L38: read audio in bounded chunks and reject uploads exceeding the configured limit.
  • backend/app/api/v1/health.py#L50-L60: reject oversized encoded payloads before decoding and enforce the same decoded-byte limit; configure an ingress/ASGI body limit as well.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/api/v1/health.py` around lines 36 - 38, Enforce one shared
maximum request-size limit across both endpoints in
backend/app/api/v1/health.py: in the audio upload flow at lines 36-38, read in
bounded chunks and reject payloads exceeding the limit before processing; in the
encoded-payload flow at lines 50-60, reject oversized encoded input before
decoding and reject decoded bytes over the same limit. Also configure the
ingress/ASGI body limit to match.
backend/docker-compose.yml-6-10 (1)

6-10: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Do not expose database tools with known fallback credentials. Docker publishes these ports on all host interfaces; a network peer can access Postgres using the committed fallback credentials, and Adminer provides a browser client for it.

  • backend/docker-compose.yml#L6-L10: require POSTGRES_PASSWORD instead of defaulting to aenea, and bind the development database port to 127.0.0.1.
  • backend/docker-compose.yml#L19-L23: bind Adminer to 127.0.0.1 or place it behind an explicit development-only profile.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/docker-compose.yml` around lines 6 - 10, Update
backend/docker-compose.yml at lines 6-10 to require POSTGRES_PASSWORD without
the committed fallback and bind the database port to 127.0.0.1; update lines
19-23 to bind Adminer to 127.0.0.1 or place it behind an explicit
development-only profile.
backend/app/models/medical_event.py-21-21 (1)

21-21: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Persist a normalized sortable event date. MedicalEvent.date accepts arbitrary display text, while the repository applies a lexicographic SQL sort. Non-ISO or approximate clinical dates will produce an incorrect medical timeline.

  • backend/app/models/medical_event.py#L21-L21: store a normalized Date value or a separate normalized sort key; retain approximate/original wording in a distinct display field.
  • backend/app/repositories/sqlalchemy_repository.py#L87-L93: order by that normalized date key and add a migration for existing rows.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/models/medical_event.py` at line 21, Update
backend/app/models/medical_event.py:21-21 so MedicalEvent stores a normalized
Date value or dedicated sortable date key, while preserving approximate/original
wording in a separate display field. Update
backend/app/repositories/sqlalchemy_repository.py:87-93 to order by the
normalized date key, and add a migration to populate or convert existing rows
consistently.
backend/requirements.txt-1-9 (1)

1-9: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Upgrade FastAPI and python-multipart to patched releases.

backend/requirements.txt pins fastapi==0.115.6 with Starlette 0.41.3 and python-multipart==0.0.19, both affected by form-data parsing/security advisories while this app exposes upload endpoints. Update FastAPI and python-multipart to release-compatible patched versions, resolve the lockfile, and re-scan.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/requirements.txt` around lines 1 - 9, Update the FastAPI and
python-multipart pins in requirements.txt to patched, mutually compatible
releases, then regenerate or resolve the project lockfile so transitive
Starlette dependencies are updated accordingly. Verify the upload/form-data
dependencies no longer resolve to vulnerable versions.

Source: Linters/SAST tools

backend/Dockerfile-1-16 (1)

1-16: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Run the application as a non-root user.

There is no USER directive, so Alembic and Uvicorn run as root. Add an unprivileged runtime user and ensure /app has the required ownership. Trivy reports the same issue as DS-0002.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/Dockerfile` around lines 1 - 16, Add an unprivileged runtime user in
the Dockerfile, ensure `/app` and its contents are owned by that user, and
switch to it with a `USER` directive before the existing `CMD` so Alembic and
Uvicorn run without root privileges.

Source: Linters/SAST tools

readme.md-297-305 (1)

297-305: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Do not use patient_id as the only protection for medical data.

The no-login contract makes a UUID in the URL the only caller credential. Anyone who obtains it can access that patient’s passport. Add authentication/authorization before production, or explicitly restrict this deployment to a non-production demo.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@readme.md` around lines 297 - 305, Update the API documentation around the
patient endpoints and US-00 contract to explicitly state that the UUID
patient_id is not sufficient protection for medical data. Require authentication
and authorization before production use, or clearly restrict the deployment to a
non-production demo.
backend/Dockerfile-1-10 (1)

1-10: 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift

Use a multi-stage runtime image.

The final image retains gcc and libpq-dev. Move compilation/install tooling into a builder stage and copy only runtime artifacts into the production stage.

As per coding guidelines, the Render deployment must use a multi-stage build.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/Dockerfile` around lines 1 - 10, Convert the backend Dockerfile to a
multi-stage build: use a builder stage based on python:3.13-slim to install gcc,
libpq-dev, and Python dependencies, then create a separate runtime stage that
contains only the application, required runtime libraries, and installed
dependency artifacts. Ensure the final Render image does not retain compilation
tools such as gcc or libpq-dev.

Source: Coding guidelines

render.yaml-1-14 (1)

1-14: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Align the deployment topology and environment URLs.

The manifest, EAS profiles, and README do not define an isolated staging environment: preview points at production, Render provisions only one database/service, and the README names a different host.

  • render.yaml#L1-L14: add separate staging and production services/databases and configure the Oregon region.
  • frontend/eas.json#L14-L24: point preview to staging and reserve the production URL for production.
  • readme.md#L28-L30: document the actual configured hosts and separate environment URLs.

As per coding guidelines, staging and production must be separate Render services with distinct database instances.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@render.yaml` around lines 1 - 14, Update render.yaml to provision distinct
Oregon-region staging and production services and databases, preserving separate
database instances for each environment. In frontend/eas.json lines 14-24, point
the preview profile to the staging host and keep the production host exclusively
in the production profile. In readme.md lines 28-30, document the actual
configured staging and production hosts with separate environment URLs.

Source: Coding guidelines

frontend/package.json-5-22 (1)

5-22: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add the dependency required by the development build.

frontend/eas.json enables developmentClient: true, but frontend/package.json does not declare expo-dev-client. Add the Expo-SDK-compatible version with npx expo install expo-dev-client, or set developmentClient: false if this profile is intended to run in Expo Go.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/package.json` around lines 5 - 22, Update the frontend dependencies
to include the Expo-SDK-compatible expo-dev-client package, matching the
developmentClient: true setting in eas.json; use npx expo install
expo-dev-client so the package version aligns with the installed Expo SDK.
frontend/components/categoryColors.ts-17-25 (1)

17-25: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Render red flags as danger states, not only alert text. redFlag currently appends “/ ALERTA” but retains the category color, so a flagged consultation can still appear gray or blue.

  • frontend/components/categoryColors.ts#L17-L25: accept redFlag and return a dedicated danger palette including #EF4444.
  • frontend/components/CategoryBadge.tsx#L10-L16: pass redFlag into the color lookup so badge styling matches its alert label.

As per coding guidelines, “Error/Danger state must use #EF4444 (Red 500) for error messages, invalid states, and danger actions.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/components/categoryColors.ts` around lines 17 - 25, Update
frontend/components/categoryColors.ts lines 17-25 so getCategoryColor accepts
redFlag and returns a dedicated danger palette containing `#EF4444` when flagged,
while preserving the existing category lookup otherwise. Update
frontend/components/CategoryBadge.tsx lines 10-16 to pass redFlag into
getCategoryColor so flagged badges use the danger styling.

Source: Coding guidelines

frontend/app/onboarding.tsx-84-120 (1)

84-120: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add visible focus states to every Pressable.

The sex options, date selector, and submit button have no keyboard-focus treatment. Provide an equivalent visible 2px Indigo-500 focus ring/border for focused controls.

As per coding guidelines, “All buttons must implement focus state with focus:ring-2 focus:ring-indigo-500 for keyboard accessibility.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/onboarding.tsx` around lines 84 - 120, The Pressable controls in
the sex options, date selector, and submit button need visible keyboard-focus
styling. Update the corresponding Pressable style definitions in the onboarding
screen to apply an equivalent 2px Indigo-500 focus ring or border when focused,
while preserving their existing selected, disabled, and base styles.

Source: Coding guidelines

frontend/app/onboarding.tsx-63-122 (1)

63-122: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Make the form reachable with the keyboard or date picker open.

KeyboardAvoidingView does not scroll; on smaller screens, especially Android where behavior is undefined, the keyboard/date picker can cover required fields or the submit action. Wrap the form in a scrollable container with keyboard-aware tap handling.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/onboarding.tsx` around lines 63 - 122, Wrap the onboarding form
inside a scrollable container nested with KeyboardAvoidingView, enabling
keyboard-aware tap handling so inputs and the submit action remain reachable
when the keyboard or date picker is open. Preserve the existing form fields,
date-picker behavior, and submission controls around the current component
structure.
frontend/app/onboarding.tsx-49-57 (1)

49-57: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Prevent duplicate patient records after local-storage failure.

If createPatient() succeeds but setStoredPatientId() rejects, this catch reports creation failure. Retrying submits another patient POST and leaves the first medical profile orphaned. Retain the created ID and retry persistence/navigation separately, or make creation idempotent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/onboarding.tsx` around lines 49 - 57, Update the submission flow
around createPatient and setStoredPatientId so a successful patient creation is
not repeated when local-storage persistence fails. Retain the returned
patient.id and handle persistence/navigation retry separately, or make
createPatient idempotent, while preserving the existing error alert for genuine
creation failures and routing successful persistence to /timeline.
frontend/services/pdfExportService.ts-22-25 (1)

22-25: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Use a stable, unique passport identifier.

Patients sharing the same first four letters receive the same printed ID, and one patient’s ID changes each calendar year. Use a backend-issued opaque display identifier instead of deriving one from the name and current date.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/services/pdfExportService.ts` around lines 22 - 25, Replace
buildPassportId’s name-and-year derivation with the backend-issued opaque
patient display identifier. Use the existing identifier field from Patient,
preserving its value unchanged so IDs remain stable and unique across patients
and calendar years.
frontend/components/RedFlagBanner.tsx-10-16 (1)

10-16: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Show every red-flag event in emergency summaries.

find() renders only the first flagged event. Additional urgent events are omitted from both the in-app alert and the PDF’s critical-alert section.

  • frontend/components/RedFlagBanner.tsx#L10-L16: filter all flagged events and render each justification.
  • frontend/services/pdfExportService.ts#L28-L40: generate a critical-alert block for every flagged event.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/components/RedFlagBanner.tsx` around lines 10 - 16, Update
frontend/components/RedFlagBanner.tsx lines 10-16 to collect all red-flag events
and render each alertJustification in the in-app emergency banner, preserving
the empty state when none are flagged. Update
frontend/services/pdfExportService.ts lines 28-40 to generate a critical-alert
block for every flagged event rather than only the first.
frontend/app/timeline.tsx-33-49 (1)

33-49: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Recover from initial-load failures instead of showing a permanent overlay.

Line 34 can reject outside the try, and failures in Lines 41-44 leave passport null. Lines 99-101 then render an always-visible loading modal with no retry path. Catch the entire load flow and render an error/retry state.

Also applies to: 99-101

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/timeline.tsx` around lines 33 - 49, Update loadPassport so the
patient-ID lookup and onboarding redirect are covered by the same error handling
as the patient/passport requests, and track initial-load failures instead of
leaving passport null. In the timeline render path around the loading modal,
replace the permanent loading state with an error/retry state when loading
fails, using loadPassport as the retry action while preserving the loading
indicator during active requests.
frontend/services/audioRecorder.ts-16-27 (1)

16-27: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Gate recording on confirmed microphone permission.

useVoiceNoteRecorder() starts permission setup after render and start() does not check whether permission was granted. FloatingMicButton only catches prepareToRecordAsync() rejection, so a denied permission can leave the recording flow without a recoverable UI result. Retain the permission state from useEffect, wait on the permission before exposing/start recording, and surface a clear denial message.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/services/audioRecorder.ts` around lines 16 - 27, Update
useVoiceNoteRecorder to retain microphone permission state from the useEffect
request, prevent start from proceeding until permission setup has completed, and
return a clear denial error when permission is not granted. Ensure
FloatingMicButton can receive that rejection so denied access produces a
recoverable UI result instead of attempting recorder.prepareToRecordAsync.
frontend/components/LoadingOverlay.tsx-10-15 (1)

10-15: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Announce dynamic status changes to assistive technology.

Both components render status/alert text but never announce the change to screen readers, so users won’t be notified when loading starts or when a red-flag warning appears.

  • Apply an alert role/live region for the LoadingOverlay.message.
  • Apply an alert role/live region for the urgent urgent clinical alert in RedFlagBanner.container.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/components/LoadingOverlay.tsx` around lines 10 - 15, Apply an alert
accessibility role/live-region behavior to the element rendering
LoadingOverlay.message in frontend/components/LoadingOverlay.tsx:10-15 and to
RedFlagBanner.container in frontend/components/RedFlagBanner.tsx:13-17, ensuring
dynamic loading and urgent clinical alert changes are announced to assistive
technology.

Source: Coding guidelines

frontend/app/timeline.tsx-107-109 (1)

107-109: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add button semantics and visible focus states to these Pressables.

These interactive elements do not expose button semantics or a visible focus indicator, and icon-only controls still need accessible names.

  • frontend/app/timeline.tsx#L107: add accessibilityRole="button", keyboard/focus styling, and disabled support if the export action can be unavailable.
  • frontend/components/EventDetailModal.tsx#L44: add the same button semantics/focus styling for the close control.
  • frontend/components/FloatingMicButton.tsx#L38-L44: add accessibilityLabel/accessibilityState={{ busy, disabled, pressed }}, button semantics, and focus styling for stop/start recording.
  • frontend/components/TimelineCard.tsx#L15-L28: add button semantics, focus styling, and mark the location text/helper as decorative when present.
  • frontend/components/UploadDocumentButton.tsx#L42-L44: add accessibilityLabel="Subir documento", button semantics, disabled state, and focus styling.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/timeline.tsx` around lines 107 - 109, The Pressable controls
need consistent button semantics, keyboard-visible focus styling, and
appropriate accessibility state. Update frontend/app/timeline.tsx lines 107-109
around handleExportPdf, adding button semantics, focus styling, and disabled
support if export can be unavailable; update
frontend/components/EventDetailModal.tsx lines 44-46 around the close control
with the same semantics and focus styling; update
frontend/components/FloatingMicButton.tsx lines 38-44 with an accessible label,
button role, busy/disabled/pressed state, and focus styling; update
frontend/components/TimelineCard.tsx lines 15-28 with button semantics, focus
styling, and decorative treatment for location text/helper content; update
frontend/components/UploadDocumentButton.tsx lines 42-44 with the “Subir
documento” label, button role, disabled state, and focus styling.

Source: Coding guidelines

🟡 Minor comments (12)
backend/app/repositories/interfaces.py-27-34 (1)

27-34: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Rename parameters that shadow Python’s type builtin. Ruff A002 is raised in both port methods and their implementation; this will fail linting.

  • backend/app/repositories/interfaces.py#L27-L34: rename type to baseline_type.
  • backend/app/repositories/interfaces.py#L37-L51: rename type to event_type.
  • backend/app/repositories/sqlalchemy_repository.py#L29-L47: mirror baseline_type and assign it to ClinicalBaseline.type.
  • backend/app/repositories/sqlalchemy_repository.py#L49-L81: mirror event_type and assign it to MedicalEvent.type.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/repositories/interfaces.py` around lines 27 - 34, Rename the
shadowing type parameters across all affected methods: use baseline_type in
backend/app/repositories/interfaces.py lines 27-34 and
backend/app/repositories/sqlalchemy_repository.py lines 29-47, assigning it to
ClinicalBaseline.type; use event_type in backend/app/repositories/interfaces.py
lines 37-51 and backend/app/repositories/sqlalchemy_repository.py lines 49-81,
assigning it to MedicalEvent.type.

Source: Linters/SAST tools

backend/app/models/base.py-29-36 (1)

29-36: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Return normalized UUID values for PostgreSQL UUID binds.

PG_UUID(as_uuid=True) still uses this TypeDecorator’s process_bind_param, but the PostgreSQL branch currently returns str(value) before the uuid.UUID check. Normalize non-UUID input first, then let PostgreSQL accept uuid.UUID; keep CHAR(36) serialization for SQLite.

Proposed fix
     def process_bind_param(self, value, dialect):
         if value is None:
             return value
+        if not isinstance(value, uuid.UUID):
+            value = uuid.UUID(value)
         if dialect.name == "postgresql":
-            return str(value)
-        if not isinstance(value, uuid.UUID):
-            return str(uuid.UUID(value))
+            return value
         return str(value)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/models/base.py` around lines 29 - 36, Update process_bind_param
to normalize non-UUID values with uuid.UUID before the PostgreSQL branch, then
return the UUID object for PostgreSQL while preserving string serialization for
CHAR(36)/SQLite and the existing None behavior.
readme.md-564-564 (1)

564-564: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the API field name red_flag.

This acceptance criterion uses bandera_roja, while the documented model and API use red_flag. The mismatch can make frontend/backend tests assert a field that never exists.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@readme.md` at line 564, Update the acceptance criterion to use the documented
API field name red_flag instead of bandera_roja, while preserving the required
true value and the existing mobile and PDF warning behavior.
DEPLOY.md-52-57 (1)

52-57: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make local physical-device networking consistent.

Both the deployment instructions and development profile use localhost while describing phone-based testing.

  • DEPLOY.md#L52-L57: document a LAN/tunnel API URL and bind Uvicorn to a reachable interface.
  • frontend/eas.json#L7-L12: avoid hardcoding localhost for device builds, or clearly limit the profile to emulators.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@DEPLOY.md` around lines 52 - 57, Update DEPLOY.md lines 52-57 to document
using a LAN or tunnel API URL for physical-device testing and instruct binding
Uvicorn to a reachable interface; update frontend/eas.json lines 7-12 to avoid
hardcoding localhost for device builds, or explicitly restrict that profile to
emulator use.
readme.md-577-583 (1)

577-583: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Update the stale Ticket 1 route.

It still specifies /api/v1/health/process-voice; the current contract is /api/v1/patients/{patient_id}/process-voice. Keep the ticket acceptance criteria aligned with the implemented API.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@readme.md` around lines 577 - 583, Update Ticket 1’s endpoint description to
use the current route `/api/v1/patients/{patient_id}/process-voice` instead of
`/api/v1/health/process-voice`, and align its acceptance criteria with the
implemented patient-scoped API contract while preserving the existing response
and testing requirements.
DEPLOY.md-45-46 (1)

45-46: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the EAS URL handoff step match the actual config.

frontend/eas.json already contains concrete URLs; it does not contain REPLACE_WITH_YOUR_RENDER_URL. This step is therefore a no-op and can leave deployers believing the backend URL was configured.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@DEPLOY.md` around lines 45 - 46, Update the EAS URL handoff step in DEPLOY.md
to match the actual frontend/eas.json configuration: remove the instruction to
replace REPLACE_WITH_YOUR_RENDER_URL and describe the concrete URL fields or
values deployers must verify or update for their Render backend.
readme.md-159-159 (1)

159-159: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use the current audio package name.

The documentation says expo-av, but the frontend declares and configures expo-audio in frontend/package.json and frontend/app.json. Following this section would lead developers to the wrong package/API.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@readme.md` at line 159, Update the “Frontend Mobile (React Native + Expo)”
documentation to reference the currently configured expo-audio package instead
of expo-av, including the corresponding audio API wording while preserving the
existing description of native stream recording.
readme.md-153-153 (1)

153-153: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Update the documented database provider.

This line says production PostgreSQL runs on AWS, while the deployment manifest provisions Render PostgreSQL. Use Render or provider-agnostic wording to avoid misleading operators.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@readme.md` at line 153, Update the “Justificación de Arquitectura”
documentation to replace the AWS PostgreSQL provider reference with Render
PostgreSQL or provider-agnostic wording, while preserving the existing SQLite
test-environment distinction.
readme.md-193-193 (1)

193-193: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Separate Expo internal builds from Expo Go scanning.

The EAS preview/internal distribution build has its built artifact link and QR for installer access; Expo Go is for the local npx expo start workflow. Reword readme.md:193 so these are listed as separate flows.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@readme.md` at line 193, Reword the Frontend description to distinguish EAS
preview/internal distribution builds, which provide installable artifacts via
link or QR, from the local Expo Go workflow launched with npx expo start. Remove
the implication that EAS builds are scanned directly in Expo Go, while
preserving the web static preview distribution mention.
frontend/app/onboarding.tsx-131-153 (1)

131-153: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Fix insufficient input contrast.

#94A3B8 on white is about 2.6:1, below the required 4.5:1 for normal placeholder text. #CBD5E1 on white is about 1.5:1, below the 3:1 UI-component threshold. Use darker placeholder and border colors.

As per coding guidelines, “Ensure text contrast ratios meet minimum requirements: 4.5:1 for normal text … and 3:1 for UI components.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/onboarding.tsx` around lines 131 - 153, Update the onboarding
styles `datePlaceholder`, `input`, and `sexOption` to use darker placeholder
text and border colors that meet the required 4.5:1 text contrast and 3:1
UI-component contrast thresholds, while preserving the existing layout and
selected-state styling.

Source: Coding guidelines

frontend/app/onboarding.tsx-126-163 (1)

126-163: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align these styles with the required design tokens.

  • frontend/app/onboarding.tsx#L126-L163: apply Inter, replace non-4px spacing such as 6, 10, 14, and 36, and use #4F46E5 for the primary selection/continue actions.
  • frontend/components/BaselineChip.tsx#L21-L34: apply Inter, replace paddingVertical: 6, and use Veterinary Green #10B981 for the medication health state.
  • frontend/components/CategoryBadge.tsx#L21-L29: apply Inter and replace paddingVertical: 3 with the 4px spacing scale.

As per coding guidelines, “Use 'Inter' font family”; “Use spacing scale based on 4px increments”; “Primary Blue (#4F46E5 / Indigo 600) should be used for main actions”; and “Use Veterinary Green (#10B981 / Emerald 500) for … health-related elements.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/onboarding.tsx` around lines 126 - 163, Update the styles in
frontend/app/onboarding.tsx lines 126-163 to use the Inter font, convert non-4px
spacing values including 6, 10, 14, and 36 to the 4px spacing scale, and replace
primary selection and continue-action colors with `#4F46E5`. Update
frontend/components/BaselineChip.tsx lines 21-34 to use Inter, replace
paddingVertical: 6 with a 4px-scale value, and use `#10B981` for its medication
health state. Update frontend/components/CategoryBadge.tsx lines 21-29 to use
Inter and replace paddingVertical: 3 with the 4px spacing value.

Source: Coding guidelines

frontend/components/BaselineHeader.tsx-42-42 (1)

42-42: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Replace low-contrast muted text.

#94A3B8 is roughly 2.5:1 against white/light backgrounds, below the required 4.5:1 for normal text.

  • frontend/components/BaselineHeader.tsx#L42-L42: use a compliant muted-text color.
  • frontend/app/timeline.tsx#L153-L158: use a compliant empty-state color.
  • frontend/services/pdfExportService.ts#L129-L130: use a compliant empty-note/footer color.

As per coding guidelines, normal text must meet a minimum 4.5:1 contrast ratio.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/components/BaselineHeader.tsx` at line 42, Replace the low-contrast
muted color with a color meeting the 4.5:1 contrast requirement at
frontend/components/BaselineHeader.tsx lines 42-42, frontend/app/timeline.tsx
lines 153-158, and frontend/services/pdfExportService.ts lines 129-130,
preserving each existing empty-state or footer style’s other properties.

Source: Coding guidelines

🧹 Nitpick comments (4)
frontend/app.json (1)

26-31: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Verify the foreground-service permission set.

The documented flow records voice, but the manifest requests FOREGROUND_SERVICE_MEDIA_PLAYBACK, which Android defines for media playback; microphone foreground services use FOREGROUND_SERVICE_MICROPHONE. Remove unused foreground-service permissions, or configure and test the microphone-specific background-recording path. (developer.android.com)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app.json` around lines 26 - 31, Update the permissions array in
frontend/app.json to match the documented voice-recording flow: remove the
media-playback foreground-service permission and add the microphone-specific
foreground-service permission if background recording is supported. Remove any
other unused foreground-service permissions, then verify the resulting manifest
configuration with the recording path.
readme.md (1)

577-577: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Fix the Markdown heading hierarchy.

These headings jump from ## directly to ####. Use ### or add the missing level to satisfy the reported MD001 warnings.

Also applies to: 643-643

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@readme.md` at line 577, Fix the Markdown heading hierarchy for the Ticket 1
heading and the corresponding heading at the other reported location by changing
each heading from level four to level three, or by adding the missing
intermediate level, so headings do not skip from ## to #### and MD001 warnings
are resolved.

Source: Linters/SAST tools

frontend/services/pdfExportService.ts (1)

107-107: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the required Inter font stack in the PDF.

The export explicitly starts with Helvetica instead of Inter.

Proposed fix
- body { font-family: Helvetica, Arial, sans-serif; color: `#1e293b`; padding: 32px; }
+ body { font-family: Inter, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; color: `#1e293b`; padding: 32px; }

As per coding guidelines, use “Inter” with -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, and sans-serif fallbacks.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/services/pdfExportService.ts` at line 107, Update the body
font-family declaration in the PDF export HTML template to use Inter first,
followed by -apple-system, BlinkMacSystemFont, “Segoe UI”, Roboto, and
sans-serif fallbacks, replacing Helvetica and Arial.

Source: Coding guidelines

frontend/app/timeline.tsx (1)

145-151: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Centralize and apply the mandated semantic color tokens.

Main actions currently use #0F172A/#1D4ED8, while danger states use #DC2626; these diverge from the required primary #4F46E5 and danger #EF4444 values.

  • frontend/app/timeline.tsx#L145-L151: use the primary action token for export.
  • frontend/components/EventDetailModal.tsx#L69-L76: use the primary action token for close.
  • frontend/components/FloatingMicButton.tsx#L49-L66: use primary and required danger tokens.
  • frontend/components/LoadingOverlay.tsx#L8-L14: use the primary token for the activity indicator.
  • frontend/components/RedFlagBanner.tsx#L21-L32: use the required danger token for the urgent state.
  • frontend/components/TimelineCard.tsx#L32-L58: use the required danger token and replace off-scale 14px/6px spacing with 16px/8px.
  • frontend/components/UploadDocumentButton.tsx#L48-L65: use the primary action token.
  • frontend/services/pdfExportService.ts#L107-L130: use the same semantic tokens in the exported document.

As per coding guidelines, Primary Blue (#4F46E5) is required for main actions and Error/Danger states must use #EF4444.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/app/timeline.tsx` around lines 145 - 151, Centralize the semantic
colors and apply them consistently: update frontend/app/timeline.tsx (145-151),
EventDetailModal.tsx (69-76), FloatingMicButton.tsx (49-66), LoadingOverlay.tsx
(8-14), UploadDocumentButton.tsx (48-65), and the main-action portions of
pdfExportService.ts (107-130) to use primary `#4F46E5`; update
FloatingMicButton.tsx, RedFlagBanner.tsx (21-32), TimelineCard.tsx (32-58), and
the danger portions of pdfExportService.ts to use `#EF4444`. In TimelineCard.tsx,
also replace the 14px/6px spacing values with 16px/8px.

Source: Coding guidelines


ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 171dacfc-4fe9-458e-81f7-3fabf98b6db1

📥 Commits

Reviewing files that changed from the base of the PR and between bcde5c4 and 99b96aa.

⛔ Files ignored due to path filters (9)
  • backend/tests/fixtures/sample_audio.wav is excluded by !**/*.wav
  • frontend/assets/android-icon-background.png is excluded by !**/*.png
  • frontend/assets/android-icon-foreground.png is excluded by !**/*.png
  • frontend/assets/android-icon-monochrome.png is excluded by !**/*.png
  • frontend/assets/favicon.png is excluded by !**/*.png
  • frontend/assets/icon.png is excluded by !**/*.png
  • frontend/assets/splash-icon.png is excluded by !**/*.png
  • frontend/package-lock.json is excluded by !**/package-lock.json
  • pasaporte_medico_inteligente.pdf is excluded by !**/*.pdf
📒 Files selected for processing (87)
  • .serena/.gitignore
  • .serena/project.yml
  • DEPLOY.md
  • backend/.env.example
  • backend/.gitignore
  • backend/Dockerfile
  • backend/alembic.ini
  • backend/app/__init__.py
  • backend/app/api/__init__.py
  • backend/app/api/v1/__init__.py
  • backend/app/api/v1/health.py
  • backend/app/api/v1/patients.py
  • backend/app/api/v1/router.py
  • backend/app/core/__init__.py
  • backend/app/core/config.py
  • backend/app/core/database.py
  • backend/app/core/deps.py
  • backend/app/exceptions.py
  • backend/app/main.py
  • backend/app/models/__init__.py
  • backend/app/models/base.py
  • backend/app/models/clinical_baseline.py
  • backend/app/models/medical_event.py
  • backend/app/models/patient.py
  • backend/app/repositories/__init__.py
  • backend/app/repositories/interfaces.py
  • backend/app/repositories/sqlalchemy_repository.py
  • backend/app/schemas/__init__.py
  • backend/app/schemas/ai_contracts.py
  • backend/app/schemas/clinical_baseline.py
  • backend/app/schemas/medical_event.py
  • backend/app/schemas/passport.py
  • backend/app/schemas/patient.py
  • backend/app/services/__init__.py
  • backend/app/services/ai_orchestrator.py
  • backend/app/services/openai_client.py
  • backend/app/services/prompt_templates.py
  • backend/docker-compose.yml
  • backend/migrations/env.py
  • backend/migrations/script.py.mako
  • backend/migrations/versions/0001_initial_schema.py
  • backend/pytest.ini
  • backend/requirements-dev.txt
  • backend/requirements.txt
  • backend/tests/__init__.py
  • backend/tests/conftest.py
  • backend/tests/e2e/__init__.py
  • backend/tests/e2e/test_process_voice_e2e.py
  • backend/tests/fixtures/README.md
  • backend/tests/integration/__init__.py
  • backend/tests/integration/test_api_endpoints.py
  • backend/tests/integration/test_health_repository.py
  • backend/tests/integration/test_patient_repository.py
  • backend/tests/unit/__init__.py
  • backend/tests/unit/test_ai_orchestrator_parsing.py
  • frontend/.env.example
  • frontend/.gitignore
  • frontend/.npmrc
  • frontend/app.json
  • frontend/app/_layout.tsx
  • frontend/app/index.tsx
  • frontend/app/onboarding.tsx
  • frontend/app/timeline.tsx
  • frontend/components/BaselineChip.tsx
  • frontend/components/BaselineHeader.tsx
  • frontend/components/CategoryBadge.tsx
  • frontend/components/EventDetailModal.tsx
  • frontend/components/FloatingMicButton.tsx
  • frontend/components/LoadingOverlay.tsx
  • frontend/components/RedFlagBanner.tsx
  • frontend/components/TimelineCard.tsx
  • frontend/components/UploadDocumentButton.tsx
  • frontend/components/categoryColors.ts
  • frontend/eas.json
  • frontend/package.json
  • frontend/services/audioRecorder.ts
  • frontend/services/healthRepository.ts
  • frontend/services/httpClient.ts
  • frontend/services/patientStore.ts
  • frontend/services/pdfExportService.ts
  • frontend/tsconfig.json
  • frontend/types/clinicalBaseline.ts
  • frontend/types/medicalEvent.ts
  • frontend/types/passport.ts
  • frontend/types/patient.ts
  • readme.md
  • render.yaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant