Phase (b), qbit side, of QRun-IO/qqq#1136 (spec §4 rows 3 and 4, §7.5): favorites and recently viewed.
Tables:
collaboration_favorite and collaboration_recent, locked to their owner through the collaboration_user security key. collaboration.admin gets all-access. This is the same pattern as qbit-alerts' per-user tables.
Neither table is in the nav, and audit is off for this personal, high-volume data.
Services:
FavoritesService:
star and unstar are idempotent. Starring checks that the target is visible: a record that isn't visible gives "Not found".
list refreshes record labels with one batched query per table. Targets the user can no longer see come back as "Unavailable", never with the old label.
reorder, with folders.
RecentsService:
records a view at most once per minute per target;
lists the newest 50, re-checked for visibility;
trims to recentsPerUser per user (default 200) with the hidden daily process collaborationTrimRecents, when a scheduler is configured.
The home shows real favorites and recents counts.
Not in this PR: the /qqq/v1/qbit/collaboration/favorites|recents endpoints. They need the UI API extension point (QRun-IO/qqq#1128) in a released RC.
Note: the generated Postgres unique indexes use NULLS NOT DISTINCT, which needs PostgreSQL 15 or later.
Test plan
./mvnw -o verify: 25 tests, 98.4% instruction and 100% class coverage, checkstyle clean.
## Summary
Phase (b), qbit side, of QRun-IO/qqq#1136 (spec §4 rows 3 and 4, §7.5): favorites and recently viewed.
**Tables:**
- `collaboration_favorite` and `collaboration_recent`, locked to their owner through the `collaboration_user` security key. `collaboration.admin` gets all-access. This is the same pattern as qbit-alerts' per-user tables.
- Neither table is in the nav, and audit is off for this personal, high-volume data.
**Services:**
- `FavoritesService`:
- star and unstar are idempotent. Starring checks that the target is visible: a record that isn't visible gives "Not found".
- list refreshes record labels with one batched query per table. Targets the user can no longer see come back as "Unavailable", never with the old label.
- reorder, with folders.
- `RecentsService`:
- records a view at most once per minute per target;
- lists the newest 50, re-checked for visibility;
- trims to `recentsPerUser` per user (default 200) with the hidden daily process `collaborationTrimRecents`, when a scheduler is configured.
- The home shows real favorites and recents counts.
**Not in this PR:** the `/qqq/v1/qbit/collaboration/favorites|recents` endpoints. They need the UI API extension point (QRun-IO/qqq#1128) in a released RC.
**Note:** the generated Postgres unique indexes use `NULLS NOT DISTINCT`, which needs PostgreSQL 15 or later.
## Test plan
- [x] `./mvnw -o verify`: 25 tests, 98.4% instruction and 100% class coverage, checkstyle clean.
- [ ] CircleCI `test_only`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Phase (b), qbit side, of QRun-IO/qqq#1136 (spec §4 rows 3 and 4, §7.5): favorites and recently viewed.
Tables:
collaboration_favoriteandcollaboration_recent, locked to their owner through thecollaboration_usersecurity key.collaboration.admingets all-access. This is the same pattern as qbit-alerts' per-user tables.Services:
FavoritesService:RecentsService:recentsPerUserper user (default 200) with the hidden daily processcollaborationTrimRecents, when a scheduler is configured.Not in this PR: the
/qqq/v1/qbit/collaboration/favorites|recentsendpoints. They need the UI API extension point (QRun-IO/qqq#1128) in a released RC.Note: the generated Postgres unique indexes use
NULLS NOT DISTINCT, which needs PostgreSQL 15 or later.Test plan
./mvnw -o verify: 25 tests, 98.4% instruction and 100% class coverage, checkstyle clean.test_only.🤖 Generated with Claude Code