Files
delphi-database/app/main.py
2025-08-15 22:04:43 -05:00

224 lines
8.0 KiB
Python

"""
Delphi Consulting Group Database System - Main FastAPI Application
"""
from fastapi import FastAPI, Request, Depends
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.middleware.cors import CORSMiddleware
from app.config import settings
from app.database.base import engine
from app.database.fts import ensure_rolodex_fts, ensure_files_fts, ensure_ledger_fts, ensure_qdros_fts
from app.database.indexes import ensure_secondary_indexes
from app.database.schema_updates import ensure_schema_updates
from app.models import BaseModel
from app.models.user import User
from app.auth.security import get_admin_user
from app.core.logging import setup_logging, get_logger
from app.middleware.logging import LoggingMiddleware
from app.middleware.errors import register_exception_handlers
# Initialize logging
setup_logging()
logger = get_logger("main")
# Create database tables
logger.info("Creating database tables")
BaseModel.metadata.create_all(bind=engine)
# Initialize SQLite FTS (if available)
logger.info("Initializing FTS (if available)")
ensure_rolodex_fts(engine)
ensure_files_fts(engine)
ensure_ledger_fts(engine)
ensure_qdros_fts(engine)
# Ensure helpful secondary indexes
logger.info("Ensuring secondary indexes (status, type, employee, etc.)")
ensure_secondary_indexes(engine)
# Ensure idempotent schema updates for added columns
logger.info("Ensuring schema updates (new columns)")
ensure_schema_updates(engine)
# Initialize FastAPI app
logger.info("Initializing FastAPI application", version=settings.app_version, debug=settings.debug)
app = FastAPI(
title=settings.app_name,
version=settings.app_version,
description="Modern Python web application for Delphi Consulting Group",
)
# Add logging middleware
logger.info("Adding request logging middleware")
app.add_middleware(LoggingMiddleware, log_requests=True, log_responses=settings.debug)
# Register global exception handlers
logger.info("Registering global exception handlers")
register_exception_handlers(app)
# Configure CORS
logger.info("Configuring CORS middleware")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # Configure appropriately for production
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Mount static files
logger.info("Mounting static file directories")
app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount("/uploads", StaticFiles(directory="uploads"), name="uploads")
# Templates
logger.info("Initializing Jinja2 templates")
templates = Jinja2Templates(directory="templates")
# Include routers
from app.api.auth import router as auth_router
from app.api.customers import router as customers_router
from app.api.files import router as files_router
from app.api.financial import router as financial_router
from app.api.documents import router as documents_router
from app.api.billing import router as billing_router
from app.api.search import router as search_router
from app.api.admin import router as admin_router
from app.api.import_data import router as import_router
from app.api.flexible import router as flexible_router
from app.api.support import router as support_router
from app.api.settings import router as settings_router
from app.api.mortality import router as mortality_router
from app.api.pensions import router as pensions_router
from app.api.templates import router as templates_router
from app.api.qdros import router as qdros_router
logger.info("Including API routers")
app.include_router(auth_router, prefix="/api/auth", tags=["authentication"])
app.include_router(customers_router, prefix="/api/customers", tags=["customers"])
app.include_router(files_router, prefix="/api/files", tags=["files"])
app.include_router(financial_router, prefix="/api/financial", tags=["financial"])
app.include_router(billing_router, prefix="/api/billing", tags=["billing"])
app.include_router(documents_router, prefix="/api/documents", tags=["documents"])
app.include_router(search_router, prefix="/api/search", tags=["search"])
app.include_router(admin_router, prefix="/api/admin", tags=["admin"])
app.include_router(import_router, prefix="/api/import", tags=["import"])
app.include_router(support_router, prefix="/api/support", tags=["support"])
app.include_router(settings_router, prefix="/api/settings", tags=["settings"])
app.include_router(flexible_router, prefix="/api")
app.include_router(mortality_router, prefix="/api/mortality", tags=["mortality"])
app.include_router(pensions_router, prefix="/api/pensions", tags=["pensions"])
app.include_router(templates_router, prefix="/api/templates", tags=["templates"])
app.include_router(qdros_router, prefix="/api", tags=["qdros"])
@app.get("/", response_class=HTMLResponse)
async def root(request: Request):
"""Dashboard as the main landing page. Client-side JS handles auth redirect."""
return templates.TemplateResponse(
"dashboard.html",
{"request": request, "title": "Dashboard - " + settings.app_name}
)
@app.get("/login", response_class=HTMLResponse)
async def login_page(request: Request):
"""Login page"""
return templates.TemplateResponse(
"login.html",
{"request": request, "title": "Login - " + settings.app_name}
)
@app.get("/customers", response_class=HTMLResponse)
async def customers_page(request: Request):
"""Customer management page"""
return templates.TemplateResponse(
"customers.html",
{"request": request, "title": "Customers - " + settings.app_name}
)
@app.get("/files", response_class=HTMLResponse)
async def files_page(request: Request):
"""File cabinet management page"""
return templates.TemplateResponse(
"files.html",
{"request": request, "title": "File Cabinet - " + settings.app_name}
)
@app.get("/financial", response_class=HTMLResponse)
async def financial_page(request: Request):
"""Financial/Ledger management page"""
return templates.TemplateResponse(
"financial.html",
{"request": request, "title": "Financial/Ledger - " + settings.app_name}
)
@app.get("/billing", response_class=HTMLResponse)
async def billing_page(request: Request):
"""Billing Statements page"""
return templates.TemplateResponse(
"billing.html",
{"request": request, "title": "Billing Statements - " + settings.app_name}
)
@app.get("/documents", response_class=HTMLResponse)
async def documents_page(request: Request):
"""Document management page"""
return templates.TemplateResponse(
"documents.html",
{"request": request, "title": "Document Management - " + settings.app_name}
)
@app.get("/search", response_class=HTMLResponse)
async def search_page(request: Request):
"""Advanced search page"""
return templates.TemplateResponse(
"search.html",
{"request": request, "title": "Advanced Search - " + settings.app_name}
)
@app.get("/admin", response_class=HTMLResponse)
async def admin_page(request: Request):
"""System administration page (admin only)"""
return templates.TemplateResponse(
"admin.html",
{"request": request, "title": "System Administration - " + settings.app_name}
)
@app.get("/import", response_class=HTMLResponse)
async def import_page(request: Request):
"""Data import management page (admin only)"""
return templates.TemplateResponse(
"import.html",
{"request": request, "title": "Data Import - " + settings.app_name}
)
@app.get("/flexible", response_class=HTMLResponse)
async def flexible_page(request: Request):
"""Flexible imports admin page (admin only)."""
return templates.TemplateResponse(
"flexible.html",
{"request": request, "title": "Flexible Imports - " + settings.app_name}
)
@app.get("/health")
async def health_check():
"""Health check endpoint"""
return {"status": "healthy", "version": settings.app_version}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000, reload=settings.debug)