This commit introduces two major features:
1. Project Custom Fields: Add custom_fields JSON column to projects table (migration 085), support for flexible custom data storage, display and edit in project views
2. File Attachments System: Add project_attachments and client_attachments tables (migration 086), new ProjectAttachment and ClientAttachment models, full CRUD operations, file upload/download/delete, client-visible attachments support
Additional improvements: Enhanced data tables, updated project/client/invoice/timer views, improved UI for attachments and custom fields management
Implement a reusable form validation system that provides immediate,
contextual feedback to users with inline error messages and visual indicators.
Features:
- Real-time validation on input, blur, and submit events
- Inline error and success messages displayed near form fields
- Visual indicators for required vs optional fields (asterisks)
- Subtle validation styling with softer colors and smaller icons
- Phone number validation for tel/phone fields (7-15 digits, optional country code)
- Email, URL, number, date, and pattern validation support
- Debounced validation to reduce performance impact
- Form-level error messages on submit
- Automatic focus management for invalid fields
Technical improvements:
- Prevent duplicate initialization with form and field flags
- Smart message container insertion that respects existing form structure
- Better detection of existing required indicators to prevent duplicates
- Hidden messages take zero space (height: 0) to prevent layout shifts
- Graceful error handling with try-catch blocks
Styling:
- Subtle visual feedback with green-300/red-300 borders (softer than before)
- Smaller validation icons (0.875rem) and reduced padding (2rem)
- Reduced opacity for messages (0.75-0.85) for less intrusive appearance
- Lighter focus shadows (0.08 opacity) for subtle feedback
- Dark mode support with appropriate color adjustments
Applied to all forms:
- Projects (create/edit)
- Clients (create/edit)
- Tasks (create/edit)
- Invoices (create/edit)
- Payments (create/edit)
- Expenses, Mileage, Per Diem forms
- Time Entry (manual entry)
- Weekly Goals
Fixes:
- Prevent duplicate message containers and layout breaks
- Better insertion logic that respects existing help text
- Improved container detection to avoid duplicates
- Fixed required indicator duplication issues
- Enhanced form submission handler management
The validation system automatically initializes on forms with
data-validate-form attribute or novalidate attribute, providing
consistent validation UX across the application.
Fixed a critical bug where changes to project descriptions were not
being persisted when editing projects via Work > Projects > Edit Project.
The issue was caused by an incorrect CSS selector pattern in the form
submit handler that syncs the markdown editor content. The selector
`form[action*="projects/edit"]` failed to match URLs like
`/projects/123/edit` because the project ID breaks the substring match.
Changes:
- Updated form selector to use more generic pattern: `form[action*="/edit"]`
- Added explicit null checking with `if (form)` guard
- Enhanced error logging with console.error for debugging
- Improved code formatting and structure
Testing:
- Added integration test: test_edit_project_description
- Added smoke test: test_project_edit_page_has_markdown_editor
- All 166 project-related tests pass successfully
- No regressions introduced
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