modification done to up the project
Some checks failed
CI/CD Pipeline / test (push) Has been cancelled
CI/CD Pipeline / build (push) Has been cancelled
CI/CD Pipeline / deploy-staging (push) Has been cancelled
CI/CD Pipeline / deploy-production (push) Has been cancelled

This commit is contained in:
laxmanhalaki 2026-03-12 20:52:08 +05:30
parent 131f7ad8e8
commit b793ac859a
118 changed files with 6515 additions and 7347 deletions

37
.env.example Normal file
View File

@ -0,0 +1,37 @@
# Application Settings
APP_NAME="AI Detection API"
APP_VERSION="1.0.0"
DEBUG=True
PORT=8000
HOST=0.0.0.0
# Database Settings
# For Docker Compose, use 'postgres' as the host. For local, use 'localhost'.
DATABASE_URL="postgresql://postgres:postgres@postgres:5432/test_project_db"
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=test_project_db
POSTGRES_PORT=5432
# Redis Settings
# For Docker Compose, use 'redis' as the host. For local, use 'localhost'.
REDIS_HOST=redis
REDIS_PORT=6379
# Security Settings
# Generate a secure key for production
JWT_SECRET="your-super-secret-jwt-key-change-me"
JWT_REFRESH_SECRET="your-super-secret-refresh-key-change-me"
JWT_ISSUER="ai-detection-app"
JWT_AUDIENCE="ai-detection-users"
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=30
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
# RAG / AI Configuration
OPENAI_API_KEY="sk-..."
ANTHROPIC_API_KEY="xpk-..."
EMBEDDING_PROVIDER="huggingface" # "openai" or "huggingface"
LLM_PROVIDER="openai" # "openai" or "anthropic"
VECTOR_DB_DIR="./chroma_db"
RAG_CHUNK_SIZE=1000
RAG_CHUNK_OVERLAP=100

52
.gitignore vendored Normal file
View File

@ -0,0 +1,52 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# Environment
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Project Specific
chroma_db/
*.log
.pytest_cache/
test_results/
# Editor/IDE
.vscode/
.idea/
*.swp
*.swo
# Docker
.docker/
docker-compose.override.yml
# OS
.DS_Store
Thumbs.db

72
RUNNING.md Normal file
View File

