feat: Add personalized feed endpoint with vertical filtering
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
Some checks failed
Deploy Fediversion / deploy (push) Failing after 1s
- Add GET /feed/me endpoint - Filters reviews and attendance by user's band preferences - Excludes 'hidden' display_mode bands - Falls back to all bands if no preferences set
This commit is contained in:
parent
c1c041bbe9
commit
5ced96f4e6
1 changed files with 90 additions and 0 deletions
|
|
@ -5,6 +5,7 @@ from database import get_session
|
|||
from models import Review, Attendance, GroupPost, User, Profile, Performance, Show, Song
|
||||
from schemas import ReviewRead, AttendanceRead, GroupPostRead
|
||||
from datetime import datetime
|
||||
from auth import get_current_user_optional
|
||||
|
||||
router = APIRouter(prefix="/feed", tags=["feed"])
|
||||
|
||||
|
|
@ -129,3 +130,92 @@ def get_global_feed(
|
|||
feed_items.sort(key=lambda x: x.timestamp, reverse=True)
|
||||
|
||||
return feed_items[:limit]
|
||||
|
||||
|
||||
@router.get("/me", response_model=List[FeedItem])
|
||||
def get_personalized_feed(
|
||||
limit: int = 20,
|
||||
session: Session = Depends(get_session),
|
||||
current_user: User = Depends(get_current_user_optional)
|
||||
):
|
||||
"""Get feed filtered by user's band preferences (or all bands if not logged in)"""
|
||||
from models import UserVerticalPreference, Vertical
|
||||
|
||||
# Get user's preferred vertical IDs
|
||||
preferred_vertical_ids = None
|
||||
if current_user:
|
||||
prefs = session.exec(
|
||||
select(UserVerticalPreference)
|
||||
.where(UserVerticalPreference.user_id == current_user.id)
|
||||
.where(UserVerticalPreference.display_mode != "hidden")
|
||||
).all()
|
||||
if prefs:
|
||||
preferred_vertical_ids = [p.vertical_id for p in prefs]
|
||||
|
||||
# Fetch reviews (filtered by vertical if user has preferences)
|
||||
review_query = select(Review).order_by(desc(Review.created_at)).limit(limit * 2)
|
||||
reviews = session.exec(review_query).all()
|
||||
|
||||
# Fetch attendance (filtered by show's vertical)
|
||||
attendance_query = select(Attendance).order_by(desc(Attendance.created_at)).limit(limit * 2)
|
||||
attendance = session.exec(attendance_query).all()
|
||||
|
||||
feed_items = []
|
||||
|
||||
for r in reviews:
|
||||
# Filter by vertical if user has preferences
|
||||
vertical_id = None
|
||||
if r.performance_id:
|
||||
perf = session.get(Performance, r.performance_id)
|
||||
if perf:
|
||||
show = session.get(Show, perf.show_id)
|
||||
if show:
|
||||
vertical_id = show.vertical_id
|
||||
elif r.show_id:
|
||||
show = session.get(Show, r.show_id)
|
||||
if show:
|
||||
vertical_id = show.vertical_id
|
||||
elif r.song_id:
|
||||
song = session.get(Song, r.song_id)
|
||||
if song:
|
||||
vertical_id = song.vertical_id
|
||||
|
||||
if preferred_vertical_ids and vertical_id and vertical_id not in preferred_vertical_ids:
|
||||
continue
|
||||
|
||||
feed_items.append(FeedItem(
|
||||
type="review",
|
||||
timestamp=r.created_at or datetime.utcnow(),
|
||||
data=r,
|
||||
user=get_user_display(session, r.user_id),
|
||||
entity=get_entity_info(session, r)
|
||||
))
|
||||
|
||||
for a in attendance:
|
||||
show = session.get(Show, a.show_id) if a.show_id else None
|
||||
|
||||
# Filter by vertical
|
||||
if preferred_vertical_ids and show and show.vertical_id not in preferred_vertical_ids:
|
||||
continue
|
||||
|
||||
entity_info = None
|
||||
if show:
|
||||
entity_info = {
|
||||
"type": "show",
|
||||
"slug": show.slug,
|
||||
"title": show.date.strftime("%Y-%m-%d") if show.date else "Unknown",
|
||||
}
|
||||
|
||||
feed_items.append(FeedItem(
|
||||
type="attendance",
|
||||
timestamp=a.created_at,
|
||||
data=a,
|
||||
user=get_user_display(session, a.user_id),
|
||||
entity=entity_info
|
||||
))
|
||||
|
||||
# Sort by timestamp desc
|
||||
feed_items.sort(key=lambda x: x.timestamp, reverse=True)
|
||||
|
||||
return feed_items[:limit]
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue