Skip to main content

Upload Token System

Upload Token System

Event Framework - Agreed First Consumer of Generic Intake

Status: Design frozen for first Reunion/BOD Meeting implementation.

Generic Intake remains the common transport and processing layer.
The first reusable consumer is an Event framework, initially proven
against Reunion and BOD Meeting workflows.

Bootstrap, Durable Authority, and Reunion Continuity

  • For Reunion source updates, the contributor filename is provenance and presentation metadata, not semantic authority. Acceptance must not require a month, year, Event name, or other business meaning to be encoded in the filename. The workflow determines the target Event; exactly one real PDF and the applicable authorization, duplicate-content, persistence, and public-verification gates determine acceptance. Skyhawk may use a deterministic internal stored path while preserving the original contributor filename.

  • A Reunion benefit is initiated by the Association member who accepts responsibility for it. Normal future design requires that member to be authenticated.
  • The authenticated Drupal UID is the durable identity. Account email is the authoritative contact value presented from Drupal; a changed email must be verified before becoming authoritative.
  • Once responsibility has been established, routine Reunion newsletter/source updates are performed through authenticated Ready Room access. A new Generic Intake token is not required for each update.
  • Existing token/request records remain immutable historical evidence of how earlier authority was established. The 2026 A-4 JULY bootstrap remains token-established history.
  • Each consequential Reunion update records the executing UID, time, previous current file, resulting current file, and verification outcome. Drupal revision history is preferred where it provides that evidence without another custom tracking subsystem.
  • Current Association membership is required to exercise production Reunion authority. Reliable generalized current-member eligibility must use the authoritative membership state after the documented roster reconciliation; it must not be guessed from unrelated data.
  • Each durable Reunion Unit has one primary accountable current member and at least one additional current-member continuity contact by the start of the Reunion. Additional authorized helpers may be supported.
  • The Reunion Unit persists across successive reunion occurrences. A future reunion is a new occurrence associated with the same durable Unit rather than an overwrite of an earlier reunion occurrence.
  • Reunion photographs and historical material are retained and displayed for their historical and sentimental value. Loss of a responsible member does not automatically delete public history.
  • If all eligible responsible contacts are lost, the Association determines succession and continued stewardship.
  • Existing agreed reminder behavior remains unchanged. Reminders prompt authorized members to maintain their existing Reunion relationship; they do not recreate authority.
  • The model should remain reusable for other future member-supported benefits without prematurely constructing a universal custom framework.

Source-Material Workflow

  • The responsible authenticated member may provide Reunion source material either by uploading one ordinary source document through Drupal core managed_file or by pasting source text directly.
  • Uploaded source intake remains format-agnostic. PDF, DOC/DOCX, TXT and other ordinary source documents are not assigned business meaning from their filename or extension. Normal Drupal and hosting safety constraints still apply.
  • Pasted text is stored directly as submitted source content. The system does not manufacture a fake text file merely to force pasted material through a file-upload abstraction.
  • The submitted source is authoritative input. Parsing or model extraction produces proposed structured facts only. Extraction failure does not invalidate an otherwise preserved source.
  • A new self-service Reunion request creates an unpublished Reunion Event draft owned by the authenticated requester. That draft is the durable occurrence identity; later parsing/review updates the same entity rather than creating a duplicate Event.
  • General production activation still requires authoritative current-membership eligibility and the required primary/continuity-member relationship. Until the membership-roster reconciliation provides that deterministic contract, creation of a private draft does not itself grant publication/update authority.
  • Replacement/update sources reconcile the existing Event. Prior accepted sources and relevant source history remain associated with the same Event.

Ready Room Reunion Navigation

  • Association > Reunions is the public-facing Reunion destination. Published Reunion information, current material, photographs and historical material are consumed there. It is not the keeper-management path.
  • Ready Room > My Reunion Events is the authenticated keeper management and recovery destination. Responsible members use it to rediscover the Reunions they are authorized to maintain if they lose or delete an instructional email.
  • Ready Room > Request a Reunion is the authenticated self-service entry point for requesting a new Reunion.
  • Email links are conveniences, not authorization secrets. Authentication, current membership eligibility and the stored Reunion authorization relationship control consequential access.
  • There is no separate My Reunions Ready Room destination. The duplicate introduced during the self-service installation is superseded by the established My Reunion Events destination.

Reunion Keeper Handoff Gate

  • Every Reunion Unit requires one primary accountable current member and at least one continuity current member before active stewardship is established.
  • Before a proof/test Reunion is renamed or transferred to its real keepers, verify the intended primary and continuity member email/account relationships first.
  • The Drupal UID is the durable identity. An account email that is being changed must be verified before the new email becomes authoritative.
  • Until both keeper identity/email checks pass, do not rename the proof Event, reassign ownership, establish keeper relationships, or send permanent keeper instructions.
  • After verified handoff, keeper instructions explain the distinction between the public Association > Reunions destination and the authenticated Ready Room > My Reunion Events management/recovery destination.

