Files
rips_manager/main.py
T
Lizandro GuarnizoandClaude Sonnet 4.6 8e27225326 feat: módulos de envío TNS/ERP Lab + sync de médico, empresa y valor total
- Hub /envios/tns con 5 sub-tabs (Terceros, Transacción RIPS, Facturas Venta, Prueba RDA, Automatización) via iframe lazy
- Hub /envios/erp con sub-tabs Pacientes y Sync Automático (historial scheduler)
- Modo embed (?embed=1) en base.html para cargar páginas sin sidebar/header dentro de iframes
- Sidebar simplificado: 6 ítems individuales reemplazados por módulos TNS y ERP Lab
- Scheduler y endpoint /pacientes/examenes ahora incluyen médico ordenante (DOCIDMEDICO), empresa/EPS (NIT_EMPRESA) y valor total (VALORTOTAL) desde Firebird

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-16 21:13:48 -05:00

109 lines
3.3 KiB
Python

import os
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent))
from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse
from fastapi.templating import Jinja2Templates
import uvicorn
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from app.database import init_db
from app.auth import decode_token
from app.services.scheduler import sync_recientes
app = FastAPI(title="RIPS Manager", version="1.0.0")
_scheduler = AsyncIOScheduler()
templates = Jinja2Templates(
directory=os.path.join(os.path.dirname(__file__), "app", "templates")
)
app.state.templates = templates
def get_user_from_request(request: Request):
token = request.cookies.get("token")
if not token:
auth = request.headers.get("Authorization", "")
if auth.startswith("Bearer "):
token = auth[7:]
if token:
decoded = decode_token(token)
if decoded:
return decoded
print(f" [AUTH] Invalid token: {token[:30]}...", flush=True)
return None
@app.middleware("http")
async def auth_middleware(request: Request, call_next):
if request.url.path.startswith("/auth") or request.url.path.startswith("/static"):
return await call_next(request)
user = get_user_from_request(request)
print(f" [AUTH] path={request.url.path} user={user['username'] if user else None}", flush=True)
if not user:
if request.url.path.startswith("/api/"):
from fastapi.responses import JSONResponse
return JSONResponse({"detail": "Not authenticated"}, status_code=401)
return RedirectResponse(url="/auth/login")
request.state.user = user
return await call_next(request)
@app.on_event("startup")
async def startup():
init_db()
from app.routes.config import ensure_defaults as config_defaults
from app.routes.queries import ensure_defaults as query_defaults
from app.routes.contratos import ensure_defaults as contratos_defaults
config_defaults()
query_defaults()
contratos_defaults()
_scheduler.add_job(sync_recientes, "interval", minutes=1, id="wa_sync_recientes",
max_instances=1, coalesce=True)
_scheduler.start()
@app.on_event("shutdown")
async def shutdown():
_scheduler.shutdown(wait=False)
@app.get("/")
async def root():
return RedirectResponse(url="/dashboard")
from app.routes import auth, dashboard, config, queries, terceros, transaccion, logs, automation, test_rda, debug_fb, pacientes, contratos, ventas, envios
app.include_router(auth.router)
app.include_router(dashboard.router)
app.include_router(config.router)
app.include_router(queries.router)
app.include_router(envios.router)
app.include_router(terceros.router)
app.include_router(transaccion.router)
app.include_router(logs.router)
app.include_router(automation.router)
app.include_router(test_rda.router)
app.include_router(debug_fb.router)
app.include_router(pacientes.router)
app.include_router(contratos.router)
app.include_router(ventas.router)
if __name__ == "__main__":
import socket
hostname = socket.gethostname()
try:
lan_ip = socket.gethostbyname(hostname)
except Exception:
lan_ip = "0.0.0.0"
print(f" Local: http://localhost:8080")
print(f" Red: http://{lan_ip}:8080")
uvicorn.run("main:app", host="0.0.0.0", port=8080, reload=False)