InnerVoice / backend /models /database.py
E5K7's picture
feat: Connect Trusted Circle invites to real Brevo transactional email sender
9a86182
Raw
History Blame Contribute Delete
5.55 kB
import uuid
from datetime import datetime
from typing import Optional, List
from sqlalchemy import (
create_engine, Column, String, Float, Integer,
Boolean, Text, ForeignKey, DateTime, JSON
)
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship
import os
from dotenv import load_dotenv
load_dotenv()
DATABASE_URL = os.getenv("DATABASE_URL", "sqlite:///./innervoice.db")
engine = create_engine(
DATABASE_URL,
connect_args={"check_same_thread": False} if "sqlite" in DATABASE_URL else {}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
class User(Base):
__tablename__ = "users"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
email = Column(String, unique=True, nullable=False, index=True)
name = Column(String, nullable=False)
password_hash = Column(String, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
baseline_pitch = Column(Float, nullable=True)
baseline_energy = Column(Float, nullable=True)
baseline_speech_rate = Column(Float, nullable=True)
voice_entries = relationship("VoiceEntry", back_populates="user", cascade="all, delete-orphan")
mood_alerts = relationship("MoodAlert", back_populates="user", cascade="all, delete-orphan")
chat_messages = relationship("ChatMessage", back_populates="user", cascade="all, delete-orphan")
chat_channels = relationship("ChatChannel", back_populates="user", cascade="all, delete-orphan")
trusted_members = relationship("TrustedMember", back_populates="user", cascade="all, delete-orphan")
class VoiceEntry(Base):
__tablename__ = "voice_entries"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
user_id = Column(String, ForeignKey("users.id"), nullable=False, index=True)
created_at = Column(DateTime, default=datetime.utcnow)
audio_url = Column(String, nullable=True)
duration_seconds = Column(Float, nullable=True)
transcription = Column(Text, nullable=True)
primary_emotion = Column(String, nullable=True)
emotion_confidence = Column(Float, nullable=True)
energy_score = Column(Integer, nullable=True)
calmness_score = Column(Integer, nullable=True)
mood_score = Column(Integer, nullable=True)
clarity_score = Column(Integer, nullable=True)
pitch_mean = Column(Float, nullable=True)
pitch_std = Column(Float, nullable=True)
energy_raw = Column(Float, nullable=True)
speech_rate = Column(Float, nullable=True)
pause_count = Column(Integer, nullable=True)
avg_pause_duration = Column(Float, nullable=True)
filler_rate = Column(Float, nullable=True)
mfcc_features = Column(JSON, nullable=True)
sleep_hours = Column(Float, nullable=True) # hours slept before this check-in
user = relationship("User", back_populates="voice_entries")
chat_messages = relationship("ChatMessage", back_populates="voice_entry")
class MoodAlert(Base):
__tablename__ = "mood_alerts"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
user_id = Column(String, ForeignKey("users.id"), nullable=False, index=True)
created_at = Column(DateTime, default=datetime.utcnow)
alert_type = Column(String, nullable=False)
severity = Column(String, nullable=False)
message = Column(Text, nullable=False)
is_read = Column(Boolean, default=False)
suggested_action = Column(Text, nullable=True)
user = relationship("User", back_populates="mood_alerts")
class ChatChannel(Base):
__tablename__ = "chat_channels"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
user_id = Column(String, ForeignKey("users.id"), nullable=False, index=True)
title = Column(String, nullable=False, default="New Chat")
created_at = Column(DateTime, default=datetime.utcnow)
updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
user = relationship("User", back_populates="chat_channels")
messages = relationship("ChatMessage", back_populates="channel", cascade="all, delete-orphan")
class ChatMessage(Base):
__tablename__ = "chat_messages"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
user_id = Column(String, ForeignKey("users.id"), nullable=False, index=True)
channel_id = Column(String, ForeignKey("chat_channels.id"), nullable=True, index=True)
created_at = Column(DateTime, default=datetime.utcnow)
role = Column(String, nullable=False) # user / assistant
content = Column(Text, nullable=False)
voice_entry_id = Column(String, ForeignKey("voice_entries.id"), nullable=True)
user = relationship("User", back_populates="chat_messages")
channel = relationship("ChatChannel", back_populates="messages")
voice_entry = relationship("VoiceEntry", back_populates="chat_messages")
class TrustedMember(Base):
__tablename__ = "trusted_members"
id = Column(String, primary_key=True, default=lambda: str(uuid.uuid4()))
user_id = Column(String, ForeignKey("users.id"), nullable=False, index=True)
email = Column(String, nullable=False)
created_at = Column(DateTime, default=datetime.utcnow)
is_active = Column(Boolean, default=True)
user = relationship("User", back_populates="trusted_members")
def init_db():
Base.metadata.create_all(bind=engine)