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.

Public Upload Page Workflow

  • The public page has no redundant generic Upload page title. Its identifying heading is Upload Files: [label].
  • The secret token value is never displayed.
  • Selecting files is the upload action. Drupal core managed_file immediately starts AJAX transfer from the file-input change event.
  • Successful initial uploads become temporary Drupal managed files under private://uploads/[token]/.
  • The final action is Finish submission.
  • Skyhawk custom-form results never use Drupal messenger/status popups. Upload/finalization results render inline on the form using the established PageMessageTrait pattern required by Tier-1 Rule 8.3.

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 State

Generic initial upload: ACCEPTED. Drupal core managed_file selection and automatic AJAX transfer to token-scoped private storage are functionally proven.

Finish submission permanent-file transition: ACCEPTED. A completed Pixel batch produced a permanent managed file in token-scoped private storage and reset the form for another batch.

Public upload-page UX: ACCEPTED on Pixel/Chrome. The redundant generic Upload title is absent, the identifying Upload Files: [label] presentation is correct, and the repaired public-page formatting has passed direct browser inspection. This gate is closed absent contradictory evidence.

Current acceptance boundary: upload history. The next requirement is to prove that Finish submission records each finalized file in skyhawk_upload_file as required by the product contract. Do not reopen generic upload, permanent-file transition, or the accepted public-page UX while testing history.

Current Regression Token

No token label is permanently reserved as the regression token. Use a currently active, unexpired test token from the existing token system. Do not create a replacement token merely because an upload test fails.