This document outlines the operational guidelines, architectural rules, and best practices that all AI coding agents must follow when contributing to the TrialPulse repository.
- Role: You are an AI coding agent contributing to TrialPulse, a clinical trial patient safety and engagement platform.
- Structure: The application is a monorepo consisting of:
- Backend: A fully asynchronous Python FastAPI monolith.
- Frontend (Web): A React 18 + TypeScript web dashboard for researchers.
- Mobile App: A React Native (Expo) app for patients.
- Goal: Maintain clean, async, event-driven, and highly observable code suitable for a healthcare prototype.
All agents must adhere to a strict branching and commit workflow to ensure code quality and traceability.
- Never Push to Main: Direct pushes to the
mainbranch are strictly prohibited. All changes must go through a Pull Request. - Branch Naming: Branch names MUST use a
type/descriptionformat.- Examples:
feat/voice-checkin-ui,fix/anomaly-detection-math,refactor/alert-engine,docs/api-specs
- Examples:
- Conventional Commits: You must strictly follow the Conventional Commits format for all commit subjects.
- Examples:
feat(backend): implement point anomaly detection for wearables,fix(mobile): resolve quick reply rendering issue
- Examples:
- Commit Bodies (Mandatory): Every commit MUST include a descriptive subject line AND a detailed, multiline commit description.
- The body should explain the why and how of the change, not just the what.
- If a commit contains multiple logical changes or touches several components, use bullet points in the description body to detail each change.
- Pull Requests: Always open Pull Requests for review. PR descriptions must accurately summarize the changes and link to any relevant issue tracking numbers.
Detailed, structured logging is a project-wide requirement. Visibility into event flows, AI state, and asynchronous tasks is critical.
- Action Tracking: Every significant action, state change (e.g., LangGraph node transitions), or external API call MUST be logged.
- Structured Logging: Use the configured structured Python logger (e.g., standard
loggingwith JSON formatting orloguru). - Log Levels: Use
INFOfor lifecycle events/requests,WARNINGfor recoverable issues/retries,ERRORfor exceptions, andDEBUGfor verbose AI/API traces. - Prohibition on Print Output: Do not use
print()orconsole.log()for operational logging. These are strictly for temporary local debugging and must be removed before committing. - Contextual Logs: Include relevant context (e.g.,
patient_id,session_id,trial_id,event_type) in log events to facilitate debugging.
- Async First: The entire backend is built on
asyncio. Useawaitfor database calls, Redis pub/sub, external requests, and LLM generation. Do not block the event loop with synchronous operations. - Event-Driven Communication: Modules must not tightly couple their business logic. Instead, publish events to the Redis event bus (
app/events/bus.py).- Example: The
checkinmodule shouldn't call thealertmodule directly. It publishessymptom.reported, which the alert engine listens to.
- Example: The
- Database Access: Use the async
SQLAlchemyORM andasyncpg. Avoid raw SQL strings unless optimizing a complex analytics query. Use UUIDs for IDs andTIMESTAMPTZfor timestamps. - Dependency Injection: Heavily utilize FastAPI's
Depends()for database sessions, Redis clients, and current user extraction. - LLM Abstraction: NEVER hardcode Anthropic or OpenAI API calls. All LLM calls must go through the vendor-agnostic LangChain/LangGraph abstraction (
app/ai/llm.py).
- State Management: Use
React Queryfor all server-state (fetching, caching, background refetching, mutations). UseZustandonly for local, lightweight UI state. - Styling: Use
Tailwind CSSfor web andNativeWindfor mobile. Keep styling logic utility-first and avoid custom CSS files. - Type Safety: Ensure strict TypeScript typing for all API responses, component props, and state slices. Avoid
any. - Real-time Updates: Use the native FastAPI WebSockets for dashboard live updates. Handle connection drops and reconnects gracefully.
- Mock Data First: As this is a hackathon prototype, do not write code that connects to real external patient data streams unless explicitly requested. Rely on the
seed.sqland data generation scripts. - Secrets Management: Never hardcode API keys or database passwords. Always rely on the
Pydantic Settingsobject inapp/config.pyto load from environment variables.
- Ensure coverage for critical paths: the symptom check-in flow, anomaly detection math, and alert engine rules.
- For backend updates, use
pytestwithpytest-asyncio. - Mock external dependencies (like LiveKit or external LLMs) when writing unit tests to keep CI fast.