# main.py — Profit Engine Backend
# Deploy to Render.com as Web Service
# Requirements: fastapi uvicorn python-multipart pandas reportlab requests
from fastapi import FastAPI, UploadFile, File, HTTPException, Header, Depends
from fastapi.responses import JSONResponse, FileResponse
from fastapi.middleware.cors import CORSMiddleware
import uvicorn, os, uuid, tempfile, shutil, requests
from pathlib import Path
# Your existing modules
from audit_engine import run_audit
from audit_report import generate_pdf_report
API_SECRET = os.getenv(
"API_SECRET",
"changeme")
RESEND_KEY = os.getenv(
"RESEND_API_KEY",
"")
FROM_EMAIL = os.getenv(
"FROM_EMAIL",
"[email protected]")
app = FastAPI(title=
"Profit Engine API", version=
"2.0")
app.add_middleware(CORSMiddleware,
allow_origins=[
"*"], allow_methods=[
"*"], allow_headers=[
"*"])
def verify(x_api_key: str = Header(None)):
if x_api_key != API_SECRET:
raise HTTPException(
401,
"Invalid API key")
return x_api_key
@app.get(
"/health")
def health():
return {
"status":
"online",
"engine":
"Profit Engine v2.0"}
@app.post(
"/run-audit")
async def run_audit_endpoint(
file: UploadFile = File(...),
restaurant_name: str =
"Restaurant",
client_email: str =
"",
auth: str = Depends(verify)
):
"""
Accepts CSV/Excel P&L file.
Runs audit_engine → generates PDF → emails client → returns JSON results.
Call from: dashboard JS, Make.com, Zapier.
"""
job_id = str(uuid.uuid4())[:
8]
tmp = Path(tempfile.mkdtemp())
ext = Path(file.filename).suffix.lower()
src_path = tmp /
f"data_{job_id}{ext}"
pdf_path = tmp /
f"audit_{job_id}.pdf"
try:
# Save uploaded file
src_path.write_bytes(
await file.read())
# Run your existing audit engine
results = run_audit(str(src_path), restaurant_name)
# Generate PDF report
generate_pdf_report(results, str(pdf_path))
# Persist PDF for download
final_pdf = Path(
f"/tmp/audit_{job_id}.pdf")
shutil.copy(pdf_path, final_pdf)
# Auto-email if client_email provided
if client_email
and RESEND_KEY:
send_audit_email(client_email, restaurant_name, job_id, results)
return JSONResponse({
"ok":
True,
"job_id": job_id,
"restaurant": restaurant_name,
"total_leak": results.get(
"total_leak",
0),
"leak_count": len(results.get(
"leaks", [])),
"leaks": results.get(
"leaks", []),
"actions": results.get(
"actions", []),
"summary": results.get(
"summary", {}),
"pdf_url":
f"/download/{job_id}",
})
except Exception
as e:
raise HTTPException(
500, str(e))
finally:
shutil.rmtree(tmp, ignore_errors=
True)
@app.get(
"/download/{job_id}")
def download_pdf(job_id: str):
p = Path(
f"/tmp/audit_{job_id}.pdf")
if not p.exists():
raise HTTPException(
404,
"Audit not found or expired")
return FileResponse(p, media_type=
"application/pdf",
filename=
f"profit_engine_audit_{job_id}.pdf")
def send_audit_email(to: str, name: str, job_id: str, results: dict):
"""Send audit results email via Resend."""
total = results.get(
"total_leak",
0)
top_leaks = results.get(
"leaks", [])[:3]
leaks_html =
"".join([
f'<li><strong>{l["name"]}</strong>: ${l["monthly_impact"]:,}/mo — {l["detail"]}</li>'
for l
in top_leaks
])
requests.post(
"https://api.resend.com/emails",
headers={
"Authorization":
f"Bearer {RESEND_KEY}"},
json={
"from": FROM_EMAIL,
"to": to,
"subject":
f"Profit Engine Results — ${total:,}/mo found at {name}",
"html":
f"""
<div style="font-family:sans-serif;max-width:600px;margin:0 auto">
<div style="background:#04040a;padding:24px;border-radius:8px 8px 0 0">
<h2 style="color:#a3ff47;margin:0;font-size:22px">
Profit Engine Results
</h2>
<p style="color:#9999b5;margin:8px 0 0;font-size:14px">{name}</p>
</div>
<div style="padding:32px;background:#0d0d18;border:1px solid #1e1e30">
<div style="background:#13131e;border:1px solid #a3ff47;border-radius:8px;padding:24px;margin-bottom:24px;text-align:center">
<div style="font-size:13px;color:#9999b5;text-transform:uppercase;letter-spacing:0.1em;margin-bottom:8px">
Total Recoverable Monthly Profit
</div>
<div style="font-size:52px;font-weight:800;color:#a3ff47;line-height:1">
${total:,}
</div>
</div>
<h3 style="color:#eeeef5;margin:0 0 12px">Top 3 Leaks Found</h3>
<ul style="color:#9999b5;line-height:1.9;padding-left:20px">{leaks_html}</ul>
<div style="text-align:center;margin-top:28px">
<a href="https://profitengine.live/download/{job_id}"
style="background:#a3ff47;color:#04040a;padding:14px 32px;
font-weight:700;text-decoration:none;border-radius:4px;
display:inline-block;font-size:15px">
Download Full PDF Report
</a>
</div>
</div>
</div>"""
}
)
if __name__ ==
"__main__":
uvicorn.run(
"main:app", host=
"0.0.0.0", port=
10000)