Maintain patron reading history in a dedicated table.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
Evergreen |
Fix Released
|
Wishlist
|
Unassigned |
Bug Description
Evergreen all versions circa 2.9.
This bug was derived from discussion in bug #1497335.
Patron reading history is derived directly from action.circulation. This creates a number of complications and privacy concerns:
1. It complicates the circ aging process, since we cannot age circs that represent entries in an active reading history.
2. Circs that persist for reading history are accessible via API and appear in staff interfaces when they otherwise would not. The goal of reading history is to allow patrons to see their own history, but as is, it also allows staff to see a patron's reading history. There are some protections in place here, but they are not applied universally and are easily and sometimes unintentionally bypassed via API.
2. Patrons cannot (truly) remove specific items from their history, since they have no way of deleting circulations, short of disabling all reading history. (See also bug #1312699).
I propose we track patron reading history in a separate database table. The table (or materialized view) may be similar to action circulation, though likely with much fewer columns.
More to follow. Comments appreciated.
Changed in evergreen: | |
milestone: | none → 2.next |
Changed in evergreen: | |
assignee: | Bill Erickson (berick) → nobody |
Changed in evergreen: | |
milestone: | 2.next → 2.10-beta |
Changed in evergreen: | |
status: | New → Fix Committed |
Changed in evergreen: | |
status: | Fix Committed → Fix Released |
What data do we want to track for checkout history? We'll need the following columns at minimum on our new table for parity with the TPAC checkout history display.
* id
* xact_start
-- Set to xact_start from the first checkout in the renewal chain.
* usr
* target_copy
* due_date
-- Set to due_date of most recent checkout in the renewal chain.
* checkin_time
-- Checkin time of the most recent checkout in the renewal chain.
-- Will be NULL until final checkin.
* source_circ
-- Points to the first circulation in the renewal chain.
-- Useful for locating the history object during renewal and checkin for modifying dynamic fields (e.g. due_date).
-- Set to NULL when source circ is aged.
I could see adding these as well:
* circ_lib
-- Set to circ_lib from the first checkout in the renewal chain.
* checkin_lib
-- Set to checkin_lib from the last checkout in the renewal chain.
-- Remains NULL until final checkin.
Alternatively, we could mimic action.circulation entirely and track the entire circulation chain, but that seems like overkill and may be storing more data than we really want to retain.
I would expect rows in the new table being added and updated via DB trigger, which fires on create/ update/ delete for action.circulation.
Also, there was conversation in bug #1497335 about maintaining static copies of copy/call number/bib data as part of moving checkout history out to its own table, the idea being that a bib record could be modified or deleted, thus changing the history after the fact. I think this is a worthy goal, but it also adds a lot of questions and complications to the implementation. Since the current checkout history implementation does not protect against these kinds of issues, I'm not planning to address it here. That could be added to this new structure later if desired.