2026 A-4 Skyhawk Reunion Acceptance Corpus

  1. July 2026 Newsletter: bootstrap source. It must
    create the Event.
  2. August 2026 Newsletter: update/reconciliation
    source. It must update the same Event and identify meaningful
    changes without duplicate nodes.
  3. September 2026 Newsletter: final current
    pre-event source. It must reconcile the same Event to the current
    state while preserving July and August as prior updates.

The September result should be equivalent in current Event facts
to a correct direct September creation, while retaining the prior
source/update history produced by July and August.

Event Lifecycle

  • One Event identity persists through pre-event, live-event, and
    post-event use.
  • Dates and deadlines should drive phase/status automatically where
    practical, with an authorized override when real life differs.
  • Hotel, registration, travel/flight, transportation and discount
    information may include links, discount codes/rates, booking or
    registration cutoff dates, and other actionable deadlines.
  • Responsible managers receive reasonable deadline/staleness
    nudges so they can review the Event page and send updates.
  • Send Update means a Drupal-mediated reminder to the responsible
    manager, not a broadcast to members.

Members-Only Event Participation

  • Reunion and BOD Meeting Event/photo destinations may be
    members-only according to template policy.
  • Anonymous visitors receive a friendly explanation and login/join
    path instead of relying on generic Drupal access-denied messaging.
  • A valid bootstrap/intake token may authorize contribution without
    granting access to otherwise restricted destination content.
  • Once the Event exists, authenticated members may contribute
    photos directly without another upload token where policy permits.

Photo Batches and Comments

  • A photo upload creates a batch associated with the Event and the
    authenticated member UID.
  • Displayed contributor identity uses callsign when available,
    otherwise first name, while authoritative provenance retains UID
    and appropriate internal identity data.
  • Each batch has one group heading/comment displayed with the
    thumbnail collection.
  • Individual photo comments/names are optional and belong primarily
    with the enlarged/full-photo presentation rather than cluttering
    the thumbnail grid.
  • The photo contributor moderates comments submitted against their
    photos/batch.
  • Pending commenters are told that moderation is pending.
  • Pending comments have a maximum 30-day moderation period with
    reasonable reminder nudges. If no action occurs by day 30, the
    comment publishes automatically.
  • Authorized staff retain exceptional moderation authority.

ZIP Photo Transport

  • ZIP is a transport container, not a gallery object.
  • Supported photographs are safely extracted and become normal
    Drupal-managed photo/media assets.
  • Thumbnail and full-size display use normal Drupal image/media
    facilities and Views.
  • The ZIP is deleted after extraction, file-count/reconciliation,
    destination association, and usable photo display are positively
    verified.
  • The individual extracted photographs are the durable assets
    unless a particular future intake policy explicitly requires
    archival preservation of the original ZIP.

BOD Meeting Parity

The current Board/leadership page is outside this work. The Event
framework applies to pre/live/post BOD Meeting announcement and
history pages: source documents, Event facts, links, documents,
member photos, batches and comments use the same common framework
with BOD-specific labels/policy rather than a separate uploader.

User-Facing Messaging

Success, information and error/action-required messages remain
inline, subdued and aesthetically integrated, but positioned and
styled so that a user is unlikely to miss required action. Generic
Drupal messenger popups are not the target UX for these custom
member-facing workflows.

CURRENT STATE - GENERIC INTAKE SYSTEM

Project: Generic Intake System

Status: In development

Ultimate goal: A self-service, reusable, aesthetically integrated intake framework that lets authorized nontechnical Ready Room users create purpose-specific public file requests without webmaster assistance. The underlying upload engine remains generic for future uses.

Current accepted functionality:

  • Drupal core managed_file owns automatic initial file transfer.
  • Generic file acceptance is proven. Format-specific diagnosis is closed absent contradictory evidence.
  • Token-specific private storage under private://uploads/[token]/ is proven.
  • Finish submission and permanent-file finalization are proven.
  • Reusable token behavior is proven.
  • The current Pixel/Chrome public upload presentation is accepted.
  • The redundant generic Upload title is closed work.
  • Public Drupal status-popup behavior was corrected toward the established inline PageMessage pattern.

Accepted request/invitation gate: real Ready Room testing proved explicit recipient routing, request-data persistence, the canonical https://skyhawk.org/upload/{token} invitation, the same stored request instructions in the actual email and public upload page, and on-page Ready Room request confirmation. Accepted by Report-ID 20260830T161100Z-2299062. Current implementation slice: prove the shared Event framework with the real 2026 A-4 Skyhawk Reunion corpus. JULY creates exactly one Event; AUGUST reconciles that same Event; SEPTEMBER reconciles the same Event to the current pre-event state while preserving prior updates. No duplicate Event nodes.

Next implementation principle: preserve the proven uploader/finalization engine and evolve the surrounding request-management system. Do not rewrite the working upload path merely to implement the broader framework.

Closed work: extension and MIME enumeration, image-versus-video diagnosis, synthetic upload triggering, custom serializer/queue transfer experiments, generic Upload page title, and repeated reproving of accepted core transfer/finalization behavior.

Reopen closed work only when: new contradictory functional evidence demonstrates that the accepted behavior is no longer true.

