Backend (replaces PHP api.php + auth.php): - FastAPI app with routers: jobs, auth, billing - Supabase JWT authentication in deps.py - Celery + Redis job queue (process_pdf_task) - MinIO S3-compatible storage service - PDF checker wrapper (delegates to enterprise_pdf_checker.py) - Stripe billing: checkout, portal, webhook handler Multi-tenancy (Phase 3): - Alembic migration 001: workspaces, workspace_members, jobs, usage_events - Row-Level Security on all tenant tables via app.workspace_id session var - Monthly quota enforcement per workspace (402 on exceeded) - Plan tiers: free(5) / pro(100) / business(unlimited) Config: - pydantic-settings based config.py (no hardcoded values) - docker-compose.yml rewritten: postgres, redis, minio, api, celery Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
34 lines
1.1 KiB
Python
34 lines
1.1 KiB
Python
"""Wrapper around enterprise_pdf_checker.py — runs in Celery worker."""
|
|
import sys
|
|
import os
|
|
import tempfile
|
|
import structlog
|
|
from pathlib import Path
|
|
|
|
# enterprise_pdf_checker.py lives at repo root (parent of backend/)
|
|
REPO_ROOT = Path(__file__).parents[3]
|
|
if str(REPO_ROOT) not in sys.path:
|
|
sys.path.insert(0, str(REPO_ROOT))
|
|
|
|
from enterprise_pdf_checker import EnterprisePDFChecker # noqa: E402
|
|
|
|
logger = structlog.get_logger()
|
|
|
|
|
|
def run_check(pdf_bytes: bytes, filename: str) -> dict:
|
|
"""Run WCAG accessibility check on PDF bytes. Returns result dict."""
|
|
with tempfile.NamedTemporaryFile(suffix=".pdf", delete=False) as tmp:
|
|
tmp.write(pdf_bytes)
|
|
tmp_path = tmp.name
|
|
|
|
try:
|
|
checker = EnterprisePDFChecker(tmp_path)
|
|
result = checker.check_all()
|
|
result["filename"] = filename
|
|
logger.info("check_complete", filename=filename, score=result.get("accessibility_score"))
|
|
return result
|
|
except Exception as exc:
|
|
logger.error("check_failed", filename=filename, error=str(exc))
|
|
raise
|
|
finally:
|
|
os.unlink(tmp_path)
|