apac-ops-bot/backend/app/models/message.py
SamoilenkoVadym a8151fbe66 Add comprehensive backend test suite and Phase 1 foundation
Backend Tests:
- Add pytest configuration with async support (conftest.py)
- Add model tests: User, Conversation, Message, TokenUsage, Session, UserMemory
- Add configuration tests: Settings validation and environment variables
- Add API tests: Health endpoint and future endpoint stubs
- Add database tests: Connection, transactions, query execution

Phase 1 Foundation:
- FastAPI application structure with main.py
- SQLAlchemy async models for all entities
- Alembic migrations setup
- Configuration management via Pydantic Settings
- Logging system (English only)
- Docker multi-stage builds for backend
- Docker Compose orchestration (PostgreSQL, Redis, backend)
- Frontend React + TypeScript structure
- Dark & Gold theme CSS implementation
- Environment configuration examples

All code and comments in English as per requirements.
Tests cover model relationships, cascade deletes, and constraints.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-27 14:24:59 +00:00

58 lines
1.7 KiB
Python

"""
Message model for storing individual chat messages
"""
from sqlalchemy import Column, String, Text, Integer, DateTime, JSON, ForeignKey, CheckConstraint
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import uuid
from app.database import Base
class Message(Base):
"""
Message model representing a single message in a conversation
"""
__tablename__ = "messages"
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, index=True)
conversation_id = Column(
UUID(as_uuid=True),
ForeignKey("conversations.id", ondelete="CASCADE"),
nullable=False,
index=True
)
# OpenAI Responses API response_id
openai_response_id = Column(String(255), index=True)
# Message content
role = Column(String(50), nullable=False) # user, assistant, system
content = Column(Text, nullable=False)
# Token count for this message
token_count = Column(Integer, default=0)
# Timestamp
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False, index=True)
# JSON field for metadata (file_search_results, etc.)
metadata = Column(JSON, default=dict, nullable=False)
# Relationships
conversation = relationship("Conversation", back_populates="messages")
token_usage_records = relationship("TokenUsage", back_populates="message")
# Constraints
__table_args__ = (
CheckConstraint(
"role IN ('user', 'assistant', 'system')",
name="check_message_role"
),
)
def __repr__(self):
return f"<Message {self.id} - {self.role}>"