Current Agreed Product Decisions

  • The Ready Room menu links directly to an Upload Requests dashboard. Individual public requests do not become menu entries.
  • Granular Drupal permissions, assigned to roles, govern creation, management, reassignment, lifecycle actions, viewing submissions, and permanent deletion.
  • Request-specific instructions are entered once and dynamically reused in both the invitation email and public upload page. The live page is authoritative when instructions change.
  • The underlying uploader remains format-agnostic even when a request expects ZIP files, photographs, video, documents, or other material.
  • Public size language uses industry-standard decimal MB where 1 MB equals 1,000,000 bytes, plus the exact comma-separated byte count where useful.
  • The configured limit is per individual file, not the aggregate of multiple files in a submission.
  • Large collections are split among multiple files or ZIP archives rather than reducing original photo or video quality merely to fit a limit.
  • Removal before Finish submission is required. Each file gets a clear individual Remove action rather than Drupal selection checkboxes.
  • The pre-finish manifest shows filename, MB, exact bytes, status, and Remove, plus file count and aggregate size.
  • Resumable transfer is desirable for large files if a maintained Drupal-compatible solution can provide it simply. Do not build a custom resumable-upload platform.
  • SA controls stored/internal filenames for sortable, collision-resistant recovery. Original contributor filenames remain preserved as metadata. Database fields, not filename parsing, remain authoritative for Views.
  • Each request has an immutable human-friendly ID and each Finish submission has a batch identity.
  • Useful provenance is retained, including original/generated filename, request, batch, known source/contributor information, timestamps, size, and relevant supplied metadata.
  • Exact duplicate hashes may be retained for integrity and later duplicate identification, but exact duplicates are not automatically rejected because provenance can differ.
  • The responsible party determines the intended disposition of each request. Receipt and automatic publication are separate concepts.
  • Original files are preserved by default, while storage and retention policy may be revisited if storage becomes a material constraint.
  • ZIP preservation or extraction depends on purpose, permissions, and downstream workflow rather than one universal rule.
  • Copyright remains with whoever legally owns it. Upload does not itself transfer copyright to SA.
  • Contributors should represent, to the best of their knowledge, that they are entitled to provide the material and are not knowingly violating another persons rights.
  • Applicable photo policy grants SA appropriate continuing non-exclusive permission to preserve, reproduce, migrate or convert, adapt for presentation, publish, and use contributed material in Association activities and publications.
  • SA remains the sole arbiter of whether and under what conditions photographs administered or distributed through the SA website are provided or authorized for third-party use, without claiming copyright SA does not own.
  • Known photographer/source and SA credit may both be used publicly as appropriate, while full provenance remains preserved internally.
  • The upload system does not ask contributors to manage future contact requests. SA may forward a legitimate contact request to the known owner/source. The requester is told that no response within the defined period means no permission or contact. Silence is never consent.
  • Photo-oriented requests may support both a batch description and optional per-photo descriptions plus other appropriate configurable metadata.
  • The exact applicable rights/agreement version, request, batch, and acceptance time are retained.
  • The existing photo-contribution workflow is superseded only after the generic framework proves equivalent or better required functionality.
  • Successful submission normally produces one internal summary per completed batch.
  • Requests may generate up to two sensible expiration reminders, but any successful submission cancels outstanding reminder prompting for that request.
  • The system does not automatically nag the contributor. The creator can resend the active request and current dynamically generated instructions.
  • Successful received material is not automatically deleted. Truly abandoned temporary material may be cleaned up conservatively under documented policy.
  • Arbitrary contributed files are treated as untrusted until appropriately reviewed or scanned. Prefer a simple maintained scanning mechanism rather than custom antivirus infrastructure.
  • Desktop, tablet, and mobile are supported where practical. Device parity must not make important functionality unreasonably complex or impossible.
  • After Finish submission, show a meaningful receipt before offering Upload another batch while the request remains active.
  • Errors remain inline and explain what happened, why, and what the contributor should do. Successfully transferred files are not needlessly retransmitted because another file failed.
  • KISS governs implementation.

Implementation order: request data model and Ready Room dashboard; shared instructions and email workflow; public manifest/removal/size/receipt/error UX; naming/batch/history/accounting/provenance/hash; permissions/expiration/reminders/lifecycle; then evaluate maintained resumable upload and malware scanning; replace photo-contribute only after parity is proven.

Deterministic AI instruction: routine work on this project must begin by rereading the ACTIVE RULES block and this CURRENT STATE block. Deeper historical or diagnostic material is supporting evidence and must not override current accepted truth unless new evidence changes that truth.

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 proven. File-format diagnosis is closed.

Finish submission permanent-file transition: ACCEPTED. Direct Pixel testing proved selection, automatic upload, Finish submission, permanent managed-file state in private://uploads/[token]/, and reset of the form for another batch.

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

Current acceptance boundary: upload history. The first remaining unproven transition is whether Finish submission creates the required skyhawk_upload_file history row for each finalized file. Do not reopen generic upload, permanent-file finalization, or the accepted Pixel UX while resolving 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.