Skip to content

[Feature] Add favorites/bookmarking for conversations #6

@Franpastoragusti

Description

@Franpastoragusti

Problem Statement

Currently, users have no way to mark important conversations for quick access. When managing multiple conversations, users lose track of the ones they want to revisit frequently. The conversation list only sorts by recency, making it difficult to prioritize specific conversations.

Current Limitations:

  • No way to bookmark/favorite important conversations
  • All conversations have equal visual priority
  • No filtering mechanism to view only preferred conversations
  • Users must scroll through all conversations to find important ones

User Value

This feature will significantly improve conversation management by allowing users to:

  1. Quick Access: Mark important conversations with a single click and filter to view only favorites
  2. Better Organization: Separate frequently-used conversations from one-time chats
  3. Visual Clarity: Favorited conversations appear first in the list with a clear indicator
  4. Improved Workflow: Reduce time spent searching for important conversations by 80%+

Concrete Examples:

  • A developer can favorite conversations about specific projects they're actively working on
  • A researcher can bookmark conversations containing important findings or references
  • A user can prioritize ongoing discussions while keeping exploratory chats accessible but lower in the list

Technical Approach

Architecture:

  • Hexagonal architecture with Domain-Driven Design
  • Property name: isFavorite (metadata-backed, not the existing isPinned field)
  • Explicit domain methods for type safety and discoverability
  • Optimistic updates for immediate UI feedback

Backend Changes:

  1. Fix critical metadata serialization bug in Conversation entity
  2. Add domain methods: markAsFavorite(), unmarkAsFavorite(), toggleFavorite(), isFavorite()
  3. Extend repository with findFavorites() and isFavorite filter in findAll()
  4. Create PUT /api/conversations/[id]/favorite endpoint
  5. Update GET /api/conversations/list to return isFavorite field and support query param

Frontend Changes:

  1. Add star toggle button in ConversationListItem (visible on hover when unfavorited, always visible when favorited)
  2. Add filter tabs in ConversationSidebar (All / Favorites)
  3. Implement useToggleFavoriteMutation with optimistic updates
  4. Extend useConversationsListQuery with favorites filter
  5. Update Zod schemas to include isFavorite field

Business Rules:

  • Archived conversations cannot be favorited (400 error)
  • Unlimited favorites allowed
  • Favorites appear first in list, sorted by updatedAt
  • Default state: NOT favorited

Definition of Done

Implementation

  • Backend metadata serialization bug fixed (Conversation.toObject() and Conversation.restore())
  • Domain methods added with business rule validation
  • Repository layer implements findFavorites() and filter support
  • PUT /api/conversations/[id]/favorite endpoint created
  • GET /api/conversations/list updated with isFavorite support
  • Frontend schemas updated (ConversationMetadataSchema and ConversationListItemSchema)
  • Service layer implements toggleFavorite() method
  • React Query hooks implement optimistic updates with rollback
  • Star button added to ConversationListItem component
  • Filter tabs added to ConversationSidebar component
  • All edge cases handled (archived conversations, errors, empty states)

Unit Tests (125+ total tests, >80% coverage)

Backend Tests (70+ tests, >95% coverage):

  • Domain layer: Favorite methods, business rules, idempotent operations
  • Repository layer: Metadata persistence, filtering, sorting
  • Application layer: Use case methods, error handling
  • API layer: Endpoint validation, error codes, query parameters
  • Integration: End-to-end workflows

Frontend Tests (55+ tests, >80% coverage):

  • Component tests: Rendering states, hover behavior, accessibility
  • Hook tests: Optimistic updates, cache invalidation, error rollback
  • Integration tests: Complete user flows

Documentation

  • API contract documented in backend route files
  • JSDoc comments added to all new methods
  • Session context updated with implementation details
  • Architecture decisions documented

Code Review

  • Follows hexagonal architecture principles (domain purity, dependency injection)
  • Matches existing code style and patterns
  • No temporal naming conventions
  • ABOUTME comments added to new files
  • TypeScript strict mode compliance

CI/CD

  • All linting checks pass
  • Type checking passes (yarn tsc --noEmit)
  • Build succeeds (yarn build)
  • All tests pass in CI environment

Manual Testing

  • Complete manual testing checklist (see below)

Manual Testing Checklist

Basic Flow

  • Open conversation list
  • Hover over unfavorited conversation → Star button appears
  • Click star button → Conversation marked as favorite (filled yellow star, always visible)
  • Star appears immediately (optimistic update, no loading spinner)
  • Switch to "Favorites" tab → Only favorited conversations shown
  • Favorited conversations appear first in "All" tab
  • Click star again → Unfavorite (outline star, hidden until hover)
  • Toast notifications appear for success/error states

Edge Case Testing

  • Empty favorites list shows appropriate message
  • Archived conversation cannot be favorited (400 error, error toast)
  • Rapid toggling (multiple clicks) works correctly (React Query deduplication)
  • Delete favorited conversation → Removed from both tabs
  • Archive favorited conversation → Remains favorite (but cannot be favorited again)
  • Create new conversation → Default state is NOT favorited
  • Switch tabs multiple times → Filter state persists
  • Conversation counts accurate in tab labels and footer

Error Handling

  • Network error during toggle → Rollback to previous state
  • Error toast appears with clear message
  • API returns 404 for non-existent conversation → Error toast shown
  • API returns 400 for archived conversation → Error toast shown
  • Retry after error works correctly

Integration

  • Favorite status persists across page reloads
  • Metadata saved/loaded correctly in both InMemoryConversationRepository and MongoDBConversationRepository
  • Multiple browser tabs stay in sync (React Query cache)
  • Favorite status maintained through status transitions (active → completed → active)
  • Works correctly with existing conversation list filters (status)

Accessibility

  • Keyboard navigation: Tab to star button, Enter/Space to toggle
  • ARIA labels correct and dynamic ("Add to favorites" / "Remove from favorites")
  • Screen reader announces toast notifications
  • Focus indicators visible for star button
  • Color contrast meets WCAG AA (yellow star vs backgrounds: 4.8:1 ratio)
  • Tab order logical: Conversation → Star → Delete

Visual/UX

  • Star button transitions smooth (opacity, scale animations)
  • Hover states work correctly (star appears/disappears)
  • Favorited state clear (filled yellow star)
  • Active conversation highlighting preserved when favorited
  • Works in both light and dark themes
  • Responsive on mobile/tablet (button size, touch targets)
  • Tooltip shows on hover with correct message

Performance

  • No loading spinners needed (optimistic updates)
  • Smooth animations (CSS transitions, no jank)
  • Filter switching instant (<100ms)
  • Large lists (100+ conversations) perform well

Implementation Resources

Planning Documents:

  • Backend Architecture: .claude/doc/favorites/backend-architecture.md
  • Frontend Architecture: .claude/doc/favorites/frontend.md
  • UI/UX Design: .claude/doc/favorites/shadcn_ui.md
  • Backend Testing: .claude/doc/favorites/backend-testing.md
  • Frontend Testing: .claude/doc/favorites/frontend-testing.md
  • Session Context: .claude/sessions/context_session_favorites_conversations.md

Estimated Effort: 8-12 hours for complete implementation + testing

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions