fix: file display, persistence, PDF support and save error handling
- Add file proxy route in maker blueprint (X-API-Key auth for browser requests) - Persist file_path/annotations_json to DB via RecipeCreate/RecipeUpdate schemas - Fix canvas sizing using grandparent container instead of Fabric.js wrapper div - Defer canvas init with requestAnimationFrame for x-show timing - Add PDF.js support in annotation-editor and annotation-viewer - Fix annotations_json double-serialization (parse string to object before send) - Handle FastAPI 422 validation error arrays in api_client and JS error display - Update template URLs to use /maker/api/files/ proxy path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
"""Maker blueprint - recipe creation and editing."""
|
||||
from flask import Blueprint, flash, jsonify, redirect, render_template, request, url_for
|
||||
import requests as http_requests
|
||||
|
||||
from flask import Blueprint, Response, flash, jsonify, redirect, render_template, request, session, url_for
|
||||
from flask_babel import gettext as _
|
||||
|
||||
from blueprints.auth import login_required, role_required
|
||||
from config import Config
|
||||
from services.api_client import api_client
|
||||
|
||||
maker_bp = Blueprint("maker", __name__, url_prefix="/maker")
|
||||
@@ -349,6 +352,25 @@ def api_upload_file():
|
||||
return jsonify(resp), 201
|
||||
|
||||
|
||||
@maker_bp.route("/api/files/<path:file_path>", methods=["GET"])
|
||||
@login_required
|
||||
def api_get_file(file_path: str):
|
||||
"""Proxy: Serve file from API server (browser can't send X-API-Key)."""
|
||||
api_key = session.get("api_key", "")
|
||||
base_url = Config.API_SERVER_URL.rstrip("/")
|
||||
resp = http_requests.get(
|
||||
f"{base_url}/api/files/{file_path}",
|
||||
headers={"X-API-Key": api_key},
|
||||
timeout=30,
|
||||
)
|
||||
if resp.status_code != 200:
|
||||
return Response(resp.text, status=resp.status_code)
|
||||
return Response(
|
||||
resp.content,
|
||||
content_type=resp.headers.get("content-type", "application/octet-stream"),
|
||||
)
|
||||
|
||||
|
||||
@maker_bp.route("/api/files/<path:file_path>", methods=["DELETE"])
|
||||
@login_required
|
||||
@role_required("Maker")
|
||||
|
||||
Reference in New Issue
Block a user