Skip to main content

Syntropy Health - Development Best Practices

Overview

Syntropy Health is a healthtech application that manages sensitive health data. As such, it requires strict adherence to software development best practices to ensure reliability, security, and maintainability.

Architecture Principles

1. Type Safety

All data structures use strict typing:
  • TypedDict schemas for state management (not DB models)
  • Pydantic models for API validation
  • SQLModel for database models with proper relationships
# Example: Flat TypedDict for Reflex rx.foreach compatibility
class ChatMessageDict(TypedDict):
    """Flat schema - Reflex doesn't support nested TypedDict access."""
    id: Optional[int]
    session_id: str
    message_type: str  # "human", "ai", "system"
    content: str
    created_at: str

2. Schema Separation

syntropy_journals/app/models/syntropy/
├── chat.py           # Database models (SQLModel)
├── schemas/
│   └── chat.py       # State schemas (TypedDict) - for UI/state management
Why separate?
  • DB models have relationships that can’t serialize to Reflex state
  • TypedDicts provide type hints for rx.foreach and other Reflex components
  • Keeps concerns separated (persistence vs presentation)

3. Reflex-Specific Patterns

rx.foreach Type Safety

Reflex’s rx.foreach requires explicit type casting:
# In component:
rx.foreach(
    ChatState.current_chat_messages.to(list[ChatMessageDict]),
    message_bubble,
)

# In state - flatten nested structures:
@rx.var
def current_chat_messages(self) -> list[ChatMessageDict]:
    return [
        ChatMessageDict(
            id=msg.id,
            message_type=msg.message.get("data", {}).get("type", "unknown"),
            content=msg.message.get("data", {}).get("content", ""),
            ...
        )
        for msg in self.active_session_messages
    ]

State Management

  • Use @rx.var for computed properties
  • Use @rx.event for state mutations
  • Use @rx.event(background=True) for async DB operations
  • Always use async with self: when updating state in background events

Testing Strategy

Unit Tests

Located in tests/unit/:
  • Schema validation tests
  • State logic tests
  • Utility function tests

Integration Tests

Located in tests/integration/:
  • Database seeding tests
  • API endpoint tests
  • State + DB interaction tests

Running Tests

# Run all tests
uv run pytest

# Run with coverage
uv run pytest --cov=syntropy_journals/app --cov-report=html

# Run specific test file
uv run pytest tests/unit/test_chat_schemas.py -v

Code Quality

Linting & Formatting

# Format code
uv run ruff format syntropy_journals/app/

# Lint code
uv run ruff check syntropy_journals/app/ --fix

Pre-commit Checks

Before committing:
  1. uv run reflex run - Verify app compiles
  2. uv run pytest - Run test suite
  3. uv run ruff check syntropy_journals/app/ - Lint check

Security Considerations

HealthTech Compliance

  1. Data Encryption: All health data encrypted at rest and in transit
  2. Authentication: Clerk-based auth with session management
  3. Audit Logging: All data access logged for compliance
  4. Input Validation: Strict schema validation on all inputs

Environment Variables

Never commit secrets. Required env vars:
  • REFLEX_DB_URL - Database connection string
  • CLERK_SECRET_KEY - Authentication
  • OPENAI_API_KEY - AI features (if applicable)

Deployment

Railway Deployment

# Trigger deployment via GitHub Actions
git push origin test  # Test environment
git push origin main  # Production (requires PR approval)

Health Checks

  • Backend: GET /health
  • Frontend: Reflex handles automatically

Completed Optimizations

2026-02-02: Chat Schema Refactoring

Problem: rx.foreach failed with nested TypedDict access
UntypedVarError: Cannot foreach on untyped var
Solution:
  1. Flattened ChatMessageDict schema (removed nested message field)
  2. State converts DB models to flat dicts in current_chat_messages
  3. Added .to(list[ChatMessageDict]) cast in foreach
Files Changed:
  • syntropy_journals/app/models/syntropy/schemas/chat.py - Flattened schema
  • syntropy_journals/app/states/chat/chat.py - Flatten in state var
  • syntropy_journals/app/components/chat/message_bubble.py - Direct access
  • syntropy_journals/app/components/chat/interface.py - Type cast

Deprecation Warnings to Address

WarningLocationFix
check_circle icon invalidMultiple filesUse circle-check
codeblock deprecatedlanding/message_bubble.pyUse pre
RouterData.page deprecatednavbar.py, sidebar.pyUse RouterData.url
rx.Base deprecatedExternal packageUpdate reflex_audio_capture

Contact

For questions about this codebase, contact the Syntropy Health engineering team.