Features: Add favorite projects feature allowing users to star/bookmark frequently used projects New UserFavoriteProject association model with user-project relationships Star icons in project list for one-click favorite toggling via AJAX Filter to display only favorite projects Per-user favorites with proper isolation and cascade delete behavior Activity logging for favorite/unfavorite actions Database: Add user_favorite_projects table with migration (023_add_user_favorite_projects.py) Foreign keys to users and projects with CASCADE delete Unique constraint preventing duplicate favorites Indexes on user_id and project_id for query optimization Models: User model: Add favorite_projects relationship with helper methods add_favorite_project() - add project to favorites remove_favorite_project() - remove from favorites is_project_favorite() - check favorite status get_favorite_projects() - retrieve favorites with status filter Project model: Add is_favorited_by() method and include favorite status in to_dict() Export UserFavoriteProject model in app/models/__init__.py Routes: Add /projects/<id>/favorite POST endpoint to favorite a project Add /projects/<id>/unfavorite POST endpoint to unfavorite a project Update /projects GET route to support favorites=true query parameter Fix status filtering to work correctly with favorites JOIN query Add /reports/export/form GET endpoint for enhanced CSV export form Templates: Update projects/list.html: Add favorites filter dropdown to filter form (5-column grid) Add star icon column with Font Awesome icons (filled/unfilled) Add JavaScript toggleFavorite() function for AJAX favorite toggling Improve hover states and transitions for better UX Pass favorite_project_ids and favorites_only to template Update reports/index.html: Update CSV export link to point to new export form Add icon and improve hover styling Reports: Enhance CSV export functionality with dedicated form page Add filter options for users, projects, clients, and date ranges Set default date range to last 30 days Import Client model and or_ operator for advanced filtering Testing: Comprehensive test suite in tests/test_favorite_projects.py (550+ lines) Model tests for UserFavoriteProject creation and validation User/Project method tests for favorite operations Route tests for favorite/unfavorite endpoints Filtering tests for favorites-only view Relationship tests for cascade delete behavior Smoke tests for complete workflows Coverage for edge cases and error handling Documentation: Add comprehensive feature documentation in docs/FAVORITE_PROJECTS_FEATURE.md User guide with step-by-step instructions Technical implementation details API documentation for new endpoints Migration guide and troubleshooting Performance and security considerations Template Cleanup: Remove duplicate templates from root templates/ directory Admin templates (dashboard, users, settings, OIDC debug, etc.) Client CRUD templates Error page templates Invoice templates Project templates Report templates Timer templates All templates now properly located in app/templates/ Breaking Changes: None - fully backward compatible Migration Required: Run alembic upgrade head to create user_favorite_projects table
10 KiB
Favorite Projects Feature
Overview
The Favorite Projects feature allows users to mark frequently used projects as favorites for quick access. This feature enhances user productivity by providing easy access to the projects they work with most often.
Features
- Star Icon: Each project in the project list has a star icon that can be clicked to favorite/unfavorite
- Quick Filter: Filter to show only favorite projects
- Per-User: Each user has their own set of favorite projects
- Real-time Updates: Favorite status updates immediately via AJAX
- Status Awareness: Favorites work with all project statuses (active, inactive, archived)
User Guide
Marking a Project as Favorite
- Navigate to the Projects list page (
/projects) - Find the project you want to favorite
- Click the star icon (☆) next to the project name
- The star will turn yellow/gold (★) indicating it's now a favorite
Removing a Project from Favorites
- Navigate to the Projects list page
- Find the favorited project (marked with a gold star ★)
- Click the star icon
- The star will become hollow (☆) indicating it's no longer a favorite
Filtering by Favorites
- Navigate to the Projects list page
- In the filters section, find the "Filter" dropdown
- Select "Favorites Only"
- Click "Filter"
- The list will show only your favorite projects
Combining Filters
You can combine the favorites filter with other filters:
- Status Filter: Show only active favorites, archived favorites, etc.
- Client Filter: Show favorites for a specific client
- Search: Search within your favorite projects
Technical Implementation
Database Schema
A new association table user_favorite_projects was created with the following structure:
CREATE TABLE user_favorite_projects (
id INTEGER PRIMARY KEY,
user_id INTEGER NOT NULL,
project_id INTEGER NOT NULL,
created_at DATETIME NOT NULL,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE,
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
UNIQUE (user_id, project_id)
);
CREATE INDEX ix_user_favorite_projects_user_id ON user_favorite_projects(user_id);
CREATE INDEX ix_user_favorite_projects_project_id ON user_favorite_projects(project_id);
Model Relationships
User Model
New methods added to app/models/user.py:
add_favorite_project(project): Add a project to favoritesremove_favorite_project(project): Remove a project from favoritesis_project_favorite(project): Check if a project is favoritedget_favorite_projects(status='active'): Get list of favorite projects
New relationship:
favorite_projects = db.relationship('Project',
secondary='user_favorite_projects',
lazy='dynamic',
backref=db.backref('favorited_by', lazy='dynamic'))
Project Model
New method added to app/models/project.py:
is_favorited_by(user): Check if project is favorited by a specific user
Updated method:
to_dict(user=None): Now includesis_favoritefield when user is provided
API Endpoints
POST /projects/<project_id>/favorite
Mark a project as favorite.
Authentication: Required
Method: POST
Parameters: None
Returns: JSON response
Example Request:
curl -X POST https://timetracker.example.com/projects/123/favorite \
-H "X-Requested-With: XMLHttpRequest" \
-H "Cookie: session=..."
Example Response (Success):
{
"success": true,
"message": "Project added to favorites"
}
Example Response (Error):
{
"success": false,
"message": "Project is already in favorites"
}
POST /projects/<project_id>/unfavorite
Remove a project from favorites.
Authentication: Required
Method: POST
Parameters: None
Returns: JSON response
Example Request:
curl -X POST https://timetracker.example.com/projects/123/unfavorite \
-H "X-Requested-With: XMLHttpRequest" \
-H "Cookie: session=..."
Example Response (Success):
{
"success": true,
"message": "Project removed from favorites"
}
Routes
GET /projects?favorites=true
List projects filtered by favorites.
Authentication: Required
Method: GET
Parameters:
favorites: "true" to show only favoritesstatus: Filter by status (active/inactive/archived)client: Filter by client namesearch: Search in project name/description
Example:
GET /projects?favorites=true&status=active
Frontend Implementation
JavaScript
The toggleFavorite(projectId, button) function handles the star icon clicks:
- Performs optimistic UI update (changes star immediately)
- Sends AJAX POST request to favorite/unfavorite endpoint
- Reverts UI if request fails
- Shows success/error message
UI Components
- Star Icon: FontAwesome icons (
fas fa-starfor favorited,far fa-starfor not favorited) - Color Coding: Yellow/gold for favorited, muted gray for not favorited
- Filter Dropdown: Added "Favorites Only" option to the filters form
Migration
Running the Migration
To add the favorite projects table to an existing database:
# Using Alembic
alembic upgrade head
# Or using the migration management script
python migrations/manage_migrations.py upgrade
Rollback
To rollback the favorite projects feature:
alembic downgrade -1
Activity Logging
The following activities are logged:
project.favorited: When a user adds a project to favoritesproject.unfavorited: When a user removes a project from favorites
These activities can be viewed in:
- User activity logs
- System audit trail
- Analytics dashboards (if enabled)
Testing
Comprehensive test coverage is provided in tests/test_favorite_projects.py:
Test Categories
- Model Tests: Testing the
UserFavoriteProjectmodel - Method Tests: Testing User and Project model methods
- Route Tests: Testing API endpoints
- Filtering Tests: Testing the favorites filter
- Relationship Tests: Testing cascade delete behavior
- Smoke Tests: End-to-end workflow tests
Running Tests
# Run all favorite projects tests
pytest tests/test_favorite_projects.py -v
# Run specific test class
pytest tests/test_favorite_projects.py::TestUserFavoriteProjectModel -v
# Run with coverage
pytest tests/test_favorite_projects.py --cov=app.models --cov=app.routes -v
Performance Considerations
Database Indexes
The feature includes indexes on both user_id and project_id columns in the user_favorite_projects table for optimal query performance.
Query Optimization
- Favorites are loaded once per page load and stored in a set for O(1) lookup
- The favorites filter uses an efficient JOIN query
- Lazy loading is used for relationships to avoid N+1 queries
Scalability
The feature is designed to scale:
- Indexes ensure fast lookups even with thousands of projects
- Per-user favorites don't impact other users
- AJAX requests are lightweight (no page reloads)
Security Considerations
- Authentication Required: All favorite endpoints require user login
- User Isolation: Users can only manage their own favorites
- CSRF Protection: All POST requests use CSRF tokens
- Input Validation: Project IDs are validated before database operations
- Cascade Delete: Favorites are automatically cleaned up when users/projects are deleted
Browser Compatibility
The feature works in all modern browsers:
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
Required browser features:
- Fetch API for AJAX requests
- ES6 JavaScript (arrow functions, const/let)
- CSS3 for animations
Future Enhancements
Potential improvements for future versions:
- Favorite Count Badge: Show number of favorites in summary cards
- Recently Used: Track and show recently accessed projects
- Favorite Ordering: Allow users to reorder their favorites
- Quick Access Menu: Add favorites to navigation menu
- Keyboard Shortcuts: Add keyboard shortcut to favorite/unfavorite
- Bulk Favorite: Select and favorite multiple projects at once
- Favorites Dashboard: Dedicated dashboard showing favorite project metrics
- Export Favorites: Export list of favorite projects
- Favorite Teams: Share favorite project lists with team members
- Smart Favorites: Auto-suggest favorites based on usage patterns
Troubleshooting
Star Icon Not Appearing
Symptom: Star icon column is missing in project list
Solution:
- Clear browser cache and reload
- Verify template file is up to date
- Check browser console for JavaScript errors
Favorite Not Saving
Symptom: Clicking star doesn't persist the favorite
Solution:
- Check browser console for network errors
- Verify CSRF token is present in page
- Check database migration was applied
- Review server logs for errors
Migration Fails
Symptom: Migration script fails to create table
Solution:
- Check database user has CREATE TABLE permissions
- Verify Alembic is up to date
- Check for conflicting table names
- Review migration logs for specific errors
Support
For issues or questions about this feature:
- Check the FAQ section
- Review the test cases for usage examples
- Check GitHub Issues
- Contact the development team
Changelog
Version 1.0.0 (2025-10-23)
Added:
- Initial implementation of favorite projects feature
- Star icon for each project in project list
- Favorites filter in projects page
- User model methods for managing favorites
- Project model methods for checking favorite status
- API endpoints for favorite/unfavorite actions
- Comprehensive test coverage
- Documentation
Database:
- Added
user_favorite_projectstable - Migration script:
023_add_user_favorite_projects.py
Security:
- CSRF protection on all favorite endpoints
- User authentication required
- Per-user favorite isolation