Skip to content

Phase 14d-1: editor upload endpoint + FilePond vendoring#29

Merged
bigin merged 1 commit into
imanager-2.0from
phase-14d1-upload-endpoint
May 3, 2026
Merged

Phase 14d-1: editor upload endpoint + FilePond vendoring#29
bigin merged 1 commit into
imanager-2.0from
phase-14d1-upload-endpoint

Conversation

@bigin
Copy link
Copy Markdown
Owner

@bigin bigin commented May 3, 2026

Summary

Backend half of the upload pipeline: a JSON API mounted at
/editor/api/upload that wraps Phase 13's UploadHandler, persists
the file via the iManager 2.0 FileRepository + FileStorage, and
emits a matching <W>x<H>_<file> thumbnail next to the original via
ImageProcessor.

Editor\Api\UploadEndpoint:

  • POST multipart {file, itemId, fieldId, tokenName, tokenValue}
    → 200 {fileId, name, url, mime, size, width, height, thumbnailUrl?}
    → 400 / 403 / 401 / 405 with {"error":"..."}
  • DELETE form-urlencoded body {fileId, tokenName, tokenValue}
    (also accepts FilePond's revert raw-body shape)
    → 200 {"status":"ok"} (removes thumbnail siblings best-effort)

EditorRouter intercepts /editor/api/* before any other module:

  • anonymous → 401 JSON (XHR-friendly, not a 302 redirect)
  • logged-in → dispatchApi()UploadEndpoint::handle($method)
  • non-upload resource → 404 JSON

CSRF tokens are validated per request; the /editor/pages form's
"pages" token is what FilePond will submit in 14d-2.

FilePond vendoring under editor/theme/scripts/filepond/ (~170 KB):
filepond 4.32.7, image-preview 4.6.12, file-validate-type 1.2.9,
file-validate-size 2.2.8. Form integration ships in 14d-2.

Test plan

  • POST upload (64×64 PNG) → 200 JSON; files row + asset on disk
  • GET thumbnailUrl → 200 image (300×300 generated)
  • DELETE fileId → 200; files row gone, asset gone
  • POST without CSRF → 403 {"error":"CSRF token invalid"}
  • POST anonymous → 401 {"error":"Authentication required"}
  • POST 11 MB binary → 400 (size constraint)
  • Browser smoke against ServBay

Backend half of the upload pipeline: a JSON API mounted at
/editor/api/upload that wraps Phase 13's UploadHandler, persists the
file via the iManager 2.0 FileRepository + FileStorage, and emits a
matching <W>x<H>_<file> thumbnail next to the original via
ImageProcessor.

Editor\Api\UploadEndpoint:
  POST   multipart, fields {file, itemId, fieldId, tokenName, tokenValue}
         → 200 {fileId, name, url, mime, size, width, height,
                                                  thumbnailUrl?}
         → 400 / 403 / 401 / 405 with {"error":"..."}
  DELETE form-urlencoded body {fileId, tokenName, tokenValue} (also
         accepts FilePond's `revert` raw-body shape)
         → 200 {"status":"ok"} (removes thumbnail siblings best-effort)

EditorRouter intercepts /editor/api/* before any other module:
  - anonymous → 401 JSON (XHR-friendly, not a 302 redirect)
  - logged-in → dispatchApi() → UploadEndpoint::handle($method)
  - non-`upload` resource → 404 JSON

CSRF tokens are validated per request; the /editor/pages form's
"pages" token is what FilePond will submit in 14d-2.

FilePond vendoring under editor/theme/scripts/filepond/ (~170 KB):
  - filepond.{js,css}                     (4.32.7)
  - filepond-image-preview.{js,css}       (4.6.12)
  - filepond-file-validate-type.js        (1.2.9)
  - filepond-file-validate-size.js        (2.2.8)
The actual <script> wiring + page-edit form integration ships in 14d-2.

Manual smoke (PHP built-in server, 64×64 PNG fixture):
  POST upload (image)              → 200 JSON; files row + asset on disk
  GET  thumbnailUrl                → 200 image (300×300 generated)
  DELETE fileId                    → 200; files row gone, asset gone
  POST without CSRF                → 403 {"error":"CSRF token invalid"}
  POST anonymous                   → 401 {"error":"Authentication required"}
  POST 11 MB binary                → 400 {"error":"... max allowed is 10485760"}
@bigin bigin merged commit a9f520c into imanager-2.0 May 3, 2026
@bigin bigin deleted the phase-14d1-upload-endpoint branch May 15, 2026 05:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant