feat: Update .env.example and Docker Compose configurations to enhance service performance and health checks. Adjust OCR settings for improved document processing efficiency, and refine API Gateway health checks for better service monitoring. Revise desktop application documentation to reflect new API Gateway URL and installation instructions.
This commit is contained in:
@@ -138,6 +138,8 @@ class ExtractionRequest(BaseModel):
|
||||
radicado_filter: list[str] | None = None
|
||||
documents: list[DesktopDocument] | None = None
|
||||
document_count: int | None = None
|
||||
job_id: str | None = None # vincular al job existente
|
||||
model: str | None = None
|
||||
|
||||
@model_validator(mode="after")
|
||||
def validate_source(self) -> "ExtractionRequest":
|
||||
@@ -538,6 +540,7 @@ def create_extraction_task(request: ExtractionRequest, background_tasks: Backgro
|
||||
session.flush()
|
||||
batch_id = batch.id
|
||||
task = Task(
|
||||
job_id=request.job_id,
|
||||
type="extraction",
|
||||
status="running",
|
||||
title=title,
|
||||
@@ -560,6 +563,7 @@ def create_extraction_task(request: ExtractionRequest, background_tasks: Backgro
|
||||
|
||||
with session_scope() as session:
|
||||
task = Task(
|
||||
job_id=request.job_id,
|
||||
type="extraction",
|
||||
status="pending",
|
||||
title=f"Extraccion {request.root_path}",
|
||||
@@ -966,6 +970,52 @@ def serialize_job(job: Job) -> dict[str, Any]:
|
||||
}
|
||||
|
||||
|
||||
class CreateJobRequest(BaseModel):
|
||||
title: str | None = None
|
||||
folder_path: str | None = None
|
||||
|
||||
|
||||
class UpdateJobRequest(BaseModel):
|
||||
title: str | None = None
|
||||
folder_path: str | None = None
|
||||
status: str | None = None
|
||||
|
||||
|
||||
@app.post("/jobs", response_model=JobRead)
|
||||
def create_job(request: CreateJobRequest) -> dict[str, Any]:
|
||||
"""Crea un trabajo (job) independiente como contenedor para módulos."""
|
||||
with session_scope() as session:
|
||||
job = Job(
|
||||
status="pending",
|
||||
title=request.title,
|
||||
job_metadata={"folder_path": request.folder_path} if request.folder_path else {},
|
||||
updated_at=utcnow(),
|
||||
)
|
||||
session.add(job)
|
||||
session.flush()
|
||||
return serialize_job(job)
|
||||
|
||||
|
||||
@app.patch("/jobs/{job_id}", response_model=JobRead)
|
||||
def update_job(job_id: str, request: UpdateJobRequest) -> dict[str, Any]:
|
||||
"""Actualiza título, metadata o estado de un job."""
|
||||
with session_scope() as session:
|
||||
job = session.get(Job, job_id)
|
||||
if job is None:
|
||||
raise HTTPException(status_code=404, detail="Job no encontrado")
|
||||
if request.title is not None:
|
||||
job.title = request.title
|
||||
if request.status is not None:
|
||||
job.status = request.status
|
||||
if request.folder_path is not None:
|
||||
meta = dict(job.job_metadata or {})
|
||||
meta["folder_path"] = request.folder_path
|
||||
job.job_metadata = meta
|
||||
job.updated_at = utcnow()
|
||||
session.flush()
|
||||
return serialize_job(job)
|
||||
|
||||
|
||||
@app.get("/jobs", response_model=list[JobRead])
|
||||
def list_jobs() -> list[dict[str, Any]]:
|
||||
with session_scope() as session:
|
||||
@@ -1011,6 +1061,7 @@ class CountJobFileCreate(BaseModel):
|
||||
|
||||
class CreateCountJobRequest(BaseModel):
|
||||
title: str | None = None
|
||||
job_id: str | None = None # si se pasa, se usa el job existente
|
||||
results: list[CountJobFileCreate]
|
||||
|
||||
|
||||
@@ -1036,6 +1087,8 @@ class UpdateCountJobFileRequest(BaseModel):
|
||||
class ExtractionFromCountRequest(BaseModel):
|
||||
counting_task_id: str
|
||||
min_service_count: int = 0
|
||||
valid_counts: list[int] | None = None # conteos exactos válidos (vacío = todos)
|
||||
job_id: str | None = None # vincular al job existente del conteo
|
||||
fields: list[str] = Field(default_factory=list)
|
||||
alias_map: dict[str, str] = Field(default_factory=dict)
|
||||
doc_types: list[DocumentType] | None = None
|
||||
@@ -1067,20 +1120,30 @@ def serialize_count_file(f: CountJobFile) -> dict[str, Any]:
|
||||
def create_count_job(request: CreateCountJobRequest) -> dict[str, Any]:
|
||||
"""Persiste los resultados del servicio de conteo de facturas en la BD compartida."""
|
||||
total = len(request.results)
|
||||
default_title = request.title or f"Conteo ({total} archivos)"
|
||||
with session_scope() as session:
|
||||
job = Job(
|
||||
status="completed",
|
||||
title=request.title or f"Conteo ({total} archivos)",
|
||||
updated_at=utcnow(),
|
||||
)
|
||||
session.add(job)
|
||||
if request.job_id:
|
||||
job = session.get(Job, request.job_id)
|
||||
if job is None:
|
||||
raise HTTPException(status_code=404, detail="Job no encontrado")
|
||||
if request.title:
|
||||
job.title = request.title
|
||||
job.status = "running"
|
||||
job.updated_at = utcnow()
|
||||
else:
|
||||
job = Job(
|
||||
status="completed",
|
||||
title=default_title,
|
||||
updated_at=utcnow(),
|
||||
)
|
||||
session.add(job)
|
||||
session.flush()
|
||||
|
||||
task = Task(
|
||||
job_id=job.id,
|
||||
type="counting",
|
||||
status="completed",
|
||||
title=job.title,
|
||||
title=default_title,
|
||||
request={},
|
||||
result={
|
||||
"total": total,
|
||||
@@ -1266,11 +1329,19 @@ def create_extraction_from_count(
|
||||
)
|
||||
).all()
|
||||
|
||||
use_exact_counts = request.valid_counts is not None and len(request.valid_counts) > 0
|
||||
valid_files = [
|
||||
f for f in all_files
|
||||
if f.status == "ok"
|
||||
and f.is_valid is not False
|
||||
and (f.service_count is None or f.service_count >= request.min_service_count)
|
||||
and (
|
||||
# Si el usuario marcó manualmente como válido, siempre se incluye
|
||||
f.is_valid is True
|
||||
# Si hay conteos exactos definidos, el service_count debe estar en la lista
|
||||
or (use_exact_counts and f.service_count in request.valid_counts)
|
||||
# Sin filtro exacto, usar umbral mínimo (compatibilidad hacia atrás)
|
||||
or (not use_exact_counts and (f.service_count is None or f.service_count >= request.min_service_count))
|
||||
)
|
||||
]
|
||||
|
||||
if not valid_files:
|
||||
@@ -1292,12 +1363,19 @@ def create_extraction_from_count(
|
||||
]
|
||||
total = len(files_data)
|
||||
|
||||
job = Job(
|
||||
status="running",
|
||||
title=f"Extraccion desde conteo ({total} archivos)",
|
||||
updated_at=utcnow(),
|
||||
)
|
||||
session.add(job)
|
||||
if request.job_id:
|
||||
job = session.get(Job, request.job_id)
|
||||
if job is None:
|
||||
raise HTTPException(status_code=404, detail="Job no encontrado")
|
||||
job.status = "running"
|
||||
job.updated_at = utcnow()
|
||||
else:
|
||||
job = Job(
|
||||
status="running",
|
||||
title=f"Extraccion desde conteo ({total} archivos)",
|
||||
updated_at=utcnow(),
|
||||
)
|
||||
session.add(job)
|
||||
session.flush()
|
||||
|
||||
batch = ExtractionBatch(
|
||||
|
||||
@@ -27,7 +27,13 @@ DATABASE_URL = os.getenv(
|
||||
"postgresql+psycopg://ipsextractor:ipsextractor@database:5432/ipsextractor",
|
||||
)
|
||||
|
||||
engine = create_engine(DATABASE_URL, pool_pre_ping=True)
|
||||
engine = create_engine(
|
||||
DATABASE_URL,
|
||||
pool_pre_ping=True,
|
||||
pool_size=10,
|
||||
pool_timeout=30,
|
||||
connect_args={"connect_timeout": 10},
|
||||
)
|
||||
SessionLocal = sessionmaker(bind=engine, autoflush=False, autocommit=False)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user