Replace the check-in QR's signed token with a compact, indexed ticket hash

Resolves #3613083.

The door check-in QR encoded a ~93-char signed token (kind.uuid.expiry.HMAC), making a dense QR. The check-in route is permission-gated (check in tickets, restricted), so the QR value need not resist forging, only identify the entity. This swaps it for a compact handle: a one-char kind prefix (b/o) plus the entity's own ticket_hash (~12 chars), resolved back at the door. QR drops from ~49x49 to ~33x33 modules.

Reusable core primitives

  • yoyaku_indexed_string field type: a base field that carries its own DB index (optionally unique) in schema(), so any submodule can add indexed columns to core entities with no storage-schema-handler collision. (Composite cross-field indexes stay the storage schema's job.)
  • yoyaku_hash extends it: unique, ASCII, case-sensitive, self-generating on create (like the uuid field).

This featureyoyaku_ticket adds ticket_hash (yoyaku_hash) to the booking and the transaction; TicketHash builds/reads the handle; the QR route shortens to /yykc/; the signed TicketToken is retired (the order download link keeps its own token).

Check-in kiosk polish (a consequence of the change)

  • The manual code field and submit button are removed from view: an opaque handle is not something a person types, so the camera fills a hidden input and submits itself. This also fixes a focus-scroll that pushed the result banner off-screen (data-disable-refocus). A human fallback (typing the order number) is a separate follow-up.
  • The order summary is made responsive with container queries, so it stacks cleanly in a narrow container (the check-in banner) instead of breaking place names mid-word, while staying columnar on wide pages.

Kernel tests, README + fr.po, phpcs/phpstan/cspell/eslint/stylelint all green. Pre-1.0: field installed via installFieldStorageDefinition + backfill, no update hook.

Edited by Frank Mably

Merge request reports

Loading