Spaces:
Sleeping
Sleeping
| import uuid | |
| from datetime import datetime | |
| from sqlalchemy import Boolean, Column, DateTime, Integer, String, Text | |
| from app.db.database import Base | |
| class IntakeSession(Base): | |
| __tablename__ = "intake_sessions" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| created_at = Column(DateTime, default=datetime.utcnow, index=True) | |
| patient_name = Column(String, nullable=True) # Optional for now | |
| # Original Data | |
| transcript = Column(Text, nullable=False) | |
| detected_language = Column(String, default="en") | |
| # Extracted Data | |
| chief_complaint = Column(Text, nullable=True) | |
| # SOAP Sections | |
| soap_subjective = Column(Text, nullable=True) | |
| soap_objective = Column(Text, nullable=True) | |
| soap_assessment = Column(Text, nullable=True) | |
| soap_plan = Column(Text, nullable=True) | |
| # Encryption tracking | |
| is_encrypted = Column(Boolean, default=False, nullable=False) | |
| class User(Base): | |
| __tablename__ = "users" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| username = Column(String, unique=True, index=True, nullable=False) | |
| full_name = Column(String, nullable=True) | |
| role = Column(String, index=True, nullable=False) | |
| hashed_password = Column(Text, nullable=False) | |
| is_active = Column(Boolean, default=True, nullable=False) | |
| created_at = Column(DateTime, default=datetime.utcnow, index=True) | |
| updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow) | |
| # Phase 4: MFA | |
| totp_secret = Column(Text, nullable=True) | |
| mfa_enrolled_at = Column(DateTime, nullable=True) | |
| class AuditLog(Base): | |
| __tablename__ = "audit_logs" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| timestamp = Column(DateTime, default=datetime.utcnow, index=True) | |
| user_id = Column(String, nullable=True, index=True) | |
| username = Column(String, nullable=True, index=True) | |
| role = Column(String, nullable=True, index=True) | |
| action = Column(String, nullable=False) | |
| resource = Column(String, nullable=False) | |
| resource_id = Column(String, nullable=True) | |
| endpoint = Column(String, nullable=False, index=True) | |
| http_method = Column(String, nullable=False) | |
| status_code = Column(Integer, nullable=False) | |
| ip_address = Column(String, nullable=True) | |
| user_agent = Column(Text, nullable=True) | |
| details = Column(Text, nullable=True) | |
| # Enhanced HIPAA fields | |
| data_access_type = Column(String, nullable=True, index=True) # read, write, export, delete, purge | |
| phi_accessed = Column(Boolean, default=False, nullable=False) | |
| correlation_id = Column(String, nullable=True, index=True) | |
| class ConversationSession(Base): | |
| """Stores AI Voice Assistant conversation sessions.""" | |
| __tablename__ = "conversation_sessions" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| created_at = Column(DateTime, default=datetime.utcnow, index=True) | |
| ended_at = Column(DateTime, nullable=True) | |
| intake_session_id = Column(String, nullable=True, index=True) | |
| mode = Column(String, nullable=False, default="patient") # "patient" or "clinician" | |
| state = Column(String, default="greeting") | |
| turns_json = Column(Text, nullable=True) # JSON array of conversation turns | |
| accumulated_transcript = Column(Text, nullable=True) | |
| entities_json = Column(Text, nullable=True) # JSON of extracted entities | |
| is_encrypted = Column(Boolean, default=False, nullable=False) | |
| class RefreshToken(Base): | |
| """Stores hashed refresh tokens for JWT auth.""" | |
| __tablename__ = "refresh_tokens" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| user_id = Column(String, nullable=False, index=True) | |
| token_hash = Column(String, nullable=False, unique=True, index=True) | |
| expires_at = Column(DateTime, nullable=False) | |
| revoked = Column(Boolean, default=False, nullable=False) | |
| created_at = Column(DateTime, default=datetime.utcnow) | |
| ip_address = Column(String, nullable=True) | |
| user_agent = Column(Text, nullable=True) | |
| class ConsentRecord(Base): | |
| """Records patient verbal/written consent before intake processing.""" | |
| __tablename__ = "consent_records" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| session_id = Column(String, nullable=False, index=True) | |
| patient_identifier = Column(String, nullable=True) | |
| consent_type = Column(String, nullable=False, default="verbal") # verbal, written, electronic | |
| consented_at = Column(DateTime, default=datetime.utcnow) | |
| recorded_by_user_id = Column(String, nullable=True) | |
| recorded_by_username = Column(String, nullable=True) | |
| details = Column(Text, nullable=True) | |
| revoked = Column(Boolean, default=False, nullable=False) | |
| revoked_at = Column(DateTime, nullable=True) | |
| class DataExportLog(Base): | |
| """Tracks all data exports for HIPAA compliance — who exported what, when, and where.""" | |
| __tablename__ = "data_export_logs" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| timestamp = Column(DateTime, default=datetime.utcnow, index=True) | |
| user_id = Column(String, nullable=True, index=True) | |
| username = Column(String, nullable=True, index=True) | |
| export_type = Column(String, nullable=False) # fhir, csv, json, pdf | |
| resource_type = Column(String, nullable=False) # session, audit_log, report | |
| resource_ids = Column(Text, nullable=True) # JSON list of exported resource IDs | |
| record_count = Column(Integer, default=0) | |
| destination = Column(String, nullable=True) # e.g., "ehr_endpoint", "download", "api" | |
| ip_address = Column(String, nullable=True) | |
| status = Column(String, default="success") # success, failed, partial | |
| details = Column(Text, nullable=True) | |
| # ===================================================================== | |
| # Phase 2: Document Versioning & Collaborative Annotations | |
| # ===================================================================== | |
| class DocumentVersion(Base): | |
| """Versioned SOAP document with diff tracking. | |
| Each edit to a SOAP note creates a new version, preserving full history | |
| for audit compliance and collaborative editing. | |
| """ | |
| __tablename__ = "document_versions" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| session_id = Column(String, nullable=False, index=True) | |
| version_number = Column(Integer, nullable=False, default=1) | |
| created_at = Column(DateTime, default=datetime.utcnow, index=True) | |
| # Author | |
| author_id = Column(String, nullable=True, index=True) | |
| author_username = Column(String, nullable=True) | |
| author_role = Column(String, nullable=True) # clinician, system, ai | |
| # SOAP content (JSON blob with all sections) | |
| content_json = Column(Text, nullable=False) | |
| # Change tracking | |
| diff_json = Column(Text, nullable=True) # JSON diff from previous version | |
| change_summary = Column(Text, nullable=True) # Human-readable summary | |
| change_type = Column(String, nullable=False, default="edit") # initial, edit, ai_generated, review, correction | |
| # Metadata | |
| confidence_json = Column(Text, nullable=True) # Confidence scores per section | |
| is_encrypted = Column(Boolean, default=False, nullable=False) | |
| class DocumentAnnotation(Base): | |
| """Inline annotation on a specific field of a SOAP document version. | |
| Supports corrections, additions, questions, and approval markers | |
| from collaborating clinicians. | |
| """ | |
| __tablename__ = "document_annotations" | |
| id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4())) | |
| document_version_id = Column(String, nullable=False, index=True) | |
| session_id = Column(String, nullable=False, index=True) | |
| created_at = Column(DateTime, default=datetime.utcnow, index=True) | |
| # Author | |
| author_id = Column(String, nullable=True, index=True) | |
| author_username = Column(String, nullable=True) | |
| # Location within the SOAP note | |
| soap_section = Column(String, nullable=False) # subjective, objective, assessment, plan | |
| field_path = Column(String, nullable=True) # e.g., "symptom_details.onset" | |
| text_offset_start = Column(Integer, nullable=True) # Character offset in section text | |
| text_offset_end = Column(Integer, nullable=True) | |
| # Annotation content | |
| annotation_type = Column(String, nullable=False) # correction, addition, question, approval, flag | |
| content = Column(Text, nullable=False) | |
| suggested_replacement = Column(Text, nullable=True) # For corrections | |
| # Status | |
| status = Column(String, default="open") # open, resolved, rejected | |
| resolved_by_id = Column(String, nullable=True) | |
| resolved_at = Column(DateTime, nullable=True) | |