ticket: site metadata header + scannable Albanian ticket; widen barcode

- site_config gains optional park identity (park_name, operator_name, nius,
  address, phone, email); additive Drizzle migration 0001. GET/PUT
  /api/site-config read/write the full config (PUT partial patch, admin only);
  SiteSettings + SetupWizard expose the fields.
- renderTicket() prints an Albanian header sourced from site_config, the
  all-numeric 13-digit ticket id (12 random + Luhn) as Code128, large digits,
  and a lost-ticket footer. CP852 codepage so ë/ç render.
- Widen the Code128 module width 2->3 and height 80->100 dots so the
  short-range "Simple" QR/barcode reader decodes reliably (was barely reading
  at module width 2 on the 80mm head).

See wiki/concepts/site-metadata.md and ticket-encoding.md.
This commit is contained in:
2026-06-17 12:17:21 +02:00
parent 1efa77bf56
commit 727c62da90
20 changed files with 1596 additions and 155 deletions
+14
View File
@@ -190,9 +190,23 @@ export interface Snapshot {
}
// --- Printers (ticket dispenser / booth printer) -------------------------
/** Optional park identity printed at the top of a ticket/receipt. All fields
* optional — the driver prints only what's set. Sourced from site_config; an
* Albanian parking receipt commonly must show the park name + NIUS. */
export interface TicketHeader {
readonly parkName?: string | null;
readonly operatorName?: string | null;
/** NIUS — Albanian tax/identification number. */
readonly nius?: string | null;
readonly address?: string | null;
readonly phone?: string | null;
}
export interface TicketData {
readonly ticketId: string;
readonly issuedAt: string; // ISO-8601
/** Park identity for the header. Absent → driver prints the generic "PARKING". */
readonly header?: TicketHeader;
}
export interface PrinterDevice extends Device {