Skip to main content

Upload Token System

Upload Token System

Upload Token System

This is the authoritative reference for the generic public upload-token product implemented in skyhawk_site_fixes.

Architecture

  • Public route: /upload/{token}.
  • Admin route: /admin/skyhawk/upload-tokens.
  • The public route is owned by UploadTokenForm.
  • Drupal core managed_file owns file selection, AJAX transfer, validation, and temporary file entities.
  • Files are stored under private://uploads/[token]/.
  • No custom synthetic mouse event or parallel direct-upload controller participates in the live product.

Token Lifecycle

  • A token is valid when it exists, has status active, and has not expired.
  • Generated tokens have a minimum lifetime of seven days.
  • A token may be used for multiple upload sessions until expiry or explicit administrative revocation.
  • A successful upload does not consume or invalidate the token.
  • uses_count records cumulative finalized files for administrative information only.
  • uses_allowed = 0 is retained as the unlimited-until-expiry/revocation sentinel for schema compatibility.

Upload Rules

  • Multiple files may be selected.
  • Maximum individual file size is 511 MiB (535,822,336 bytes).
  • The hosting transport ceiling remains 512 MiB for an HTTP POST, so exceptionally large batches may need to be selected/uploaded separately even though each individual file is legal.
  • After Drupal receives temporary managed files, final submission makes them permanent, records each file in skyhawk_upload_file, increments cumulative file accounting, and sends the configured batch notification.
  • Completion notifications contain only the files finalized in that batch, not every historical file associated with the token.

Administration

  • The admin form creates reusable tokens and sends the upload URL by email.
  • The admin form can explicitly revoke an active token.
  • Existing contact and purpose data are reused.
  • The current history table remains operational; conversion to a Drupal View is a later Views-first improvement, not part of the uploader replacement.

Replacement State

The public and admin upload forms were replaced in toto after a discovery audit found contradictory one-use lifecycle logic, a redundant unrouted direct-upload controller, and a custom mobile workaround that duplicated Drupal core behavior.

The old UploadTokenController and upload_token_mobile_fix.js are retired into the timestamped replacement backup rather than destroyed during initial acceptance testing.

Functional acceptance remains pending until the Pixel test verifies: legal multi-file upload, final submission, private storage, history rows, notification, reuse of the same token, explicit revocation, expiry rejection, and oversize rejection.

Current Functional Failure

Proven: Drupal 11 core managed_file AJAX reliably uploads one file at a time on the production stack and Pixel. Final submission, permanent file status, success redirect, and reusable token behavior are proven.

Proven: Native simultaneous three-file managed_file selection is unreliable even on the pristine Drupal control. Server request size, multipart parsing, multiple multipart parts, and slow-client timing have been independently cleared.

Implementation boundary: Preserve the human multiple-selection interface, but replay each selected File through Drupal core one-file behavior sequentially. The adapter may replace the browser FileList and dispatch one standard change event per file. Drupal core itself must own the resulting managed_file AJAX transaction. No custom upload endpoint, custom HTTP transport, manual upload-button click, mousedown fabrication, MutationObserver transaction engine, or device-specific branch is permitted.

Public interface: Uploaded filenames remain visible. Per-file removal-selection checkboxes and the Remove selected control are hidden on the public token uploader because they are confusing and unnecessary for the contributor workflow. This presentation change must not alter Drupal file state.

Closed branches: Pixel-specific behavior, token validity, route validity, PHP upload limits, HTTP body size, multipart ingress, slow-client timeout, single-file managed_file AJAX, final submission, and reusable-token behavior remain closed absent contradictory evidence.

Current Regression Token

Chatgpt 4 remains the regression token while it is active and unexpired. Do not generate another token merely because an upload test fails.