Upload Token System
Architecture
Generic, purpose-agnostic token system in skyhawk_site_fixes. Tables: skyhawk_upload_token (token, purpose, expiry, contact_id, status), skyhawk_contact (address book, links to Drupal uid when the contact is a member so email is always read live — never duplicated), skyhawk_notify_list (purpose to contact_id, who gets notified on redemption), skyhawk_upload_file (individual files received per token).
Admin form: /admin/skyhawk/upload-tokens (Blade menu) — generate token, select/create contact, purpose dropdown (self-registering from existing purposes plus Other), expiry, auto-emails a one-time link.
Public upload form: /upload/{token} — Drupal Form using native managed_file element (matching the established pattern in skyhawk_gallery/PhotoContributionForm.php), multi-file, private:// storage.
Mail cases live in skyhawk_site_fixes.module hook_mail(): upload_token_notify (sent on generation), upload_token_completed (sent to the notify list on redemption, includes filenames and sizes).
Confirmed Working
- Token generation, contact selection/creation, email delivery
- 512M real ceiling confirmed via testing (536,870,912 bytes exact); LiteSpeed returns a 503, not a clean 413, when exceeded
- Per-file limit set to 511MB to stay safely under that ceiling
- Private storage confirmed working (files land in private://uploads/[token]/)
Known Issue (last session, unresolved)
Mobile file upload does not complete — files select, spinner shows briefly, but no request reaches the server (confirmed via empty error_log and empty uploads directory for the attempt). Two real bugs found and fixed along the way: (1) Drupal's page cache was serving a stale copy of the form before any code change took effect — fixed via page_cache_kill_switch trigger at the top of buildForm(). (2) A JS mobile-touch fix (skyhawk_site_fixes/upload_token_mobile_fix library) was written to bind file-input 'change' instead of relying on 'mousedown', to work around a known Drupal core mobile/touch AJAX quirk.
Unverified at handoff: whether the mobile-fix JS is actually being delivered/executed. The verification method used (grepping page HTML for the library's machine name) was invalid — Drupal never prints library names into HTML, only script src paths. Correct next step: fetch the actual script src output from a fresh (cache-bypassed) page load, resolve any aggregated bundle, and grep that content for the function name skyhawkUploadTokenMobileFix.
Deferred
- Reunion system migration onto this same token mechanism (not yet started)
- Token-history admin view — currently a hand-rolled table in the admin form; should be rebuilt as a proper Drupal View per the core/contrib-first rule