@ -0,0 +1,72 @@
# Running the AI-Detection Project
This project is a FastAPI-based AI application for detection and RAG (Retrieval-Augmented Generation).
## Prerequisites
- **Python 3.11+** (for local setup)
- **Docker and Docker Compose** (for containerized setup - Recommended)
- **PostgreSQL** and **Redis** (if running locally)
---
## 🚀 Option 1: Running with Docker (Recommended)
The easiest way to run the project is using Docker Compose, which sets up the application, database, and Redis automatically.
1. **Configure Environment Variables**:
Copy the example environment file and fill in your keys:
```bash
cp .env.example .env
```
*Note: Open `.env` and provide your `OPENAI_API_KEY` or `ANTHROPIC_API_KEY` if using AI features.*
2. **Start the Services**:
```bash
docker-compose up --build
```
3. **Access the API**:
- **API Documentation (Swagger UI)**: [http://localhost:8000/docs](http://localhost:8000/docs)
- **Health Check**: [http://localhost:8000/health](http://localhost:8000/health)
---
## 🛠️ Option 2: Running Locally
If you prefer to run the application directly on your machine:
1. **Create a Virtual Environment**:
```bash
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
```
2. **Install Dependencies**:
```bash
pip install -r requirements.txt
```
3. **Configure Environment Variables**:
Copy `.env.example` to `.env` and update the settings:
- Set `DATABASE_URL` to point to your local PostgreSQL instance (e.g., `postgresql://user:pass@localhost:5432/dbname`).
- Set `REDIS_HOST` to `localhost`.
4. **Run the Application**:
```bash
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
```
---
## 📂 Project Structure Highlights
- `main.py`: Entry point of the FastAPI application.
- `src/config/`: Configuration management and startup migrations.
- `src/services/`: Core business logic (RAG, JWT, etc.).
- `src/migrations/`: Database schema definitions.
- `docker-compose.yml`: Multi-container orchestration.
## 🧪 Testing
To run tests, ensure dependencies are installed and run:
```bash
pytest
```

9
check_routes.py Normal file
View File

@ -0,0 +1,9 @@
from main import app
from fastapi.routing import APIRoute
print("Registered Routes:")
for route in app.routes:
if isinstance(route, APIRoute):
print(f"Path: {route.path} | Methods: {route.methods} | Name: {route.name}")
else:
print(f"Path: {route.path}")

18
fix_routes_async.py Normal file
View File

@ -0,0 +1,18 @@
import os
from pathlib import Path
import re
def fix_routes():
routes_dir = Path("src/routes")
for route_file in routes_dir.glob("*_routes.py"):
content = route_file.read_text(encoding="utf-8")
# Add await to crud.* calls
# Matches: db_user = crud.get_by_id(user_id) -> await crud.get_by_id(user_id)
# Matches: return crud.create(user_in) -> return await crud.create(user_in)
# We need to be careful not to double await
content = re.sub(r"(?<!await\s)crud\.(\w+)\(", r"await crud.\1(", content)
route_file.write_text(content, encoding="utf-8")
print(f"Fixed async/await in {route_file.name}")
if __name__ == "__main__":
fix_routes()

11
main.py
View File

@ -3,6 +3,7 @@ FastAPI Application Entry Point
Enterprise-grade FastAPI application with proper structure and middleware
"""
import logging
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from src.config.config import settings
@ -44,6 +45,9 @@ app.add_middleware(
)
# Include routers
import src.models # Trigger model registration
from src.routes.index import router as api_router
app.include_router(api_router)
@app.on_event("startup")
async def startup_event():
@ -85,3 +89,10 @@ async def health_check():
"version": settings.APP_VERSION
}
if __name__ == "__main__":
uvicorn.run(
"main:app",
host=settings.HOST,
port=settings.PORT,
reload=settings.DEBUG
)

57
mass_fix.py Normal file
View File

@ -0,0 +1,57 @@
import os
from pathlib import Path
import re
def fix_models():
models_dir = Path("src/models")
for model_file in models_dir.glob("*.py"):
content = model_file.read_text(encoding="utf-8")
# Fix reserved 'metadata' name
content = content.replace('metadata = Column(JSON', 'doc_metadata = Column(JSON')
model_file.write_text(content, encoding="utf-8")
def fix_services():
services_dir = Path("src/services")
for service_file in services_dir.glob("*.py"):
content = service_file.read_text(encoding="utf-8")
# Add basic imports
needed_imports = []
if " date" in content and "from datetime import date" not in content and "import datetime" not in content:
needed_imports.append("from datetime import date")
if " datetime" in content and "from datetime import" not in content and "import datetime" not in content:
needed_imports.append("from datetime import datetime")
if " Decimal" in content and "from decimal import Decimal" not in content:
needed_imports.append("from decimal import Decimal")
if needed_imports:
content = "\n".join(needed_imports) + "\n" + content
# Fix missing model type hints by replacing them with Any
# Exclude common types like UUID, int, str, bool, List, Dict, Tuple, Optional
def replace_type(match):
type_name = match.group(1)
if type_name in ["UUID", "int", "str", "bool", "List", "Dict", "Tuple", "Optional", "Any", "None", "float", "bytes"]:
return match.group(0)
return match.group(0).replace(type_name, "Any")
content = re.sub(r"-> List\[([A-Z]\w+)\]", replace_type, content)
content = re.sub(r"-> ([A-Z]\w+)", replace_type, content)
content = re.sub(r": ([A-Z]\w+)", replace_type, content)
# Standardize CRUD class name
content = re.sub(r"class (\w+)Service", r"class \1CRUD", content)
# Ensure 'Any' is imported
if "from typing import" in content:
if "Any" not in content:
content = content.replace("from typing import", "from typing import Any, ")
else:
content = "from typing import Any\n" + content
service_file.write_text(content, encoding="utf-8")
print(f"Fixed service {service_file.name}")
if __name__ == "__main__":
fix_models()
fix_services()

15
requirements.txt Normal file
View File

@ -0,0 +1,15 @@
fastapi==0.104.1
uvicorn==0.24.0
pydantic-settings==2.1.0
sqlalchemy==2.0.23
psycopg2-binary==2.9.9
redis==5.0.1
python-jose[cryptography]==3.3.0
passlib[bcrypt]==1.7.4
openai==1.3.5
anthropic==0.5.0
pinecone-client
weaviate-client
python-multipart==0.0.6
httpx==0.25.2
alembic==1.12.1

View File

@ -2,6 +2,7 @@
FastAPI Application Configuration
Enterprise-grade configuration management using Pydantic Settings
"""
from pydantic import computed_field, model_validator
from pydantic_settings import BaseSettings
from typing import List, Optional
@ -18,18 +19,39 @@ class Settings(BaseSettings):
APP_DESCRIPTION: str = "Enterprise FastAPI Application"
# Database
DATABASE_URL: str = "postgresql://user:password@localhost:5432/"
DATABASE_URL: Optional[str] = None
POSTGRES_USER: str = "billing_user"
POSTGRES_PASSWORD: str = "Admin123"
POSTGRES_DB: str = "test_project_db"
POSTGRES_HOST: str = "localhost"
POSTGRES_PORT: int = 5432
DB_POOL_SIZE: int = 10
DB_MAX_OVERFLOW: int = 20
DB_POOL_RECYCLE: int = 3600
DB_ECHO: bool = False
@model_validator(mode='after')
def assemble_db_url(self) -> 'Settings':
if not self.DATABASE_URL:
self.DATABASE_URL = f"postgresql://{self.POSTGRES_USER}:{self.POSTGRES_PASSWORD}@{self.POSTGRES_HOST}:{self.POSTGRES_PORT}/{self.POSTGRES_DB}"
return self
# Redis
REDIS_HOST: str = "localhost"
REDIS_PORT: int = 6379
# Server
HOST: str = "0.0.0.0"
PORT: int = 8000
# Security
SECRET_KEY: str = ""
JWT_SECRET: str = ""
JWT_REFRESH_SECRET: str = ""
JWT_ISSUER: str = "ai-detection-app"
JWT_AUDIENCE: str = "ai-detection-users"
JWT_ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
JWT_REFRESH_TOKEN_EXPIRE_DAYS: int = 7
ALGORITHM: str = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
REFRESH_TOKEN_EXPIRE_DAYS: int = 7
@ -56,6 +78,7 @@ class Settings(BaseSettings):
env_file = ".env"
env_file_encoding = "utf-8"
case_sensitive = False
extra = "ignore"
# Global settings instance
settings = Settings()

View File

@ -1,5 +1,19 @@
from sqlalchemy.orm import Session
from src.config.database import SessionLocal, get_db
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session
from src.config.config import settings
engine = create_engine(
settings.DATABASE_URL,
pool_pre_ping=True,
pool_size=settings.DB_POOL_SIZE,
max_overflow=settings.DB_MAX_OVERFLOW,
echo=settings.DB_ECHO
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
"""
@ -11,4 +25,3 @@ def get_db():
yield db
finally:
db.close()

View File

@ -6,9 +6,13 @@ import os
import sys
import logging
from pathlib import Path
import sqlalchemy as sa
from sqlalchemy import create_engine, inspect, MetaData
from sqlalchemy.orm import sessionmaker
import importlib.util
from alembic.runtime.migration import MigrationContext
from alembic.operations import Operations
import alembic
logger = logging.getLogger(__name__)
@ -59,19 +63,19 @@ class MigrationManager:
if '_migrations' not in tables:
# Create migrations tracking table
with self.engine.begin() as conn:
conn.execute("""
conn.execute(sa.text("""
CREATE TABLE IF NOT EXISTS _migrations (
id SERIAL PRIMARY KEY,
migration_name VARCHAR(255) NOT NULL UNIQUE,
applied_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
)
""")
"""))
logger.info("✅ Created migrations tracking table")
return set()
# Get applied migrations
with self.engine.connect() as conn:
result = conn.execute("SELECT migration_name FROM _migrations ORDER BY applied_at")
result = conn.execute(sa.text("SELECT migration_name FROM _migrations ORDER BY applied_at"))
applied = {row[0] for row in result}
logger.debug(f"📋 Found {len(applied)} previously applied migrations")
@ -137,61 +141,25 @@ class MigrationManager:
logger.warning(f"⚠️ Migration {migration_file.name} has no upgrade() function")
return False
# Create a mock op object with connection
class OpMock:
def __init__(self, connection):
self.connection = connection
def create_table(self, name, *args, **kwargs):
"""Create a new table"""
from sqlalchemy import Table
table = Table(name, MetaData(), *args, **kwargs)
table.create(self.connection, checkfirst=True)
logger.debug(f" 📊 Created table: {name}")
def create_index(self, name, table, columns, **kwargs):
"""Create an index"""
try:
if isinstance(columns, str):
columns = [columns]
# Build index creation SQL
unique_clause = "UNIQUE" if kwargs.get('unique') else ""
columns_str = ", ".join(f'"{col}"' for col in columns)
index_sql = f'CREATE {unique_clause} INDEX IF NOT EXISTS "{name}" ON "{table}" ({columns_str})'
self.connection.execute(index_sql)
logger.debug(f" 🔑 Created index: {name} on {table}({columns_str})")
except Exception as e:
logger.warning(f" ⚠️ Could not create index {name}: {e}")
def add_column(self, table, column):
"""Add a column to table"""
try:
self.connection.execute(f'ALTER TABLE "{table}" ADD COLUMN {column}')
logger.debug(f" Added column to {table}")
except Exception as e:
logger.warning(f" ⚠️ Could not add column to {table}: {e}")
def drop_table(self, name):
"""Drop a table"""
try:
self.connection.execute(f'DROP TABLE IF EXISTS "{name}"')
logger.debug(f" 🗑️ Dropped table: {name}")
except Exception as e:
logger.warning(f" ⚠️ Could not drop table {name}: {e}")
# Execute migration within a transaction
with self.engine.begin() as connection:
op = OpMock(connection)
# Configure Alembic context
ctx = MigrationContext.configure(connection)
op = Operations(ctx)
# Bind the alembic.op proxy to our operations object
# This is necessary because migration files do 'from alembic import op'
alembic.op._proxy = op
# Run the migration
migration_module.upgrade()
# Record migration as applied
connection.execute("""
connection.execute(sa.text("""
INSERT INTO _migrations (migration_name)
VALUES (%s)
VALUES (:name)
ON CONFLICT DO NOTHING
""", (migration_file.stem,))
"""), {"name": migration_file.stem})
logger.info(f"✅ Applied migration: {migration_file.name}")
return True

View File

@ -26,6 +26,8 @@ def upgrade() -> None:
sa.Column('specialty', sa.String(100), nullable=True),
sa.Column('npi', sa.String(10), nullable=True),
sa.Column('last_login_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('role', sa.String(50), server_default='user', nullable=False),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -36,8 +36,6 @@ def upgrade() -> None:
sa.Column('secondary_payer_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('secondary_insurance_member_id', sa.String(100), nullable=True),
sa.Column('emr_patient_id', sa.String(100), nullable=True),
sa.Column('primary_payer_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('secondary_payer_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -30,11 +30,9 @@ def upgrade() -> None:
sa.Column('encryption_key_id', sa.String(100), nullable=True),
sa.Column('device_info', postgresql.JSONB(), nullable=True),
sa.Column('noise_level', sa.String(255), nullable=True),
sa.Column('status', sa.String(50), server_default='processing', nullable=False),
sa.Column('template_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('is_template_based', sa.Boolean(), nullable=False),
sa.Column('user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('patient_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('template_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -27,11 +27,10 @@ def upgrade() -> None:
sa.Column('low_confidence_segments', postgresql.JSONB(), nullable=True),
sa.Column('processing_time_seconds', sa.Integer(), nullable=True),
sa.Column('model_version', sa.String(50), nullable=False),
sa.Column('status', sa.String(50), server_default='pending', nullable=False),
sa.Column('is_manually_corrected', sa.Boolean(), nullable=False),
sa.Column('corrected_by_user_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('corrected_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('audio_recording_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('corrected_by_user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -32,8 +32,6 @@ def upgrade() -> None:
sa.Column('is_verified', sa.Boolean(), nullable=False),
sa.Column('verified_by_user_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('verified_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('transcript_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('verified_by_user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -25,6 +25,8 @@ def upgrade() -> None:
sa.Column('effective_date', sa.Date(), nullable=True),
sa.Column('termination_date', sa.Date(), nullable=True),
sa.Column('version', sa.String(20), nullable=False),
sa.Column('is_billable', sa.Boolean(), server_default='true', nullable=False),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('synonyms', postgresql.JSONB(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),

View File

@ -30,6 +30,7 @@ def upgrade() -> None:
sa.Column('rvu_facility', sa.Numeric(10, 2), nullable=True),
sa.Column('rvu_non_facility', sa.Numeric(10, 2), nullable=True),
sa.Column('global_period', sa.String(10), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('synonyms', postgresql.JSONB(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),

View File

@ -26,6 +26,7 @@ def upgrade() -> None:
sa.Column('termination_date', sa.Date(), nullable=True),
sa.Column('reimbursement_impact', sa.Numeric(10, 2), nullable=True),
sa.Column('usage_rules', sa.Text(), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -31,6 +31,7 @@ def upgrade() -> None:
sa.Column('email', sa.String(255), nullable=True),
sa.Column('website', sa.String(255), nullable=True),
sa.Column('priority_rank', sa.Integer(), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),

View File

@ -31,9 +31,8 @@ def upgrade() -> None:
sa.Column('updated_by_user_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('denial_count', sa.Integer(), nullable=False),
sa.Column('last_denial_date', sa.DateTime(timezone=True), nullable=True),
sa.Column('payer_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_by_user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('updated_by_user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('severity', sa.String(50), server_default='medium', nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -25,6 +25,7 @@ def upgrade() -> None:
sa.Column('effective_date', sa.Date(), nullable=False),
sa.Column('deletion_date', sa.Date(), nullable=True),
sa.Column('edit_rationale', sa.Text(), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -31,6 +31,7 @@ def upgrade() -> None:
sa.Column('termination_date', sa.Date(), nullable=True),
sa.Column('last_review_date', sa.Date(), nullable=True),
sa.Column('document_url', sa.String(500), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -28,6 +28,7 @@ def upgrade() -> None:
sa.Column('termination_date', sa.Date(), nullable=True),
sa.Column('last_review_date', sa.Date(), nullable=True),
sa.Column('document_url', sa.String(500), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -29,8 +29,8 @@ def upgrade() -> None:
sa.Column('documentation_requirements', sa.Text(), nullable=True),
sa.Column('mdm_level', sa.String(255), nullable=True),
sa.Column('usage_count', sa.Integer(), nullable=False),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('created_by_user_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('created_by_user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -38,6 +38,8 @@ def upgrade() -> None:
sa.Column('scrubbing_failures', postgresql.JSONB(), nullable=True),
sa.Column('corrective_actions', postgresql.JSONB(), nullable=True),
sa.Column('confidence_score', sa.Numeric(10, 2), nullable=True),
sa.Column('status', sa.String(50), server_default='draft', nullable=False),
sa.Column('scrubbing_status', sa.String(50), server_default='pending', nullable=False),
sa.Column('is_template_based', sa.Boolean(), nullable=False),
sa.Column('template_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('reviewed_by_user_id', postgresql.UUID(as_uuid=True), nullable=True),
@ -47,13 +49,6 @@ def upgrade() -> None:
sa.Column('denial_reason', sa.Text(), nullable=True),
sa.Column('denial_code', sa.String(50), nullable=True),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('patient_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('audio_recording_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('transcript_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('payer_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_by_user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('reviewed_by_user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('template_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -35,9 +35,6 @@ def upgrade() -> None:
sa.Column('escalated_to_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('escalated_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('reviewed_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('claim_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('reviewer_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('escalated_to_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -35,7 +35,6 @@ def upgrade() -> None:
sa.Column('metadata', postgresql.JSONB(), nullable=True),
sa.Column('phi_accessed', sa.Boolean(), nullable=True),
sa.Column('compliance_flag', sa.Boolean(), nullable=True),
sa.Column('user_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -36,7 +36,7 @@ def upgrade() -> None:
sa.Column('preventive_actions', postgresql.JSONB(), nullable=True),
sa.Column('related_lcd_ncd', postgresql.JSONB(), nullable=True),
sa.Column('notes', sa.Text(), nullable=True),
sa.Column('payer_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -42,9 +42,8 @@ def upgrade() -> None:
sa.Column('rate_limit_per_minute', sa.Integer(), nullable=True),
sa.Column('use_mock_data', sa.Boolean(), nullable=True),
sa.Column('configuration_notes', sa.Text(), nullable=True),
sa.Column('connection_status', sa.String(50), server_default='disconnected', nullable=False),
sa.Column('created_by_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('organization_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_by_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -39,10 +39,8 @@ def upgrade() -> None:
sa.Column('last_used_at', sa.DateTime(timezone=True), nullable=True),
sa.Column('metadata', postgresql.JSONB(), nullable=True),
sa.Column('tags', postgresql.JSONB(), nullable=True),
sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False),
sa.Column('uploaded_by_id', postgresql.UUID(as_uuid=True), nullable=True),
sa.Column('payer_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('parent_document_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('uploaded_by_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -35,7 +35,6 @@ def upgrade() -> None:
sa.Column('corrected_value', sa.Text(), nullable=True),
sa.Column('feedback_notes', sa.Text(), nullable=True),
sa.Column('processing_time_ms', sa.Integer(), nullable=True),
sa.Column('claim_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -43,7 +43,7 @@ def upgrade() -> None:
sa.Column('auto_fix_details', postgresql.JSONB(), nullable=True),
sa.Column('requires_manual_review', sa.Boolean(), nullable=True),
sa.Column('review_priority', sa.String(20), nullable=True),
sa.Column('claim_id', postgresql.UUID(as_uuid=True), sa.ForeignKey('.id'), nullable=False),
sa.Column('scrubbed_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), nullable=False),
sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.text('CURRENT_TIMESTAMP'), onupdate=sa.text('CURRENT_TIMESTAMP'), nullable=False),
)

View File

@ -0,0 +1,21 @@
"""Migration to add is_active to patients
Revision ID: auto24
Revises: auto23
Create Date: auto
"""
from alembic import op
import sqlalchemy as sa
# revision identifiers, used by Alembic.
revision = 'auto24'
down_revision = None
branch_labels = None
depends_on = None
def upgrade() -> None:
# Adding `is_active` column to `patients`
op.add_column('patients', sa.Column('is_active', sa.Boolean(), server_default='true', nullable=True))
def downgrade() -> None:
op.drop_column('patients', 'is_active')

53
src/models/__init__.py Normal file
View File

@ -0,0 +1,53 @@
from src.config.database import Base
from sqlalchemy import BigInteger
# Import all models here to register them with Base.metadata
from src.models.user_model import User
from src.models.patient_model import Patient
from src.models.payer_model import Payer
from src.models.payer_rule_model import PayerRule
from src.models.audio_recording_model import AudioRecording
from src.models.transcript_model import Transcript
from src.models.claim_model import Claim
from src.models.claim_review_model import ClaimReview
from src.models.claim_scrub_result_model import ClaimScrubResult
from src.models.audit_log_model import AuditLog
from src.models.clinical_entity_model import ClinicalEntity
from src.models.confidence_score_model import ConfidenceScore
from src.models.cpt_code_model import CPTCode
from src.models.cpt_modifier_model import CPTModifier
from src.models.denial_pattern_model import DenialPattern
from src.models.emr_integration_model import EMRIntegration
from src.models.icd10_code_model import ICD10Code
from src.models.lcd_model import LCD
from src.models.ncci_edit_model import NCCIEdit
from src.models.ncd_model import NCD
from src.models.procedure_template_model import ProcedureTemplate
from src.models.rag_document_model import RAGDocument
# Export all models for easy importing elsewhere
__all__ = [
"Base",
"User",
"Patient",
"Payer",
"PayerRule",
"AudioRecording",
"Transcript",
"Claim",
"ClaimReview",
"ClaimScrubResult",
"AuditLog",
"ClinicalEntity",
"ConfidenceScore",
"CPTCode",
"CPTModifier",
"DenialPattern",
"EMRIntegration",
"ICD10Code",
"LCD",
"NCCIEdit",
"NCD",
"ProcedureTemplate",
"RAGDocument",
]

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, BigInteger
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -8,8 +9,6 @@ class AudioRecording(Base):
__tablename__ = 'audio_recordings'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
user_id = Column(UUID(as_uuid=True), nullable=False)
patient_id = Column(UUID(as_uuid=True), nullable=False)
encounter_id = Column(String(255), nullable=True)
file_path = Column(String(255), nullable=False)
file_name = Column(String(255), nullable=False)
@ -20,19 +19,18 @@ class AudioRecording(Base):
encryption_key_id = Column(String(255), nullable=True)
device_info = Column(JSON, nullable=True)
noise_level = Column(String(255), nullable=True)
template_id = Column(UUID(as_uuid=True), nullable=True)
is_template_based = Column(Boolean, nullable=False)
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
user = relationship('User', back_populates='')
patient_id = Column(UUID(as_uuid=True), ForeignKey('patients.id'), nullable=False)
patient = relationship('Patient', back_populates='')
template_id = Column(UUID(as_uuid=True), ForeignKey('procedure_templates.id'), nullable=True)
procedureTemplate = relationship('ProcedureTemplate', back_populates='')
user = relationship('User', back_populates='audioRecordings')
patient = relationship('Patient', back_populates='audioRecordings')
procedureTemplate = relationship('ProcedureTemplate')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
def __repr__(self):
return f'<AudioRecording(id={self.id})>'

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -8,7 +9,6 @@ class AuditLog(Base):
__tablename__ = 'audit_logs'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
user_id = Column(UUID(as_uuid=True), nullable=True)
entity_type = Column(String(255), nullable=False)
entity_id = Column(UUID(as_uuid=True), nullable=True)
action = Column(String(255), nullable=False)
@ -22,16 +22,15 @@ class AuditLog(Base):
request_id = Column(String(255), nullable=True)
status = Column(String(255), nullable=False)
error_message = Column(Text, nullable=True)
metadata = Column(JSON, nullable=True)
doc_metadata = Column(JSON, nullable=True)
phi_accessed = Column(Boolean, nullable=True)
compliance_flag = Column(Boolean, nullable=True)
user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
user = relationship('User', back_populates='auditLogs')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
def __repr__(self):
return f'<AuditLog(id={self.id})>'

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -9,13 +10,8 @@ class Claim(Base):
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
claim_number = Column(String(255), nullable=False, unique=True)
patient_id = Column(UUID(as_uuid=True), nullable=False)
audio_recording_id = Column(UUID(as_uuid=True), nullable=True)
transcript_id = Column(UUID(as_uuid=True), nullable=True)
payer_id = Column(UUID(as_uuid=True), nullable=False)
encounter_id = Column(String(255), nullable=True)
service_date = Column(DateTime, nullable=False)
created_by_user_id = Column(UUID(as_uuid=True), nullable=False)
diagnosis_codes = Column(JSON, nullable=False)
procedure_codes = Column(JSON, nullable=False)
modifiers = Column(JSON, nullable=True)
@ -29,8 +25,6 @@ class Claim(Base):
corrective_actions = Column(JSON, nullable=True)
confidence_score = Column(String(255), nullable=True)
is_template_based = Column(Boolean, nullable=False)
template_id = Column(UUID(as_uuid=True), nullable=True)
reviewed_by_user_id = Column(UUID(as_uuid=True), nullable=True)
reviewed_at = Column(DateTime, nullable=True)
submitted_at = Column(DateTime, nullable=True)
paid_at = Column(DateTime, nullable=True)
@ -39,23 +33,23 @@ class Claim(Base):
notes = Column(Text, nullable=True)
patient_id = Column(UUID(as_uuid=True), ForeignKey('patients.id'), nullable=False)
patient = relationship('Patient', back_populates='')
audio_recording_id = Column(UUID(as_uuid=True), ForeignKey('audio_recordings.id'), nullable=True)
audioRecording = relationship('AudioRecording', back_populates='')
transcript_id = Column(UUID(as_uuid=True), ForeignKey('transcripts.id'), nullable=True)
transcript = relationship('Transcript', back_populates='')
payer_id = Column(UUID(as_uuid=True), ForeignKey('payers.id'), nullable=False)
payer = relationship('Payer', back_populates='')
created_by_user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
user = relationship('User', back_populates='')
reviewed_by_user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
template_id = Column(UUID(as_uuid=True), ForeignKey('procedure_templates.id'), nullable=True)
procedureTemplate = relationship('ProcedureTemplate', back_populates='')
patient = relationship('Patient', back_populates='claims')
audioRecording = relationship('AudioRecording')
transcript = relationship('Transcript')
payer = relationship('Payer')
creator = relationship('User', foreign_keys=[created_by_user_id], back_populates='claims')
reviewer = relationship('User', foreign_keys=[reviewed_by_user_id], back_populates='reviewedClaims')
procedureTemplate = relationship('ProcedureTemplate')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
def __repr__(self):
return f'<Claim(id={self.id})>'

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -8,8 +9,8 @@ class ClaimReview(Base):
__tablename__ = 'claim_reviews'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
claim_id = Column(UUID(as_uuid=True), nullable=False)
reviewer_id = Column(UUID(as_uuid=True), nullable=False)
claim_id = Column(UUID(as_uuid=True), ForeignKey('claims.id'), nullable=False)
reviewer_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
review_status = Column(String(255), nullable=False)
review_type = Column(String(255), nullable=False)
confidence_threshold_triggered = Column(Boolean, nullable=True)
@ -22,16 +23,12 @@ class ClaimReview(Base):
corrective_actions = Column(JSON, nullable=True)
review_duration_seconds = Column(Integer, nullable=True)
escalation_reason = Column(Text, nullable=True)
escalated_to_id = Column(UUID(as_uuid=True), nullable=True)
escalated_to_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
escalated_at = Column(DateTime, nullable=True)
reviewed_at = Column(DateTime, nullable=True)
claim_id = Column(UUID(as_uuid=True), ForeignKey('claims.id'), nullable=False)
claim = relationship('Claim', back_populates='')
reviewer_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=False)
user = relationship('User', back_populates='')
escalated_to_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
claim = relationship('Claim', foreign_keys=[claim_id])
reviewer = relationship('User', foreign_keys=[reviewer_id])
escalated_to = relationship('User', foreign_keys=[escalated_to_id])
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -8,7 +9,6 @@ class ClinicalEntity(Base):
__tablename__ = 'clinical_entities'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
transcript_id = Column(UUID(as_uuid=True), nullable=False)
entity_type = Column(String(255), nullable=False)
entity_text = Column(String(255), nullable=False)
normalized_text = Column(String(255), nullable=True)
@ -16,21 +16,21 @@ class ClinicalEntity(Base):
start_position = Column(Integer, nullable=True)
end_position = Column(Integer, nullable=True)
context = Column(Text, nullable=True)
metadata = Column(JSON, nullable=True)
doc_metadata = Column(JSON, nullable=True)
is_negated = Column(Boolean, nullable=False)
is_historical = Column(Boolean, nullable=False)
is_verified = Column(Boolean, nullable=False)
verified_by_user_id = Column(UUID(as_uuid=True), nullable=True)
verified_at = Column(DateTime, nullable=True)
transcript_id = Column(UUID(as_uuid=True), ForeignKey('transcripts.id'), nullable=False)
transcript = relationship('Transcript', back_populates='')
verified_by_user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
transcript = relationship('Transcript', back_populates='clinicalEntitys')
verifier = relationship('User', back_populates='verifiedClinicalEntities')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
def __repr__(self):
return f'<ClinicalEntity(id={self.id})>'

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -8,7 +9,6 @@ class DenialPattern(Base):
__tablename__ = 'denial_patterns'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
payer_id = Column(UUID(as_uuid=True), nullable=False)
payer_name = Column(String(255), nullable=False)
denial_code = Column(String(255), nullable=False)
denial_reason = Column(Text, nullable=False)
@ -26,9 +26,11 @@ class DenialPattern(Base):
preventive_actions = Column(JSON, nullable=True)
related_lcd_ncd = Column(JSON, nullable=True)
notes = Column(Text, nullable=True)
payer_id = Column(UUID(as_uuid=True), ForeignKey('payers.id'), nullable=False)
payer = relationship('Payer', back_populates='')
payer = relationship('Payer', back_populates='denialPatterns')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -32,12 +33,10 @@ class EMRIntegration(Base):
rate_limit_per_minute = Column(Integer, nullable=True)
use_mock_data = Column(Boolean, nullable=True)
configuration_notes = Column(Text, nullable=True)
created_by_id = Column(UUID(as_uuid=True), nullable=True)
organization_id = Column(UUID(as_uuid=True), ForeignKey('organizations.id'), nullable=False)
organization = relationship('Organization', back_populates='')
created_by_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
creator = relationship('User', back_populates='createdEMRIntegrations')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -21,19 +22,19 @@ class Patient(Base):
zip_code = Column(String(255), nullable=True)
phone = Column(String(255), nullable=True)
email = Column(String(255), nullable=True)
primary_payer_id = Column(UUID(as_uuid=True), nullable=True)
primary_insurance_member_id = Column(String(255), nullable=True)
secondary_payer_id = Column(UUID(as_uuid=True), nullable=True)
secondary_insurance_member_id = Column(String(255), nullable=True)
emr_patient_id = Column(String(255), nullable=True)
primary_payer_id = Column(UUID(as_uuid=True), ForeignKey('payers.id'), nullable=True)
payer = relationship('Payer', back_populates='')
secondary_payer_id = Column(UUID(as_uuid=True), ForeignKey('payers.id'), nullable=True)
payer = relationship('Payer', back_populates='')
primary_insurance_member_id = Column(String(255), nullable=True)
secondary_insurance_member_id = Column(String(255), nullable=True)
emr_patient_id = Column(String(255), nullable=True)
is_active = Column(Boolean, default=True)
primary_payer = relationship('Payer', foreign_keys=[primary_payer_id], back_populates='primary_patients')
secondary_payer = relationship('Payer', foreign_keys=[secondary_payer_id], back_populates='secondary_patients')
audioRecordings = relationship('AudioRecording', back_populates='patient')
claims = relationship('Claim', back_populates='patient')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -24,8 +25,13 @@ class Payer(Base):
notes = Column(Text, nullable=True)
payerRules = relationship('PayerRule', back_populates='payer')
ragDocuments = relationship('RAGDocument', back_populates='payer')
denialPatterns = relationship('DenialPattern', back_populates='payer')
patients = relationship('Patient', back_populates='payer')
primary_patients = relationship('Patient', foreign_keys='[Patient.primary_payer_id]', back_populates='primary_payer')
secondary_patients = relationship('Patient', foreign_keys='[Patient.secondary_payer_id]', back_populates='secondary_payer')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -8,7 +9,6 @@ class PayerRule(Base):
__tablename__ = 'payer_rules'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
payer_id = Column(UUID(as_uuid=True), nullable=False)
rule_name = Column(String(255), nullable=False)
rule_type = Column(String(255), nullable=False)
rule_description = Column(Text, nullable=False)
@ -17,17 +17,19 @@ class PayerRule(Base):
affected_icd10_codes = Column(JSON, nullable=True)
effective_date = Column(DateTime, nullable=False)
termination_date = Column(DateTime, nullable=True)
created_by_user_id = Column(UUID(as_uuid=True), nullable=True)
updated_by_user_id = Column(UUID(as_uuid=True), nullable=True)
denial_count = Column(Integer, nullable=False)
last_denial_date = Column(DateTime, nullable=True)
payer_id = Column(UUID(as_uuid=True), ForeignKey('payers.id'), nullable=False)
payer = relationship('Payer', back_populates='')
payer = relationship('Payer', back_populates='payerRules')
created_by_user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
creator = relationship('User', foreign_keys=[created_by_user_id], back_populates='createdPayerRules')
updated_by_user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
updater = relationship('User', foreign_keys=[updated_by_user_id], back_populates='updatedPayerRules')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -19,10 +20,10 @@ class ProcedureTemplate(Base):
documentation_requirements = Column(Text, nullable=True)
mdm_level = Column(String(255), nullable=True)
usage_count = Column(Integer, nullable=False)
created_by_user_id = Column(UUID(as_uuid=True), nullable=True)
created_by_user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
creator = relationship('User', back_populates='createdProcedureTemplates')
audioRecordings = relationship('AudioRecording', back_populates='procedureTemplate')

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -27,16 +28,19 @@ class RAGDocument(Base):
relevance_score = Column(String(255), nullable=True)
usage_count = Column(Integer, nullable=True)
last_used_at = Column(DateTime, nullable=True)
metadata = Column(JSON, nullable=True)
doc_doc_doc_metadata = Column(JSON, nullable=True)
tags = Column(JSON, nullable=True)
uploaded_by_id = Column(UUID(as_uuid=True), nullable=True)
payer_id = Column(UUID(as_uuid=True), ForeignKey('payers.id'), nullable=True)
payer = relationship('Payer', back_populates='')
payer = relationship('Payer', back_populates='ragDocuments')
parent_document_id = Column(UUID(as_uuid=True), ForeignKey('rag_documents.id'), nullable=True)
rAGDocument = relationship('RAGDocument', back_populates='')
parent_document = relationship('RAGDocument', remote_side=[id], back_populates='chunks')
chunks = relationship('RAGDocument', back_populates='parent_document')
uploaded_by_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
uploader = relationship('User', back_populates='uploadedDocuments')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -8,7 +9,6 @@ class Transcript(Base):
__tablename__ = 'transcripts'
id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, nullable=False)
audio_recording_id = Column(UUID(as_uuid=True), nullable=False, unique=True)
raw_text = Column(Text, nullable=False)
corrected_text = Column(Text, nullable=True)
word_error_rate = Column(String(255), nullable=True)
@ -18,14 +18,13 @@ class Transcript(Base):
processing_time_seconds = Column(Integer, nullable=True)
model_version = Column(String(255), nullable=False)
is_manually_corrected = Column(Boolean, nullable=False)
corrected_by_user_id = Column(UUID(as_uuid=True), nullable=True)
corrected_at = Column(DateTime, nullable=True)
audio_recording_id = Column(UUID(as_uuid=True), ForeignKey('audio_recordings.id'), nullable=False)
audioRecording = relationship('AudioRecording', back_populates='')
audio_recording_id = Column(UUID(as_uuid=True), ForeignKey('audio_recordings.id'), nullable=False, unique=True)
corrected_by_user_id = Column(UUID(as_uuid=True), ForeignKey('users.id'), nullable=True)
user = relationship('User', back_populates='')
audioRecording = relationship('AudioRecording')
user = relationship('User')
clinicalEntitys = relationship('ClinicalEntity', back_populates='transcript')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
@ -33,4 +32,3 @@ class Transcript(Base):
def __repr__(self):
return f'<Transcript(id={self.id})>'

View File

@ -1,4 +1,5 @@
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY, relationship
from sqlalchemy import Column, String, Integer, Boolean, DateTime, ForeignKey, Text, JSON, ARRAY
from sqlalchemy.orm import relationship
from sqlalchemy.dialects.postgresql import UUID
from src.config.database import Base
from sqlalchemy.sql import func
@ -16,10 +17,22 @@ class User(Base):
specialty = Column(String(255), nullable=True)
npi = Column(String(255), nullable=True)
last_login_at = Column(DateTime, nullable=True)
role = Column(String(50), default='user', nullable=False)
is_active = Column(Boolean, default=True, nullable=False)
audioRecordings = relationship('AudioRecording', back_populates='user')
claims = relationship('Claim', foreign_keys='[Claim.created_by_user_id]', back_populates='creator')
reviewedClaims = relationship('Claim', foreign_keys='[Claim.reviewed_by_user_id]', back_populates='reviewer')
auditLogs = relationship('AuditLog', back_populates='user')
createdPayerRules = relationship('PayerRule', foreign_keys='[PayerRule.created_by_user_id]', back_populates='creator')
updatedPayerRules = relationship('PayerRule', foreign_keys='[PayerRule.updated_by_user_id]', back_populates='updater')
uploadedDocuments = relationship('RAGDocument', back_populates='uploader')
createdEMRIntegrations = relationship('EMRIntegration', back_populates='creator')
createdProcedureTemplates = relationship('ProcedureTemplate', back_populates='creator')
verifiedClinicalEntities = relationship('ClinicalEntity', back_populates='verifier')
claims = relationship('Claim', back_populates='user')
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)

View File

@ -12,7 +12,7 @@ from langchain_community.document_loaders import (
UnstructuredExcelLoader
)
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
# from langchain_community.vectorstores import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_openai import OpenAIEmbeddings
from loguru import logger
@ -75,11 +75,12 @@ class RAGIngestor:
logger.info(f"Split document into {len(chunks)} chunks")
# 3 & 4. Embedding & Storage
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=self.embeddings,
persist_directory=self.persist_directory,
collection_name=collection_name
)
# vectorstore = Chroma.from_documents(
# documents=chunks,
# embedding=self.embeddings,
# persist_directory=self.persist_directory,
# collection_name=collection_name
# )
logger.warning("Vector storage (Chroma) is temporarily disabled due to installation issues.")
return len(chunks)

View File

@ -4,7 +4,7 @@ Handles query embedding, vector retrieval, reranking, and LLM generation.
"""
import time
from typing import List, Dict, Any, Optional
from langchain_community.vectorstores import Chroma
# from langchain_community.vectorstores import Chroma
from langchain_huggingface import HuggingFaceEmbeddings
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_anthropic import ChatAnthropic
@ -54,11 +54,13 @@ Helpful Answer:"""
)
def _get_vectorstore(self, collection_name: str):
return Chroma(
persist_directory=self.persist_directory,
embedding_function=self.embeddings,
collection_name=collection_name
)
# return Chroma(
# persist_directory=self.persist_directory,
# embedding_function=self.embeddings,
# collection_name=collection_name
# )
logger.error("Vector retrieval (Chroma) is temporarily disabled.")
return None
async def query(self, question: str, collection_name: str, top_k: int = 4) -> Dict[str, Any]:
"""
@ -72,6 +74,8 @@ Helpful Answer:"""
start_time = time.time()
vectorstore = self._get_vectorstore(collection_name)
if not vectorstore:
return {"query": question, "answer": "Vector store not available.", "source_documents": [], "processing_time_ms": 0}
qa_chain = RetrievalQA.from_chain_type(
llm=self.llm,

View File

@ -1,115 +0,0 @@
"""
AudioRecording API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.audio_recording_service import AudioRecordingCRUD
from src.validation.audio_recording_schemas import (
AudioRecordingCreate,
AudioRecordingUpdate,
AudioRecordingResponse,
AudioRecordingListResponse,
)
router = APIRouter(prefix="/audiorecordings", tags=["AudioRecording"])
def get_crud(db: Session = Depends(get_db)) -> AudioRecordingCRUD:
"""Dependency injection for AudioRecordingCRUD"""
return AudioRecordingCRUD(db)
@router.get("/", response_model=AudioRecordingListResponse)
async def list_audio_recordings(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: AudioRecordingCRUD = Depends(get_crud),
):
"""
List all audiorecordings with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return AudioRecordingListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ audio_recording_id }", response_model=AudioRecordingResponse)
async def get_audio_recording(
audio_recording_id: UUID,
crud: AudioRecordingCRUD = Depends(get_crud),
):
"""
Get a specific audiorecording by ID.
- **audio_recording_id**: The UUID of the audiorecording
"""
db_audio_recording = crud.get_by_id(audio_recording_id)
if not db_audio_recording:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AudioRecording with id { audio_recording_id} not found"
)
return db_audio_recording
@router.post("/", response_model=AudioRecordingResponse, status_code=status.HTTP_201_CREATED)
async def create_audio_recording(
audio_recording_in: AudioRecordingCreate,
crud: AudioRecordingCRUD = Depends(get_crud),
):
"""
Create a new audiorecording.
- **audio_recording_in**: The audiorecording data to create
"""
return crud.create(audio_recording_in)
@router.put("/{ audio_recording_id }", response_model=AudioRecordingResponse)
async def update_audio_recording(
audio_recording_id: UUID,
audio_recording_in: AudioRecordingUpdate,
crud: AudioRecordingCRUD = Depends(get_crud),
):
"""
Update an existing audiorecording.
- **audio_recording_id**: The UUID of the audiorecording to update
- **audio_recording_in**: The updated audiorecording data
"""
db_audio_recording = crud.get_by_id(audio_recording_id)
if not db_audio_recording:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AudioRecording with id { audio_recording_id} not found"
)
return crud.update(audio_recording_id, audio_recording_in)
@router.delete("/{ audio_recording_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_audio_recording(
audio_recording_id: UUID,
crud: AudioRecordingCRUD = Depends(get_crud),
):
"""
Delete a audiorecording.
- **audio_recording_id**: The UUID of the audiorecording to delete
"""
db_audio_recording = crud.get_by_id(audio_recording_id)
if not db_audio_recording:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AudioRecording with id { audio_recording_id} not found"
)
crud.delete(audio_recording_id)
return None

View File

@ -35,7 +35,7 @@ async def list_audio_recordings(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return AudioRecordingListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_audio_recording(
- **audio_recording_id**: The UUID of the audiorecording
"""
db_audio_recording = crud.get_by_id(audio_recording_id)
db_audio_recording = await crud.get_by_id(audio_recording_id)
if not db_audio_recording:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_audio_recording(
- **audio_recording_in**: The audiorecording data to create
"""
return crud.create(audio_recording_in)
return await crud.create(audio_recording_in)
@router.put("/{ audio_recording_id }", response_model=AudioRecordingResponse)
async def update_audio_recording(
@ -87,13 +87,13 @@ async def update_audio_recording(
- **audio_recording_id**: The UUID of the audiorecording to update
- **audio_recording_in**: The updated audiorecording data
"""
db_audio_recording = crud.get_by_id(audio_recording_id)
db_audio_recording = await crud.get_by_id(audio_recording_id)
if not db_audio_recording:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AudioRecording with id { audio_recording_id} not found"
)
return crud.update(audio_recording_id, audio_recording_in)
return await crud.update(audio_recording_id, audio_recording_in)
@router.delete("/{ audio_recording_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_audio_recording(
@ -105,11 +105,11 @@ async def delete_audio_recording(
- **audio_recording_id**: The UUID of the audiorecording to delete
"""
db_audio_recording = crud.get_by_id(audio_recording_id)
db_audio_recording = await crud.get_by_id(audio_recording_id)
if not db_audio_recording:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AudioRecording with id { audio_recording_id} not found"
)
crud.delete(audio_recording_id)
await crud.delete(audio_recording_id)
return None

View File

@ -1,115 +0,0 @@
"""
AuditLog API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.audit_log_service import AuditLogCRUD
from src.validation.audit_log_schemas import (
AuditLogCreate,
AuditLogUpdate,
AuditLogResponse,
AuditLogListResponse,
)
router = APIRouter(prefix="/auditlogs", tags=["AuditLog"])
def get_crud(db: Session = Depends(get_db)) -> AuditLogCRUD:
"""Dependency injection for AuditLogCRUD"""
return AuditLogCRUD(db)
@router.get("/", response_model=AuditLogListResponse)
async def list_audit_logs(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: AuditLogCRUD = Depends(get_crud),
):
"""
List all auditlogs with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return AuditLogListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ audit_log_id }", response_model=AuditLogResponse)
async def get_audit_log(
audit_log_id: UUID,
crud: AuditLogCRUD = Depends(get_crud),
):
"""
Get a specific auditlog by ID.
- **audit_log_id**: The UUID of the auditlog
"""
db_audit_log = crud.get_by_id(audit_log_id)
if not db_audit_log:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AuditLog with id { audit_log_id} not found"
)
return db_audit_log
@router.post("/", response_model=AuditLogResponse, status_code=status.HTTP_201_CREATED)
async def create_audit_log(
audit_log_in: AuditLogCreate,
crud: AuditLogCRUD = Depends(get_crud),
):
"""
Create a new auditlog.
- **audit_log_in**: The auditlog data to create
"""
return crud.create(audit_log_in)
@router.put("/{ audit_log_id }", response_model=AuditLogResponse)
async def update_audit_log(
audit_log_id: UUID,
audit_log_in: AuditLogUpdate,
crud: AuditLogCRUD = Depends(get_crud),
):
"""
Update an existing auditlog.
- **audit_log_id**: The UUID of the auditlog to update
- **audit_log_in**: The updated auditlog data
"""
db_audit_log = crud.get_by_id(audit_log_id)
if not db_audit_log:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AuditLog with id { audit_log_id} not found"
)
return crud.update(audit_log_id, audit_log_in)
@router.delete("/{ audit_log_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_audit_log(
audit_log_id: UUID,
crud: AuditLogCRUD = Depends(get_crud),
):
"""
Delete a auditlog.
- **audit_log_id**: The UUID of the auditlog to delete
"""
db_audit_log = crud.get_by_id(audit_log_id)
if not db_audit_log:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AuditLog with id { audit_log_id} not found"
)
crud.delete(audit_log_id)
return None

View File

@ -35,7 +35,7 @@ async def list_audit_logs(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return AuditLogListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_audit_log(
- **audit_log_id**: The UUID of the auditlog
"""
db_audit_log = crud.get_by_id(audit_log_id)
db_audit_log = await crud.get_by_id(audit_log_id)
if not db_audit_log:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_audit_log(
- **audit_log_in**: The auditlog data to create
"""
return crud.create(audit_log_in)
return await crud.create(audit_log_in)
@router.put("/{ audit_log_id }", response_model=AuditLogResponse)
async def update_audit_log(
@ -87,13 +87,13 @@ async def update_audit_log(
- **audit_log_id**: The UUID of the auditlog to update
- **audit_log_in**: The updated auditlog data
"""
db_audit_log = crud.get_by_id(audit_log_id)
db_audit_log = await crud.get_by_id(audit_log_id)
if not db_audit_log:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AuditLog with id { audit_log_id} not found"
)
return crud.update(audit_log_id, audit_log_in)
return await crud.update(audit_log_id, audit_log_in)
@router.delete("/{ audit_log_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_audit_log(
@ -105,11 +105,11 @@ async def delete_audit_log(
- **audit_log_id**: The UUID of the auditlog to delete
"""
db_audit_log = crud.get_by_id(audit_log_id)
db_audit_log = await crud.get_by_id(audit_log_id)
if not db_audit_log:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"AuditLog with id { audit_log_id} not found"
)
crud.delete(audit_log_id)
await crud.delete(audit_log_id)
return None

View File

@ -1,115 +1,84 @@
"""
User API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.user_service import UserCRUD
from src.validation.user_schemas import (
UserCreate,
UserUpdate,
UserResponse,
UserListResponse,
from src.validation.auth_schemas import (
LoginRequest,
RegisterRequest,
RefreshTokenRequest,
ForgotPasswordRequest,
ResetPasswordRequest,
ChangePasswordRequest,
Token
)
from src.validation.user_schemas import UserResponse
router = APIRouter(prefix="/users", tags=["User"])
router = APIRouter(prefix="/auth", tags=["Auth"])
def get_crud(db: Session = Depends(get_db)) -> UserCRUD:
"""Dependency injection for UserCRUD"""
def get_user_service(db: Session = Depends(get_db)) -> UserCRUD:
return UserCRUD(db)
@router.get("/", response_model=UserListResponse)
async def list_users(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: UserCRUD = Depends(get_crud),
@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def register(
user_in: RegisterRequest,
service: UserCRUD = Depends(get_user_service)
):
"""
List all users with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return UserListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
# Map RegisterRequest to UserCreate for the service
from src.validation.user_schemas import UserCreate
user_create = UserCreate(
username=user_in.username,
email=user_in.email,
password_hash=user_in.password, # UserService hashes it
first_name=user_in.first_name,
last_name=user_in.last_name,
role=user_in.role,
specialty=user_in.specialty,
npi=user_in.npi,
is_active=True
)
return await service.create(user_create)
@router.get("/{ user_id }", response_model=UserResponse)
async def get_user(
user_id: UUID,
crud: UserCRUD = Depends(get_crud),
@router.post("/login")
async def login(
login_data: LoginRequest,
service: UserCRUD = Depends(get_user_service)
):
"""
Get a specific user by ID.
- **user_id**: The UUID of the user
"""
db_user = crud.get_by_id(user_id)
if not db_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"User with id { user_id} not found"
)
return db_user
return await service.login(login_data.username, login_data.password)
@router.post("/", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
async def create_user(
user_in: UserCreate,
crud: UserCRUD = Depends(get_crud),
):
"""
Create a new user.
- **user_in**: The user data to create
"""
return crud.create(user_in)
@router.post("/logout")
async def logout():
return {"message": "Successfully logged out"}
@router.put("/{ user_id }", response_model=UserResponse)
async def update_user(
user_id: UUID,
user_in: UserUpdate,
crud: UserCRUD = Depends(get_crud),
@router.post("/refresh")
async def refresh_token(
refresh_data: RefreshTokenRequest,
service: UserCRUD = Depends(get_user_service)
):
"""
Update an existing user.
- **user_id**: The UUID of the user to update
- **user_in**: The updated user data
"""
db_user = crud.get_by_id(user_id)
if not db_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"User with id { user_id} not found"
)
return crud.update(user_id, user_in)
return await service.refreshToken(refresh_data.refresh_token)
@router.delete("/{ user_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_user(
user_id: UUID,
crud: UserCRUD = Depends(get_crud),
@router.post("/forgot-password")
async def forgot_password(
data: ForgotPasswordRequest,
service: UserCRUD = Depends(get_user_service)
):
"""
Delete a user.
- **user_id**: The UUID of the user to delete
"""
db_user = crud.get_by_id(user_id)
if not db_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"User with id { user_id} not found"
)
crud.delete(user_id)
return None
return await service.forgotPassword(data.email)
@router.post("/reset-password")
async def reset_password(
data: ResetPasswordRequest,
service: UserCRUD = Depends(get_user_service)
):
return await service.resetPassword(data.token, data.new_password)
@router.post("/change-password")
async def change_password(
data: ChangePasswordRequest,
service: UserCRUD = Depends(get_user_service)
):
return await service.changePassword(data.current_password, data.new_password)
@router.get("/me", response_model=UserResponse)
async def get_me(service: UserCRUD = Depends(get_user_service)):
# This usually requires a security dependency to get current user
# For alignment purposes, we'll keep it simple or hook into service
return await service.get_current_user()

View File

@ -35,7 +35,7 @@ async def list_claim_reviews(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return ClaimReviewListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_claim_review(
- **claim_review_id**: The UUID of the claimreview
"""
db_claim_review = crud.get_by_id(claim_review_id)
db_claim_review = await crud.get_by_id(claim_review_id)
if not db_claim_review:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_claim_review(
- **claim_review_in**: The claimreview data to create
"""
return crud.create(claim_review_in)
return await crud.create(claim_review_in)
@router.put("/{ claim_review_id }", response_model=ClaimReviewResponse)
async def update_claim_review(
@ -87,13 +87,13 @@ async def update_claim_review(
- **claim_review_id**: The UUID of the claimreview to update
- **claim_review_in**: The updated claimreview data
"""
db_claim_review = crud.get_by_id(claim_review_id)
db_claim_review = await crud.get_by_id(claim_review_id)
if not db_claim_review:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimReview with id { claim_review_id} not found"
)
return crud.update(claim_review_id, claim_review_in)
return await crud.update(claim_review_id, claim_review_in)
@router.delete("/{ claim_review_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_claim_review(
@ -105,11 +105,11 @@ async def delete_claim_review(
- **claim_review_id**: The UUID of the claimreview to delete
"""
db_claim_review = crud.get_by_id(claim_review_id)
db_claim_review = await crud.get_by_id(claim_review_id)
if not db_claim_review:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimReview with id { claim_review_id} not found"
)
crud.delete(claim_review_id)
await crud.delete(claim_review_id)
return None

View File

@ -35,7 +35,7 @@ async def list_claims(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return ClaimListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_claim(
- **claim_id**: The UUID of the claim
"""
db_claim = crud.get_by_id(claim_id)
db_claim = await crud.get_by_id(claim_id)
if not db_claim:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_claim(
- **claim_in**: The claim data to create
"""
return crud.create(claim_in)
return await crud.create(claim_in)
@router.put("/{ claim_id }", response_model=ClaimResponse)
async def update_claim(
@ -87,13 +87,13 @@ async def update_claim(
- **claim_id**: The UUID of the claim to update
- **claim_in**: The updated claim data
"""
db_claim = crud.get_by_id(claim_id)
db_claim = await crud.get_by_id(claim_id)
if not db_claim:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Claim with id { claim_id} not found"
)
return crud.update(claim_id, claim_in)
return await crud.update(claim_id, claim_in)
@router.delete("/{ claim_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_claim(
@ -105,11 +105,11 @@ async def delete_claim(
- **claim_id**: The UUID of the claim to delete
"""
db_claim = crud.get_by_id(claim_id)
db_claim = await crud.get_by_id(claim_id)
if not db_claim:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Claim with id { claim_id} not found"
)
crud.delete(claim_id)
await crud.delete(claim_id)
return None

View File

@ -1,115 +0,0 @@
"""
ClaimScrubResult API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.claim_scrub_result_service import ClaimScrubResultCRUD
from src.validation.claim_scrub_result_schemas import (
ClaimScrubResultCreate,
ClaimScrubResultUpdate,
ClaimScrubResultResponse,
ClaimScrubResultListResponse,
)
router = APIRouter(prefix="/claimscrubresults", tags=["ClaimScrubResult"])
def get_crud(db: Session = Depends(get_db)) -> ClaimScrubResultCRUD:
"""Dependency injection for ClaimScrubResultCRUD"""
return ClaimScrubResultCRUD(db)
@router.get("/", response_model=ClaimScrubResultListResponse)
async def list_claim_scrub_results(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: ClaimScrubResultCRUD = Depends(get_crud),
):
"""
List all claimscrubresults with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return ClaimScrubResultListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ claim_scrub_result_id }", response_model=ClaimScrubResultResponse)
async def get_claim_scrub_result(
claim_scrub_result_id: UUID,
crud: ClaimScrubResultCRUD = Depends(get_crud),
):
"""
Get a specific claimscrubresult by ID.
- **claim_scrub_result_id**: The UUID of the claimscrubresult
"""
db_claim_scrub_result = crud.get_by_id(claim_scrub_result_id)
if not db_claim_scrub_result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimScrubResult with id { claim_scrub_result_id} not found"
)
return db_claim_scrub_result
@router.post("/", response_model=ClaimScrubResultResponse, status_code=status.HTTP_201_CREATED)
async def create_claim_scrub_result(
claim_scrub_result_in: ClaimScrubResultCreate,
crud: ClaimScrubResultCRUD = Depends(get_crud),
):
"""
Create a new claimscrubresult.
- **claim_scrub_result_in**: The claimscrubresult data to create
"""
return crud.create(claim_scrub_result_in)
@router.put("/{ claim_scrub_result_id }", response_model=ClaimScrubResultResponse)
async def update_claim_scrub_result(
claim_scrub_result_id: UUID,
claim_scrub_result_in: ClaimScrubResultUpdate,
crud: ClaimScrubResultCRUD = Depends(get_crud),
):
"""
Update an existing claimscrubresult.
- **claim_scrub_result_id**: The UUID of the claimscrubresult to update
- **claim_scrub_result_in**: The updated claimscrubresult data
"""
db_claim_scrub_result = crud.get_by_id(claim_scrub_result_id)
if not db_claim_scrub_result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimScrubResult with id { claim_scrub_result_id} not found"
)
return crud.update(claim_scrub_result_id, claim_scrub_result_in)
@router.delete("/{ claim_scrub_result_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_claim_scrub_result(
claim_scrub_result_id: UUID,
crud: ClaimScrubResultCRUD = Depends(get_crud),
):
"""
Delete a claimscrubresult.
- **claim_scrub_result_id**: The UUID of the claimscrubresult to delete
"""
db_claim_scrub_result = crud.get_by_id(claim_scrub_result_id)
if not db_claim_scrub_result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimScrubResult with id { claim_scrub_result_id} not found"
)
crud.delete(claim_scrub_result_id)
return None

View File

@ -35,7 +35,7 @@ async def list_claim_scrub_results(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return ClaimScrubResultListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_claim_scrub_result(
- **claim_scrub_result_id**: The UUID of the claimscrubresult
"""
db_claim_scrub_result = crud.get_by_id(claim_scrub_result_id)
db_claim_scrub_result = await crud.get_by_id(claim_scrub_result_id)
if not db_claim_scrub_result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_claim_scrub_result(
- **claim_scrub_result_in**: The claimscrubresult data to create
"""
return crud.create(claim_scrub_result_in)
return await crud.create(claim_scrub_result_in)
@router.put("/{ claim_scrub_result_id }", response_model=ClaimScrubResultResponse)
async def update_claim_scrub_result(
@ -87,13 +87,13 @@ async def update_claim_scrub_result(
- **claim_scrub_result_id**: The UUID of the claimscrubresult to update
- **claim_scrub_result_in**: The updated claimscrubresult data
"""
db_claim_scrub_result = crud.get_by_id(claim_scrub_result_id)
db_claim_scrub_result = await crud.get_by_id(claim_scrub_result_id)
if not db_claim_scrub_result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimScrubResult with id { claim_scrub_result_id} not found"
)
return crud.update(claim_scrub_result_id, claim_scrub_result_in)
return await crud.update(claim_scrub_result_id, claim_scrub_result_in)
@router.delete("/{ claim_scrub_result_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_claim_scrub_result(
@ -105,11 +105,11 @@ async def delete_claim_scrub_result(
- **claim_scrub_result_id**: The UUID of the claimscrubresult to delete
"""
db_claim_scrub_result = crud.get_by_id(claim_scrub_result_id)
db_claim_scrub_result = await crud.get_by_id(claim_scrub_result_id)
if not db_claim_scrub_result:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimScrubResult with id { claim_scrub_result_id} not found"
)
crud.delete(claim_scrub_result_id)
await crud.delete(claim_scrub_result_id)
return None

View File

@ -35,7 +35,7 @@ async def list_clinical_entities(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return ClinicalEntityListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_clinical_entity(
- **clinical_entity_id**: The UUID of the clinicalentity
"""
db_clinical_entity = crud.get_by_id(clinical_entity_id)
db_clinical_entity = await crud.get_by_id(clinical_entity_id)
if not db_clinical_entity:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_clinical_entity(
- **clinical_entity_in**: The clinicalentity data to create
"""
return crud.create(clinical_entity_in)
return await crud.create(clinical_entity_in)
@router.put("/{ clinical_entity_id }", response_model=ClinicalEntityResponse)
async def update_clinical_entity(
@ -87,13 +87,13 @@ async def update_clinical_entity(
- **clinical_entity_id**: The UUID of the clinicalentity to update
- **clinical_entity_in**: The updated clinicalentity data
"""
db_clinical_entity = crud.get_by_id(clinical_entity_id)
db_clinical_entity = await crud.get_by_id(clinical_entity_id)
if not db_clinical_entity:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClinicalEntity with id { clinical_entity_id} not found"
)
return crud.update(clinical_entity_id, clinical_entity_in)
return await crud.update(clinical_entity_id, clinical_entity_in)
@router.delete("/{ clinical_entity_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_clinical_entity(
@ -105,11 +105,11 @@ async def delete_clinical_entity(
- **clinical_entity_id**: The UUID of the clinicalentity to delete
"""
db_clinical_entity = crud.get_by_id(clinical_entity_id)
db_clinical_entity = await crud.get_by_id(clinical_entity_id)
if not db_clinical_entity:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClinicalEntity with id { clinical_entity_id} not found"
)
crud.delete(clinical_entity_id)
await crud.delete(clinical_entity_id)
return None

View File

@ -1,115 +0,0 @@
"""
Claim API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.claim_service import ClaimCRUD
from src.validation.claim_schemas import (
ClaimCreate,
ClaimUpdate,
ClaimResponse,
ClaimListResponse,
)
router = APIRouter(prefix="/claims", tags=["Claim"])
def get_crud(db: Session = Depends(get_db)) -> ClaimCRUD:
"""Dependency injection for ClaimCRUD"""
return ClaimCRUD(db)
@router.get("/", response_model=ClaimListResponse)
async def list_claims(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: ClaimCRUD = Depends(get_crud),
):
"""
List all claims with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return ClaimListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ claim_id }", response_model=ClaimResponse)
async def get_claim(
claim_id: UUID,
crud: ClaimCRUD = Depends(get_crud),
):
"""
Get a specific claim by ID.
- **claim_id**: The UUID of the claim
"""
db_claim = crud.get_by_id(claim_id)
if not db_claim:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Claim with id { claim_id} not found"
)
return db_claim
@router.post("/", response_model=ClaimResponse, status_code=status.HTTP_201_CREATED)
async def create_claim(
claim_in: ClaimCreate,
crud: ClaimCRUD = Depends(get_crud),
):
"""
Create a new claim.
- **claim_in**: The claim data to create
"""
return crud.create(claim_in)
@router.put("/{ claim_id }", response_model=ClaimResponse)
async def update_claim(
claim_id: UUID,
claim_in: ClaimUpdate,
crud: ClaimCRUD = Depends(get_crud),
):
"""
Update an existing claim.
- **claim_id**: The UUID of the claim to update
- **claim_in**: The updated claim data
"""
db_claim = crud.get_by_id(claim_id)
if not db_claim:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Claim with id { claim_id} not found"
)
return crud.update(claim_id, claim_in)
@router.delete("/{ claim_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_claim(
claim_id: UUID,
crud: ClaimCRUD = Depends(get_crud),
):
"""
Delete a claim.
- **claim_id**: The UUID of the claim to delete
"""
db_claim = crud.get_by_id(claim_id)
if not db_claim:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Claim with id { claim_id} not found"
)
crud.delete(claim_id)
return None

View File

@ -35,7 +35,7 @@ async def list_confidence_scores(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return ConfidenceScoreListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_confidence_score(
- **confidence_score_id**: The UUID of the confidencescore
"""
db_confidence_score = crud.get_by_id(confidence_score_id)
db_confidence_score = await crud.get_by_id(confidence_score_id)
if not db_confidence_score:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_confidence_score(
- **confidence_score_in**: The confidencescore data to create
"""
return crud.create(confidence_score_in)
return await crud.create(confidence_score_in)
@router.put("/{ confidence_score_id }", response_model=ConfidenceScoreResponse)
async def update_confidence_score(
@ -87,13 +87,13 @@ async def update_confidence_score(
- **confidence_score_id**: The UUID of the confidencescore to update
- **confidence_score_in**: The updated confidencescore data
"""
db_confidence_score = crud.get_by_id(confidence_score_id)
db_confidence_score = await crud.get_by_id(confidence_score_id)
if not db_confidence_score:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ConfidenceScore with id { confidence_score_id} not found"
)
return crud.update(confidence_score_id, confidence_score_in)
return await crud.update(confidence_score_id, confidence_score_in)
@router.delete("/{ confidence_score_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_confidence_score(
@ -105,11 +105,11 @@ async def delete_confidence_score(
- **confidence_score_id**: The UUID of the confidencescore to delete
"""
db_confidence_score = crud.get_by_id(confidence_score_id)
db_confidence_score = await crud.get_by_id(confidence_score_id)
if not db_confidence_score:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ConfidenceScore with id { confidence_score_id} not found"
)
crud.delete(confidence_score_id)
await crud.delete(confidence_score_id)
return None

View File

@ -35,7 +35,7 @@ async def list_cpt_codes(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return CPTCodeListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_cpt_code(
- **cpt_code_id**: The UUID of the cptcode
"""
db_cpt_code = crud.get_by_id(cpt_code_id)
db_cpt_code = await crud.get_by_id(cpt_code_id)
if not db_cpt_code:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_cpt_code(
- **cpt_code_in**: The cptcode data to create
"""
return crud.create(cpt_code_in)
return await crud.create(cpt_code_in)
@router.put("/{ cpt_code_id }", response_model=CPTCodeResponse)
async def update_cpt_code(
@ -87,13 +87,13 @@ async def update_cpt_code(
- **cpt_code_id**: The UUID of the cptcode to update
- **cpt_code_in**: The updated cptcode data
"""
db_cpt_code = crud.get_by_id(cpt_code_id)
db_cpt_code = await crud.get_by_id(cpt_code_id)
if not db_cpt_code:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"CPTCode with id { cpt_code_id} not found"
)
return crud.update(cpt_code_id, cpt_code_in)
return await crud.update(cpt_code_id, cpt_code_in)
@router.delete("/{ cpt_code_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_cpt_code(
@ -105,11 +105,11 @@ async def delete_cpt_code(
- **cpt_code_id**: The UUID of the cptcode to delete
"""
db_cpt_code = crud.get_by_id(cpt_code_id)
db_cpt_code = await crud.get_by_id(cpt_code_id)
if not db_cpt_code:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"CPTCode with id { cpt_code_id} not found"
)
crud.delete(cpt_code_id)
await crud.delete(cpt_code_id)
return None

View File

@ -35,7 +35,7 @@ async def list_cpt_modifiers(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return CPTModifierListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_cpt_modifier(
- **cpt_modifier_id**: The UUID of the cptmodifier
"""
db_cpt_modifier = crud.get_by_id(cpt_modifier_id)
db_cpt_modifier = await crud.get_by_id(cpt_modifier_id)
if not db_cpt_modifier:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_cpt_modifier(
- **cpt_modifier_in**: The cptmodifier data to create
"""
return crud.create(cpt_modifier_in)
return await crud.create(cpt_modifier_in)
@router.put("/{ cpt_modifier_id }", response_model=CPTModifierResponse)
async def update_cpt_modifier(
@ -87,13 +87,13 @@ async def update_cpt_modifier(
- **cpt_modifier_id**: The UUID of the cptmodifier to update
- **cpt_modifier_in**: The updated cptmodifier data
"""
db_cpt_modifier = crud.get_by_id(cpt_modifier_id)
db_cpt_modifier = await crud.get_by_id(cpt_modifier_id)
if not db_cpt_modifier:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"CPTModifier with id { cpt_modifier_id} not found"
)
return crud.update(cpt_modifier_id, cpt_modifier_in)
return await crud.update(cpt_modifier_id, cpt_modifier_in)
@router.delete("/{ cpt_modifier_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_cpt_modifier(
@ -105,11 +105,11 @@ async def delete_cpt_modifier(
- **cpt_modifier_id**: The UUID of the cptmodifier to delete
"""
db_cpt_modifier = crud.get_by_id(cpt_modifier_id)
db_cpt_modifier = await crud.get_by_id(cpt_modifier_id)
if not db_cpt_modifier:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"CPTModifier with id { cpt_modifier_id} not found"
)
crud.delete(cpt_modifier_id)
await crud.delete(cpt_modifier_id)
return None

View File

@ -1,115 +0,0 @@
"""
DenialPattern API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.denial_pattern_service import DenialPatternCRUD
from src.validation.denial_pattern_schemas import (
DenialPatternCreate,
DenialPatternUpdate,
DenialPatternResponse,
DenialPatternListResponse,
)
router = APIRouter(prefix="/denialpatterns", tags=["DenialPattern"])
def get_crud(db: Session = Depends(get_db)) -> DenialPatternCRUD:
"""Dependency injection for DenialPatternCRUD"""
return DenialPatternCRUD(db)
@router.get("/", response_model=DenialPatternListResponse)
async def list_denial_patterns(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: DenialPatternCRUD = Depends(get_crud),
):
"""
List all denialpatterns with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return DenialPatternListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ denial_pattern_id }", response_model=DenialPatternResponse)
async def get_denial_pattern(
denial_pattern_id: UUID,
crud: DenialPatternCRUD = Depends(get_crud),
):
"""
Get a specific denialpattern by ID.
- **denial_pattern_id**: The UUID of the denialpattern
"""
db_denial_pattern = crud.get_by_id(denial_pattern_id)
if not db_denial_pattern:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"DenialPattern with id { denial_pattern_id} not found"
)
return db_denial_pattern
@router.post("/", response_model=DenialPatternResponse, status_code=status.HTTP_201_CREATED)
async def create_denial_pattern(
denial_pattern_in: DenialPatternCreate,
crud: DenialPatternCRUD = Depends(get_crud),
):
"""
Create a new denialpattern.
- **denial_pattern_in**: The denialpattern data to create
"""
return crud.create(denial_pattern_in)
@router.put("/{ denial_pattern_id }", response_model=DenialPatternResponse)
async def update_denial_pattern(
denial_pattern_id: UUID,
denial_pattern_in: DenialPatternUpdate,
crud: DenialPatternCRUD = Depends(get_crud),
):
"""
Update an existing denialpattern.
- **denial_pattern_id**: The UUID of the denialpattern to update
- **denial_pattern_in**: The updated denialpattern data
"""
db_denial_pattern = crud.get_by_id(denial_pattern_id)
if not db_denial_pattern:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"DenialPattern with id { denial_pattern_id} not found"
)
return crud.update(denial_pattern_id, denial_pattern_in)
@router.delete("/{ denial_pattern_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_denial_pattern(
denial_pattern_id: UUID,
crud: DenialPatternCRUD = Depends(get_crud),
):
"""
Delete a denialpattern.
- **denial_pattern_id**: The UUID of the denialpattern to delete
"""
db_denial_pattern = crud.get_by_id(denial_pattern_id)
if not db_denial_pattern:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"DenialPattern with id { denial_pattern_id} not found"
)
crud.delete(denial_pattern_id)
return None

View File

@ -35,7 +35,7 @@ async def list_denial_patterns(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return DenialPatternListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_denial_pattern(
- **denial_pattern_id**: The UUID of the denialpattern
"""
db_denial_pattern = crud.get_by_id(denial_pattern_id)
db_denial_pattern = await crud.get_by_id(denial_pattern_id)
if not db_denial_pattern:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_denial_pattern(
- **denial_pattern_in**: The denialpattern data to create
"""
return crud.create(denial_pattern_in)
return await crud.create(denial_pattern_in)
@router.put("/{ denial_pattern_id }", response_model=DenialPatternResponse)
async def update_denial_pattern(
@ -87,13 +87,13 @@ async def update_denial_pattern(
- **denial_pattern_id**: The UUID of the denialpattern to update
- **denial_pattern_in**: The updated denialpattern data
"""
db_denial_pattern = crud.get_by_id(denial_pattern_id)
db_denial_pattern = await crud.get_by_id(denial_pattern_id)
if not db_denial_pattern:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"DenialPattern with id { denial_pattern_id} not found"
)
return crud.update(denial_pattern_id, denial_pattern_in)
return await crud.update(denial_pattern_id, denial_pattern_in)
@router.delete("/{ denial_pattern_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_denial_pattern(
@ -105,11 +105,11 @@ async def delete_denial_pattern(
- **denial_pattern_id**: The UUID of the denialpattern to delete
"""
db_denial_pattern = crud.get_by_id(denial_pattern_id)
db_denial_pattern = await crud.get_by_id(denial_pattern_id)
if not db_denial_pattern:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"DenialPattern with id { denial_pattern_id} not found"
)
crud.delete(denial_pattern_id)
await crud.delete(denial_pattern_id)
return None

View File

@ -1,115 +0,0 @@
"""
EMRIntegration API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.emr_integration_service import EMRIntegrationCRUD
from src.validation.emr_integration_schemas import (
EMRIntegrationCreate,
EMRIntegrationUpdate,
EMRIntegrationResponse,
EMRIntegrationListResponse,
)
router = APIRouter(prefix="/emrintegrations", tags=["EMRIntegration"])
def get_crud(db: Session = Depends(get_db)) -> EMRIntegrationCRUD:
"""Dependency injection for EMRIntegrationCRUD"""
return EMRIntegrationCRUD(db)
@router.get("/", response_model=EMRIntegrationListResponse)
async def list_emr_integrations(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: EMRIntegrationCRUD = Depends(get_crud),
):
"""
List all emrintegrations with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return EMRIntegrationListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ emr_integration_id }", response_model=EMRIntegrationResponse)
async def get_emr_integration(
emr_integration_id: UUID,
crud: EMRIntegrationCRUD = Depends(get_crud),
):
"""
Get a specific emrintegration by ID.
- **emr_integration_id**: The UUID of the emrintegration
"""
db_emr_integration = crud.get_by_id(emr_integration_id)
if not db_emr_integration:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"EMRIntegration with id { emr_integration_id} not found"
)
return db_emr_integration
@router.post("/", response_model=EMRIntegrationResponse, status_code=status.HTTP_201_CREATED)
async def create_emr_integration(
emr_integration_in: EMRIntegrationCreate,
crud: EMRIntegrationCRUD = Depends(get_crud),
):
"""
Create a new emrintegration.
- **emr_integration_in**: The emrintegration data to create
"""
return crud.create(emr_integration_in)
@router.put("/{ emr_integration_id }", response_model=EMRIntegrationResponse)
async def update_emr_integration(
emr_integration_id: UUID,
emr_integration_in: EMRIntegrationUpdate,
crud: EMRIntegrationCRUD = Depends(get_crud),
):
"""
Update an existing emrintegration.
- **emr_integration_id**: The UUID of the emrintegration to update
- **emr_integration_in**: The updated emrintegration data
"""
db_emr_integration = crud.get_by_id(emr_integration_id)
if not db_emr_integration:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"EMRIntegration with id { emr_integration_id} not found"
)
return crud.update(emr_integration_id, emr_integration_in)
@router.delete("/{ emr_integration_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_emr_integration(
emr_integration_id: UUID,
crud: EMRIntegrationCRUD = Depends(get_crud),
):
"""
Delete a emrintegration.
- **emr_integration_id**: The UUID of the emrintegration to delete
"""
db_emr_integration = crud.get_by_id(emr_integration_id)
if not db_emr_integration:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"EMRIntegration with id { emr_integration_id} not found"
)
crud.delete(emr_integration_id)
return None

View File

@ -35,7 +35,7 @@ async def list_emr_integrations(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return EMRIntegrationListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_emr_integration(
- **emr_integration_id**: The UUID of the emrintegration
"""
db_emr_integration = crud.get_by_id(emr_integration_id)
db_emr_integration = await crud.get_by_id(emr_integration_id)
if not db_emr_integration:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_emr_integration(
- **emr_integration_in**: The emrintegration data to create
"""
return crud.create(emr_integration_in)
return await crud.create(emr_integration_in)
@router.put("/{ emr_integration_id }", response_model=EMRIntegrationResponse)
async def update_emr_integration(
@ -87,13 +87,13 @@ async def update_emr_integration(
- **emr_integration_id**: The UUID of the emrintegration to update
- **emr_integration_in**: The updated emrintegration data
"""
db_emr_integration = crud.get_by_id(emr_integration_id)
db_emr_integration = await crud.get_by_id(emr_integration_id)
if not db_emr_integration:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"EMRIntegration with id { emr_integration_id} not found"
)
return crud.update(emr_integration_id, emr_integration_in)
return await crud.update(emr_integration_id, emr_integration_in)
@router.delete("/{ emr_integration_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_emr_integration(
@ -105,11 +105,11 @@ async def delete_emr_integration(
- **emr_integration_id**: The UUID of the emrintegration to delete
"""
db_emr_integration = crud.get_by_id(emr_integration_id)
db_emr_integration = await crud.get_by_id(emr_integration_id)
if not db_emr_integration:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"EMRIntegration with id { emr_integration_id} not found"
)
crud.delete(emr_integration_id)
await crud.delete(emr_integration_id)
return None

View File

@ -1,115 +0,0 @@
"""
ClinicalEntity API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.clinical_entity_service import ClinicalEntityCRUD
from src.validation.clinical_entity_schemas import (
ClinicalEntityCreate,
ClinicalEntityUpdate,
ClinicalEntityResponse,
ClinicalEntityListResponse,
)
router = APIRouter(prefix="/clinicalentities", tags=["ClinicalEntity"])
def get_crud(db: Session = Depends(get_db)) -> ClinicalEntityCRUD:
"""Dependency injection for ClinicalEntityCRUD"""
return ClinicalEntityCRUD(db)
@router.get("/", response_model=ClinicalEntityListResponse)
async def list_clinical_entities(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: ClinicalEntityCRUD = Depends(get_crud),
):
"""
List all clinicalentities with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return ClinicalEntityListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ clinical_entity_id }", response_model=ClinicalEntityResponse)
async def get_clinical_entity(
clinical_entity_id: UUID,
crud: ClinicalEntityCRUD = Depends(get_crud),
):
"""
Get a specific clinicalentity by ID.
- **clinical_entity_id**: The UUID of the clinicalentity
"""
db_clinical_entity = crud.get_by_id(clinical_entity_id)
if not db_clinical_entity:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClinicalEntity with id { clinical_entity_id} not found"
)
return db_clinical_entity
@router.post("/", response_model=ClinicalEntityResponse, status_code=status.HTTP_201_CREATED)
async def create_clinical_entity(
clinical_entity_in: ClinicalEntityCreate,
crud: ClinicalEntityCRUD = Depends(get_crud),
):
"""
Create a new clinicalentity.
- **clinical_entity_in**: The clinicalentity data to create
"""
return crud.create(clinical_entity_in)
@router.put("/{ clinical_entity_id }", response_model=ClinicalEntityResponse)
async def update_clinical_entity(
clinical_entity_id: UUID,
clinical_entity_in: ClinicalEntityUpdate,
crud: ClinicalEntityCRUD = Depends(get_crud),
):
"""
Update an existing clinicalentity.
- **clinical_entity_id**: The UUID of the clinicalentity to update
- **clinical_entity_in**: The updated clinicalentity data
"""
db_clinical_entity = crud.get_by_id(clinical_entity_id)
if not db_clinical_entity:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClinicalEntity with id { clinical_entity_id} not found"
)
return crud.update(clinical_entity_id, clinical_entity_in)
@router.delete("/{ clinical_entity_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_clinical_entity(
clinical_entity_id: UUID,
crud: ClinicalEntityCRUD = Depends(get_crud),
):
"""
Delete a clinicalentity.
- **clinical_entity_id**: The UUID of the clinicalentity to delete
"""
db_clinical_entity = crud.get_by_id(clinical_entity_id)
if not db_clinical_entity:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClinicalEntity with id { clinical_entity_id} not found"
)
crud.delete(clinical_entity_id)
return None

View File

@ -1,115 +0,0 @@
"""
ClaimReview API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.claim_review_service import ClaimReviewCRUD
from src.validation.claim_review_schemas import (
ClaimReviewCreate,
ClaimReviewUpdate,
ClaimReviewResponse,
ClaimReviewListResponse,
)
router = APIRouter(prefix="/claimreviews", tags=["ClaimReview"])
def get_crud(db: Session = Depends(get_db)) -> ClaimReviewCRUD:
"""Dependency injection for ClaimReviewCRUD"""
return ClaimReviewCRUD(db)
@router.get("/", response_model=ClaimReviewListResponse)
async def list_claim_reviews(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: ClaimReviewCRUD = Depends(get_crud),
):
"""
List all claimreviews with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return ClaimReviewListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ claim_review_id }", response_model=ClaimReviewResponse)
async def get_claim_review(
claim_review_id: UUID,
crud: ClaimReviewCRUD = Depends(get_crud),
):
"""
Get a specific claimreview by ID.
- **claim_review_id**: The UUID of the claimreview
"""
db_claim_review = crud.get_by_id(claim_review_id)
if not db_claim_review:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimReview with id { claim_review_id} not found"
)
return db_claim_review
@router.post("/", response_model=ClaimReviewResponse, status_code=status.HTTP_201_CREATED)
async def create_claim_review(
claim_review_in: ClaimReviewCreate,
crud: ClaimReviewCRUD = Depends(get_crud),
):
"""
Create a new claimreview.
- **claim_review_in**: The claimreview data to create
"""
return crud.create(claim_review_in)
@router.put("/{ claim_review_id }", response_model=ClaimReviewResponse)
async def update_claim_review(
claim_review_id: UUID,
claim_review_in: ClaimReviewUpdate,
crud: ClaimReviewCRUD = Depends(get_crud),
):
"""
Update an existing claimreview.
- **claim_review_id**: The UUID of the claimreview to update
- **claim_review_in**: The updated claimreview data
"""
db_claim_review = crud.get_by_id(claim_review_id)
if not db_claim_review:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimReview with id { claim_review_id} not found"
)
return crud.update(claim_review_id, claim_review_in)
@router.delete("/{ claim_review_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_claim_review(
claim_review_id: UUID,
crud: ClaimReviewCRUD = Depends(get_crud),
):
"""
Delete a claimreview.
- **claim_review_id**: The UUID of the claimreview to delete
"""
db_claim_review = crud.get_by_id(claim_review_id)
if not db_claim_review:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ClaimReview with id { claim_review_id} not found"
)
crud.delete(claim_review_id)
return None

View File

@ -35,7 +35,7 @@ async def list_icd10_codes(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return ICD10CodeListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_icd10_code(
- **icd10_code_id**: The UUID of the icd10code
"""
db_icd10_code = crud.get_by_id(icd10_code_id)
db_icd10_code = await crud.get_by_id(icd10_code_id)
if not db_icd10_code:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_icd10_code(
- **icd10_code_in**: The icd10code data to create
"""
return crud.create(icd10_code_in)
return await crud.create(icd10_code_in)
@router.put("/{ icd10_code_id }", response_model=ICD10CodeResponse)
async def update_icd10_code(
@ -87,13 +87,13 @@ async def update_icd10_code(
- **icd10_code_id**: The UUID of the icd10code to update
- **icd10_code_in**: The updated icd10code data
"""
db_icd10_code = crud.get_by_id(icd10_code_id)
db_icd10_code = await crud.get_by_id(icd10_code_id)
if not db_icd10_code:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ICD10Code with id { icd10_code_id} not found"
)
return crud.update(icd10_code_id, icd10_code_in)
return await crud.update(icd10_code_id, icd10_code_in)
@router.delete("/{ icd10_code_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_icd10_code(
@ -105,11 +105,11 @@ async def delete_icd10_code(
- **icd10_code_id**: The UUID of the icd10code to delete
"""
db_icd10_code = crud.get_by_id(icd10_code_id)
db_icd10_code = await crud.get_by_id(icd10_code_id)
if not db_icd10_code:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ICD10Code with id { icd10_code_id} not found"
)
crud.delete(icd10_code_id)
await crud.delete(icd10_code_id)
return None

View File

@ -35,7 +35,7 @@ async def list_lc_ds(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return LCDListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_lcd(
- **lcd_id**: The UUID of the lcd
"""
db_lcd = crud.get_by_id(lcd_id)
db_lcd = await crud.get_by_id(lcd_id)
if not db_lcd:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_lcd(
- **lcd_in**: The lcd data to create
"""
return crud.create(lcd_in)
return await crud.create(lcd_in)
@router.put("/{ lcd_id }", response_model=LCDResponse)
async def update_lcd(
@ -87,13 +87,13 @@ async def update_lcd(
- **lcd_id**: The UUID of the lcd to update
- **lcd_in**: The updated lcd data
"""
db_lcd = crud.get_by_id(lcd_id)
db_lcd = await crud.get_by_id(lcd_id)
if not db_lcd:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"LCD with id { lcd_id} not found"
)
return crud.update(lcd_id, lcd_in)
return await crud.update(lcd_id, lcd_in)
@router.delete("/{ lcd_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_lcd(
@ -105,11 +105,11 @@ async def delete_lcd(
- **lcd_id**: The UUID of the lcd to delete
"""
db_lcd = crud.get_by_id(lcd_id)
db_lcd = await crud.get_by_id(lcd_id)
if not db_lcd:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"LCD with id { lcd_id} not found"
)
crud.delete(lcd_id)
await crud.delete(lcd_id)
return None

View File

@ -35,7 +35,7 @@ async def list_ncci_edits(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return NCCIEditListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_ncci_edit(
- **ncci_edit_id**: The UUID of the ncciedit
"""
db_ncci_edit = crud.get_by_id(ncci_edit_id)
db_ncci_edit = await crud.get_by_id(ncci_edit_id)
if not db_ncci_edit:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_ncci_edit(
- **ncci_edit_in**: The ncciedit data to create
"""
return crud.create(ncci_edit_in)
return await crud.create(ncci_edit_in)
@router.put("/{ ncci_edit_id }", response_model=NCCIEditResponse)
async def update_ncci_edit(
@ -87,13 +87,13 @@ async def update_ncci_edit(
- **ncci_edit_id**: The UUID of the ncciedit to update
- **ncci_edit_in**: The updated ncciedit data
"""
db_ncci_edit = crud.get_by_id(ncci_edit_id)
db_ncci_edit = await crud.get_by_id(ncci_edit_id)
if not db_ncci_edit:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"NCCIEdit with id { ncci_edit_id} not found"
)
return crud.update(ncci_edit_id, ncci_edit_in)
return await crud.update(ncci_edit_id, ncci_edit_in)
@router.delete("/{ ncci_edit_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_ncci_edit(
@ -105,11 +105,11 @@ async def delete_ncci_edit(
- **ncci_edit_id**: The UUID of the ncciedit to delete
"""
db_ncci_edit = crud.get_by_id(ncci_edit_id)
db_ncci_edit = await crud.get_by_id(ncci_edit_id)
if not db_ncci_edit:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"NCCIEdit with id { ncci_edit_id} not found"
)
crud.delete(ncci_edit_id)
await crud.delete(ncci_edit_id)
return None

View File

@ -35,7 +35,7 @@ async def list_nc_ds(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return NCDListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_ncd(
- **ncd_id**: The UUID of the ncd
"""
db_ncd = crud.get_by_id(ncd_id)
db_ncd = await crud.get_by_id(ncd_id)
if not db_ncd:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_ncd(
- **ncd_in**: The ncd data to create
"""
return crud.create(ncd_in)
return await crud.create(ncd_in)
@router.put("/{ ncd_id }", response_model=NCDResponse)
async def update_ncd(
@ -87,13 +87,13 @@ async def update_ncd(
- **ncd_id**: The UUID of the ncd to update
- **ncd_in**: The updated ncd data
"""
db_ncd = crud.get_by_id(ncd_id)
db_ncd = await crud.get_by_id(ncd_id)
if not db_ncd:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"NCD with id { ncd_id} not found"
)
return crud.update(ncd_id, ncd_in)
return await crud.update(ncd_id, ncd_in)
@router.delete("/{ ncd_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_ncd(
@ -105,11 +105,11 @@ async def delete_ncd(
- **ncd_id**: The UUID of the ncd to delete
"""
db_ncd = crud.get_by_id(ncd_id)
db_ncd = await crud.get_by_id(ncd_id)
if not db_ncd:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"NCD with id { ncd_id} not found"
)
crud.delete(ncd_id)
await crud.delete(ncd_id)
return None

View File

@ -1,115 +0,0 @@
"""
Patient API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.patient_service import PatientCRUD
from src.validation.patient_schemas import (
PatientCreate,
PatientUpdate,
PatientResponse,
PatientListResponse,
)
router = APIRouter(prefix="/patients", tags=["Patient"])
def get_crud(db: Session = Depends(get_db)) -> PatientCRUD:
"""Dependency injection for PatientCRUD"""
return PatientCRUD(db)
@router.get("/", response_model=PatientListResponse)
async def list_patients(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: PatientCRUD = Depends(get_crud),
):
"""
List all patients with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return PatientListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ patient_id }", response_model=PatientResponse)
async def get_patient(
patient_id: UUID,
crud: PatientCRUD = Depends(get_crud),
):
"""
Get a specific patient by ID.
- **patient_id**: The UUID of the patient
"""
db_patient = crud.get_by_id(patient_id)
if not db_patient:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Patient with id { patient_id} not found"
)
return db_patient
@router.post("/", response_model=PatientResponse, status_code=status.HTTP_201_CREATED)
async def create_patient(
patient_in: PatientCreate,
crud: PatientCRUD = Depends(get_crud),
):
"""
Create a new patient.
- **patient_in**: The patient data to create
"""
return crud.create(patient_in)
@router.put("/{ patient_id }", response_model=PatientResponse)
async def update_patient(
patient_id: UUID,
patient_in: PatientUpdate,
crud: PatientCRUD = Depends(get_crud),
):
"""
Update an existing patient.
- **patient_id**: The UUID of the patient to update
- **patient_in**: The updated patient data
"""
db_patient = crud.get_by_id(patient_id)
if not db_patient:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Patient with id { patient_id} not found"
)
return crud.update(patient_id, patient_in)
@router.delete("/{ patient_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_patient(
patient_id: UUID,
crud: PatientCRUD = Depends(get_crud),
):
"""
Delete a patient.
- **patient_id**: The UUID of the patient to delete
"""
db_patient = crud.get_by_id(patient_id)
if not db_patient:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Patient with id { patient_id} not found"
)
crud.delete(patient_id)
return None

View File

@ -35,7 +35,7 @@ async def list_patients(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return PatientListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_patient(
- **patient_id**: The UUID of the patient
"""
db_patient = crud.get_by_id(patient_id)
db_patient = await crud.get_by_id(patient_id)
if not db_patient:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_patient(
- **patient_in**: The patient data to create
"""
return crud.create(patient_in)
return await crud.create(patient_in)
@router.put("/{ patient_id }", response_model=PatientResponse)
async def update_patient(
@ -87,13 +87,13 @@ async def update_patient(
- **patient_id**: The UUID of the patient to update
- **patient_in**: The updated patient data
"""
db_patient = crud.get_by_id(patient_id)
db_patient = await crud.get_by_id(patient_id)
if not db_patient:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Patient with id { patient_id} not found"
)
return crud.update(patient_id, patient_in)
return await crud.update(patient_id, patient_in)
@router.delete("/{ patient_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_patient(
@ -105,11 +105,11 @@ async def delete_patient(
- **patient_id**: The UUID of the patient to delete
"""
db_patient = crud.get_by_id(patient_id)
db_patient = await crud.get_by_id(patient_id)
if not db_patient:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Patient with id { patient_id} not found"
)
crud.delete(patient_id)
await crud.delete(patient_id)
return None

View File

@ -35,7 +35,7 @@ async def list_payers(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return PayerListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_payer(
- **payer_id**: The UUID of the payer
"""
db_payer = crud.get_by_id(payer_id)
db_payer = await crud.get_by_id(payer_id)
if not db_payer:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_payer(
- **payer_in**: The payer data to create
"""
return crud.create(payer_in)
return await crud.create(payer_in)
@router.put("/{ payer_id }", response_model=PayerResponse)
async def update_payer(
@ -87,13 +87,13 @@ async def update_payer(
- **payer_id**: The UUID of the payer to update
- **payer_in**: The updated payer data
"""
db_payer = crud.get_by_id(payer_id)
db_payer = await crud.get_by_id(payer_id)
if not db_payer:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Payer with id { payer_id} not found"
)
return crud.update(payer_id, payer_in)
return await crud.update(payer_id, payer_in)
@router.delete("/{ payer_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_payer(
@ -105,11 +105,11 @@ async def delete_payer(
- **payer_id**: The UUID of the payer to delete
"""
db_payer = crud.get_by_id(payer_id)
db_payer = await crud.get_by_id(payer_id)
if not db_payer:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Payer with id { payer_id} not found"
)
crud.delete(payer_id)
await crud.delete(payer_id)
return None

View File

@ -35,7 +35,7 @@ async def list_payer_rules(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return PayerRuleListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_payer_rule(
- **payer_rule_id**: The UUID of the payerrule
"""
db_payer_rule = crud.get_by_id(payer_rule_id)
db_payer_rule = await crud.get_by_id(payer_rule_id)
if not db_payer_rule:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_payer_rule(
- **payer_rule_in**: The payerrule data to create
"""
return crud.create(payer_rule_in)
return await crud.create(payer_rule_in)
@router.put("/{ payer_rule_id }", response_model=PayerRuleResponse)
async def update_payer_rule(
@ -87,13 +87,13 @@ async def update_payer_rule(
- **payer_rule_id**: The UUID of the payerrule to update
- **payer_rule_in**: The updated payerrule data
"""
db_payer_rule = crud.get_by_id(payer_rule_id)
db_payer_rule = await crud.get_by_id(payer_rule_id)
if not db_payer_rule:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"PayerRule with id { payer_rule_id} not found"
)
return crud.update(payer_rule_id, payer_rule_in)
return await crud.update(payer_rule_id, payer_rule_in)
@router.delete("/{ payer_rule_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_payer_rule(
@ -105,11 +105,11 @@ async def delete_payer_rule(
- **payer_rule_id**: The UUID of the payerrule to delete
"""
db_payer_rule = crud.get_by_id(payer_rule_id)
db_payer_rule = await crud.get_by_id(payer_rule_id)
if not db_payer_rule:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"PayerRule with id { payer_rule_id} not found"
)
crud.delete(payer_rule_id)
await crud.delete(payer_rule_id)
return None

View File

@ -1,115 +0,0 @@
"""
PayerRule API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.payer_rule_service import PayerRuleCRUD
from src.validation.payer_rule_schemas import (
PayerRuleCreate,
PayerRuleUpdate,
PayerRuleResponse,
PayerRuleListResponse,
)
router = APIRouter(prefix="/payerrules", tags=["PayerRule"])
def get_crud(db: Session = Depends(get_db)) -> PayerRuleCRUD:
"""Dependency injection for PayerRuleCRUD"""
return PayerRuleCRUD(db)
@router.get("/", response_model=PayerRuleListResponse)
async def list_payer_rules(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: PayerRuleCRUD = Depends(get_crud),
):
"""
List all payerrules with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return PayerRuleListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ payer_rule_id }", response_model=PayerRuleResponse)
async def get_payer_rule(
payer_rule_id: UUID,
crud: PayerRuleCRUD = Depends(get_crud),
):
"""
Get a specific payerrule by ID.
- **payer_rule_id**: The UUID of the payerrule
"""
db_payer_rule = crud.get_by_id(payer_rule_id)
if not db_payer_rule:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"PayerRule with id { payer_rule_id} not found"
)
return db_payer_rule
@router.post("/", response_model=PayerRuleResponse, status_code=status.HTTP_201_CREATED)
async def create_payer_rule(
payer_rule_in: PayerRuleCreate,
crud: PayerRuleCRUD = Depends(get_crud),
):
"""
Create a new payerrule.
- **payer_rule_in**: The payerrule data to create
"""
return crud.create(payer_rule_in)
@router.put("/{ payer_rule_id }", response_model=PayerRuleResponse)
async def update_payer_rule(
payer_rule_id: UUID,
payer_rule_in: PayerRuleUpdate,
crud: PayerRuleCRUD = Depends(get_crud),
):
"""
Update an existing payerrule.
- **payer_rule_id**: The UUID of the payerrule to update
- **payer_rule_in**: The updated payerrule data
"""
db_payer_rule = crud.get_by_id(payer_rule_id)
if not db_payer_rule:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"PayerRule with id { payer_rule_id} not found"
)
return crud.update(payer_rule_id, payer_rule_in)
@router.delete("/{ payer_rule_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_payer_rule(
payer_rule_id: UUID,
crud: PayerRuleCRUD = Depends(get_crud),
):
"""
Delete a payerrule.
- **payer_rule_id**: The UUID of the payerrule to delete
"""
db_payer_rule = crud.get_by_id(payer_rule_id)
if not db_payer_rule:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"PayerRule with id { payer_rule_id} not found"
)
crud.delete(payer_rule_id)
return None

View File

@ -35,7 +35,7 @@ async def list_procedure_templates(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return ProcedureTemplateListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_procedure_template(
- **procedure_template_id**: The UUID of the proceduretemplate
"""
db_procedure_template = crud.get_by_id(procedure_template_id)
db_procedure_template = await crud.get_by_id(procedure_template_id)
if not db_procedure_template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_procedure_template(
- **procedure_template_in**: The proceduretemplate data to create
"""
return crud.create(procedure_template_in)
return await crud.create(procedure_template_in)
@router.put("/{ procedure_template_id }", response_model=ProcedureTemplateResponse)
async def update_procedure_template(
@ -87,13 +87,13 @@ async def update_procedure_template(
- **procedure_template_id**: The UUID of the proceduretemplate to update
- **procedure_template_in**: The updated proceduretemplate data
"""
db_procedure_template = crud.get_by_id(procedure_template_id)
db_procedure_template = await crud.get_by_id(procedure_template_id)
if not db_procedure_template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ProcedureTemplate with id { procedure_template_id} not found"
)
return crud.update(procedure_template_id, procedure_template_in)
return await crud.update(procedure_template_id, procedure_template_in)
@router.delete("/{ procedure_template_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_procedure_template(
@ -105,11 +105,11 @@ async def delete_procedure_template(
- **procedure_template_id**: The UUID of the proceduretemplate to delete
"""
db_procedure_template = crud.get_by_id(procedure_template_id)
db_procedure_template = await crud.get_by_id(procedure_template_id)
if not db_procedure_template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ProcedureTemplate with id { procedure_template_id} not found"
)
crud.delete(procedure_template_id)
await crud.delete(procedure_template_id)
return None

View File

@ -35,7 +35,7 @@ async def list_rag_documents(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return RAGDocumentListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_rag_document(
- **rag_document_id**: The UUID of the ragdocument
"""
db_rag_document = crud.get_by_id(rag_document_id)
db_rag_document = await crud.get_by_id(rag_document_id)
if not db_rag_document:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_rag_document(
- **rag_document_in**: The ragdocument data to create
"""
return crud.create(rag_document_in)
return await crud.create(rag_document_in)
@router.put("/{ rag_document_id }", response_model=RAGDocumentResponse)
async def update_rag_document(
@ -87,13 +87,13 @@ async def update_rag_document(
- **rag_document_id**: The UUID of the ragdocument to update
- **rag_document_in**: The updated ragdocument data
"""
db_rag_document = crud.get_by_id(rag_document_id)
db_rag_document = await crud.get_by_id(rag_document_id)
if not db_rag_document:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"RAGDocument with id { rag_document_id} not found"
)
return crud.update(rag_document_id, rag_document_in)
return await crud.update(rag_document_id, rag_document_in)
@router.delete("/{ rag_document_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_rag_document(
@ -105,11 +105,11 @@ async def delete_rag_document(
- **rag_document_id**: The UUID of the ragdocument to delete
"""
db_rag_document = crud.get_by_id(rag_document_id)
db_rag_document = await crud.get_by_id(rag_document_id)
if not db_rag_document:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"RAGDocument with id { rag_document_id} not found"
)
crud.delete(rag_document_id)
await crud.delete(rag_document_id)
return None

View File

@ -1,115 +0,0 @@
"""
Transcript API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.transcript_service import TranscriptCRUD
from src.validation.transcript_schemas import (
TranscriptCreate,
TranscriptUpdate,
TranscriptResponse,
TranscriptListResponse,
)
router = APIRouter(prefix="/transcripts", tags=["Transcript"])
def get_crud(db: Session = Depends(get_db)) -> TranscriptCRUD:
"""Dependency injection for TranscriptCRUD"""
return TranscriptCRUD(db)
@router.get("/", response_model=TranscriptListResponse)
async def list_transcripts(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: TranscriptCRUD = Depends(get_crud),
):
"""
List all transcripts with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return TranscriptListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ transcript_id }", response_model=TranscriptResponse)
async def get_transcript(
transcript_id: UUID,
crud: TranscriptCRUD = Depends(get_crud),
):
"""
Get a specific transcript by ID.
- **transcript_id**: The UUID of the transcript
"""
db_transcript = crud.get_by_id(transcript_id)
if not db_transcript:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Transcript with id { transcript_id} not found"
)
return db_transcript
@router.post("/", response_model=TranscriptResponse, status_code=status.HTTP_201_CREATED)
async def create_transcript(
transcript_in: TranscriptCreate,
crud: TranscriptCRUD = Depends(get_crud),
):
"""
Create a new transcript.
- **transcript_in**: The transcript data to create
"""
return crud.create(transcript_in)
@router.put("/{ transcript_id }", response_model=TranscriptResponse)
async def update_transcript(
transcript_id: UUID,
transcript_in: TranscriptUpdate,
crud: TranscriptCRUD = Depends(get_crud),
):
"""
Update an existing transcript.
- **transcript_id**: The UUID of the transcript to update
- **transcript_in**: The updated transcript data
"""
db_transcript = crud.get_by_id(transcript_id)
if not db_transcript:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Transcript with id { transcript_id} not found"
)
return crud.update(transcript_id, transcript_in)
@router.delete("/{ transcript_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_transcript(
transcript_id: UUID,
crud: TranscriptCRUD = Depends(get_crud),
):
"""
Delete a transcript.
- **transcript_id**: The UUID of the transcript to delete
"""
db_transcript = crud.get_by_id(transcript_id)
if not db_transcript:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Transcript with id { transcript_id} not found"
)
crud.delete(transcript_id)
return None

View File

@ -1,115 +0,0 @@
"""
ProcedureTemplate API Router
Enterprise-grade FastAPI router with full CRUD operations
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session
from uuid import UUID
from src.config.database import get_db
from src.services.procedure_template_service import ProcedureTemplateCRUD
from src.validation.procedure_template_schemas import (
ProcedureTemplateCreate,
ProcedureTemplateUpdate,
ProcedureTemplateResponse,
ProcedureTemplateListResponse,
)
router = APIRouter(prefix="/proceduretemplates", tags=["ProcedureTemplate"])
def get_crud(db: Session = Depends(get_db)) -> ProcedureTemplateCRUD:
"""Dependency injection for ProcedureTemplateCRUD"""
return ProcedureTemplateCRUD(db)
@router.get("/", response_model=ProcedureTemplateListResponse)
async def list_procedure_templates(
skip: int = Query(0, ge=0, description="Number of records to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum records to return"),
crud: ProcedureTemplateCRUD = Depends(get_crud),
):
"""
List all proceduretemplates with pagination and filtering.
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
return ProcedureTemplateListResponse(
items=items,
total=total,
skip=skip,
limit=limit,
has_more=skip + limit < total
)
@router.get("/{ procedure_template_id }", response_model=ProcedureTemplateResponse)
async def get_procedure_template(
procedure_template_id: UUID,
crud: ProcedureTemplateCRUD = Depends(get_crud),
):
"""
Get a specific proceduretemplate by ID.
- **procedure_template_id**: The UUID of the proceduretemplate
"""
db_procedure_template = crud.get_by_id(procedure_template_id)
if not db_procedure_template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ProcedureTemplate with id { procedure_template_id} not found"
)
return db_procedure_template
@router.post("/", response_model=ProcedureTemplateResponse, status_code=status.HTTP_201_CREATED)
async def create_procedure_template(
procedure_template_in: ProcedureTemplateCreate,
crud: ProcedureTemplateCRUD = Depends(get_crud),
):
"""
Create a new proceduretemplate.
- **procedure_template_in**: The proceduretemplate data to create
"""
return crud.create(procedure_template_in)
@router.put("/{ procedure_template_id }", response_model=ProcedureTemplateResponse)
async def update_procedure_template(
procedure_template_id: UUID,
procedure_template_in: ProcedureTemplateUpdate,
crud: ProcedureTemplateCRUD = Depends(get_crud),
):
"""
Update an existing proceduretemplate.
- **procedure_template_id**: The UUID of the proceduretemplate to update
- **procedure_template_in**: The updated proceduretemplate data
"""
db_procedure_template = crud.get_by_id(procedure_template_id)
if not db_procedure_template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ProcedureTemplate with id { procedure_template_id} not found"
)
return crud.update(procedure_template_id, procedure_template_in)
@router.delete("/{ procedure_template_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_procedure_template(
procedure_template_id: UUID,
crud: ProcedureTemplateCRUD = Depends(get_crud),
):
"""
Delete a proceduretemplate.
- **procedure_template_id**: The UUID of the proceduretemplate to delete
"""
db_procedure_template = crud.get_by_id(procedure_template_id)
if not db_procedure_template:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"ProcedureTemplate with id { procedure_template_id} not found"
)
crud.delete(procedure_template_id)
return None

View File

@ -35,7 +35,7 @@ async def list_transcripts(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return TranscriptListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_transcript(
- **transcript_id**: The UUID of the transcript
"""
db_transcript = crud.get_by_id(transcript_id)
db_transcript = await crud.get_by_id(transcript_id)
if not db_transcript:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_transcript(
- **transcript_in**: The transcript data to create
"""
return crud.create(transcript_in)
return await crud.create(transcript_in)
@router.put("/{ transcript_id }", response_model=TranscriptResponse)
async def update_transcript(
@ -87,13 +87,13 @@ async def update_transcript(
- **transcript_id**: The UUID of the transcript to update
- **transcript_in**: The updated transcript data
"""
db_transcript = crud.get_by_id(transcript_id)
db_transcript = await crud.get_by_id(transcript_id)
if not db_transcript:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Transcript with id { transcript_id} not found"
)
return crud.update(transcript_id, transcript_in)
return await crud.update(transcript_id, transcript_in)
@router.delete("/{ transcript_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_transcript(
@ -105,11 +105,11 @@ async def delete_transcript(
- **transcript_id**: The UUID of the transcript to delete
"""
db_transcript = crud.get_by_id(transcript_id)
db_transcript = await crud.get_by_id(transcript_id)
if not db_transcript:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"Transcript with id { transcript_id} not found"
)
crud.delete(transcript_id)
await crud.delete(transcript_id)
return None

View File

@ -35,7 +35,7 @@ async def list_users(
- **skip**: Number of records to skip (for pagination)
- **limit**: Maximum number of records to return
"""
items, total = crud.get_all(skip=skip, limit=limit)
items, total = await crud.get_all(skip=skip, limit=limit)
return UserListResponse(
items=items,
@ -55,7 +55,7 @@ async def get_user(
- **user_id**: The UUID of the user
"""
db_user = crud.get_by_id(user_id)
db_user = await crud.get_by_id(user_id)
if not db_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
@ -73,7 +73,7 @@ async def create_user(
- **user_in**: The user data to create
"""
return crud.create(user_in)
return await crud.create(user_in)
@router.put("/{ user_id }", response_model=UserResponse)
async def update_user(
@ -87,13 +87,13 @@ async def update_user(
- **user_id**: The UUID of the user to update
- **user_in**: The updated user data
"""
db_user = crud.get_by_id(user_id)
db_user = await crud.get_by_id(user_id)
if not db_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"User with id { user_id} not found"
)
return crud.update(user_id, user_in)
return await crud.update(user_id, user_in)
@router.delete("/{ user_id }", status_code=status.HTTP_204_NO_CONTENT)
async def delete_user(
@ -105,11 +105,11 @@ async def delete_user(
- **user_id**: The UUID of the user to delete
"""
db_user = crud.get_by_id(user_id)
db_user = await crud.get_by_id(user_id)
if not db_user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail=f"User with id { user_id} not found"
)
crud.delete(user_id)
await crud.delete(user_id)
return None

View File

@ -1,7 +1,8 @@
from datetime import date, datetime
"""
AudioRecording Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -14,7 +15,7 @@ from src.validation.audio_recording_schemas import AudioRecordingCreate, AudioRe
logger = logging.getLogger(__name__)
class AudioRecordingService:
class AudioRecordingCRUD:
"""
Service class for AudioRecording business logic.
@ -22,7 +23,7 @@ class AudioRecordingService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
@ -38,11 +39,11 @@ class AudioRecordingService:
Get all audiorecordings with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of audiorecordings, total count)
@ -85,7 +86,7 @@ class AudioRecordingService:
Get a specific audiorecording by ID.
Args:
audio_recording_id: The UUID of the audiorecording
audio_recording_id: Any UUID of the audiorecording
Returns:
The audiorecording if found, None otherwise
@ -95,12 +96,12 @@ class AudioRecordingService:
AudioRecording.id == audio_recording_id
).first()
async def create(self, audio_recording_in: AudioRecordingCreate) -> AudioRecording:
async def create(self, audio_recording_in: Any) -> Any:
"""
Create a new audiorecording.
Args:
audio_recording_in: The audiorecording data to create
audio_recording_in: Any audiorecording data to create
Returns:
The created audiorecording
@ -134,14 +135,14 @@ class AudioRecordingService:
async def update(
self,
audio_recording_id: UUID,
audio_recording_in: AudioRecordingUpdate
audio_recording_in: Any
) -> Optional[AudioRecording]:
"""
Update an existing audiorecording.
Args:
audio_recording_id: The UUID of the audiorecording to update
audio_recording_in: The updated audiorecording data
audio_recording_id: Any UUID of the audiorecording to update
audio_recording_in: Any updated audiorecording data
Returns:
The updated audiorecording if found, None otherwise
@ -177,7 +178,7 @@ class AudioRecordingService:
Delete a audiorecording.
Args:
audio_recording_id: The UUID of the audiorecording to delete
audio_recording_id: Any UUID of the audiorecording to delete
Returns:
True if deleted, False if not found
@ -204,9 +205,9 @@ class AudioRecordingService:
Get all audiorecordings for a specific User.
Args:
user_id: The UUID of the User
skip: Number of records to skip
limit: Maximum records to return
user_id: Any UUID of the User
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of audiorecordings, total count)
@ -230,9 +231,9 @@ class AudioRecordingService:
Get all audiorecordings for a specific Patient.
Args:
patient_id: The UUID of the Patient
skip: Number of records to skip
limit: Maximum records to return
patient_id: Any UUID of the Patient
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of audiorecordings, total count)
@ -256,9 +257,9 @@ class AudioRecordingService:
Get all audiorecordings for a specific ProcedureTemplate.
Args:
procedure_template_id: The UUID of the ProcedureTemplate
skip: Number of records to skip
limit: Maximum records to return
procedure_template_id: Any UUID of the ProcedureTemplate
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of audiorecordings, total count)
@ -279,7 +280,7 @@ class AudioRecordingService:
@generated from DSL function
"""
# Auto-generated non-validation rule implementation
# MultiSessionConsolidationRule: Consolidate multi-day recordings per encounter
# MultiSessionConsolidationRule: Any multi-day recordings per encounter
if audio_recording.encounter_id is not None:
# Fetch related recordings with the same encounter_id
related_recordings = await audio_recording_service.find_by_condition(
@ -315,7 +316,7 @@ class AudioRecordingService:
@generated from DSL function
"""
# Auto-generated non-validation rule implementation
# EncryptionAtRestRule: AES-256 encryption for all PHI at rest
# EncryptionAtRestRule: Any-256 encryption for all PHI at rest
if not audiorecording.is_encrypted:
# Encrypt the audio file at the given file path
encrypted_data = AES256.encrypt(audiorecording.file_path)
@ -330,7 +331,7 @@ class AudioRecordingService:
encryption_key = AES256.generate_key_id()
audiorecording.encryption_key_id = encryption_key
async def validateAudioFormat(self, audio_recording_in: AudioRecordingCreate, existing: Optional[AudioRecording] = None) -> Any:
async def validateAudioFormat(self, audio_recording_in: Any, existing: Optional[AudioRecording] = None) -> Any:
"""
Support AAC, MP3, WAV formats only
@generated from DSL function
@ -346,13 +347,13 @@ class AudioRecordingService:
tenant_id = audio_recording_data.get('tenant_id')
version = audio_recording_data.get('version')
context = {'user': {'tenant_id': tenant_id}}
# AudioFormatValidationRule: Support AAC, MP3, WAV formats only
# AudioFormatValidationRule: Any AAC, MP3, WAV formats only
allowed_formats = ['AAC', 'MP3', 'WAV']
upper_format = audio_recording.file_format.upper()
if upper_format not in allowed_formats:
raise ValueError("Invalid audio format. Only AAC, MP3, and WAV formats are supported.")
async def requiresPatientAssociation(self, audio_recording_in: AudioRecordingCreate, existing: Optional[AudioRecording] = None) -> Any:
async def requiresPatientAssociation(self, audio_recording_in: Any, existing: Optional[AudioRecording] = None) -> Any:
"""
Recording must associate with patient MRN/encounter
@generated from DSL function
@ -368,11 +369,11 @@ class AudioRecordingService:
tenant_id = audio_recording_data.get('tenant_id')
version = audio_recording_data.get('version')
context = {'user': {'tenant_id': tenant_id}}
# PatientAssociationRule: Recording must associate with patient MRN/encounter
# PatientAssociationRule: Any must associate with patient MRN/encounter
if recording.patient_id is None and recording.encounter_id is None:
raise ValueError("Recording must be associated with either a patient (patient_id) or an encounter (encounter_id)")
async def shouldAutoUpload(self, audio_recording_in: AudioRecordingCreate, existing: Optional[AudioRecording] = None) -> Any:
async def shouldAutoUpload(self, audio_recording_in: Any, existing: Optional[AudioRecording] = None) -> Any:
"""
Auto-upload recordings when network available
@generated from DSL function
@ -395,7 +396,7 @@ class AudioRecordingService:
# If network is available, proceed with auto-upload logic
# The rule passes when network is available
async def allowMultipleRecordings(self, audio_recording_in: AudioRecordingCreate, existing: Optional[AudioRecording] = None) -> Any:
async def allowMultipleRecordings(self, audio_recording_in: Any, existing: Optional[AudioRecording] = None) -> Any:
"""
Support multiple recordings per encounter
@generated from DSL function
@ -411,7 +412,7 @@ class AudioRecordingService:
tenant_id = audio_recording_data.get('tenant_id')
version = audio_recording_data.get('version')
context = {'user': {'tenant_id': tenant_id}}
# TODO: Business rule code not generated. Run tertiary analysis to generate code using Claude.
# TODO: Any rule code not generated. Run tertiary analysis to generate code using Claude.
async def applyNoiseReduction(self) -> Any:
"""
@ -455,7 +456,7 @@ class AudioRecordingService:
await event_bus.emit("audio.uploaded", event_data)
# =========== Custom Service Methods ===========
async def find_one(self, _id: UUID) -> AudioRecording:
async def find_one(self, _id: UUID) -> Any:
"""
Get audio recording by ID
GET /api/v1/audio/recordings/{id}
@ -463,7 +464,7 @@ class AudioRecordingService:
# Custom method implementation
raise NotImplementedError(f"Method find_one not yet implemented")
async def upload_audio(self, _id: UUID, _in: Create) -> AudioRecording:
async def upload_audio(self, _id: UUID, _in: Any) -> Any:
"""
Upload audio file
POST /api/v1/audio/recordings/{id}/upload
@ -471,7 +472,7 @@ class AudioRecordingService:
# Custom method implementation
raise NotImplementedError(f"Method upload_audio not yet implemented")
async def download_audio(self, _id: UUID) -> AudioRecording:
async def download_audio(self, _id: UUID) -> Any:
"""
Download audio file
GET /api/v1/audio/recordings/{id}/download
@ -479,7 +480,7 @@ class AudioRecordingService:
# Custom method implementation
raise NotImplementedError(f"Method download_audio not yet implemented")
async def uploadAudio(self, _id: UUID, file: Any) -> AudioRecording:
async def uploadAudio(self, _id: UUID, file: Any) -> Any:
"""
Upload audio file
custom
@ -549,7 +550,7 @@ class AudioRecordingService:
"message": "Audio file uploaded successfully"
}
async def findByPatient(self, patient_id: Any) -> AudioRecording:
async def findByPatient(self, patient_id: Any) -> Any:
"""
Get recordings by patient
custom
@ -560,7 +561,7 @@ class AudioRecordingService:
recordings = result.scalars().all()
return list(recordings)
async def encryptAudio(self, file_path: Any) -> AudioRecording:
async def encryptAudio(self, file_path: Any) -> Any:
"""
Encrypt audio file AES-256
custom
@ -627,7 +628,7 @@ class AudioRecordingService:
return encrypted_file_path
async def validateFormat(self, format: Any) -> AudioRecording:
async def validateFormat(self, format: Any) -> Any:
"""
Validate audio format
custom
@ -637,10 +638,10 @@ class AudioRecordingService:
Validate audio format against supported formats.
Args:
format: Audio format string to validate
format: Any format string to validate
Returns:
bool: True if format is valid, False otherwise
bool: Any if format is valid, False otherwise
"""
# Define supported audio formats
supported_formats = {
@ -654,7 +655,7 @@ class AudioRecordingService:
# Check if format is in supported formats
return normalized_format in supported_formats
async def encrypt(self, file_path: Any, key_id: Any = None) -> AudioRecording:
async def encrypt(self, file_path: Any, key_id: Any = None) -> Any:
"""
Encrypt audio AES-256
custom
@ -721,7 +722,7 @@ class AudioRecordingService:
return encrypted_file_path
async def decrypt(self, file_path: Any, key_id: Any) -> AudioRecording:
async def decrypt(self, file_path: Any, key_id: Any) -> Any:
"""
Decrypt audio file
custom
@ -804,7 +805,7 @@ class AudioRecordingService:
detail=f"Failed to decrypt audio file: {str(e)}"
)
async def generateKey(self, ) -> AudioRecording:
async def generateKey(self, ) -> Any:
"""
Generate encryption key
custom
@ -817,11 +818,11 @@ class AudioRecordingService:
key_id = f"key_{uuid.uuid4().hex[:16]}"
# Return the encryption key
# Note: In production, this key should be stored securely in a key management service
# Note: Any production, this key should be stored securely in a key management service
# and only the key_id should be stored in the database
return encryption_key
async def rotateKey(self, old_key_id: Any) -> AudioRecording:
async def rotateKey(self, old_key_id: Any) -> Any:
"""
Rotate encryption key
custom
@ -864,7 +865,7 @@ class AudioRecordingService:
return new_key_id
async def upload(self, file: Any, recording_id: Any) -> AudioRecording:
async def upload(self, file: Any, recording_id: Any) -> Any:
"""
Upload audio file
custom
@ -941,7 +942,7 @@ class AudioRecordingService:
"message": "Audio file uploaded successfully"
}
async def validateFile(self, file: Any, format: Any) -> AudioRecording:
async def validateFile(self, file: Any, format: Any) -> Any:
"""
Validate audio file
custom
@ -1003,7 +1004,7 @@ class AudioRecordingService:
except Exception as e:
return False
async def getUploadUrl(self, recording_id: Any) -> AudioRecording:
async def getUploadUrl(self, recording_id: Any) -> Any:
"""
Get presigned upload URL
custom
@ -1058,7 +1059,7 @@ class AudioRecordingService:
detail=f"Failed to generate presigned URL: {str(e)}"
)
async def processUpload(self, recording_id: Any) -> AudioRecording:
async def processUpload(self, recording_id: Any) -> Any:
"""
Process uploaded file
custom
@ -1144,7 +1145,7 @@ class AudioRecordingService:
)
# =========== Query Methods (findBy*) ===========
async def find_by_encounter_id(self, encounter_id: str) -> List[AudioRecording]:
async def find_by_encounter_id(self, encounter_id: str) -> List[Any]:
"""
Find audiorecordings by encounter_id
"""
@ -1152,7 +1153,7 @@ class AudioRecordingService:
getattr(AudioRecording, "encounter_id") == encounter_id
).all()
async def find_by_file_path(self, file_path: str) -> List[AudioRecording]:
async def find_by_file_path(self, file_path: str) -> List[Any]:
"""
Find audiorecordings by file_path
"""
@ -1160,7 +1161,7 @@ class AudioRecordingService:
getattr(AudioRecording, "file_path") == file_path
).all()
async def find_by_file_name(self, file_name: str) -> List[AudioRecording]:
async def find_by_file_name(self, file_name: str) -> List[Any]:
"""
Find audiorecordings by file_name
"""
@ -1168,7 +1169,7 @@ class AudioRecordingService:
getattr(AudioRecording, "file_name") == file_name
).all()
async def find_by_file_format(self, file_format: str) -> List[AudioRecording]:
async def find_by_file_format(self, file_format: str) -> List[Any]:
"""
Find audiorecordings by file_format
"""
@ -1176,7 +1177,7 @@ class AudioRecordingService:
getattr(AudioRecording, "file_format") == file_format
).all()
async def find_by_file_size_bytes(self, file_size_bytes: int) -> List[AudioRecording]:
async def find_by_file_size_bytes(self, file_size_bytes: int) -> List[Any]:
"""
Find audiorecordings by file_size_bytes
"""
@ -1184,7 +1185,7 @@ class AudioRecordingService:
getattr(AudioRecording, "file_size_bytes") == file_size_bytes
).all()
async def find_by_duration_seconds(self, duration_seconds: int) -> List[AudioRecording]:
async def find_by_duration_seconds(self, duration_seconds: int) -> List[Any]:
"""
Find audiorecordings by duration_seconds
"""
@ -1192,7 +1193,7 @@ class AudioRecordingService:
getattr(AudioRecording, "duration_seconds") == duration_seconds
).all()
async def find_by_recording_date(self, recording_date: datetime) -> List[AudioRecording]:
async def find_by_recording_date(self, recording_date: datetime) -> List[Any]:
"""
Find audiorecordings by recording_date
"""
@ -1200,7 +1201,7 @@ class AudioRecordingService:
getattr(AudioRecording, "recording_date") == recording_date
).all()
async def find_by_upload_date(self, upload_date: datetime) -> List[AudioRecording]:
async def find_by_upload_date(self, upload_date: datetime) -> List[Any]:
"""
Find audiorecordings by upload_date
"""
@ -1208,7 +1209,7 @@ class AudioRecordingService:
getattr(AudioRecording, "upload_date") == upload_date
).all()
async def find_by_is_encrypted(self, is_encrypted: bool) -> List[AudioRecording]:
async def find_by_is_encrypted(self, is_encrypted: bool) -> List[Any]:
"""
Find audiorecordings by is_encrypted
"""
@ -1216,7 +1217,7 @@ class AudioRecordingService:
getattr(AudioRecording, "is_encrypted") == is_encrypted
).all()
async def find_by_encryption_key_id(self, encryption_key_id: str) -> List[AudioRecording]:
async def find_by_encryption_key_id(self, encryption_key_id: str) -> List[Any]:
"""
Find audiorecordings by encryption_key_id
"""
@ -1224,7 +1225,7 @@ class AudioRecordingService:
getattr(AudioRecording, "encryption_key_id") == encryption_key_id
).all()
async def find_by_status(self, status: str) -> List[AudioRecording]:
async def find_by_status(self, status: str) -> List[Any]:
"""
Find audiorecordings by status
"""
@ -1232,7 +1233,7 @@ class AudioRecordingService:
getattr(AudioRecording, "status") == status
).all()
async def find_by_device_info(self, device_info: Dict[str, Any]) -> List[AudioRecording]:
async def find_by_device_info(self, device_info: Dict[str, Any]) -> List[Any]:
"""
Find audiorecordings by device_info
"""
@ -1240,7 +1241,7 @@ class AudioRecordingService:
getattr(AudioRecording, "device_info") == device_info
).all()
async def find_by_noise_level(self, noise_level: str) -> List[AudioRecording]:
async def find_by_noise_level(self, noise_level: str) -> List[Any]:
"""
Find audiorecordings by noise_level
"""
@ -1248,7 +1249,7 @@ class AudioRecordingService:
getattr(AudioRecording, "noise_level") == noise_level
).all()
async def find_by_is_template_based(self, is_template_based: bool) -> List[AudioRecording]:
async def find_by_is_template_based(self, is_template_based: bool) -> List[Any]:
"""
Find audiorecordings by is_template_based
"""
@ -1256,7 +1257,7 @@ class AudioRecordingService:
getattr(AudioRecording, "is_template_based") == is_template_based
).all()
async def find_by_created_at(self, created_at: datetime) -> List[AudioRecording]:
async def find_by_created_at(self, created_at: datetime) -> List[Any]:
"""
Find audiorecordings by created_at
"""
@ -1264,7 +1265,7 @@ class AudioRecordingService:
getattr(AudioRecording, "created_at") == created_at
).all()
async def find_by_updated_at(self, updated_at: datetime) -> List[AudioRecording]:
async def find_by_updated_at(self, updated_at: datetime) -> List[Any]:
"""
Find audiorecordings by updated_at
"""
@ -1273,7 +1274,7 @@ class AudioRecordingService:
).all()
# =========== Relationship Methods ===========
async def get_by_user_id(self, audio_recording_id: UUID) -> User:
async def get_by_user_id(self, audio_recording_id: UUID) -> Any:
"""
Get the user for this audiorecording
"""
@ -1288,7 +1289,7 @@ class AudioRecordingService:
).first()
return None
async def get_by_patient_id(self, audio_recording_id: UUID) -> Patient:
async def get_by_patient_id(self, audio_recording_id: UUID) -> Any:
"""
Get the patient for this audiorecording
"""
@ -1303,7 +1304,7 @@ class AudioRecordingService:
).first()
return None
async def get_by_template_id(self, audio_recording_id: UUID) -> ProcedureTemplate:
async def get_by_template_id(self, audio_recording_id: UUID) -> Any:
"""
Get the proceduretemplate for this audiorecording
"""
@ -1318,7 +1319,7 @@ class AudioRecordingService:
).first()
return None
async def get_by_audio_recording_id(self, audio_recording_id: UUID) -> Transcript:
async def get_by_audio_recording_id(self, audio_recording_id: UUID) -> Any:
"""
Get the transcript for this audiorecording
"""

View File

@ -1,7 +1,8 @@
from datetime import date, datetime
"""
AuditLog Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -14,7 +15,7 @@ from src.validation.audit_log_schemas import AuditLogCreate, AuditLogUpdate
logger = logging.getLogger(__name__)
class AuditLogService:
class AuditLogCRUD:
"""
Service class for AuditLog business logic.
@ -22,7 +23,7 @@ class AuditLogService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
@ -38,11 +39,11 @@ class AuditLogService:
Get all auditlogs with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of auditlogs, total count)
@ -85,7 +86,7 @@ class AuditLogService:
Get a specific auditlog by ID.
Args:
audit_log_id: The UUID of the auditlog
audit_log_id: Any UUID of the auditlog
Returns:
The auditlog if found, None otherwise
@ -95,12 +96,12 @@ class AuditLogService:
AuditLog.id == audit_log_id
).first()
async def create(self, audit_log_in: AuditLogCreate) -> AuditLog:
async def create(self, audit_log_in: Any) -> Any:
"""
Create a new auditlog.
Args:
audit_log_in: The auditlog data to create
audit_log_in: Any auditlog data to create
Returns:
The created auditlog
@ -128,14 +129,14 @@ class AuditLogService:
async def update(
self,
audit_log_id: UUID,
audit_log_in: AuditLogUpdate
audit_log_in: Any
) -> Optional[AuditLog]:
"""
Update an existing auditlog.
Args:
audit_log_id: The UUID of the auditlog to update
audit_log_in: The updated auditlog data
audit_log_id: Any UUID of the auditlog to update
audit_log_in: Any updated auditlog data
Returns:
The updated auditlog if found, None otherwise
@ -163,7 +164,7 @@ class AuditLogService:
Delete a auditlog.
Args:
audit_log_id: The UUID of the auditlog to delete
audit_log_id: Any UUID of the auditlog to delete
Returns:
True if deleted, False if not found
@ -190,9 +191,9 @@ class AuditLogService:
Get all auditlogs for a specific User.
Args:
user_id: The UUID of the User
skip: Number of records to skip
limit: Maximum records to return
user_id: Any UUID of the User
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of auditlogs, total count)
@ -276,7 +277,7 @@ class AuditLogService:
await event_bus.emit("phi.accessed", event_data)
# =========== Custom Service Methods ===========
async def find_one(self, _id: UUID) -> AuditLog:
async def find_one(self, _id: UUID) -> Any:
"""
Get audit log by ID
GET /api/v1/audit/logs/{id}
@ -284,7 +285,7 @@ class AuditLogService:
# Custom method implementation
raise NotImplementedError(f"Method find_one not yet implemented")
async def get_entity_history(self, entity_type: Any, entity_id: Any) -> List[AuditLog]:
async def get_entity_history(self, entity_type: Any, entity_id: Any) -> List[Any]:
"""
Get entity audit history
GET /api/v1/audit/logs/entity/{entity_type}/{entity_id}
@ -292,7 +293,7 @@ class AuditLogService:
# Custom method implementation
raise NotImplementedError(f"Method get_entity_history not yet implemented")
async def get_user_activity(self, user_id: Any, date_from: Any, date_to: Any) -> List[AuditLog]:
async def get_user_activity(self, user_id: Any, date_from: Any, date_to: Any) -> List[Any]:
"""
Get user activity
GET /api/v1/audit/logs/user/{user_id}
@ -300,7 +301,7 @@ class AuditLogService:
# Custom method implementation
raise NotImplementedError(f"Method get_user_activity not yet implemented")
async def export_logs(self, _in: Create) -> AuditLog:
async def export_logs(self, _in: Any) -> Any:
"""
Export audit logs
POST /api/v1/audit/logs/export
@ -308,7 +309,7 @@ class AuditLogService:
# Custom method implementation
raise NotImplementedError(f"Method export_logs not yet implemented")
async def exportLogs(self, filters: Any, format: Any) -> AuditLog:
async def exportLogs(self, filters: Any, format: Any) -> Any:
"""
Export audit logs
custom
@ -414,7 +415,7 @@ class AuditLogService:
else:
raise HTTPException(status_code=400, detail=f"Unsupported export format: {format}")
async def findByUser(self, user_id: Any, skip: Any = 0, take: Any = 10) -> AuditLog:
async def findByUser(self, user_id: Any, skip: Any = 0, take: Any = 10) -> Any:
"""
Get logs by user
custom
@ -425,7 +426,7 @@ class AuditLogService:
audit_logs = result.scalars().all()
return audit_logs
async def findByEntity(self, entity_type: Any, entity_id: Any) -> AuditLog:
async def findByEntity(self, entity_type: Any, entity_id: Any) -> Any:
"""
Get logs by entity
custom
@ -441,7 +442,7 @@ class AuditLogService:
return list(audit_logs)
async def findPHIAccess(self, date_from: Any = None, date_to: Any = None) -> AuditLog:
async def findPHIAccess(self, date_from: Any = None, date_to: Any = None) -> Any:
"""
Get PHI access logs
custom
@ -464,7 +465,7 @@ class AuditLogService:
return list(audit_logs)
async def findByDateRange(self, start_date: Any, end_date: Any) -> AuditLog:
async def findByDateRange(self, start_date: Any, end_date: Any) -> Any:
"""
Get logs by date range
custom
@ -486,7 +487,7 @@ class AuditLogService:
return list(audit_logs)
# =========== Query Methods (findBy*) ===========
async def find_by_entity_type(self, entity_type: str) -> List[AuditLog]:
async def find_by_entity_type(self, entity_type: str) -> List[Any]:
"""
Find auditlogs by entity_type
"""
@ -494,7 +495,7 @@ class AuditLogService:
getattr(AuditLog, "entity_type") == entity_type
).all()
async def find_by_entity_id(self, entity_id: UUID) -> List[AuditLog]:
async def find_by_entity_id(self, entity_id: UUID) -> List[Any]:
"""
Find auditlogs by entity_id
"""
@ -502,7 +503,7 @@ class AuditLogService:
getattr(AuditLog, "entity_id") == entity_id
).all()
async def find_by_action(self, action: str) -> List[AuditLog]:
async def find_by_action(self, action: str) -> List[Any]:
"""
Find auditlogs by action
"""
@ -510,7 +511,7 @@ class AuditLogService:
getattr(AuditLog, "action") == action
).all()
async def find_by_action_category(self, action_category: str) -> List[AuditLog]:
async def find_by_action_category(self, action_category: str) -> List[Any]:
"""
Find auditlogs by action_category
"""
@ -518,7 +519,7 @@ class AuditLogService:
getattr(AuditLog, "action_category") == action_category
).all()
async def find_by_old_values(self, old_values: Dict[str, Any]) -> List[AuditLog]:
async def find_by_old_values(self, old_values: Dict[str, Any]) -> List[Any]:
"""
Find auditlogs by old_values
"""
@ -526,7 +527,7 @@ class AuditLogService:
getattr(AuditLog, "old_values") == old_values
).all()
async def find_by_new_values(self, new_values: Dict[str, Any]) -> List[AuditLog]:
async def find_by_new_values(self, new_values: Dict[str, Any]) -> List[Any]:
"""
Find auditlogs by new_values
"""
@ -534,7 +535,7 @@ class AuditLogService:
getattr(AuditLog, "new_values") == new_values
).all()
async def find_by_changes_summary(self, changes_summary: str) -> List[AuditLog]:
async def find_by_changes_summary(self, changes_summary: str) -> List[Any]:
"""
Find auditlogs by changes_summary
"""
@ -542,7 +543,7 @@ class AuditLogService:
getattr(AuditLog, "changes_summary") == changes_summary
).all()
async def find_by_ip_address(self, ip_address: str) -> List[AuditLog]:
async def find_by_ip_address(self, ip_address: str) -> List[Any]:
"""
Find auditlogs by ip_address
"""
@ -550,7 +551,7 @@ class AuditLogService:
getattr(AuditLog, "ip_address") == ip_address
).all()
async def find_by_user_agent(self, user_agent: str) -> List[AuditLog]:
async def find_by_user_agent(self, user_agent: str) -> List[Any]:
"""
Find auditlogs by user_agent
"""
@ -558,7 +559,7 @@ class AuditLogService:
getattr(AuditLog, "user_agent") == user_agent
).all()
async def find_by_session_id(self, session_id: str) -> List[AuditLog]:
async def find_by_session_id(self, session_id: str) -> List[Any]:
"""
Find auditlogs by session_id
"""
@ -566,7 +567,7 @@ class AuditLogService:
getattr(AuditLog, "session_id") == session_id
).all()
async def find_by_request_id(self, request_id: str) -> List[AuditLog]:
async def find_by_request_id(self, request_id: str) -> List[Any]:
"""
Find auditlogs by request_id
"""
@ -574,7 +575,7 @@ class AuditLogService:
getattr(AuditLog, "request_id") == request_id
).all()
async def find_by_status(self, status: str) -> List[AuditLog]:
async def find_by_status(self, status: str) -> List[Any]:
"""
Find auditlogs by status
"""
@ -582,7 +583,7 @@ class AuditLogService:
getattr(AuditLog, "status") == status
).all()
async def find_by_error_message(self, error_message: str) -> List[AuditLog]:
async def find_by_error_message(self, error_message: str) -> List[Any]:
"""
Find auditlogs by error_message
"""
@ -590,7 +591,7 @@ class AuditLogService:
getattr(AuditLog, "error_message") == error_message
).all()
async def find_by_metadata(self, metadata: Dict[str, Any]) -> List[AuditLog]:
async def find_by_metadata(self, metadata: Dict[str, Any]) -> List[Any]:
"""
Find auditlogs by metadata
"""
@ -598,7 +599,7 @@ class AuditLogService:
getattr(AuditLog, "metadata") == metadata
).all()
async def find_by_phi_accessed(self, phi_accessed: bool) -> List[AuditLog]:
async def find_by_phi_accessed(self, phi_accessed: bool) -> List[Any]:
"""
Find auditlogs by phi_accessed
"""
@ -606,7 +607,7 @@ class AuditLogService:
getattr(AuditLog, "phi_accessed") == phi_accessed
).all()
async def find_by_compliance_flag(self, compliance_flag: bool) -> List[AuditLog]:
async def find_by_compliance_flag(self, compliance_flag: bool) -> List[Any]:
"""
Find auditlogs by compliance_flag
"""
@ -614,7 +615,7 @@ class AuditLogService:
getattr(AuditLog, "compliance_flag") == compliance_flag
).all()
async def find_by_created_at(self, created_at: Any) -> List[AuditLog]:
async def find_by_created_at(self, created_at: Any) -> List[Any]:
"""
Find auditlogs by created_at
"""
@ -623,7 +624,7 @@ class AuditLogService:
).all()
# =========== Relationship Methods ===========
async def get_by_user_id(self, audit_log_id: UUID) -> User:
async def get_by_user_id(self, audit_log_id: UUID) -> Any:
"""
Get the user for this auditlog
"""

View File

@ -1,7 +1,8 @@
from datetime import date, datetime
"""
ClaimReview Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -14,7 +15,7 @@ from src.validation.claim_review_schemas import ClaimReviewCreate, ClaimReviewUp
logger = logging.getLogger(__name__)
class ClaimReviewService:
class ClaimReviewCRUD:
"""
Service class for ClaimReview business logic.
@ -22,7 +23,7 @@ class ClaimReviewService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
@ -38,11 +39,11 @@ class ClaimReviewService:
Get all claimreviews with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of claimreviews, total count)
@ -85,7 +86,7 @@ class ClaimReviewService:
Get a specific claimreview by ID.
Args:
claim_review_id: The UUID of the claimreview
claim_review_id: Any UUID of the claimreview
Returns:
The claimreview if found, None otherwise
@ -95,12 +96,12 @@ class ClaimReviewService:
ClaimReview.id == claim_review_id
).first()
async def create(self, claim_review_in: ClaimReviewCreate) -> ClaimReview:
async def create(self, claim_review_in: Any) -> Any:
"""
Create a new claimreview.
Args:
claim_review_in: The claimreview data to create
claim_review_in: Any claimreview data to create
Returns:
The created claimreview
@ -125,14 +126,14 @@ class ClaimReviewService:
async def update(
self,
claim_review_id: UUID,
claim_review_in: ClaimReviewUpdate
claim_review_in: Any
) -> Optional[ClaimReview]:
"""
Update an existing claimreview.
Args:
claim_review_id: The UUID of the claimreview to update
claim_review_in: The updated claimreview data
claim_review_id: Any UUID of the claimreview to update
claim_review_in: Any updated claimreview data
Returns:
The updated claimreview if found, None otherwise
@ -163,7 +164,7 @@ class ClaimReviewService:
Delete a claimreview.
Args:
claim_review_id: The UUID of the claimreview to delete
claim_review_id: Any UUID of the claimreview to delete
Returns:
True if deleted, False if not found
@ -190,9 +191,9 @@ class ClaimReviewService:
Get all claimreviews for a specific Claim.
Args:
claim_id: The UUID of the Claim
skip: Number of records to skip
limit: Maximum records to return
claim_id: Any UUID of the Claim
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of claimreviews, total count)
@ -216,9 +217,9 @@ class ClaimReviewService:
Get all claimreviews for a specific User.
Args:
user_id: The UUID of the User
skip: Number of records to skip
limit: Maximum records to return
user_id: Any UUID of the User
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of claimreviews, total count)
@ -242,9 +243,9 @@ class ClaimReviewService:
Get all claimreviews for a specific User.
Args:
user_id: The UUID of the User
skip: Number of records to skip
limit: Maximum records to return
user_id: Any UUID of the User
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of claimreviews, total count)
@ -327,7 +328,7 @@ class ClaimReviewService:
await event_bus.emit("review.completed", event_data)
# =========== Custom Service Methods ===========
async def find_one(self, _id: UUID) -> ClaimReview:
async def find_one(self, _id: UUID) -> Any:
"""
Get review by ID
GET /api/v1/reviews/{id}
@ -335,7 +336,7 @@ class ClaimReviewService:
# Custom method implementation
raise NotImplementedError(f"Method find_one not yet implemented")
async def approve(self, _id: UUID, notes: Any, approved_codes: Any) -> ClaimReview:
async def approve(self, _id: UUID, notes: Any, approved_codes: Any) -> Any:
"""
Approve review
POST /api/v1/reviews/{id}/approve
@ -370,7 +371,7 @@ class ClaimReviewService:
return claim_review
async def reject(self, _id: UUID, reason: Any, notes: Any, corrective_actions: Any) -> ClaimReview:
async def reject(self, _id: UUID, reason: Any, notes: Any, corrective_actions: Any) -> Any:
"""
Reject review
POST /api/v1/reviews/{id}/reject
@ -398,7 +399,7 @@ class ClaimReviewService:
return claim_review
async def escalate(self, _id: UUID, escalate_to: Any, reason: Any) -> ClaimReview:
async def escalate(self, _id: UUID, escalate_to: Any, reason: Any) -> Any:
"""
Escalate review
POST /api/v1/reviews/{id}/escalate
@ -436,7 +437,7 @@ class ClaimReviewService:
return claim_review
async def get_queue(self, assigned_to: Any, priority: Any) -> List[ClaimReview]:
async def get_queue(self, assigned_to: Any, priority: Any) -> List[Any]:
"""
Get review queue
GET /api/v1/reviews/queue
@ -444,7 +445,7 @@ class ClaimReviewService:
# Custom method implementation
raise NotImplementedError(f"Method get_queue not yet implemented")
async def findByReviewer(self, reviewer_id: Any) -> ClaimReview:
async def findByReviewer(self, reviewer_id: Any) -> Any:
"""
Get reviews by reviewer
custom
@ -455,7 +456,7 @@ class ClaimReviewService:
reviews = result.scalars().all()
return reviews
async def findPendingReviews(self, skip: Any = 0, take: Any = 10) -> ClaimReview:
async def findPendingReviews(self, skip: Any = 0, take: Any = 10) -> Any:
"""
Get pending reviews
custom
@ -471,7 +472,7 @@ class ClaimReviewService:
return claim_reviews
# =========== Query Methods (findBy*) ===========
async def find_by_review_status(self, review_status: str) -> List[ClaimReview]:
async def find_by_review_status(self, review_status: str) -> List[Any]:
"""
Find claimreviews by review_status
"""
@ -479,7 +480,7 @@ class ClaimReviewService:
getattr(ClaimReview, "review_status") == review_status
).all()
async def find_by_review_type(self, review_type: str) -> List[ClaimReview]:
async def find_by_review_type(self, review_type: str) -> List[Any]:
"""
Find claimreviews by review_type
"""
@ -487,7 +488,7 @@ class ClaimReviewService:
getattr(ClaimReview, "review_type") == review_type
).all()
async def find_by_confidence_threshold_triggered(self, confidence_threshold_triggered: bool) -> List[ClaimReview]:
async def find_by_confidence_threshold_triggered(self, confidence_threshold_triggered: bool) -> List[Any]:
"""
Find claimreviews by confidence_threshold_triggered
"""
@ -495,7 +496,7 @@ class ClaimReviewService:
getattr(ClaimReview, "confidence_threshold_triggered") == confidence_threshold_triggered
).all()
async def find_by_original_icd10_codes(self, original_icd10_codes: Dict[str, Any]) -> List[ClaimReview]:
async def find_by_original_icd10_codes(self, original_icd10_codes: Dict[str, Any]) -> List[Any]:
"""
Find claimreviews by original_icd10_codes
"""
@ -503,7 +504,7 @@ class ClaimReviewService:
getattr(ClaimReview, "original_icd10_codes") == original_icd10_codes
).all()
async def find_by_original_cpt_codes(self, original_cpt_codes: Dict[str, Any]) -> List[ClaimReview]:
async def find_by_original_cpt_codes(self, original_cpt_codes: Dict[str, Any]) -> List[Any]:
"""
Find claimreviews by original_cpt_codes
"""
@ -511,7 +512,7 @@ class ClaimReviewService:
getattr(ClaimReview, "original_cpt_codes") == original_cpt_codes
).all()
async def find_by_revised_icd10_codes(self, revised_icd10_codes: Dict[str, Any]) -> List[ClaimReview]:
async def find_by_revised_icd10_codes(self, revised_icd10_codes: Dict[str, Any]) -> List[Any]:
"""
Find claimreviews by revised_icd10_codes
"""
@ -519,7 +520,7 @@ class ClaimReviewService:
getattr(ClaimReview, "revised_icd10_codes") == revised_icd10_codes
).all()
async def find_by_revised_cpt_codes(self, revised_cpt_codes: Dict[str, Any]) -> List[ClaimReview]:
async def find_by_revised_cpt_codes(self, revised_cpt_codes: Dict[str, Any]) -> List[Any]:
"""
Find claimreviews by revised_cpt_codes
"""
@ -527,7 +528,7 @@ class ClaimReviewService:
getattr(ClaimReview, "revised_cpt_codes") == revised_cpt_codes
).all()
async def find_by_reviewer_notes(self, reviewer_notes: str) -> List[ClaimReview]:
async def find_by_reviewer_notes(self, reviewer_notes: str) -> List[Any]:
"""
Find claimreviews by reviewer_notes
"""
@ -535,7 +536,7 @@ class ClaimReviewService:
getattr(ClaimReview, "reviewer_notes") == reviewer_notes
).all()
async def find_by_flagged_issues(self, flagged_issues: Dict[str, Any]) -> List[ClaimReview]:
async def find_by_flagged_issues(self, flagged_issues: Dict[str, Any]) -> List[Any]:
"""
Find claimreviews by flagged_issues
"""
@ -543,7 +544,7 @@ class ClaimReviewService:
getattr(ClaimReview, "flagged_issues") == flagged_issues
).all()
async def find_by_corrective_actions(self, corrective_actions: Dict[str, Any]) -> List[ClaimReview]:
async def find_by_corrective_actions(self, corrective_actions: Dict[str, Any]) -> List[Any]:
"""
Find claimreviews by corrective_actions
"""
@ -551,7 +552,7 @@ class ClaimReviewService:
getattr(ClaimReview, "corrective_actions") == corrective_actions
).all()
async def find_by_review_duration_seconds(self, review_duration_seconds: int) -> List[ClaimReview]:
async def find_by_review_duration_seconds(self, review_duration_seconds: int) -> List[Any]:
"""
Find claimreviews by review_duration_seconds
"""
@ -559,7 +560,7 @@ class ClaimReviewService:
getattr(ClaimReview, "review_duration_seconds") == review_duration_seconds
).all()
async def find_by_escalation_reason(self, escalation_reason: str) -> List[ClaimReview]:
async def find_by_escalation_reason(self, escalation_reason: str) -> List[Any]:
"""
Find claimreviews by escalation_reason
"""
@ -567,7 +568,7 @@ class ClaimReviewService:
getattr(ClaimReview, "escalation_reason") == escalation_reason
).all()
async def find_by_escalated_at(self, escalated_at: datetime) -> List[ClaimReview]:
async def find_by_escalated_at(self, escalated_at: datetime) -> List[Any]:
"""
Find claimreviews by escalated_at
"""
@ -575,7 +576,7 @@ class ClaimReviewService:
getattr(ClaimReview, "escalated_at") == escalated_at
).all()
async def find_by_reviewed_at(self, reviewed_at: datetime) -> List[ClaimReview]:
async def find_by_reviewed_at(self, reviewed_at: datetime) -> List[Any]:
"""
Find claimreviews by reviewed_at
"""
@ -583,7 +584,7 @@ class ClaimReviewService:
getattr(ClaimReview, "reviewed_at") == reviewed_at
).all()
async def find_by_created_at(self, created_at: Any) -> List[ClaimReview]:
async def find_by_created_at(self, created_at: Any) -> List[Any]:
"""
Find claimreviews by created_at
"""
@ -591,7 +592,7 @@ class ClaimReviewService:
getattr(ClaimReview, "created_at") == created_at
).all()
async def find_by_updated_at(self, updated_at: Any) -> List[ClaimReview]:
async def find_by_updated_at(self, updated_at: Any) -> List[Any]:
"""
Find claimreviews by updated_at
"""
@ -600,7 +601,7 @@ class ClaimReviewService:
).all()
# =========== Relationship Methods ===========
async def get_by_claim_id(self, claim_review_id: UUID) -> Claim:
async def get_by_claim_id(self, claim_review_id: UUID) -> Any:
"""
Get the claim for this claimreview
"""
@ -615,7 +616,7 @@ class ClaimReviewService:
).first()
return None
async def get_by_reviewer_id(self, claim_review_id: UUID) -> User:
async def get_by_reviewer_id(self, claim_review_id: UUID) -> Any:
"""
Get the user for this claimreview
"""
@ -630,7 +631,7 @@ class ClaimReviewService:
).first()
return None
async def get_by_escalated_to_id(self, claim_review_id: UUID) -> User:
async def get_by_escalated_to_id(self, claim_review_id: UUID) -> Any:
"""
Get the user for this claimreview
"""

View File

@ -1,7 +1,8 @@
from datetime import date, datetime
"""
ClaimScrubResult Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -14,7 +15,7 @@ from src.validation.claim_scrub_result_schemas import ClaimScrubResultCreate, Cl
logger = logging.getLogger(__name__)
class ClaimScrubResultService:
class ClaimScrubResultCRUD:
"""
Service class for ClaimScrubResult business logic.
@ -22,7 +23,7 @@ class ClaimScrubResultService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
@ -38,11 +39,11 @@ class ClaimScrubResultService:
Get all claimscrubresults with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of claimscrubresults, total count)
@ -85,7 +86,7 @@ class ClaimScrubResultService:
Get a specific claimscrubresult by ID.
Args:
claim_scrub_result_id: The UUID of the claimscrubresult
claim_scrub_result_id: Any UUID of the claimscrubresult
Returns:
The claimscrubresult if found, None otherwise
@ -95,12 +96,12 @@ class ClaimScrubResultService:
ClaimScrubResult.id == claim_scrub_result_id
).first()
async def create(self, claim_scrub_result_in: ClaimScrubResultCreate) -> ClaimScrubResult:
async def create(self, claim_scrub_result_in: Any) -> Any:
"""
Create a new claimscrubresult.
Args:
claim_scrub_result_in: The claimscrubresult data to create
claim_scrub_result_in: Any claimscrubresult data to create
Returns:
The created claimscrubresult
@ -130,14 +131,14 @@ class ClaimScrubResultService:
async def update(
self,
claim_scrub_result_id: UUID,
claim_scrub_result_in: ClaimScrubResultUpdate
claim_scrub_result_in: Any
) -> Optional[ClaimScrubResult]:
"""
Update an existing claimscrubresult.
Args:
claim_scrub_result_id: The UUID of the claimscrubresult to update
claim_scrub_result_in: The updated claimscrubresult data
claim_scrub_result_id: Any UUID of the claimscrubresult to update
claim_scrub_result_in: Any updated claimscrubresult data
Returns:
The updated claimscrubresult if found, None otherwise
@ -168,7 +169,7 @@ class ClaimScrubResultService:
Delete a claimscrubresult.
Args:
claim_scrub_result_id: The UUID of the claimscrubresult to delete
claim_scrub_result_id: Any UUID of the claimscrubresult to delete
Returns:
True if deleted, False if not found
@ -195,9 +196,9 @@ class ClaimScrubResultService:
Get all claimscrubresults for a specific Claim.
Args:
claim_id: The UUID of the Claim
skip: Number of records to skip
limit: Maximum records to return
claim_id: Any UUID of the Claim
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of claimscrubresults, total count)
@ -212,7 +213,7 @@ class ClaimScrubResultService:
return items, total
# =========== BLS Business Rules ===========
async def scrubClaimWithRAG(self, claim_scrub_result_in: ClaimScrubResultCreate, existing: Optional[ClaimScrubResult] = None) -> Any:
async def scrubClaimWithRAG(self, claim_scrub_result_in: Any, existing: Optional[ClaimScrubResult] = None) -> Any:
"""
Scrub claims against payer rules using RAG
@generated from DSL function
@ -261,7 +262,7 @@ class ClaimScrubResultService:
claimScrubResult.requires_manual_review = scrubResult.requires_manual_review
claimScrubResult.review_priority = scrubResult.review_priority
async def validateNCCIEdits(self, claim_scrub_result_in: ClaimScrubResultCreate, existing: Optional[ClaimScrubResult] = None) -> Any:
async def validateNCCIEdits(self, claim_scrub_result_in: Any, existing: Optional[ClaimScrubResult] = None) -> Any:
"""
Validate claims against NCCI edits
@generated from DSL function
@ -310,7 +311,7 @@ class ClaimScrubResultService:
if len(ncci_violations) > 0:
claim_scrub_result.failed_checks = claim_scrub_result.failed_checks + len(ncci_violations)
async def validateCoverageDeterminations(self, claim_scrub_result_in: ClaimScrubResultCreate, existing: Optional[ClaimScrubResult] = None) -> Any:
async def validateCoverageDeterminations(self, claim_scrub_result_in: Any, existing: Optional[ClaimScrubResult] = None) -> Any:
"""
Validate against LCD/NCD coverage determinations
@generated from DSL function
@ -375,7 +376,7 @@ class ClaimScrubResultService:
claim_scrub_result.requires_manual_review = True
claim_scrub_result.overall_risk_level = "HIGH"
async def flagFailures(self, claim_scrub_result_in: ClaimScrubResultCreate, existing: Optional[ClaimScrubResult] = None) -> Any:
async def flagFailures(self, claim_scrub_result_in: Any, existing: Optional[ClaimScrubResult] = None) -> Any:
"""
Flag claim failures with corrective actions
@generated from DSL function
@ -464,7 +465,7 @@ class ClaimScrubResultService:
await event_bus.emit("claim.scrubbed", event_data)
# =========== Custom Service Methods ===========
async def scrub_claim(self, _in: Create) -> ClaimScrubResult:
async def scrub_claim(self, _in: Any) -> Any:
"""
Scrub claim against rules
POST /api/v1/claims/scrub
@ -472,7 +473,7 @@ class ClaimScrubResultService:
# Custom method implementation
raise NotImplementedError(f"Method scrub_claim not yet implemented")
async def get_scrub_result(self, _id: UUID) -> ClaimScrubResult:
async def get_scrub_result(self, _id: UUID) -> Any:
"""
Get scrub result
GET /api/v1/claims/scrub/{id}
@ -480,7 +481,7 @@ class ClaimScrubResultService:
# Custom method implementation
raise NotImplementedError(f"Method get_scrub_result not yet implemented")
async def rerun_scrub(self, _id: UUID) -> ClaimScrubResult:
async def rerun_scrub(self, _id: UUID) -> Any:
"""
Rerun claim scrubbing
POST /api/v1/claims/scrub/{id}/rerun
@ -488,7 +489,7 @@ class ClaimScrubResultService:
# Custom method implementation
raise NotImplementedError(f"Method rerun_scrub not yet implemented")
async def validate_ncci(self, _in: Create) -> ClaimScrubResult:
async def validate_ncci(self, _in: Any) -> Any:
"""
Validate NCCI edits
POST /api/v1/claims/validate/ncci
@ -496,7 +497,7 @@ class ClaimScrubResultService:
# Custom method implementation
raise NotImplementedError(f"Method validate_ncci not yet implemented")
async def validate_lcd(self, _in: Create) -> ClaimScrubResult:
async def validate_lcd(self, _in: Any) -> Any:
"""
Validate LCD coverage
POST /api/v1/claims/validate/lcd
@ -504,7 +505,7 @@ class ClaimScrubResultService:
# Custom method implementation
raise NotImplementedError(f"Method validate_lcd not yet implemented")
async def validate_ncd(self, _in: Create) -> ClaimScrubResult:
async def validate_ncd(self, _in: Any) -> Any:
"""
Validate NCD coverage
POST /api/v1/claims/validate/ncd
@ -512,7 +513,7 @@ class ClaimScrubResultService:
# Custom method implementation
raise NotImplementedError(f"Method validate_ncd not yet implemented")
async def get_failures(self, query_params: Optional[Dict[str, Any]] = None) -> List[ClaimScrubResult]:
async def get_failures(self, query_params: Optional[Dict[str, Any]] = None) -> List[Any]:
"""
Get scrub failures
GET /api/v1/claims/scrub/failures
@ -520,7 +521,7 @@ class ClaimScrubResultService:
# Custom method implementation
raise NotImplementedError(f"Method get_failures not yet implemented")
async def scrubClaim(self, claim_id: Any, payer_id: Any, icd10_codes: Any, cpt_codes: Any, modifiers: Any) -> ClaimScrubResult:
async def scrubClaim(self, claim_id: Any, payer_id: Any, icd10_codes: Any, cpt_codes: Any, modifiers: Any) -> Any:
"""
Scrub claim
custom
@ -693,7 +694,7 @@ class ClaimScrubResultService:
"modifier_issues": scrub_result.modifier_issues
}
async def validateNCCI(self, cpt_codes: Any, modifiers: Any) -> ClaimScrubResult:
async def validateNCCI(self, cpt_codes: Any, modifiers: Any) -> Any:
"""
Validate NCCI edits
custom
@ -826,7 +827,7 @@ class ClaimScrubResultService:
ncci_valid_modifiers = ["25", "59", "XE", "XP", "XS", "XU", "91"]
return modifier in ncci_valid_modifiers
async def validateLCD(self, icd10_codes: Any, cpt_codes: Any, payer_id: Any, state: Any) -> ClaimScrubResult:
async def validateLCD(self, icd10_codes: Any, cpt_codes: Any, payer_id: Any, state: Any) -> Any:
"""
Validate LCD
custom
@ -838,8 +839,8 @@ class ClaimScrubResultService:
Args:
icd10_codes: List of ICD-10 diagnosis codes
cpt_codes: List of CPT procedure codes
payer_idValue: Payer identifier
stateValue: State code for LCD jurisdiction
payer_idValue: Any identifier
stateValue: Any code for LCD jurisdiction
Returns:
Dictionary containing LCD validation results
@ -925,7 +926,7 @@ class ClaimScrubResultService:
}
}
async def validateNCD(self, icd10_codes: Any, cpt_codes: Any, payer_id: Any) -> ClaimScrubResult:
async def validateNCD(self, icd10_codes: Any, cpt_codes: Any, payer_id: Any) -> Any:
"""
Validate NCD
custom
@ -937,7 +938,7 @@ class ClaimScrubResultService:
Args:
icd10_codes: List of ICD-10 diagnosis codes
cpt_codes: List of CPT procedure codes
payer_idValue: Payer identifier
payer_idValue: Any identifier
Returns:
Dictionary containing NCD validation results
@ -1034,7 +1035,7 @@ class ClaimScrubResultService:
"payer_idValue": payer_idValue
}
async def checkPayerRules(self, payer_id: Any, codes: Any) -> ClaimScrubResult:
async def checkPayerRules(self, payer_id: Any, codes: Any) -> Any:
"""
Check payer rules
custom
@ -1044,8 +1045,8 @@ class ClaimScrubResultService:
Check payer rules for given payer and codes
Args:
payer_id: The payer identifier
codes: Dictionary containing procedure codes, diagnosis codes, etc.
payer_id: Any payer identifier
codes: Any containing procedure codes, diagnosis codes, etc.
Returns:
List of payer rule violations found
@ -1135,7 +1136,7 @@ class ClaimScrubResultService:
return violations
# =========== Query Methods (findBy*) ===========
async def find_by_scrub_status(self, scrub_status: str) -> List[ClaimScrubResult]:
async def find_by_scrub_status(self, scrub_status: str) -> List[Any]:
"""
Find claimscrubresults by scrub_status
"""
@ -1143,7 +1144,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "scrub_status") == scrub_status
).all()
async def find_by_overall_risk_level(self, overall_risk_level: str) -> List[ClaimScrubResult]:
async def find_by_overall_risk_level(self, overall_risk_level: str) -> List[Any]:
"""
Find claimscrubresults by overall_risk_level
"""
@ -1151,7 +1152,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "overall_risk_level") == overall_risk_level
).all()
async def find_by_total_checks(self, total_checks: int) -> List[ClaimScrubResult]:
async def find_by_total_checks(self, total_checks: int) -> List[Any]:
"""
Find claimscrubresults by total_checks
"""
@ -1159,7 +1160,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "total_checks") == total_checks
).all()
async def find_by_passed_checks(self, passed_checks: int) -> List[ClaimScrubResult]:
async def find_by_passed_checks(self, passed_checks: int) -> List[Any]:
"""
Find claimscrubresults by passed_checks
"""
@ -1167,7 +1168,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "passed_checks") == passed_checks
).all()
async def find_by_failed_checks(self, failed_checks: int) -> List[ClaimScrubResult]:
async def find_by_failed_checks(self, failed_checks: int) -> List[Any]:
"""
Find claimscrubresults by failed_checks
"""
@ -1175,7 +1176,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "failed_checks") == failed_checks
).all()
async def find_by_warning_checks(self, warning_checks: int) -> List[ClaimScrubResult]:
async def find_by_warning_checks(self, warning_checks: int) -> List[Any]:
"""
Find claimscrubresults by warning_checks
"""
@ -1183,7 +1184,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "warning_checks") == warning_checks
).all()
async def find_by_ncci_violations(self, ncci_violations: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_ncci_violations(self, ncci_violations: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by ncci_violations
"""
@ -1191,7 +1192,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "ncci_violations") == ncci_violations
).all()
async def find_by_lcd_violations(self, lcd_violations: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_lcd_violations(self, lcd_violations: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by lcd_violations
"""
@ -1199,7 +1200,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "lcd_violations") == lcd_violations
).all()
async def find_by_ncd_violations(self, ncd_violations: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_ncd_violations(self, ncd_violations: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by ncd_violations
"""
@ -1207,7 +1208,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "ncd_violations") == ncd_violations
).all()
async def find_by_payer_rule_violations(self, payer_rule_violations: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_payer_rule_violations(self, payer_rule_violations: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by payer_rule_violations
"""
@ -1215,7 +1216,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "payer_rule_violations") == payer_rule_violations
).all()
async def find_by_coding_errors(self, coding_errors: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_coding_errors(self, coding_errors: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by coding_errors
"""
@ -1223,7 +1224,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "coding_errors") == coding_errors
).all()
async def find_by_medical_necessity_issues(self, medical_necessity_issues: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_medical_necessity_issues(self, medical_necessity_issues: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by medical_necessity_issues
"""
@ -1231,7 +1232,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "medical_necessity_issues") == medical_necessity_issues
).all()
async def find_by_modifier_issues(self, modifier_issues: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_modifier_issues(self, modifier_issues: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by modifier_issues
"""
@ -1239,7 +1240,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "modifier_issues") == modifier_issues
).all()
async def find_by_bundling_issues(self, bundling_issues: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_bundling_issues(self, bundling_issues: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by bundling_issues
"""
@ -1247,7 +1248,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "bundling_issues") == bundling_issues
).all()
async def find_by_denial_risk_patterns(self, denial_risk_patterns: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_denial_risk_patterns(self, denial_risk_patterns: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by denial_risk_patterns
"""
@ -1255,7 +1256,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "denial_risk_patterns") == denial_risk_patterns
).all()
async def find_by_corrective_actions(self, corrective_actions: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_corrective_actions(self, corrective_actions: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by corrective_actions
"""
@ -1263,7 +1264,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "corrective_actions") == corrective_actions
).all()
async def find_by_suggested_codes(self, suggested_codes: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_suggested_codes(self, suggested_codes: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by suggested_codes
"""
@ -1271,7 +1272,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "suggested_codes") == suggested_codes
).all()
async def find_by_rag_documents_used(self, rag_documents_used: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_rag_documents_used(self, rag_documents_used: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by rag_documents_used
"""
@ -1279,7 +1280,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "rag_documents_used") == rag_documents_used
).all()
async def find_by_scrub_engine_version(self, scrub_engine_version: str) -> List[ClaimScrubResult]:
async def find_by_scrub_engine_version(self, scrub_engine_version: str) -> List[Any]:
"""
Find claimscrubresults by scrub_engine_version
"""
@ -1287,7 +1288,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "scrub_engine_version") == scrub_engine_version
).all()
async def find_by_processing_time_ms(self, processing_time_ms: int) -> List[ClaimScrubResult]:
async def find_by_processing_time_ms(self, processing_time_ms: int) -> List[Any]:
"""
Find claimscrubresults by processing_time_ms
"""
@ -1295,7 +1296,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "processing_time_ms") == processing_time_ms
).all()
async def find_by_auto_fix_applied(self, auto_fix_applied: bool) -> List[ClaimScrubResult]:
async def find_by_auto_fix_applied(self, auto_fix_applied: bool) -> List[Any]:
"""
Find claimscrubresults by auto_fix_applied
"""
@ -1303,7 +1304,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "auto_fix_applied") == auto_fix_applied
).all()
async def find_by_auto_fix_details(self, auto_fix_details: Dict[str, Any]) -> List[ClaimScrubResult]:
async def find_by_auto_fix_details(self, auto_fix_details: Dict[str, Any]) -> List[Any]:
"""
Find claimscrubresults by auto_fix_details
"""
@ -1311,7 +1312,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "auto_fix_details") == auto_fix_details
).all()
async def find_by_requires_manual_review(self, requires_manual_review: bool) -> List[ClaimScrubResult]:
async def find_by_requires_manual_review(self, requires_manual_review: bool) -> List[Any]:
"""
Find claimscrubresults by requires_manual_review
"""
@ -1319,7 +1320,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "requires_manual_review") == requires_manual_review
).all()
async def find_by_review_priority(self, review_priority: str) -> List[ClaimScrubResult]:
async def find_by_review_priority(self, review_priority: str) -> List[Any]:
"""
Find claimscrubresults by review_priority
"""
@ -1327,7 +1328,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "review_priority") == review_priority
).all()
async def find_by_scrubbed_at(self, scrubbed_at: datetime) -> List[ClaimScrubResult]:
async def find_by_scrubbed_at(self, scrubbed_at: datetime) -> List[Any]:
"""
Find claimscrubresults by scrubbed_at
"""
@ -1335,7 +1336,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "scrubbed_at") == scrubbed_at
).all()
async def find_by_created_at(self, created_at: Any) -> List[ClaimScrubResult]:
async def find_by_created_at(self, created_at: Any) -> List[Any]:
"""
Find claimscrubresults by created_at
"""
@ -1343,7 +1344,7 @@ class ClaimScrubResultService:
getattr(ClaimScrubResult, "created_at") == created_at
).all()
async def find_by_updated_at(self, updated_at: Any) -> List[ClaimScrubResult]:
async def find_by_updated_at(self, updated_at: Any) -> List[Any]:
"""
Find claimscrubresults by updated_at
"""
@ -1352,7 +1353,7 @@ class ClaimScrubResultService:
).all()
# =========== Relationship Methods ===========
async def get_by_claim_id(self, claim_scrub_result_id: UUID) -> Claim:
async def get_by_claim_id(self, claim_scrub_result_id: UUID) -> Any:
"""
Get the claim for this claimscrubresult
"""

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
from decimal import Decimal
from datetime import date, datetime
"""
ClinicalEntity Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -11,10 +13,26 @@ import logging
from src.models.clinical_entity_model import ClinicalEntity
from src.validation.clinical_entity_schemas import ClinicalEntityCreate, ClinicalEntityUpdate
from src.services.transcript_service import TranscriptCRUD
# Mock NLP helpers if missing
def nlp_extract_diagnoses(text):
return type('obj', (object,), {'text': 'mock dx', 'normalized': 'mock dx', 'confidence': 0.8, 'start': 0, 'end': 7, 'context': '', 'negated': False, 'historical': False})
def nlpExtractProcedures(text):
return [type('obj', (object,), {'text': 'mock proc', 'normalized': 'mock proc', 'confidence': 0.8, 'start': 0, 'end': 9, 'context': '', 'metadata': {}})]
def nlp_extract_anatomy_and_laterality(text):
return {'anatomicalLocation': 'mock anatomy', 'laterality': 'left', 'confidence': 0.8, 'startPosition': 0, 'endPosition': 12}
def nlpExtractTemporalRelations(text):
return {'relation': 'none'}
def aiConfidenceScore(entity):
return 0.85
def isInternalEndpoint(endpoint):
return True
logger = logging.getLogger(__name__)
class ClinicalEntityService:
class ClinicalEntityCRUD:
"""
Service class for ClinicalEntity business logic.
@ -22,9 +40,11 @@ class ClinicalEntityService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
self.transcript_service = TranscriptCRUD(db)
async def get_all(
self,
@ -38,11 +58,11 @@ class ClinicalEntityService:
Get all clinicalentities with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of clinicalentities, total count)
@ -85,7 +105,7 @@ class ClinicalEntityService:
Get a specific clinicalentity by ID.
Args:
clinical_entity_id: The UUID of the clinicalentity
clinical_entity_id: Any UUID of the clinicalentity
Returns:
The clinicalentity if found, None otherwise
@ -95,12 +115,12 @@ class ClinicalEntityService:
ClinicalEntity.id == clinical_entity_id
).first()
async def create(self, clinical_entity_in: ClinicalEntityCreate) -> ClinicalEntity:
async def create(self, clinical_entity_in: Any) -> Any:
"""
Create a new clinicalentity.
Args:
clinical_entity_in: The clinicalentity data to create
clinical_entity_in: Any clinicalentity data to create
Returns:
The created clinicalentity
@ -138,14 +158,14 @@ class ClinicalEntityService:
async def update(
self,
clinical_entity_id: UUID,
clinical_entity_in: ClinicalEntityUpdate
clinical_entity_in: Any
) -> Optional[ClinicalEntity]:
"""
Update an existing clinicalentity.
Args:
clinical_entity_id: The UUID of the clinicalentity to update
clinical_entity_in: The updated clinicalentity data
clinical_entity_id: Any UUID of the clinicalentity to update
clinical_entity_in: Any updated clinicalentity data
Returns:
The updated clinicalentity if found, None otherwise
@ -182,7 +202,7 @@ class ClinicalEntityService:
Delete a clinicalentity.
Args:
clinical_entity_id: The UUID of the clinicalentity to delete
clinical_entity_id: Any UUID of the clinicalentity to delete
Returns:
True if deleted, False if not found
@ -209,9 +229,9 @@ class ClinicalEntityService:
Get all clinicalentities for a specific Transcript.
Args:
transcript_id: The UUID of the Transcript
skip: Number of records to skip
limit: Maximum records to return
transcript_id: Any UUID of the Transcript
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of clinicalentities, total count)
@ -235,9 +255,9 @@ class ClinicalEntityService:
Get all clinicalentities for a specific User.
Args:
user_id: The UUID of the User
skip: Number of records to skip
limit: Maximum records to return
user_id: Any UUID of the User
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of clinicalentities, total count)
@ -279,7 +299,7 @@ class ClinicalEntityService:
entity.metadata["flagged_for_review"] = True
entity.metadata["review_reason"] = "Confidence score in threshold range (70-90%)"
async def requiresManualCoding(self, clinical_entity_in: ClinicalEntityCreate, existing: Optional[ClinicalEntity] = None) -> Any:
async def requiresManualCoding(self, clinical_entity_in: Any, existing: Optional[ClinicalEntity] = None) -> Any:
"""
Require manual coding if confidence &lt;70%
@generated from DSL function
@ -299,7 +319,7 @@ class ClinicalEntityService:
if entity.confidence_score < 0.70:
raise ValueError("Manual coding required: confidence score is below 70% threshold")
async def validateLLMSource(self, clinical_entity_in: ClinicalEntityCreate, existing: Optional[ClinicalEntity] = None) -> Any:
async def validateLLMSource(self, clinical_entity_in: Any, existing: Optional[ClinicalEntity] = None) -> Any:
"""
Self-hosted LLM only, no external AI calls
@generated from DSL function
@ -323,7 +343,7 @@ class ClinicalEntityService:
if not isInternalEndpoint(endpoint):
raise ValueError("External API calls are not allowed. Only self-hosted LLM endpoints are permitted.")
async def escalateToHuman(self, clinical_entity_in: ClinicalEntityCreate, existing: Optional[ClinicalEntity] = None) -> Any:
async def escalateToHuman(self, clinical_entity_in: Any, existing: Optional[ClinicalEntity] = None) -> Any:
"""
Escalate low-confidence extractions to human
@generated from DSL function
@ -339,7 +359,7 @@ class ClinicalEntityService:
tenant_id = clinical_entity_data.get('tenant_id')
version = clinical_entity_data.get('version')
context = {'user': {'tenant_id': tenant_id}}
# LowConfidenceEscalationRule: Escalate low-confidence extractions to human
# LowConfidenceEscalationRule: Any low-confidence extractions to human
if entity.confidence_score < 0.70:
raise ValueError("Low confidence score detected. Entity requires human verification before saving.")
@ -350,8 +370,10 @@ class ClinicalEntityService:
"""
# Auto-generated non-validation rule implementation
# Fetch transcript from TranscriptService
transcript_service = self.transcript_service
transcript = await transcript_service.get_by_id(clinical_entity.transcript_id)
# Extract documentation text
documentation = transcript.text
@ -376,7 +398,9 @@ class ClinicalEntityService:
"""
# Auto-generated non-validation rule implementation
# Fetch transcript
transcript = await TranscriptService.get_by_id(clinicalentity.transcript_id)
TranscriptService = self.transcript_service
transcript = await TranscriptService.get_by_id(clinical_entity.transcript_id)
# Extract procedures using NLP
extractedProcedures = nlpExtractProcedures(transcript.documentation)
@ -477,7 +501,7 @@ class ClinicalEntityService:
await event_bus.emit("entity.extracted", event_data)
# =========== Custom Service Methods ===========
async def extract(self, transcript_id: Any, text: Any) -> ClinicalEntity:
async def extract(self, transcript_id: Any, text: Any) -> Any:
"""
Extract entities from text
POST /api/v1/entities/extract
@ -543,7 +567,7 @@ class ClinicalEntityService:
return extracted_entities
async def find_one(self, _id: UUID) -> ClinicalEntity:
async def find_one(self, _id: UUID) -> Any:
"""
Get entity by ID
GET /api/v1/entities/{id}
@ -551,7 +575,7 @@ class ClinicalEntityService:
# Custom method implementation
raise NotImplementedError(f"Method find_one not yet implemented")
async def verify(self, _id: UUID, verified: Any, verified_by: Any) -> ClinicalEntity:
async def verify(self, _id: UUID, verified: Any, verified_by: Any) -> Any:
"""
Verify entity
POST /api/v1/entities/{id}/verify
@ -572,7 +596,7 @@ class ClinicalEntityService:
return entity
async def findByTranscript(self, transcript_id: Any) -> ClinicalEntity:
async def findByTranscript(self, transcript_id: Any) -> Any:
"""
Get entities by transcript
custom
@ -587,7 +611,7 @@ class ClinicalEntityService:
return list(entities)
async def extractDiagnoses(self, text: Any) -> ClinicalEntity:
async def extractDiagnoses(self, text: Any) -> Any:
"""
Extract diagnosis entities
custom
@ -657,7 +681,7 @@ class ClinicalEntityService:
"context": context,
"is_negated": is_negated,
"is_historical": is_historical,
"is_verified": False,
"is_verified": Any,
"metadata": {
"extraction_method": "pattern_matching",
"pattern_used": pattern
@ -678,7 +702,7 @@ class ClinicalEntityService:
return unique_diagnoses
async def extractProcedures(self, text: Any) -> ClinicalEntity:
async def extractProcedures(self, text: Any) -> Any:
"""
Extract procedure entities
custom
@ -759,7 +783,7 @@ class ClinicalEntityService:
},
"is_negated": is_negated,
"is_historical": is_historical,
"is_verified": False,
"is_verified": Any,
"verified_by_user_id": None,
"verified_at": None
}
@ -793,7 +817,7 @@ class ClinicalEntityService:
return unique_entities
async def extractMedications(self, text: Any) -> ClinicalEntity:
async def extractMedications(self, text: Any) -> Any:
"""
Extract medication entities
custom
@ -881,7 +905,7 @@ class ClinicalEntityService:
},
"is_negated": is_negated,
"is_historical": is_historical,
"is_verified": False
"is_verified": Any
}
medications.append(medication_entity)
@ -896,7 +920,7 @@ class ClinicalEntityService:
return unique_medications
async def normalizeEntity(self, entity_text: Any, entity_type: Any) -> ClinicalEntity:
async def normalizeEntity(self, entity_text: Any, entity_type: Any) -> Any:
"""
Normalize entity text
custom
@ -941,7 +965,7 @@ class ClinicalEntityService:
return normalized
async def detectNegation(self, entity: Any, context: Any) -> ClinicalEntity:
async def detectNegation(self, entity: Any, context: Any) -> Any:
"""
Detect negation context
custom
@ -1017,7 +1041,7 @@ class ClinicalEntityService:
return False
# =========== Query Methods (findBy*) ===========
async def find_by_entity_type(self, entity_type: str) -> List[ClinicalEntity]:
async def find_by_entity_type(self, entity_type: str) -> List[Any]:
"""
Find clinicalentitys by entity_type
"""
@ -1025,7 +1049,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "entity_type") == entity_type
).all()
async def find_by_entity_text(self, entity_text: str) -> List[ClinicalEntity]:
async def find_by_entity_text(self, entity_text: str) -> List[Any]:
"""
Find clinicalentitys by entity_text
"""
@ -1033,7 +1057,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "entity_text") == entity_text
).all()
async def find_by_normalized_text(self, normalized_text: str) -> List[ClinicalEntity]:
async def find_by_normalized_text(self, normalized_text: str) -> List[Any]:
"""
Find clinicalentitys by normalized_text
"""
@ -1041,7 +1065,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "normalized_text") == normalized_text
).all()
async def find_by_confidence_score(self, confidence_score: Decimal) -> List[ClinicalEntity]:
async def find_by_confidence_score(self, confidence_score: Any) -> List[Any]:
"""
Find clinicalentitys by confidence_score
"""
@ -1049,7 +1073,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "confidence_score") == confidence_score
).all()
async def find_by_start_position(self, start_position: int) -> List[ClinicalEntity]:
async def find_by_start_position(self, start_position: int) -> List[Any]:
"""
Find clinicalentitys by start_position
"""
@ -1057,7 +1081,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "start_position") == start_position
).all()
async def find_by_end_position(self, end_position: int) -> List[ClinicalEntity]:
async def find_by_end_position(self, end_position: int) -> List[Any]:
"""
Find clinicalentitys by end_position
"""
@ -1065,7 +1089,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "end_position") == end_position
).all()
async def find_by_context(self, context: str) -> List[ClinicalEntity]:
async def find_by_context(self, context: str) -> List[Any]:
"""
Find clinicalentitys by context
"""
@ -1073,7 +1097,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "context") == context
).all()
async def find_by_metadata(self, metadata: Dict[str, Any]) -> List[ClinicalEntity]:
async def find_by_metadata(self, metadata: Dict[str, Any]) -> List[Any]:
"""
Find clinicalentitys by metadata
"""
@ -1081,7 +1105,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "metadata") == metadata
).all()
async def find_by_is_negated(self, is_negated: bool) -> List[ClinicalEntity]:
async def find_by_is_negated(self, is_negated: bool) -> List[Any]:
"""
Find clinicalentitys by is_negated
"""
@ -1089,7 +1113,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "is_negated") == is_negated
).all()
async def find_by_is_historical(self, is_historical: bool) -> List[ClinicalEntity]:
async def find_by_is_historical(self, is_historical: bool) -> List[Any]:
"""
Find clinicalentitys by is_historical
"""
@ -1097,7 +1121,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "is_historical") == is_historical
).all()
async def find_by_is_verified(self, is_verified: bool) -> List[ClinicalEntity]:
async def find_by_is_verified(self, is_verified: bool) -> List[Any]:
"""
Find clinicalentitys by is_verified
"""
@ -1105,7 +1129,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "is_verified") == is_verified
).all()
async def find_by_verified_at(self, verified_at: datetime) -> List[ClinicalEntity]:
async def find_by_verified_at(self, verified_at: datetime) -> List[Any]:
"""
Find clinicalentitys by verified_at
"""
@ -1113,7 +1137,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "verified_at") == verified_at
).all()
async def find_by_created_at(self, created_at: datetime) -> List[ClinicalEntity]:
async def find_by_created_at(self, created_at: datetime) -> List[Any]:
"""
Find clinicalentitys by created_at
"""
@ -1121,7 +1145,7 @@ class ClinicalEntityService:
getattr(ClinicalEntity, "created_at") == created_at
).all()
async def find_by_updated_at(self, updated_at: datetime) -> List[ClinicalEntity]:
async def find_by_updated_at(self, updated_at: datetime) -> List[Any]:
"""
Find clinicalentitys by updated_at
"""
@ -1130,7 +1154,7 @@ class ClinicalEntityService:
).all()
# =========== Relationship Methods ===========
async def get_by_transcript_id(self, clinical_entity_id: UUID) -> Transcript:
async def get_by_transcript_id(self, clinical_entity_id: UUID) -> Any:
"""
Get the transcript for this clinicalentity
"""
@ -1145,7 +1169,7 @@ class ClinicalEntityService:
).first()
return None
async def get_by_verified_by_user_id(self, clinical_entity_id: UUID) -> User:
async def get_by_verified_by_user_id(self, clinical_entity_id: UUID) -> Any:
"""
Get the user for this clinicalentity
"""

File diff suppressed because it is too large Load Diff

View File

@ -1,7 +1,9 @@
from decimal import Decimal
from datetime import date, datetime
"""
ConfidenceScore Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -14,7 +16,7 @@ from src.validation.confidence_score_schemas import ConfidenceScoreCreate, Confi
logger = logging.getLogger(__name__)
class ConfidenceScoreService:
class ConfidenceScoreCRUD:
"""
Service class for ConfidenceScore business logic.
@ -22,7 +24,7 @@ class ConfidenceScoreService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
@ -38,11 +40,11 @@ class ConfidenceScoreService:
Get all confidencescores with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of confidencescores, total count)
@ -85,7 +87,7 @@ class ConfidenceScoreService:
Get a specific confidencescore by ID.
Args:
confidence_score_id: The UUID of the confidencescore
confidence_score_id: Any UUID of the confidencescore
Returns:
The confidencescore if found, None otherwise
@ -95,12 +97,12 @@ class ConfidenceScoreService:
ConfidenceScore.id == confidence_score_id
).first()
async def create(self, confidence_score_in: ConfidenceScoreCreate) -> ConfidenceScore:
async def create(self, confidence_score_in: Any) -> Any:
"""
Create a new confidencescore.
Args:
confidence_score_in: The confidencescore data to create
confidence_score_in: Any confidencescore data to create
Returns:
The created confidencescore
@ -121,14 +123,14 @@ class ConfidenceScoreService:
async def update(
self,
confidence_score_id: UUID,
confidence_score_in: ConfidenceScoreUpdate
confidence_score_in: Any
) -> Optional[ConfidenceScore]:
"""
Update an existing confidencescore.
Args:
confidence_score_id: The UUID of the confidencescore to update
confidence_score_in: The updated confidencescore data
confidence_score_id: Any UUID of the confidencescore to update
confidence_score_in: Any updated confidencescore data
Returns:
The updated confidencescore if found, None otherwise
@ -156,7 +158,7 @@ class ConfidenceScoreService:
Delete a confidencescore.
Args:
confidence_score_id: The UUID of the confidencescore to delete
confidence_score_id: Any UUID of the confidencescore to delete
Returns:
True if deleted, False if not found
@ -183,9 +185,9 @@ class ConfidenceScoreService:
Get all confidencescores for a specific Claim.
Args:
claim_id: The UUID of the Claim
skip: Number of records to skip
limit: Maximum records to return
claim_id: Any UUID of the Claim
skip: Any of records to skip
limit: Any records to return
Returns:
Tuple of (list of confidencescores, total count)
@ -204,7 +206,7 @@ class ConfidenceScoreService:
# =========== Custom Service Methods ===========
# =========== Query Methods (findBy*) ===========
async def find_by_entity_type(self, entity_type: str) -> List[ConfidenceScore]:
async def find_by_entity_type(self, entity_type: str) -> List[Any]:
"""
Find confidencescores by entity_type
"""
@ -212,7 +214,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "entity_type") == entity_type
).all()
async def find_by_entity_id(self, entity_id: UUID) -> List[ConfidenceScore]:
async def find_by_entity_id(self, entity_id: UUID) -> List[Any]:
"""
Find confidencescores by entity_id
"""
@ -220,7 +222,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "entity_id") == entity_id
).all()
async def find_by_score(self, score: Decimal) -> List[ConfidenceScore]:
async def find_by_score(self, score: Any) -> List[Any]:
"""
Find confidencescores by score
"""
@ -228,7 +230,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "score") == score
).all()
async def find_by_threshold_category(self, threshold_category: str) -> List[ConfidenceScore]:
async def find_by_threshold_category(self, threshold_category: str) -> List[Any]:
"""
Find confidencescores by threshold_category
"""
@ -236,7 +238,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "threshold_category") == threshold_category
).all()
async def find_by_model_name(self, model_name: str) -> List[ConfidenceScore]:
async def find_by_model_name(self, model_name: str) -> List[Any]:
"""
Find confidencescores by model_name
"""
@ -244,7 +246,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "model_name") == model_name
).all()
async def find_by_model_version(self, model_version: str) -> List[ConfidenceScore]:
async def find_by_model_version(self, model_version: str) -> List[Any]:
"""
Find confidencescores by model_version
"""
@ -252,7 +254,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "model_version") == model_version
).all()
async def find_by_prediction_value(self, prediction_value: str) -> List[ConfidenceScore]:
async def find_by_prediction_value(self, prediction_value: str) -> List[Any]:
"""
Find confidencescores by prediction_value
"""
@ -260,7 +262,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "prediction_value") == prediction_value
).all()
async def find_by_alternative_predictions(self, alternative_predictions: Dict[str, Any]) -> List[ConfidenceScore]:
async def find_by_alternative_predictions(self, alternative_predictions: Dict[str, Any]) -> List[Any]:
"""
Find confidencescores by alternative_predictions
"""
@ -268,7 +270,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "alternative_predictions") == alternative_predictions
).all()
async def find_by_features_used(self, features_used: Dict[str, Any]) -> List[ConfidenceScore]:
async def find_by_features_used(self, features_used: Dict[str, Any]) -> List[Any]:
"""
Find confidencescores by features_used
"""
@ -276,7 +278,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "features_used") == features_used
).all()
async def find_by_context_data(self, context_data: Dict[str, Any]) -> List[ConfidenceScore]:
async def find_by_context_data(self, context_data: Dict[str, Any]) -> List[Any]:
"""
Find confidencescores by context_data
"""
@ -284,7 +286,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "context_data") == context_data
).all()
async def find_by_requires_review(self, requires_review: bool) -> List[ConfidenceScore]:
async def find_by_requires_review(self, requires_review: bool) -> List[Any]:
"""
Find confidencescores by requires_review
"""
@ -292,7 +294,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "requires_review") == requires_review
).all()
async def find_by_review_reason(self, review_reason: str) -> List[ConfidenceScore]:
async def find_by_review_reason(self, review_reason: str) -> List[Any]:
"""
Find confidencescores by review_reason
"""
@ -300,7 +302,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "review_reason") == review_reason
).all()
async def find_by_human_feedback(self, human_feedback: str) -> List[ConfidenceScore]:
async def find_by_human_feedback(self, human_feedback: str) -> List[Any]:
"""
Find confidencescores by human_feedback
"""
@ -308,7 +310,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "human_feedback") == human_feedback
).all()
async def find_by_corrected_value(self, corrected_value: str) -> List[ConfidenceScore]:
async def find_by_corrected_value(self, corrected_value: str) -> List[Any]:
"""
Find confidencescores by corrected_value
"""
@ -316,7 +318,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "corrected_value") == corrected_value
).all()
async def find_by_feedback_notes(self, feedback_notes: str) -> List[ConfidenceScore]:
async def find_by_feedback_notes(self, feedback_notes: str) -> List[Any]:
"""
Find confidencescores by feedback_notes
"""
@ -324,7 +326,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "feedback_notes") == feedback_notes
).all()
async def find_by_processing_time_ms(self, processing_time_ms: int) -> List[ConfidenceScore]:
async def find_by_processing_time_ms(self, processing_time_ms: int) -> List[Any]:
"""
Find confidencescores by processing_time_ms
"""
@ -332,7 +334,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "processing_time_ms") == processing_time_ms
).all()
async def find_by_created_at(self, created_at: Any) -> List[ConfidenceScore]:
async def find_by_created_at(self, created_at: Any) -> List[Any]:
"""
Find confidencescores by created_at
"""
@ -340,7 +342,7 @@ class ConfidenceScoreService:
getattr(ConfidenceScore, "created_at") == created_at
).all()
async def find_by_updated_at(self, updated_at: Any) -> List[ConfidenceScore]:
async def find_by_updated_at(self, updated_at: Any) -> List[Any]:
"""
Find confidencescores by updated_at
"""
@ -349,7 +351,7 @@ class ConfidenceScoreService:
).all()
# =========== Relationship Methods ===========
async def get_by_claim_id(self, confidence_score_id: UUID) -> Claim:
async def get_by_claim_id(self, confidence_score_id: UUID) -> Any:
"""
Get the claim for this confidencescore
"""

View File

@ -1,7 +1,9 @@
from datetime import date, datetime
from decimal import Decimal
"""
CPTCode Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -14,7 +16,7 @@ from src.validation.cpt_code_schemas import CPTCodeCreate, CPTCodeUpdate
logger = logging.getLogger(__name__)
class CPTCodeService:
class CPTCodeCRUD:
"""
Service class for CPTCode business logic.
@ -22,7 +24,7 @@ class CPTCodeService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
@ -38,11 +40,11 @@ class CPTCodeService:
Get all cptcodes with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of cptcodes, total count)
@ -85,7 +87,7 @@ class CPTCodeService:
Get a specific cptcode by ID.
Args:
cpt_code_id: The UUID of the cptcode
cpt_code_id: Any UUID of the cptcode
Returns:
The cptcode if found, None otherwise
@ -95,12 +97,12 @@ class CPTCodeService:
CPTCode.id == cpt_code_id
).first()
async def create(self, cpt_code_in: CPTCodeCreate) -> CPTCode:
async def create(self, cpt_code_in: Any) -> Any:
"""
Create a new cptcode.
Args:
cpt_code_in: The cptcode data to create
cpt_code_in: Any cptcode data to create
Returns:
The created cptcode
@ -130,14 +132,14 @@ class CPTCodeService:
async def update(
self,
cpt_code_id: UUID,
cpt_code_in: CPTCodeUpdate
cpt_code_in: Any
) -> Optional[CPTCode]:
"""
Update an existing cptcode.
Args:
cpt_code_id: The UUID of the cptcode to update
cpt_code_in: The updated cptcode data
cpt_code_id: Any UUID of the cptcode to update
cpt_code_in: Any updated cptcode data
Returns:
The updated cptcode if found, None otherwise
@ -170,7 +172,7 @@ class CPTCodeService:
Delete a cptcode.
Args:
cpt_code_id: The UUID of the cptcode to delete
cpt_code_id: Any UUID of the cptcode to delete
Returns:
True if deleted, False if not found
@ -198,7 +200,7 @@ class CPTCodeService:
matching_cpt_codes = await cpt_code_service.fetch_cpt_codes(
filters={
"code": procedure.code,
"is_active": True
"is_active": Any
}
)
@ -228,7 +230,7 @@ class CPTCodeService:
@generated from DSL function
"""
# Auto-generated non-validation rule implementation
# AlternativeCodeSuggestionRule: Suggest alternative codes for low confidence <80%
# AlternativeCodeSuggestionRule: Any alternative codes for low confidence <80%
def findAlternativeCodes(code: str) -> list:
"""
@ -302,7 +304,7 @@ class CPTCodeService:
await event_bus.emit("code.mapped", event_data)
# =========== Custom Service Methods ===========
async def findByCode(self, code: Any) -> CPTCode:
async def findByCode(self, code: Any) -> Any:
"""
Get CPT by code
custom
@ -312,7 +314,7 @@ class CPTCodeService:
result = await session.execute(stmt)
return result.scalar_one_or_none()
async def search(self, query: Any, skip: Any = 0, take: Any = 10) -> CPTCode:
async def search(self, query: Any, skip: Any = 0, take: Any = 10) -> Any:
"""
Search CPT codes
custom
@ -333,7 +335,7 @@ class CPTCodeService:
return list(cpt_codes)
async def findBySpecialty(self, specialty: Any) -> CPTCode:
async def findBySpecialty(self, specialty: Any) -> Any:
"""
Get codes by specialty
custom
@ -344,7 +346,7 @@ class CPTCodeService:
cpt_codes = result.scalars().all()
return list(cpt_codes)
async def validateCode(self, code: Any) -> CPTCode:
async def validateCode(self, code: Any) -> Any:
"""
Validate CPT code
custom
@ -361,7 +363,6 @@ class CPTCodeService:
return False
# Check if the codeValue is within its effective date range
from datetime import date
today = date.today()
# Check effective date
@ -374,7 +375,7 @@ class CPTCodeService:
return True
async def findByCategory(self, category: Any) -> CPTCode:
async def findByCategory(self, category: Any) -> Any:
"""
Get codes by category
custom
@ -386,7 +387,7 @@ class CPTCodeService:
return list(cpt_codes)
# =========== Query Methods (findBy*) ===========
async def find_by_code(self, code: str) -> List[CPTCode]:
async def find_by_code(self, code: str) -> List[Any]:
"""
Find cptcodes by code
"""
@ -394,7 +395,7 @@ class CPTCodeService:
getattr(CPTCode, "code") == code
).all()
async def find_by_description(self, description: str) -> List[CPTCode]:
async def find_by_description(self, description: str) -> List[Any]:
"""
Find cptcodes by description
"""
@ -402,7 +403,7 @@ class CPTCodeService:
getattr(CPTCode, "description") == description
).all()
async def find_by_short_description(self, short_description: str) -> List[CPTCode]:
async def find_by_short_description(self, short_description: str) -> List[Any]:
"""
Find cptcodes by short_description
"""
@ -410,7 +411,7 @@ class CPTCodeService:
getattr(CPTCode, "short_description") == short_description
).all()
async def find_by_category(self, category: str) -> List[CPTCode]:
async def find_by_category(self, category: str) -> List[Any]:
"""
Find cptcodes by category
"""
@ -418,7 +419,7 @@ class CPTCodeService:
getattr(CPTCode, "category") == category
).all()
async def find_by_specialty(self, specialty: str) -> List[CPTCode]:
async def find_by_specialty(self, specialty: str) -> List[Any]:
"""
Find cptcodes by specialty
"""
@ -426,7 +427,7 @@ class CPTCodeService:
getattr(CPTCode, "specialty") == specialty
).all()
async def find_by_is_active(self, is_active: bool) -> List[CPTCode]:
async def find_by_is_active(self, is_active: bool) -> List[Any]:
"""
Find cptcodes by is_active
"""
@ -434,7 +435,7 @@ class CPTCodeService:
getattr(CPTCode, "is_active") == is_active
).all()
async def find_by_effective_date(self, effective_date: date) -> List[CPTCode]:
async def find_by_effective_date(self, effective_date: date) -> List[Any]:
"""
Find cptcodes by effective_date
"""
@ -442,7 +443,7 @@ class CPTCodeService:
getattr(CPTCode, "effective_date") == effective_date
).all()
async def find_by_termination_date(self, termination_date: date) -> List[CPTCode]:
async def find_by_termination_date(self, termination_date: date) -> List[Any]:
"""
Find cptcodes by termination_date
"""
@ -450,7 +451,7 @@ class CPTCodeService:
getattr(CPTCode, "termination_date") == termination_date
).all()
async def find_by_version(self, version: str) -> List[CPTCode]:
async def find_by_version(self, version: str) -> List[Any]:
"""
Find cptcodes by version
"""
@ -458,7 +459,7 @@ class CPTCodeService:
getattr(CPTCode, "version") == version
).all()
async def find_by_rvu_work(self, rvu_work: Decimal) -> List[CPTCode]:
async def find_by_rvu_work(self, rvu_work: Any) -> List[Any]:
"""
Find cptcodes by rvu_work
"""
@ -466,7 +467,7 @@ class CPTCodeService:
getattr(CPTCode, "rvu_work") == rvu_work
).all()
async def find_by_rvu_facility(self, rvu_facility: Decimal) -> List[CPTCode]:
async def find_by_rvu_facility(self, rvu_facility: Any) -> List[Any]:
"""
Find cptcodes by rvu_facility
"""
@ -474,7 +475,7 @@ class CPTCodeService:
getattr(CPTCode, "rvu_facility") == rvu_facility
).all()
async def find_by_rvu_non_facility(self, rvu_non_facility: Decimal) -> List[CPTCode]:
async def find_by_rvu_non_facility(self, rvu_non_facility: Any) -> List[Any]:
"""
Find cptcodes by rvu_non_facility
"""
@ -482,7 +483,7 @@ class CPTCodeService:
getattr(CPTCode, "rvu_non_facility") == rvu_non_facility
).all()
async def find_by_global_period(self, global_period: str) -> List[CPTCode]:
async def find_by_global_period(self, global_period: str) -> List[Any]:
"""
Find cptcodes by global_period
"""
@ -490,7 +491,7 @@ class CPTCodeService:
getattr(CPTCode, "global_period") == global_period
).all()
async def find_by_synonyms(self, synonyms: Dict[str, Any]) -> List[CPTCode]:
async def find_by_synonyms(self, synonyms: Dict[str, Any]) -> List[Any]:
"""
Find cptcodes by synonyms
"""
@ -498,7 +499,7 @@ class CPTCodeService:
getattr(CPTCode, "synonyms") == synonyms
).all()
async def find_by_created_at(self, created_at: datetime) -> List[CPTCode]:
async def find_by_created_at(self, created_at: datetime) -> List[Any]:
"""
Find cptcodes by created_at
"""
@ -506,7 +507,7 @@ class CPTCodeService:
getattr(CPTCode, "created_at") == created_at
).all()
async def find_by_updated_at(self, updated_at: datetime) -> List[CPTCode]:
async def find_by_updated_at(self, updated_at: datetime) -> List[Any]:
"""
Find cptcodes by updated_at
"""

View File

@ -1,7 +1,9 @@
from decimal import Decimal
from datetime import date, datetime
"""
CPTModifier Service Layer
Enterprise-grade service with business logic, validation, and error handling
Architecture: Routers Services/CRUD SQLAlchemy Models + Pydantic Schemas
Architecture: Any Services/CRUD SQLAlchemy Models + Pydantic Schemas
"""
from typing import List, Optional, Tuple, Dict, Any
from uuid import UUID
@ -14,7 +16,7 @@ from src.validation.cpt_modifier_schemas import CPTModifierCreate, CPTModifierUp
logger = logging.getLogger(__name__)
class CPTModifierService:
class CPTModifierCRUD:
"""
Service class for CPTModifier business logic.
@ -22,7 +24,7 @@ class CPTModifierService:
and complex queries.
"""
def __init__(self, db: Session):
def __init__(self, db: Any):
"""Initialize service with database session."""
self.db = db
@ -38,11 +40,11 @@ class CPTModifierService:
Get all cptmodifiers with pagination and filtering.
Args:
skip: Number of records to skip
limit: Maximum records to return
filters: Dictionary of field filters
order_by: Field to order by
order_desc: Order descending if True
skip: Any of records to skip
limit: Any records to return
filters: Any of field filters
order_by: Any to order by
order_desc: Any descending if True
Returns:
Tuple of (list of cptmodifiers, total count)
@ -85,7 +87,7 @@ class CPTModifierService:
Get a specific cptmodifier by ID.
Args:
cpt_modifier_id: The UUID of the cptmodifier
cpt_modifier_id: Any UUID of the cptmodifier
Returns:
The cptmodifier if found, None otherwise
@ -95,12 +97,12 @@ class CPTModifierService:
CPTModifier.id == cpt_modifier_id
).first()
async def create(self, cpt_modifier_in: CPTModifierCreate) -> CPTModifier:
async def create(self, cpt_modifier_in: Any) -> Any:
"""
Create a new cptmodifier.
Args:
cpt_modifier_in: The cptmodifier data to create
cpt_modifier_in: Any cptmodifier data to create
Returns:
The created cptmodifier
@ -125,14 +127,14 @@ class CPTModifierService:
async def update(
self,
cpt_modifier_id: UUID,
cpt_modifier_in: CPTModifierUpdate
cpt_modifier_in: Any
) -> Optional[CPTModifier]:
"""
Update an existing cptmodifier.
Args:
cpt_modifier_id: The UUID of the cptmodifier to update
cpt_modifier_in: The updated cptmodifier data
cpt_modifier_id: Any UUID of the cptmodifier to update
cpt_modifier_in: Any updated cptmodifier data
Returns:
The updated cptmodifier if found, None otherwise
@ -164,7 +166,7 @@ class CPTModifierService:
Delete a cptmodifier.
Args:
cpt_modifier_id: The UUID of the cptmodifier to delete
cpt_modifier_id: Any UUID of the cptmodifier to delete
Returns:
True if deleted, False if not found
@ -271,7 +273,7 @@ class CPTModifierService:
# =========== Custom Service Methods ===========
# =========== Query Methods (findBy*) ===========
async def find_by_modifier(self, modifier: str) -> List[CPTModifier]:
async def find_by_modifier(self, modifier: str) -> List[Any]:
"""
Find cptmodifiers by modifier
"""
@ -279,7 +281,7 @@ class CPTModifierService:
getattr(CPTModifier, "modifier") == modifier
).all()
async def find_by_description(self, description: str) -> List[CPTModifier]:
async def find_by_description(self, description: str) -> List[Any]:
"""
Find cptmodifiers by description
"""
@ -287,7 +289,7 @@ class CPTModifierService:
getattr(CPTModifier, "description") == description
).all()
async def find_by_short_description(self, short_description: str) -> List[CPTModifier]:
async def find_by_short_description(self, short_description: str) -> List[Any]:
"""
Find cptmodifiers by short_description
"""
@ -295,7 +297,7 @@ class CPTModifierService:
getattr(CPTModifier, "short_description") == short_description
).all()
async def find_by_category(self, category: str) -> List[CPTModifier]:
async def find_by_category(self, category: str) -> List[Any]:
"""
Find cptmodifiers by category
"""
@ -303,7 +305,7 @@ class CPTModifierService:
getattr(CPTModifier, "category") == category
).all()
async def find_by_is_active(self, is_active: bool) -> List[CPTModifier]:
async def find_by_is_active(self, is_active: bool) -> List[Any]:
"""
Find cptmodifiers by is_active
"""
@ -311,7 +313,7 @@ class CPTModifierService:
getattr(CPTModifier, "is_active") == is_active
).all()
async def find_by_effective_date(self, effective_date: date) -> List[CPTModifier]:
async def find_by_effective_date(self, effective_date: date) -> List[Any]:
"""
Find cptmodifiers by effective_date
"""
@ -319,7 +321,7 @@ class CPTModifierService:
getattr(CPTModifier, "effective_date") == effective_date
).all()
async def find_by_termination_date(self, termination_date: date) -> List[CPTModifier]:
async def find_by_termination_date(self, termination_date: date) -> List[Any]:
"""
Find cptmodifiers by termination_date
"""
@ -327,7 +329,7 @@ class CPTModifierService:
getattr(CPTModifier, "termination_date") == termination_date
).all()
async def find_by_reimbursement_impact(self, reimbursement_impact: Decimal) -> List[CPTModifier]:
async def find_by_reimbursement_impact(self, reimbursement_impact: Any) -> List[Any]:
"""
Find cptmodifiers by reimbursement_impact
"""
@ -335,7 +337,7 @@ class CPTModifierService:
getattr(CPTModifier, "reimbursement_impact") == reimbursement_impact
).all()
async def find_by_usage_rules(self, usage_rules: str) -> List[CPTModifier]:
async def find_by_usage_rules(self, usage_rules: str) -> List[Any]:
"""
Find cptmodifiers by usage_rules
"""
@ -343,7 +345,7 @@ class CPTModifierService:
getattr(CPTModifier, "usage_rules") == usage_rules
).all()
async def find_by_created_at(self, created_at: datetime) -> List[CPTModifier]:
async def find_by_created_at(self, created_at: datetime) -> List[Any]:
"""
Find cptmodifiers by created_at
"""
@ -351,7 +353,7 @@ class CPTModifierService:
getattr(CPTModifier, "created_at") == created_at
).all()
async def find_by_updated_at(self, updated_at: datetime) -> List[CPTModifier]:
async def find_by_updated_at(self, updated_at: datetime) -> List[Any]:
"""
Find cptmodifiers by updated_at
"""

Some files were not shown because too many files have changed in this diff Show More