[PR #4722] [CLOSED] Community Recommendations feature (Recommend modal, Inbox/Sent, "Go to" deep-link) #4330

Closed
opened 2026-04-25 00:19:18 +02:00 by adam · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/advplyr/audiobookshelf/pull/4722
Author: @rashmi0114
Created: 10/5/2025
Status: Closed

Base: masterHead: RecommandationTags


📝 Commits (10+)

  • 8c245e8 Git commit UI changes for recommandation feature
  • a0e7218 commit dropdown menu CSS
  • b8b7a27 Commit service fil for recommandation fetaure
  • f60449e Commit backend changes for recommandation feature
  • 3a1482c commit plugin to fix data format issue in inbox and send files
  • 649f40f Commit middlewear to read login (cookie/JWT) and sets req.user, and requireAuth blocks anyone not logged in with a 401 error.
  • ae4bd94 add database changes for recommandation sent and inbox
  • 7bf2704 add routes for recommandation feature
  • 61af837 Revert "add routes for recommandation feature"
  • 7e6b7bc Revert "add database changes for recommandation sent and inbox"

📊 Changes

12 files changed (+735 additions, -0 deletions)

View changed files

📝 client/components/app/Appbar.vue (+12 -0)
client/components/recommendations/RecommendButton.vue (+141 -0)
📝 client/pages/item/_id/index.vue (+6 -0)
client/pages/me/recommendations/inbox.vue (+64 -0)
client/pages/me/recommendations/sent.vue (+82 -0)
📝 server/Database.js (+15 -0)
📝 server/Server.js (+3 -0)
server/controllers/recommendationsController.js (+101 -0)
server/managers/RecommendationManager.js (+211 -0)
server/models/BookRecommendation.js (+53 -0)
server/models/RecommendationTag.js (+20 -0)
📝 server/routers/ApiRouter.js (+27 -0)

📄 Description

Brief summary

Introduces a light Community Recommendations feature that enables a signed-in user to recommend a book with an optional tag, optional note, and optional recipient. Introduces a small CRUD API, DB models/migrations, and client UI (Recommend button + modal, Inbox/Sent pages, and a "Go to" button that deep-links to the book page). Fully gated by RECOMMENDATIONS_ENABLED=true.

In-depth Description

Problem 1: No way to share book recommendations
Symptom: Users can’t tag and send a book recommendation to others or publicly.

Solution:
New minimal API at /api/recommendations (feature-flagged).
Create/list/update/delete recommendations with visibility (public / recipient-only).
Default genre tags auto-seeded on first call.

Updated files (server):
server/models/RecommendationTag.js (new)
server/models/BookRecommendation.js (new) — includes associations to users, tag, and library item
server/routers/recommendations.js (new) — small, guarded router
server/migrations/2024092401-create-book-recommendations.js (new)
server/Server.js (edit) — mounts /api/recommendations
server/Database.js (edit) — registers models

Problem 2: Lists only showed a book ID, not the title
Symptom: Inbox/Sent rendered “Book #”.

Solution:
Linked bookRecommendation → libraryItem (as: 'item'), and included its book/podcast title.
API flattens bookTitle into each row so the client can render it without extra requests.

Updated file details:
server/models/BookRecommendation.js — belongsTo(models.libraryItem, { as: 'item', foreignKey: 'bookId', targetKey: 'id' })
server/routers/recommendations.js — common include that fetches item → book/podcast(title), plus a helper that sets bookTitle on the response JSON.

Problem 3: No UI entry point / navigation
Symptom: Users couldn’t create or navigate to recommended items.

Solution:
Recommend button on the item page opens a small modal (tag, optional note/recipient, visibility).
Inbox and Sent pages list recommendations with tag, sender/recipient, date, note, and a Go to button that deep-links to the item page.

Updated files (client):
client/pages/item/_id.vue (edit) — “Recommend” button + opens modal
client/components/recommendations/RecommendModal.vue (new)
client/pages/me/recommendations/inbox.vue (new) — includes Go to button
client/pages/me/recommendations/sent.vue (new) — includes Go to + delete
client/plugins/format-date-safe.client.js (new) — safe date formatting used by these pages

Security & Ops

Feature gated by RECOMMENDATIONS_ENABLED=true; otherwise endpoints return 501.
sessionOrJwt attaches req.user; requireAuth blocks unauthenticated calls on protected routes.
Additive DB changes (new tables only), no impact to existing flows.

How have you tested this?

  1. Enable the feature (export RECOMMENDATIONS_ENABLED=true)
  2. Run migrations / start the app (tags will auto-seed on first /tags call).
  3. Create a recommendation
    • Log in as User A → open any book → click Recommend.
    • Choose a tag, write an optional note, submit.
    • Success toast; entry appears under Sent with the correct title.
  4. Recipient flow
    • Create again with Recipient User ID = and visibility recipient-only.
    • Log in as User B → Inbox shows the recommendation (not visible to others).
  5. Public flow
    • Create with visibility public from A; log in as B → appears in Inbox (public branch).
  6. Navigation
    • Click Go to on Inbox/Sent → navigates to /audiobookshelf/item/:id for that book.
  7. Update/Delete
    • From Sent, delete an item → row disappears; reloading keeps it gone.
    • Update (via API) note/tag/visibility → reflected in lists.
  8. Auth checks
    • Call protected routes while logged out → 401.
    • Attempt to modify someone else’s recommendation → 403.

Screenshots

Screenshot 2025-10-05 213052 Screenshot 2025-10-05 213135 Screenshot 2025-10-05 213108 Screenshot 2025-10-05 213156 Screenshot 2025-10-05 213210

https://github.com/user-attachments/assets/67dfe6bf-d24e-4d09-a8d1-403e282517b7


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/advplyr/audiobookshelf/pull/4722 **Author:** [@rashmi0114](https://github.com/rashmi0114) **Created:** 10/5/2025 **Status:** ❌ Closed **Base:** `master` ← **Head:** `RecommandationTags` --- ### 📝 Commits (10+) - [`8c245e8`](https://github.com/advplyr/audiobookshelf/commit/8c245e85b5ed521216479e09ce13f1d8b41466cf) Git commit UI changes for recommandation feature - [`a0e7218`](https://github.com/advplyr/audiobookshelf/commit/a0e7218e5e35e6b7b6767f945f3e81eaa44868eb) commit dropdown menu CSS - [`b8b7a27`](https://github.com/advplyr/audiobookshelf/commit/b8b7a272f95be2483731e0628105a52071a931a6) Commit service fil for recommandation fetaure - [`f60449e`](https://github.com/advplyr/audiobookshelf/commit/f60449ed6ab54c9ae100b6b5c75ae7192fb48970) Commit backend changes for recommandation feature - [`3a1482c`](https://github.com/advplyr/audiobookshelf/commit/3a1482c721d3cb103d34ef60318acc7b86891898) commit plugin to fix data format issue in inbox and send files - [`649f40f`](https://github.com/advplyr/audiobookshelf/commit/649f40ff374fd63cb5ea6abe2d8a442f6a779694) Commit middlewear to read login (cookie/JWT) and sets req.user, and requireAuth blocks anyone not logged in with a 401 error. - [`ae4bd94`](https://github.com/advplyr/audiobookshelf/commit/ae4bd94b3879fb6ddcb7d0b977c4611ca904c928) add database changes for recommandation sent and inbox - [`7bf2704`](https://github.com/advplyr/audiobookshelf/commit/7bf27044b8779bae8844c502414484e850a7a59a) add routes for recommandation feature - [`61af837`](https://github.com/advplyr/audiobookshelf/commit/61af837cf5bc3e83fe46e46c147bd075ae4605a4) Revert "add routes for recommandation feature" - [`7e6b7bc`](https://github.com/advplyr/audiobookshelf/commit/7e6b7bc9f61f7362997d70d4db4e5818fcb07a92) Revert "add database changes for recommandation sent and inbox" ### 📊 Changes **12 files changed** (+735 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `client/components/app/Appbar.vue` (+12 -0) ➕ `client/components/recommendations/RecommendButton.vue` (+141 -0) 📝 `client/pages/item/_id/index.vue` (+6 -0) ➕ `client/pages/me/recommendations/inbox.vue` (+64 -0) ➕ `client/pages/me/recommendations/sent.vue` (+82 -0) 📝 `server/Database.js` (+15 -0) 📝 `server/Server.js` (+3 -0) ➕ `server/controllers/recommendationsController.js` (+101 -0) ➕ `server/managers/RecommendationManager.js` (+211 -0) ➕ `server/models/BookRecommendation.js` (+53 -0) ➕ `server/models/RecommendationTag.js` (+20 -0) 📝 `server/routers/ApiRouter.js` (+27 -0) </details> ### 📄 Description ## Brief summary Introduces a light Community Recommendations feature that enables a signed-in user to recommend a book with an optional tag, optional note, and optional recipient. Introduces a small CRUD API, DB models/migrations, and client UI (Recommend button + modal, Inbox/Sent pages, and a "Go to" button that deep-links to the book page). Fully gated by RECOMMENDATIONS_ENABLED=true. ## In-depth Description **Problem 1: No way to share book recommendations** Symptom: Users can’t tag and send a book recommendation to others or publicly. Solution: New minimal API at /api/recommendations (feature-flagged). Create/list/update/delete recommendations with visibility (public / recipient-only). Default genre tags auto-seeded on first call. Updated files (server): server/models/RecommendationTag.js (new) server/models/BookRecommendation.js (new) — includes associations to users, tag, and library item server/routers/recommendations.js (new) — small, guarded router server/migrations/2024092401-create-book-recommendations.js (new) server/Server.js (edit) — mounts /api/recommendations server/Database.js (edit) — registers models **Problem 2: Lists only showed a book ID, not the title** Symptom: Inbox/Sent rendered “Book #<id>”. Solution: Linked bookRecommendation → libraryItem (as: 'item'), and included its book/podcast title. API flattens bookTitle into each row so the client can render it without extra requests. Updated file details: server/models/BookRecommendation.js — belongsTo(models.libraryItem, { as: 'item', foreignKey: 'bookId', targetKey: 'id' }) server/routers/recommendations.js — common include that fetches item → book/podcast(title), plus a helper that sets bookTitle on the response JSON. **Problem 3: No UI entry point / navigation** Symptom: Users couldn’t create or navigate to recommended items. Solution: Recommend button on the item page opens a small modal (tag, optional note/recipient, visibility). Inbox and Sent pages list recommendations with tag, sender/recipient, date, note, and a Go to button that deep-links to the item page. Updated files (client): client/pages/item/_id.vue (edit) — “Recommend” button + opens modal client/components/recommendations/RecommendModal.vue (new) client/pages/me/recommendations/inbox.vue (new) — includes Go to button client/pages/me/recommendations/sent.vue (new) — includes Go to + delete client/plugins/format-date-safe.client.js (new) — safe date formatting used by these pages **Security & Ops** Feature gated by RECOMMENDATIONS_ENABLED=true; otherwise endpoints return 501. sessionOrJwt attaches req.user; requireAuth blocks unauthenticated calls on protected routes. Additive DB changes (new tables only), no impact to existing flows. ## How have you tested this? 1. Enable the feature (export RECOMMENDATIONS_ENABLED=true) 2. Run migrations / start the app (tags will auto-seed on first /tags call). 3. Create a recommendation - Log in as User A → open any book → click Recommend. - Choose a tag, write an optional note, submit. - Success toast; entry appears under Sent with the correct title. 4. Recipient flow - Create again with Recipient User ID = <User B id> and visibility recipient-only. - Log in as User B → Inbox shows the recommendation (not visible to others). 5. Public flow - Create with visibility public from A; log in as B → appears in Inbox (public branch). 6. Navigation - Click Go to on Inbox/Sent → navigates to /audiobookshelf/item/:id for that book. 7. Update/Delete - From Sent, delete an item → row disappears; reloading keeps it gone. - Update (via API) note/tag/visibility → reflected in lists. 8. Auth checks - Call protected routes while logged out → 401. - Attempt to modify someone else’s recommendation → 403. ## Screenshots <img width="1918" height="963" alt="Screenshot 2025-10-05 213052" src="https://github.com/user-attachments/assets/d9f5f977-ad4e-485e-b479-868101b3873f" /> <img width="1918" height="911" alt="Screenshot 2025-10-05 213135" src="https://github.com/user-attachments/assets/05ef04eb-5a2f-42af-a3bb-d1f095026615" /> <img width="1918" height="910" alt="Screenshot 2025-10-05 213108" src="https://github.com/user-attachments/assets/5127cf38-6ced-4b7c-9549-9654c05464bf" /> <img width="1918" height="656" alt="Screenshot 2025-10-05 213156" src="https://github.com/user-attachments/assets/3e79ec28-34e5-4a8a-b95e-199d9c374c45" /> <img width="1918" height="697" alt="Screenshot 2025-10-05 213210" src="https://github.com/user-attachments/assets/dd32e71b-2683-43d9-a9bc-a9ffd584e3b6" /> https://github.com/user-attachments/assets/67dfe6bf-d24e-4d09-a8d1-403e282517b7 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
adam added the pull-request label 2026-04-25 00:19:18 +02:00
adam closed this issue 2026-04-25 00:19:18 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#4330