commit e7b15a675ad9b525074947903229fc4f858feead Author: Lucas Gass Date: Tue Mar 24 16:50:43 2026 +0000 Bug 42166: Check for 008 before adding the date to it To test: 1. Edit or create a framework that does not require the 008. 2. Make or edit a record in that framework without a 008. 3. Turn on EnableAdvancedCatalogingEditor, and make sure you are using the advanced editor. 4. Go to the record from step 2 and click "Edit as new (duplicate)" 5. The record won't load in the advanced editor. 6. APPLY PATCH 7. Try again, this time the record should load when using "Edit as new (duplicate)". commit 89aa40cc1ea3d2fa9b1beb2cc04a87e2d1289e1a Author: Jonathan Druart Date: Tue Mar 24 17:07:30 2026 +0100 Bug 41460: Fix ALTER TABLE statement Signed-off-by: Jonathan Druart commit 852a8b802f168438928573750627babcb43ab7de Author: Martin Renvoize Date: Tue Mar 24 16:10:01 2026 +0100 Bug 40853: (RM follow-up) Fix re-base error commit caae75e80507d717cc8252bafe6844e51f1693bb Author: Martin Renvoize Date: Tue Mar 24 15:39:09 2026 +0100 Bug 40853: DBRev 25.12.00.036 Signed-off-by: Martin Renvoize commit 02fa01e146637fea697c447915affac534188805 Author: Nick Clemens Date: Fri Oct 3 19:22:06 2025 +0000 Bug 40853: Add ElasticsearchBoostFieldMatchAmount system preference This adds a new system preference to control the amount of boost. The default of 0 will act as before this patch. You can add any positive number, or a number between 0 and 1 for negative boost To test: 1 - Add a record with 245 $a novel 2 - Add a record with 245 $a A novel : $b about things / $c by me 3 - Search for: novel 4 - Search for: a novel 5 - Apply patch, restart all 6 - Repeat searches, note exact titles are boosted 7 - Test with more titles as you are able Signed-off-by: Jason Robb Signed-off-by: Thomas Klausner Signed-off-by: Martin Renvoize commit 06fa7499606b5bb51ad98e169929ee70e701ec7f Author: Nick Clemens Date: Fri Oct 3 19:35:43 2025 +0000 Bug 40853: Unit tests Signed-off-by: Jason Robb Signed-off-by: Thomas Klausner Signed-off-by: Martin Renvoize commit b18fbab8061ff97a7ae087ab89f2888a9223e5f5 Author: Martin Renvoize Date: Tue Mar 24 09:46:03 2026 +0100 Bug 39781: (QA follow-up) Fix crashes, dead code and add tests - Fix potential crash when C4::Context->userenv returns undef: use the established ternary guard pattern used throughout other TT plugins (AuthorisedValues, Branches, Desks, etc.) - Remove dead second argument passed to GetLettersAvailableForALibrary, which only accepts one argument; the group_by/columns/order_by hashref was silently dropped - Fix typo "librries" -> "libraries" in GetByModuleForLibrary POD - Update POD example to use 'add_message' module matching actual usage - Add test coverage for GetByModuleForLibrary, verifying that a user logged in to a branch sees branch-specific and all-libraries notices, while users at other branches see only all-libraries notices Signed-off-by: Martin Renvoize commit 5937d40a280a739bd07baeda0b5f5c02bc184b32 Author: Andrew Fuerste-Henry Date: Mon Mar 16 13:35:40 2026 +0000 Bug 39781: Add POD coverage Signed-off-by: Juliet Heltibridle Signed-off-by: Martin Renvoize commit 3a1bd59197a207d49bb1a2e30ce4349352b70ef2 Author: Andrew Fuerste-Henry Date: Sat Mar 14 18:25:16 2026 +0000 Bug 39781: Allow limiting of custom message notices by library To test The following should work with either email or SMS notices sent from the Add Message button in a patron record 1 - create a notice in module Patrons (custom message) for all libraries 2 - create a notice in module Patrons (custom message) for Centerville 3 - while logged in at Centerville, confirm you can see and enqueue your all libraries message 4 - while logged in at Centerville, confirm you can see but cannot successfully enqueue your Centerville message 5 - while logged in at Fairfield, confirm you can see but cannot successfully enqueue your Centerville message 6 - apply patch, restart_all 7 - while logged in at Fairfield, confirm you can see and enqueue your all libraries message 8 - while logged in at Fairfield, confirm you cannot see your Centerville message 9 - while logged in at Centervielle, confirm you can see and enqueue your Centerville message Signed-off-by: Juliet Heltibridle Signed-off-by: Martin Renvoize commit ea5936b15a7a371846823cfa9b52bf913903f8a4 Author: Martin Renvoize Date: Tue Mar 24 15:36:52 2026 +0100 Bug 42083: DBRev 25.12.00.035 Signed-off-by: Martin Renvoize commit 8eec766b5a2713c25b950d55b82ecbc8cfe1e37b Author: Martin Renvoize Date: Tue Mar 24 09:19:43 2026 +0100 Bug 42083: (QA follow-up) Simplify atomicupdate migration loop Replace the O(n²) accumulate-and-re-insert pattern with a simple per-row execute inside the while loop. Signed-off-by: Martin Renvoize commit 3dd4691076d822ef44b0aae0a86329aac5a6a3da Author: Andrew Fuerste-Henry Date: Thu Mar 12 23:00:27 2026 +0000 Bug 42083: Implement distinct permissions To test: 1 - have an staff account with 'send_messages_to_borrowers' permission but not top level 'borrowers' permission 2 - have a value in SMSSendDriver system preference 3 - log in under your staff account and confirm you can send both email and SMS messages from the Add Message button on a patron record 4 - apply patch, updatedatabase, restart_all 5 - confirm your staff account now has 'send_messages_to_borrowers_email' permission rather than 'send_messages_to_borrowers' 6 - confirm your staff account can now only send email messages from the Add Message button on a patron record 7 - add 'send_messages_to_borrowers_sms' permission to your staff account 8 - confirm your staff account can now send both email and sms messages from the Add Message button on a patron record 9 - remove 'send_messages_to_borrowers_email' from your staff account 10 - confirm your staff account can now only send sms messages from the Add Message button on a patron record Signed-off-by: Juliet Heltibridle Signed-off-by: Martin Renvoize commit 6b51873f9c5e8d8cc988a3ff46b8b008bf8dc15d Author: Andrew Fuerste-Henry Date: Thu Mar 12 21:54:09 2026 +0000 Bug 42083: atomicupdate for permissions Signed-off-by: Juliet Heltibridle Signed-off-by: Martin Renvoize commit 153a18d6038fbd9005e9421460f52899547b8c9c Author: Andrew Fuerste-Henry Date: Thu Mar 12 20:02:07 2026 +0000 Bug 42083: Create distinct permissions Signed-off-by: Juliet Heltibridle Signed-off-by: Martin Renvoize commit 9d39d80801389c1446cb470a37ab70ec21552dee Author: Martin Renvoize Date: Fri Mar 6 10:28:47 2026 +0000 Bug 42010: Escape EDIFACT special characters in BGM purchase order number Bug 20253 introduced the ability to use the basket name as a purchase order number in the BGM segment of an EDIFACT order message. However, the basket name was inserted into the BGM segment without escaping EDIFACT special characters (apostrophe, colon, plus, question mark). In EDIFACT, the apostrophe (') is the segment terminator, so any literal apostrophe in data must be escaped with the release character (?) as ?'. Without this, a basket name like "Children's Requests" would produce an invalid EDIFACT message. This fix applies encode_text() to the purchase order number in beginning_of_message() so all special characters are properly escaped. Test plan: - Run t/db_dependent/Koha/Edifact/Order.t - All tests should pass, including the new tests covering special character escaping in BGM segments Signed-off-by: Graham Jones Signed-off-by: Martin Renvoize commit 0d84b49ea7fb91171f1c2e07abd94bb54007ae86 Author: Nick Clemens Date: Tue Mar 24 08:57:30 2026 +0000 Bug 41959: (QA follow-up) Add missing POD Signed-off-by: Martin Renvoize commit 6fbcedd5db9713c856c4ba5658c400fa35ad366f Author: Andreas Jonsson Date: Fri Mar 6 20:21:50 2026 +0000 Bug 41959: Handle edge case Signed-off-by: Nick Clemens Signed-off-by: Martin Renvoize commit 890ce7cc49dcf071d7cd58936e975cf7995c07aa Author: Nick Clemens Date: Thu Mar 5 20:32:46 2026 +0000 Bug 41959: Unit tests This adds a test for the condition where there are 2 holds, 1 item, and the item cannot fulfill the first hold Signed-off-by: Nick Clemens Signed-off-by: Martin Renvoize commit 97d980a7ba358b4a06255cec58b655d296fe14f0 Author: Martin Renvoize Date: Tue Mar 24 15:34:12 2026 +0100 Bug 41460: DBRev 25.12.00.034 Signed-off-by: Martin Renvoize commit 7cebccb76f3927d6be4d80fc1079e6b65c577461 Author: Michael Hafen Date: Tue Dec 16 11:40:30 2025 -0700 Bug 41460: Remove default value from mediumtext column systempreferences.value Mysql doesn't allow text type columns to have a default. Signed-off-by: Martin Renvoize commit 1544020e57bcad18afa1ef3175d96d41e70531dd Author: Martin Renvoize Date: Tue Mar 24 12:19:31 2026 +0100 Revert "Bug 41247: Add cypress tests" This reverts commit e838b70be7cccdabd41b19469f422c73cb067151. commit 8d14dbe0f149a0882dbe0cc48558df8d0734eb23 Author: Martin Renvoize Date: Tue Mar 24 12:19:06 2026 +0100 Revert "Bug 41247: (follow-up) Fix Cypress test after administration rename" This reverts commit b7eea37e1abaa2447f79a2685c179db208f23ac1. commit aa895e95c5e1d4e12f368faed7b27506c5ea57c9 Author: Martin Renvoize Date: Tue Mar 24 12:17:58 2026 +0100 Revert "Bug 41247: Preparation: Cypress XML plugin" This reverts commit 0387ebfb97c11bd31776f9bdd79737c5fa287ded. commit 7077634044182d8bcfea24fccd4565980b2fbc8b Author: Martin Renvoize Date: Tue Mar 24 12:17:41 2026 +0100 Revert "Bug 41247: Improve ILL batches modal resetability" This reverts commit b591b668d29611fe6b9ece85cd7ec3e4293cae62. commit a12aac8957efad724ab5a30f3d221567b460967c Author: Jonathan Druart Date: Fri Jan 23 10:35:53 2026 +0100 Bug 41521: Silent perlcritic warnings Stricture disabled at line 67, column 5. See page 429 of PBP. (Severity: 5) We should deal with that later instead of ignoring the warnings Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit d0ee8f5a6e9cb4bebb209c05e938c8111273cdb2 Author: Jonathan Druart Date: Fri Jan 23 10:31:32 2026 +0100 Bug 41521: Fix forbidden patterns (trailing spaces and http) Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit 8c46e76045046d66e10a18a340728c84e4bb1cca Author: Jonathan Druart Date: Fri Jan 23 10:28:27 2026 +0100 Bug 41521: Fix spelling Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit bbf43f465e6b4e7f2cf555ad3eecf830d9f1a0f0 Author: Jonathan Druart Date: Fri Jan 23 10:22:23 2026 +0100 Bug 41521: Exclude lib/WebService from pod xt tests Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit f9788889f3866f687f0049d37133e5ad92e7dec8 Author: Jonathan Druart Date: Fri Jan 23 10:06:23 2026 +0100 Bug 41521: Remove deps from cpanfile Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit b7b85b3eebfe101dd25db822a3689c419dc2226c Author: Jonathan Druart Date: Fri Jan 23 09:55:06 2026 +0100 Bug 41521: Reject lib/ from tidy check Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit b4b62d082073d8a312b25b78c37906ad05a6f87d Author: Jonathan Druart Date: Fri Jan 23 09:32:16 2026 +0100 Bug 41521: Remove perl valid warnings % perl -wc Koha/ExternalContent/OverDrive.pm Possible precedence issue with control flow operator (die) at /kohadevbox/koha/lib/WebService/ILS/OverDrive/Patron.pm line 365. Possible precedence issue with control flow operator (die) at /kohadevbox/koha/lib/WebService/ILS/OverDrive/Patron.pm line 573. Possible precedence issue with control flow operator (die) at /kohadevbox/koha/lib/WebService/ILS/OverDrive/Patron.pm line 643. Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit 5d516102c82feb4b5100acc05803b412e30c337f Author: Jonathan Druart Date: Fri Jan 23 09:29:51 2026 +0100 Bug 41521: Add WebService::ILS to lib/ Signed-off-by: Victor Grousset/tuxayo Signed-off-by: David Cook Signed-off-by: Martin Renvoize commit 63a1924b271584c25b4a120c0318a5ca79c9f6d5 Author: Hammat Wele Date: Thu Nov 13 13:23:55 2025 +0000 Bug 33857: Avoid increasing file size while uploading image This patch prevents image size from increasing while uploading by keeping the original image format Test plan: 1. Download the attached image large-image.jpg --> It should be ~170kB and 1000×1500 pixels 2. Enable LocalCoverImages in System preferences 3. Find a record in the staff interface 4. Go to "Images" tab 5. Upload large-image.jpg image 5.1. Click on "Upload" 5.2. Click on "Drop files here or click to select a file" 5.3. Choose picture (large-image.jpg) 5.4. Click on "Process images" 6. Click on image for large image 7. Right-click on the image and save it --> It is ~930kB and 600x900 pixels 8. Apply the patch and flush browser cache (Crtl+F5) to update js files 9. Detele the previous uploaded image 10. Repeat step 3, 4, 5, 6, 7 --> The image is ~92kB and 600x900 pixels 11. prove t/db_dependent/Koha/CoverImages.t --> All tests should be successful Signed-off-by: Owen Leonard Signed-off-by: Kyle M Hall Signed-off-by: Martin Renvoize commit 699ba06eb70d3488fba0ba47f406ffe4fe96f4f9 Author: Emily Lamancusa Date: Mon Mar 23 13:22:04 2026 -0400 Bug 41386: (QA follow-up) Make sure charge is defined Check that $charge is defined before comparing, to avoid "argument isn't numeric" error if no charge is defined. Signed-off-by: Emily Lamancusa Signed-off-by: Martin Renvoize commit b33a7c1df45ff82c07a744a0b803641c111f8d8c Author: Emmi Takkinen Date: Tue Dec 9 14:56:09 2025 +0200 Bug 41386: Do not allow 0.00 values to be passed from Koha::Hold->cancel In method Koha::Hold->cancel in the section where we charge a cancel fee there is a if statement "if $charge" after calling sub add_debit. This allows value "0.00" to be passed to the add_debit and it then gets caught in statement "unless ( $amount > 0 )" which calls exception AmountNotPositive. This happens at least when syspref ExpireReservesMaxPickUpDelayCharge or circulation rule "Expired hold charge" has value 0.00 and cronscript cancel_expired_holds.pl is run. This patch fixes the if statement in Koha::Hold->cancel. To test: 1. Enable syspref ExpireReservesMaxPickUpDelay. 2. Set syspref ReservesMaxPickUpDelay value as 1. 3. Set syspref ExpireReservesMaxPickUpDelayCharge value as 0.00. 4. Make sure you have a waiting hold which has expiration date further in the past than ReservesMaxPickUpDelay value in your database. If not, create one. 5. Run cronscript cancel_expired_holds.pl. => Exception 'Koha::Exceptions::Account::AmountNotPositive' thrown 'Debit amount passed is not positive' is raised. 6. Set syspref ExpireReservesMaxPickUpDelayCharge value as 0 and run cronscript again. => No exception is raised. 7. Apply this patch and restart services if needed. 8. Create a new waiting hold with expiration date in the past. 9. Run cronscript again. => No exception is raised. => Confirm that no cancel fee was added for patron. Also prove t/db_dependent/Koha/Holds.t. Sponsored-by: Koha-Suomi Oy Signed-off-by: Bernard Scaife Signed-off-by: David Nind Signed-off-by: Emily Lamancusa Signed-off-by: Martin Renvoize commit f26e9344b001f9c9c838b6dea1f242c0a69e5c20 Author: Martin Renvoize Date: Tue Mar 24 09:53:49 2026 +0100 Bug 41479: DBRev 25.12.00.033 Signed-off-by: Martin Renvoize commit 2e853287f869b0ef7b3e0a92666f5062ed79b4fa Author: Owen Leonard Date: Wed Mar 18 08:41:44 2026 -0400 Bug 41479: (follow-up) Remove bakertaylorimages.js Signed-off-by: Jonathan Druart Signed-off-by: Martin Renvoize commit 41ea86bc27d660ed8c9dede89fd62c75d844d3eb Author: Owen Leonard Date: Thu Dec 18 08:49:32 2025 -0500 Bug 41479: Remove Baker & Taylor integration This patch removes Baker & Taylor integration following the shutdown of the company. To test, apply the patch, run the database update, and restart all. - In the staff interface go to Administration -> System preferences and search for 'Baker.' There should be no results. - If necessary enable at least one cover image service, e.g. AmazonCoverImages, OpacCoce, GoogleJackets, etc. - Log in to the OPAC and confirm that cover images display correctly on these pages: - Search results - Bibliographic detail page - Shelf browser - Your summary -> Checked out - Checkout history - Recent comments - Lists Sponsored-by: Athens County Public Libraries Signed-off-by: David Nind Signed-off-by: Jonathan Druart Signed-off-by: Martin Renvoize commit 101f292a5af8150cdb80e680e980cedbcb8410bd Author: Pedro Amorim Date: Fri Mar 13 11:54:45 2026 +0000 Bug 41614: available options template params also needed for op=list Test plan, before applying patch: 1) Visit additional contents for HTML customizations: /cgi-bin/koha/tools/additional-contents.pl?category=html_customizations 2) Click the left side 'Display location' filter. No options show under OPAC or Staff interface 3) Apply patch, restart plack, refresh. All options should now show (and working filter as expected) under OPAC and Staff interface Signed-off-by: David Nind Signed-off-by: Katrin Fischer Signed-off-by: Martin Renvoize commit 46f618d3c4e36fd2723334b01a34739fe85bd52b Author: Martin Renvoize Date: Mon Mar 23 13:01:25 2026 +0100 Bug 40286: (RM follow-up) Make codespell happy commit 50df5d5acaf8b21ee242318a8173c32c172c9ae5 Author: Martin Renvoize Date: Mon Mar 23 11:14:40 2026 +0100 Bug 40136: (RM follow-up) Add missing pod coverage for private subs Signed-off-by: Martin Renvoize commit 863b68b1356a27f1a023a53e7f57409bcef05f54 Author: Martin Renvoize Date: Mon Mar 23 11:05:36 2026 +0100 Bug 40136: (RM follow-up) Fix logaction to JSON-encode plain hashref infos Commit 55689d41ba6 changed Koha::Patron::extended_attributes() and add_extended_attribute() to pass plain hashrefs to logaction() and updated tests to expect JSON in the info column. However, logaction() still had a code path that converted any non-CATALOGUING hashref $infos to a Dumper() string before the encode_json() at line 151 could fire, so JSON was never stored and the tests failed. Remove the catch-all Dumper branch; non-CATALOGUING hashref inputs now fall through to the existing encode_json() call. The CATALOGUING/MODIFY biblio-Dumper special case is preserved. Signed-off-by: Martin Renvoize commit 25b7068b497b0014c910f3b3d8af164f6943a3eb Author: Martin Renvoize Date: Thu Mar 12 09:23:14 2026 +0000 Bug 40136: (follow-up) Log newly-filled fields when editing a patron Previously, _unblessed_for_log strips undef/empty fields, so fields that were blank before an edit were absent from $from_storage. Because @keys was built only from keys %{$from_storage}, any field that transitioned from empty to a value was never iterated and the change went unlogged. Fix by unioning keys from both old and new state so that added, changed, and cleared fields are all detected. Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize commit f4db130ad4f9a956dfee804711bb2134b8905f6c Author: Martin Renvoize Date: Wed Mar 11 12:49:05 2026 +0000 Bug 40136: (follow-up) Unify patron log entries when attributes change with patron data Three issues were reported with patron action logging: 1. CREATE followed by extended_attributes() produced two log entries (CREATE for patron fields + MODIFY for attributes) instead of one. 2. MODIFY that changed both regular fields and patron attributes produced two separate MODIFY entries instead of one unified entry. 3. DELETE log did not include the patron's extended attribute values. Fix: - logaction() now explicitly returns the stored Koha::ActionLog object so callers can capture the action_id. - Koha::Patron::store() saves the action_id of the CREATE or MODIFY log it writes into $self->{_patron_log_id}. - Koha::Patron::extended_attributes() setter checks for _patron_log_id. If set, it calls _merge_attribute_log() to fold the attribute changes into the existing log entry (updating its info and diff JSON) instead of creating a new MODIFY entry. This covers both the CREATE and MODIFY cases. - Koha::Patron::delete() now iterates extended_attributes before deletion and adds attribute.CODE keys to the patron_data snapshot, so the DELETE diff includes the removed attributes. - New private helper _merge_attribute_log() decodes an existing action log entry's info/diff JSON, merges in the attribute change data using Struct::Diff, and saves the updated entry. - Tests added to t/db_dependent/Koha/Patrons.t covering all three scenarios. Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize commit 7287b091a45691ff8f01d23229be388bf88ff340 Author: Lisette Scheer Date: Tue Mar 10 14:27:44 2026 +0000 Bug 40136: (QA follow-up) Fix tests Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize commit 543ebdc2ff6fd5b7678f1988409203454e05cd0d Author: Martin Renvoize Date: Tue Mar 10 09:39:18 2026 +0000 Bug 40136: (follow-up) Strip undef and empty fields from patron log data Exclude fields with undef or empty string values from _unblessed_for_log so that CREATE and DELETE log diffs only show fields with meaningful values. Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize commit 55689d41ba6d6e6feabc6b19ebd9ada869d338c7 Author: Martin Renvoize Date: Mon Mar 9 22:15:08 2026 +0000 Bug 40136: (follow-up) Fix extended_attributes logaction to populate diff column The extended_attributes setter and add_extended_attribute both logged attribute changes using the old custom {before, after} format passed as the info string, with no $original argument, so the diff column was never populated. Split the existing $change->{before}/$change->{after} into separate $log_from/$log_to hashrefs and call logaction with the standard signature, so Struct::Diff generates the diff column as with other MEMBERS/MODIFY entries. Update tests to reflect the new info column format (after-state only) and remove a stray debug Data::Dumper/print left in the test. Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize commit 9ae4911704082121ac18b13491272b68809db4e0 Author: Martin Renvoize Date: Mon Mar 9 22:05:08 2026 +0000 Bug 40136: (follow-up) Refactor MODIFY log to use _unblessed_for_log Replace the manual unblessed + skip_fields + blessed-stringify logic in the MODIFY actionlog section with calls to _unblessed_for_log, which already handles all three concerns. This removes the need for @skip_fields, the dateexpiry normalisation workaround, and the inline blessed checks. Also restrict the log_from/log_to hashrefs to only the changed keys, so the diff column contains only fields that actually changed rather than the full patron state. Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize commit f83424d3dd92b7ed03fded2a4725d3043eb65e3c Author: Martin Renvoize Date: Fri Mar 6 17:02:26 2026 +0000 Bug 40136: Populate diff column for patron CREATE, MODIFY and DELETE logs Previously MEMBERS/CREATE and MEMBERS/DELETE logged empty info with no diff, and MEMBERS/MODIFY stored a custom {field:{before,after}} JSON in the info column with no diff column entry. This updates all three to use the standard logaction pattern: - CREATE: diff({}, patron_data) — all fields shown as added - MODIFY: diff(old_state, new_state) via Struct::Diff; info column now holds the full updated patron state (consistent with other modules) - DELETE: diff(patron_data, {}) — all fields shown as removed - MODIFY_CARDNUMBER: likewise uses standard pattern with diff column Password, lastseen and updated_on are excluded from all log payloads. DateTime objects (inflated date/datetime columns) are stringified to their ISO representation before JSON serialisation. Tests updated to verify changes via the diff column rather than the former custom info format. Signed-off-by: David Nind Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize commit 9d20ea636ad1780beeb4086904632a8fe1775984 Author: Lisette Scheer Date: Fri Mar 6 18:05:08 2026 +0000 Bug 20956: (QA follow-up) Restore info pretty I restored the pretty code for the info file because the page needs to be able to wrap, like it does for other logs. Signed-off-by: David Nind Signed-off-by: Lisette Scheer Signed-off-by: Martin Renvoize