Skip to content

Pinakes v0.7.62

Choose a tag to compare

@github-actions github-actions released this 20 Aug 11:06
· 162 commits to main since this release
0b5c4b7

Overdue-loan recalls (solleciti) and emailing the loan receipt (#360).

Features

  • Loan recalls (solleciti): overdue loans can now be chased beyond the
    single overdue notification. Automatic recalls repeat at a configurable
    interval up to a configurable cap (Settings → Loans → "Solleciti automatici",
    off by default; sent by the notifications cron or on admin login). Staff can
    also send a manual recall for one loan — from the loan detail page or a
    per-row action on the loans list — or for many at once from the loans list
    via the bulk action bar — manual recalls ignore
    the automatic schedule but share the same per-loan counter
    (prestiti.recall_count / last_recall_at, added by
    migrate_0.7.62-rc.1.sql and self-healed at runtime). New editable email
    template loan_recall_notification in all five locales.
  • Email the loan receipt PDF: next to "Scarica Ricevuta PDF", the loan
    detail page now has "Invia Ricevuta via Email", which sends the same PDF as
    an attachment to the loan's user (new editable template
    loan_receipt_email; the mailer gained in-memory attachment support).
  • Emails in the recipient's language: user-facing notification emails
    (loan warnings/overdue/recalls, receipt, approvals, pickups, returns,
    reservations, wishlist, registration and account emails — and per-admin for
    admin alerts) now render in the recipient's preferred language
    (utenti.locale, the same value that drives their UI language), including
    date formats and translated labels, falling back to the installation locale
    when the user has none. Password-reset mail already followed the
    requester's session language.
  • Language choice at registration: on multi-language installs the
    registration form now offers a "Lingua preferita" select (defaulting to the
    language the visitor is browsing in), validated server-side against the
    shipped locales. The profile page and the admin user forms already offered
    the same choice; together they cover registration, self-service and admin.
  • Plugin ZIP updates (#358): uploading a plugin ZIP whose name matches an
    already-installed plugin now updates it in place — its id, settings, data and
    hooks are preserved and its files are swapped atomically — instead of failing
    on the existing directory. Updating an already-active plugin now runs its new
    lifecycle (onActivate()/ensureSchema()) on the next request via a
    pending-update marker, rolling back package, metadata and hooks if the new
    version fails to activate — so schema changes shipped in an update are applied
    instead of being silently skipped. Covered by contract and per-bundled-plugin
    integration tests.

Fixed

  • Book announced "ready for pickup" while still on an overdue loan (#366):
    a reservation scheduled right after a loan that then went overdue and was
    never returned was promoted to da_ritirare on its date alone, emailing the
    next patron a wrong "ready for pickup" notice while the book was still out.
    Promotion is now gated on a copy being physically free (active loans below the
    copy count; a pinned copy must be on the shelf). The full reported sequence is
    covered too: rescheduling an open reservation/pickup no longer leaves a stale
    pickup_deadline for the expiry sweep to cull a valid loan against, the
    overdue flip now runs first in the maintenance pass so an unreturned overdue
    loan keeps holding its copy, and renew() refuses a date-overdue loan.
  • Concurrent circulation actions no longer corrupt state: eight
    transactions (approve/return/reject/cancel loan and reservation) resolved the
    loan id with a plain read before taking the book lock, so under REPEATABLE
    READ their later reads were blind to a competitor that had just committed.
    A just-cancelled reservation could be promoted and emailed, and one physical
    copy could be committed to two loans. The lookups now run before the
    transaction so the first locked read fixes the snapshot, and reservation
    promotion claims the row with a state-guarded update.
  • Pickup confirmation now refuses a copy that is still out on another loan
    (prestato), preventing a double issue of the same physical copy.
  • Admin reservation cancellation now promotes the next reservation in the
    queue immediately, like every other path that frees a copy.
  • Overdue notices and automatic recalls now fire for loans whose book has
    been archived (soft-deleted) — the chase-up mail no longer filters those out.
  • The "reservation available" email can no longer be sent twice when the
    retry sweep races the request that promoted it.
  • Admin direct loans cap the pickup deadline at the due date; bulk loan
    extension and reschedules re-check borrower eligibility; expiry audit notes
    use the same day the decision was made near midnight.

Internal

  • CI: the OWASP ZAP baseline no longer fails on the ISBN/EAN-13 PII-disclosure
    false positive, allowlisted narrowly to 13-digit codes on bibliographic pages
    (#359).
  • Release verifiers now require storage/sessions/.gitkeep and reject every
    other entry there (files, symlinks, stray directories), and an unreadable
    plugin-update marker is retired instead of permanently blocking future
    updates of that plugin.

The ZIP was built twice with an identical SHA-256, audited as the
exact distributable, accompanied by an SPDX SBOM, and signed with
a GitHub artifact provenance attestation.