Pinakes v0.7.80
·
184 commits
to main
since this release
Immutable
release. Only release title and notes can be modified.
Circulation hardening: database-level integrity for the loan/reservation lifecycle, durable circulation emails, and richer lost/damaged handling (PR #415).
Added
- Durable email outbox. Failed terminal circulation notifications land in the new
email_delivery_outboxtable (migrationmigrate_0.7.80.sql, plus a runtime-compatible creator for mixed-version deployments) and are retried with claim tokens and exponential backoff; permanently undeliverable rows are discarded after 10 attempts and logged, so dead rows neither pile up nor retain recipient data forever. Transaction-safe on both MySQL and MariaDB. - Two new circulation emails, shipped in all five locales (code templates, installer seeds and settings editor): reservation assigned — awaiting approval (the reader is told a copy is allocated but must wait for the pickup email) and loan closed with a lost/damaged copy, including the outcome, closing date, notes and the charged amount formatted with the configured
app.currency. - Assessed amount on lost/damaged returns. The return form gains an optional charge field (decimal-comma tolerant, validated server-side) recorded on the loan and included in the outcome email.
Changed
- Database triggers now guard the circulation invariants: a loan start after its due date, non-positive or duplicate active queue positions, double active reservations for the same user and book, and invalid reservation windows are rejected at the source — protecting against malformed imports and direct SQL as well as application bugs. Every queue reorder (user/admin/approval/NCIP cancellations, integrity repair, ReservationManager) moves rows through a dynamically-computed temporary range first, so reorders can never trip the new guards mid-flight, even with legacy NULL positions or leftovers from interrupted runs.
- Expiry sweeps and scheduled-loan activation were hardened around the new invariants; barcode returns accept active loans on archived titles without violating the soft-delete rule.
Fixed
- The transaction probe guarding outbox creation used a MariaDB-only system variable and silently disabled the outbox on MySQL; it now uses the portable autocommit + savepoint probe.
Testing
- New behavioural suites:
circulation-hardening-0780(22 checks),email-outbox-0780(8),migration-0.7.80(real-file sandbox, idempotency);loan-edge-casesgrew to 68 scenarios and its fixtures now satisfy the triggers they exercise; adversarial reproductions for the queue-reorder collision cases.
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.