feat: upload a script PDF from the script pane

Backend: POST /api/projects/<id>/script/ (owner/collaborator) saves the script
FileField and returns the refreshed detail. Frontend: when a project has no
script, the script pane shows a PDF file picker that uploads on selection; the
returned detail carries the new URL so the pane renders it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Your Name 2026-06-30 01:09:16 -04:00
parent 9c4b56dbc6
commit b05b440922
6 changed files with 46 additions and 2 deletions

View file

@ -9,5 +9,6 @@ urlpatterns = [
path("projects/", views.projects),
path("projects/<int:pk>/", views.project),
path("projects/<int:pk>/scene/", views.scene),
path("projects/<int:pk>/script/", views.script),
path("projects/<int:pk>/revisions/", views.revisions),
]

View file

@ -174,6 +174,22 @@ def scene(request, pk):
return HttpResponseNotAllowed(["GET", "PUT"])
@csrf_exempt
def script(request, pk):
"""POST (owner/collaborator) — upload or replace the project's script PDF."""
if request.method != "POST":
return HttpResponseNotAllowed(["POST"])
if (resp := _auth(request)):
return resp
p = _editable(request, pk)
f = request.FILES.get("script")
if not f:
return JsonResponse({"detail": "script file is required"}, status=400)
p.script = f
p.save(update_fields=["script", "updated"])
return JsonResponse(_meta(request, p))
def revisions(request, pk):
"""GET /api/projects/<pk>/revisions/ — the save history (who/when/what)."""
if (resp := _auth(request)):