Implement comprehensive budget monitoring and forecasting feature with:
Database & Models:
- Add BudgetAlert model for tracking project budget alerts
- Create migration 039_add_budget_alerts_table with proper indexes
- Support alert types: 80_percent, 100_percent, over_budget
- Add acknowledgment tracking with user and timestamp
Budget Forecasting Utilities:
- Implement burn rate calculation (daily/weekly/monthly)
- Add completion date estimation based on burn rate
- Create resource allocation analysis per team member
- Build cost trend analysis with configurable granularity
- Add automatic budget alert detection with deduplication
Routes & API:
- Create budget_alerts blueprint with dashboard and detail views
- Add API endpoints for burn rate, completion estimates, and trends
- Implement resource allocation and cost trend API endpoints
- Add alert acknowledgment and manual budget check endpoints
- Fix log_event() calls to use keyword arguments
UI Templates:
- Design modern budget dashboard with Tailwind CSS
- Create detailed project budget analysis page with charts
- Add gradient stat cards with color-coded status indicators
- Implement responsive layouts with full dark mode support
- Add smooth animations and toast notifications
- Integrate Chart.js for cost trend visualization
Project Integration:
- Add Budget Alerts link to Finance navigation menu
- Enhance project view page with budget overview card
- Show budget progress bars with status indicators
- Add Budget Analysis button to project header and dashboard
- Display real-time budget status with color-coded badges
Visual Enhancements:
- Use gradient backgrounds for stat cards (blue/green/yellow/red)
- Add status badges with icons (healthy/warning/critical/over)
- Implement smooth progress bars with embedded percentages
- Support responsive grid layouts for all screen sizes
- Ensure proper type conversion (Decimal to float) in templates
Scheduled Tasks:
- Register budget alert checking job (runs every 6 hours)
- Integrate with existing APScheduler tasks
- Add logging for alert creation and monitoring
This feature provides project managers with real-time budget insights,
predictive analytics, and proactive alerts to prevent budget overruns.
Implement a feature-rich project dashboard that provides visual analytics
and key performance indicators for project tracking and management.
Features:
- Individual project dashboard route (/projects/<id>/dashboard)
- Key metrics cards: Total Hours, Budget Used, Tasks Complete, Team Size
- Budget vs. Actual bar chart with threshold warnings
- Task status distribution doughnut chart
- Team member contributions horizontal bar chart (top 10)
- Time tracking timeline line chart
- Team member details with progress bars
- Recent activity feed (last 10 activities)
- Period filtering (All Time, 7/30/90/365 Days)
- Responsive design with dark mode support
- Navigation button added to project view page
Technical Implementation:
- New route: project_dashboard() in app/routes/projects.py
- Template: app/templates/projects/dashboard.html with Chart.js 4.4.0
- Data aggregation for budget, tasks, team contributions, and timeline
- Optimized database queries with proper filtering
- JavaScript escaping handled with |tojson filters and autoescape control
Testing:
- 20 comprehensive unit tests (test_project_dashboard.py)
- 23 smoke tests (smoke_test_project_dashboard.py)
- Full test coverage for all dashboard functionality
Documentation:
- Complete feature guide (docs/features/PROJECT_DASHBOARD.md)
- Implementation summary (PROJECT_DASHBOARD_IMPLEMENTATION_SUMMARY.md)
- Usage examples and troubleshooting guide
Fixes:
- JavaScript syntax errors from HTML entity escaping
- Proper use of |tojson filter for dynamic values in JavaScript
- Autoescape disabled for script blocks to prevent operator mangling
This dashboard provides project managers and team members with valuable
insights into project health, progress, budget utilization, and resource
allocation at a glance.
Add comprehensive Activity Feed Widget to dashboard providing team visibility
and audit trail functionality. The widget displays recent user activities with
advanced filtering, pagination, and auto-refresh capabilities.
Features:
- Dashboard widget showing last 10 activities with infinite scroll
- Filter by entity type (projects, tasks, time entries, templates, users, etc.)
- Real-time auto-refresh every 30 seconds
- Visual indicators for active filters (checkmark + dot)
- Load more pagination with "has_next" detection
- Refresh button with spinning animation feedback
API Endpoints:
- GET /api/activities - Retrieve activities with filtering & pagination
- GET /api/activities/stats - Activity statistics and analytics
- Support for user_id, entity_type, action, and date range filters
Activity Logging Integration:
- Projects: create, update, delete, archive, unarchive
- Tasks: create, update, delete
- Time Entries: start timer, stop timer
- All operations log user, IP address, and user agent for security
UI/UX Improvements:
- Vanilla JS implementation (removed Alpine.js dependency)
- Dark mode support with proper color schemes
- Responsive dropdown with scrollable content
- Action-specific icons (Font Awesome)
- Relative timestamps with timeago filter
- Error handling with user-friendly messages
Testing & Documentation:
- Comprehensive test suite (model, API, integration, widget)
- Feature documentation in docs/features/activity_feed.md
- Implementation summary and integration guide
- Console logging for debugging
Bug Fixes:
- Fixed "Load More" button not appending results
- Fixed refresh clearing list without reloading
- Fixed filter dropdown using Alpine.js (now vanilla JS)
- Fixed entity_type filter sending 'all' to API
- Added missing entity types (time_entry_template, user)
Technical Details:
- Activity model with optimized indexes for performance
- Promise-based async loading with proper error handling
- Credentials included in fetch for authentication
- Filter state management with visual feedback
- Graceful degradation on API failures
Impact:
- Team visibility into real-time activities
- Comprehensive audit trail for compliance
- Better accountability and transparency
- Improved troubleshooting capabilities
Complete the Time Entry Templates feature by adding timer integration
and dashboard UI (70% → 100% complete).
Features Added:
- One-click start timer from template via new route
- Template selector in dashboard "Start Timer" modal
- Template pre-fill for manual time entries
- Auto-populate timer forms with template data
- Usage tracking when templates are used
Backend Changes:
- Added template support to /timer/start route
- Added template pre-fill to /timer/manual route
- New route: /timer/start/from-template/<id> for direct timer start
- Load recent templates (top 5) on dashboard
- All changes include proper validation and error handling
Frontend Changes:
- Template list in dashboard start timer modal
- JavaScript function to apply template data to forms
- Template cards show project/task information
- Link to full template management page
- Responsive design for mobile
Testing:
- Added 6 new integration tests for timer features
- Test start timer from template (success and error cases)
- Test manual entry pre-fill from template
- Test active timer validation
- All 32 tests passing with no linting errors
Documentation:
- Complete user guide (docs/TIME_ENTRY_TEMPLATES.md)
- Technical documentation (docs/features/TIME_ENTRY_TEMPLATES.md)
- Implementation summary with usage examples
Use Case: Quickly start timers for recurring activities
- 80% faster timer start for recurring tasks
- Zero retyping of project, task, notes, tags
- Consistent data across similar time entries
- Fix keyboard shortcuts (like 'g r' for Go to Reports) incorrectly triggering
while typing in input fields, textareas, and rich text editors
- Enhance detection for popular rich text editors:
* Toast UI Editor (used in project descriptions)
* TinyMCE, Quill, CodeMirror, Summernote
* All contenteditable elements
- Allow specific global shortcuts even in input fields:
* Ctrl+K / Cmd+K: Open command palette
* Shift+?: Show keyboard shortcuts help
* Ctrl+/: Focus search
- Clear key sequences when user starts typing to prevent partial matches
- Add debug logging for troubleshooting keyboard shortcut issues
- Update JavaScript cache busting version numbers (v=2.0, v=2.2)
Test improvements:
- Add comprehensive test suite for keyboard shortcuts input fix
* Test typing 'gr' in 'program' doesn't trigger navigation
* Test rich text editor detection logic
* Test allowed shortcuts in inputs
- Refactor smoke tests to use admin_authenticated_client fixture
instead of manual login (DRY principle)
- Fix Windows PermissionError in test cleanup for temporary files
- Add SESSION_COOKIE_HTTPONLY to test config for security
- Update test secret key length to meet requirements
- Remove duplicate admin user fixtures
Resolves issue where typing words like 'program' or 'graphics' in forms
would trigger unintended navigation shortcuts.
Major Features:
- Invoice Expenses: Allow linking billable expenses to invoices with automatic total calculations
- Add expenses to invoices via "Generate from Time/Costs" workflow
- Display expenses in invoice view, edit forms, and PDF exports
- Track expense states (approved, invoiced, reimbursed) with automatic unlinking on invoice deletion
- Update PDF generator and CSV exports to include expense line items
- Enhanced PDF Invoice Editor: Complete redesign using Konva.js for visual drag-and-drop layout design
- Add 40+ draggable elements (company info, invoice data, shapes, text, advanced elements)
- Implement comprehensive properties panel for precise element customization (position, fonts, colors, opacity)
- Add canvas toolbar with alignment tools, zoom controls, and layer management
- Support keyboard shortcuts (copy/paste, duplicate, arrow key positioning)
- Save designs as JSON for editing and generate clean HTML/CSS for rendering
- Add real-time preview with live data
- Uploads Persistence: Implement Docker volume persistence for user-uploaded files
- Add app_uploads volume to all Docker Compose configurations
- Ensure company logos and avatars persist across container rebuilds and restarts
- Create migration script for existing installations
- Update directory structure with proper permissions (755 for dirs, 644 for files)
Database & Backend:
- Add invoice_pdf_design_json column to settings table via Alembic migration
- Extend Invoice model with expenses relationship
- Update admin routes for PDF layout designer endpoints
- Enhance invoice routes to handle expense linking/unlinking
Frontend & UI:
- Redesign PDF layout editor template with Konva.js canvas (2484 lines, major overhaul)
- Update invoice edit/view templates to display and manage expenses
- Add expense sections to invoice forms with unlink functionality
- Enhance UI components with keyboard shortcuts support
- Update multiple templates for consistency and accessibility
Testing & Documentation:
- Add comprehensive test suites for invoice expenses, PDF layouts, and uploads persistence
- Create detailed documentation for all new features (5 new docs)
- Include migration guides and troubleshooting sections
Infrastructure:
- Update docker-compose files (main, example, remote, remote-dev, local-test) with uploads volume
- Configure pytest for new test modules
- Add template filters for currency formatting and expense display
This update significantly enhances TimeTracker's invoice management capabilities,
improves the PDF customization experience, and ensures uploaded files persist
reliably across deployments.
Implemented complete invoice deletion feature allowing users to delete
incorrectly generated invoices from both the view and list pages.
Changes:
- Added delete button to invoice view page with modal confirmation
- Added delete buttons to invoice list page with modal confirmation
- Implemented custom Tailwind modal matching project design patterns
- Modal displays invoice number and cascade deletion warning
- Full dark mode support with proper accessibility (ARIA attributes)
- Modal can be closed via Cancel button, clicking outside, or ESC key
Technical details:
- Backend route already existed (/invoices/<id>/delete)
- Cascade deletion automatically removes related items, goods, and payments
- Permission checks: only invoice creator or admins can delete
- Delete route returns to invoice list with success/error messages
Testing:
- Added 12 comprehensive tests covering deletion functionality
- Unit tests for basic deletion and cascade behavior
- Route tests for permissions and success/error cases
- Smoke tests for UI elements and complex deletion scenarios
- All tests passing ✅
The modal implementation follows the established pattern used in
kanban/columns.html, ensuring consistency 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
- Add sorted_payments property to Invoice model using proper SQLAlchemy column references
- Update invoice view template to use new property instead of string-based ordering
- Add comprehensive tests for sorted_payments functionality
Resolves error: "Can't resolve label reference for ORDER BY" when accessing invoice.payments.order_by() from Jinja2 templates
Remove old /invoices/<id>/payment route and update templates to use the
Payment model system (payments.create_payment). Add deprecation warning
to Invoice.record_payment() method for backward compatibility.
Benefits: Multiple payments per invoice, status tracking, gateway support,
better audit trails, and full CRUD operations.
All tests pass. Backward compatible with 6-month deprecation period.
- Add delete button to user list with confirmation dialog
- Prevent deletion of last admin and users with time entries
- Include CSRF protection on delete forms
- Add 41 comprehensive tests (unit, model, smoke)
- Document feature with usage guide and best practices
All safety checks implemented and tested.
- Separated logo upload form from main settings form (fixes nested forms)
- Excluded /uploads/ from ServiceWorker cache (fixes logo not showing)
- Added cache busting to logo URLs
- Enhanced UI with prominent logo display and preview
- Added error handling and logging
- Created cache clearing utility at /admin/clear-cache
- Added 18 comprehensive tests
- Created troubleshooting documentation
Fixes: Logo not visible after upload, settings form not saving
## Payment Analytics Integration
- Add 5 new API endpoints for payment metrics:
- /api/analytics/payments-over-time - trend visualization
- /api/analytics/payments-by-status - status distribution
- /api/analytics/payments-by-method - method breakdown
- /api/analytics/payment-summary - statistics with period comparison
- /api/analytics/revenue-vs-payments - collection rate tracking
- Integrate payment data into analytics dashboard with 4 new charts
- Add payment metrics to reports page (total, count, fees, net received)
- Update summary endpoint to include payment statistics
## UI/UX Improvements
- Standardize form styling across all payment templates
- Replace inconsistent Tailwind classes with form-input utility
- Update card backgrounds to use card-light/card-dark
- Fix label spacing to match application patterns
- Ensure consistent border colors and backgrounds
- Replace browser confirm() with system-wide modal for payment deletion
- Consistent danger variant with warning icon
- Keyboard support (Enter/Escape)
- Dark mode compatible
- Clear messaging about impact on invoice status
## Technical Changes
- Import Payment and Invoice models in analytics and reports routes
- Add proper admin/user scoping for payment queries
- Maintain responsive design across all new components
Closes payment tracking phase 2 (analytics & polish)
Refactored the existing calendar API endpoint to properly display calendar
events, tasks, and time entries with distinct visual representations.
Changes:
- Updated /api/calendar/events endpoint in api.py to use new
CalendarEvent.get_events_in_range() method that fetches all three item types
- Fixed user_id bug where it was defaulting to None instead of current_user.id
- Modified API response format to include all items in unified 'events' array
with item_type field ('event', 'task', 'time_entry') for differentiation
- Updated calendar.js to parse unified response format and filter items by type
- Added visual distinctions:
* Tasks: 📋 emoji, orange (#f59e0b) color, clickable
* Time entries: ⏱ emoji, project-based colors, non-clickable
* Calendar events: 📅 emoji, custom colors, clickable
- Fixed task detail route from /tasks/view/{id} to /tasks/{id}
- Updated all calendar view renderers (month, week, day) to use correct
data structure with extendedProps
- Added cache-busting to calendar.js (v7) and calendar.css (v2)
- Preserved backward compatibility with existing calendar filtering
(project_id, task_id, tags)
The calendar now correctly displays all time tracking data in a unified view
with proper visual hierarchy and interaction patterns.
Fixes: Calendar not showing tasks and time entries
Related: Calendar/Agenda Support feature implementation
Enhance the email support feature with better UX and debugging capabilities:
- **Fix input field styling**: Update all form inputs to use project-standard
'form-input' class and consistent checkbox styling matching other admin
pages for uniform appearance across the application
- **Add comprehensive logging**: Implement detailed logging throughout email
operations with clear prefixes ([EMAIL TEST], [EMAIL CONFIG]) to track:
- Email configuration changes and validation
- Test email sending process step-by-step
- SMTP connection details and status
- Success/failure indicators (✓/✗) for quick troubleshooting
- **Auto-reload after save**: Page now automatically refreshes 1.5 seconds
after successfully saving email configuration to ensure UI reflects the
latest settings and eliminate stale data
These improvements provide better visual consistency, easier debugging of
email issues, and smoother user experience when configuring email settings.
Files modified:
- app/templates/admin/email_support.html
- app/utils/email.py
- app/routes/admin.py
Major improvements to the backup restore system with a complete UI overhaul
and enhanced functionality:
UI/UX Improvements:
- Complete redesign of restore page with modern Tailwind CSS
- Added prominent warning banners and danger badges to prevent accidental data loss
- Implemented drag-and-drop file upload with visual feedback
- Added real-time progress tracking with auto-refresh every 2 seconds
- Added comprehensive safety information sidebar with checklists
- Full dark mode support throughout restore interface
- Enhanced confirmation flows with checkbox and modal confirmations
Functionality Enhancements:
- Added dual restore methods: upload new backup or restore from existing server backups
- Enhanced restore route to accept optional filename parameter for existing backups
- Added "Restore" button to each backup in the backups management page
- Implemented restore confirmation modal with critical warnings
- Added loading states and button disabling during restore operations
- Improved error handling and user feedback
Backend Changes:
- Enhanced admin.restore() to support both file upload and existing backup restore
- Added dual route support: /admin/restore and /admin/restore/<filename>
- Added shutil import for file copy operations during restore
- Improved security with secure_filename validation and file type checking
- Maintained existing rate limiting (3 requests per minute)
Frontend Improvements:
- Added interactive JavaScript for file selection, drag-and-drop, and modal management
- Implemented auto-refresh during restore process to show live progress
- Added escape key support for closing modals
- Enhanced user feedback with file name display and button states
Safety Features:
- Pre-restore checklist with 5 verification steps
- Multiple warning levels throughout the flow
- Confirmation checkbox required before upload restore
- Modal confirmation required before existing backup restore
- Clear documentation of what gets restored and post-restore steps
Dependencies:
- Updated flask-swagger-ui from 4.11.1 to 5.21.0
Files modified:
- app/templates/admin/restore.html (complete rewrite)
- app/templates/admin/backups.html (added restore functionality)
- app/routes/admin.py (enhanced restore route)
- requirements.txt (updated flask-swagger-ui version)
- RESTORE_BACKUP_IMPROVEMENTS.md (documentation)
This provides a significantly improved user experience for the restore process
while maintaining security and adding powerful new restore capabilities.
Implement comprehensive overtime tracking feature that allows users to
set their standard working hours per day and automatically calculates
overtime for hours worked beyond that threshold.
Core Features:
- Add standard_hours_per_day field to User model (default: 8.0 hours)
- Create Alembic migration (031_add_standard_hours_per_day.py)
- Implement overtime calculation utilities (app/utils/overtime.py)
* calculate_daily_overtime: per-day overtime calculation
* calculate_period_overtime: multi-day overtime aggregation
* get_daily_breakdown: detailed day-by-day analysis
* get_weekly_overtime_summary: weekly overtime statistics
* get_overtime_statistics: comprehensive overtime metrics
User Interface:
- Add "Overtime Settings" section to user settings page
- Display overtime data in user reports (regular vs overtime hours)
- Show "Days with Overtime" badge in reports
- Add overtime analytics API endpoint (/api/analytics/overtime)
- Improve input field styling with cleaner appearance (no spinners)
Reports Enhancement:
- Standardize form input styling across all report pages
- Replace inline Tailwind classes with consistent form-input class
- Add FontAwesome icons to form labels for better UX
- Improve button hover states and transitions
Testing:
- Add comprehensive unit tests (tests/test_overtime.py)
- Add smoke tests for quick validation (tests/test_overtime_smoke.py)
- Test coverage for models, utilities, and various overtime scenarios
Documentation:
- OVERTIME_FEATURE_DOCUMENTATION.md: complete feature guide
- OVERTIME_IMPLEMENTATION_SUMMARY.md: technical implementation details
- docs/features/OVERTIME_TRACKING.md: quick start guide
This change enables organizations to track employee overtime accurately
based on individual working hour configurations, providing better
insights into work patterns and resource allocation.
Fixed issue where invoices were always displaying EUR as the currency
regardless of what was configured in Settings. The Invoice model had a
hard-coded default of 'EUR' and the invoice creation route wasn't
explicitly setting the currency from Settings.
Changes:
- Updated invoice creation route to fetch and use currency from Settings
- Updated invoice duplication to preserve original invoice's currency
- Added currency code display to all monetary values in invoice templates
- Added currency code display to invoice list totals
- Created migration script to update existing invoices
- Added comprehensive unit tests and smoke tests
- Added detailed documentation for the fix
Backend changes:
- app/routes/invoices.py: Retrieve currency from Settings when creating
invoices, pass currency_code explicitly to Invoice constructor
- app/routes/invoices.py: Preserve currency_code when duplicating invoices
Frontend changes:
- app/templates/invoices/view.html: Display currency code next to all
monetary values (items, extra goods, subtotals, tax, totals)
- app/templates/invoices/list.html: Display currency code next to
invoice totals in list view
Testing:
- tests/test_invoice_currency_fix.py: 10 unit tests covering various
currency scenarios and edge cases
- tests/test_invoice_currency_smoke.py: 2 end-to-end smoke tests
Migration:
- migrations/fix_invoice_currency.py: Script to update existing invoices
to use the currency from Settings
This fix is fully backward compatible. Existing invoices will continue
to work with their current currency values. Run the migration script to
update existing invoices to match the Settings currency.
Resolves: #153 (invoices-display-currency-as-eur-and-not-usd)
The Time Entry Templates page (/templates) was throwing a 500 error
when displaying templates with usage data. The templates referenced
a 'timeago' Jinja2 filter that was never registered.
Changes:
- Added timeago filter to app/utils/template_filters.py
- Converts datetime to human-readable relative time (e.g., "2 hours ago")
- Handles None, naive/aware datetimes, and future dates gracefully
- Provides appropriate granularity from seconds to years
- Uses proper singular/plural forms
- Added 11 comprehensive unit tests in tests/test_utils.py
- Tests for None values, all time ranges, edge cases
- Tests for naive datetimes and future dates
- Tests for singular/plural formatting
- Added smoke test in tests/test_time_entry_templates.py
- Specifically tests templates with usage_count and last_used_at
- Ensures the filter renders correctly in the template
The filter is used in:
- app/templates/time_entry_templates/list.html (line 96)
- app/templates/time_entry_templates/edit.html (line 140)
Fixes#151
Implement comprehensive support for exporting extra goods (products,
services, materials, licenses) in invoice PDF documents. Extra goods
now appear in the invoice items table alongside time-based billing
entries with rich formatting including name, description, SKU codes,
and category labels.
Changes:
- Enhanced InvoicePDFGenerator._generate_items_rows() to include extra
goods with detailed formatting (name, description, SKU, category)
- Updated pdf_default.html template to render extra goods loop in the
invoice items table with conditional display of optional fields
- Enhanced InvoicePDFGeneratorFallback._build_items_table() for
ReportLab compatibility with multi-line descriptions
- Added 6 comprehensive tests covering both WeasyPrint and ReportLab
generators (unit tests and smoke tests)
- Created complete feature documentation in
docs/INVOICE_EXTRA_GOODS_PDF_EXPORT.md
Technical Details:
- Extra goods display quantity, unit price, and total amount
- Automatic inclusion in invoice totals via existing calculate_totals()
- No database migrations required (extra_goods table already exists)
- Backward compatible - invoices without goods unchanged
- Supports both primary (WeasyPrint) and fallback (ReportLab) generators
Testing:
- 6 new tests added to tests/test_invoices.py
- 3 tests pass on Windows (ReportLab fallback)
- 3 tests require WeasyPrint system dependencies (Linux/Docker)
- All code changes validated with no linter errors
Files Modified:
- app/utils/pdf_generator.py
- app/templates/invoices/pdf_default.html
- app/utils/pdf_generator_fallback.py
- tests/test_invoices.py
Files Created:
- docs/INVOICE_EXTRA_GOODS_PDF_EXPORT.md
- INVOICE_GOODS_EXPORT_IMPLEMENTATION_SUMMARY.md
BREAKING CHANGE: Permission system now actively enforced across all routes
## Summary
Complete implementation of advanced role-based access control (RBAC) system
with full route protection, UI conditionals, and enhanced management interface.
## Route Protection
- Updated all admin routes to use @admin_or_permission_required decorator
- Replaced inline admin checks with granular permission checks in:
* Admin routes: user management, settings, backups, telemetry, OIDC
* Project routes: create, edit, delete, archive, bulk operations
* Client routes: create, edit, delete, archive, bulk operations
- Maintained backward compatibility with existing @admin_required decorator
## UI Permission Integration
- Added template helpers (has_permission, has_any_permission) to all templates
- Navigation conditionally shows admin/OIDC links based on permissions
- Action buttons (Edit, Delete, Archive) conditional on user permissions
- Project and client pages respect permission requirements
- Create buttons visible only with appropriate permissions
## Enhanced Roles & Permissions UI
- Added statistics dashboard showing:
* Total roles, system roles, custom roles, assigned users
- Implemented expandable permission details in roles list
* Click to view all permissions grouped by category
* Visual checkmarks for assigned permissions
- Enhanced user list with role visibility:
* Shows all assigned roles as color-coded badges
* Blue badges for system roles, gray for custom roles
* Yellow badges for legacy roles with migration prompt
* Merged legacy role column into unified "Roles & Permissions"
- User count per role now clickable and accurate
## Security Improvements
- Added CSRF tokens to all new permission system forms:
* Role creation/edit form
* Role deletion form
* User role assignment form
- All POST requests now protected against CSRF attacks
## Technical Details
- Fixed SQLAlchemy relationship query issues (AppenderQuery)
- Proper use of .count() for relationship aggregation
- Jinja2 namespace for accumulating counts in templates
- Responsive grid layouts for statistics and permission cards
## Documentation
- Created comprehensive implementation guides
- Added permission enforcement documentation
- Documented UI enhancements and features
- Included CSRF protection review
## Impact
- Permissions are now actively enforced, not just defined
- Admins can easily see who has what access
- Clear visual indicators of permission assignments
- Secure forms with CSRF protection
- Production-ready permission system
Implement a complete expense tracking feature that allows users to record,
manage, approve, and track business expenses with full integration into
existing project management and invoicing systems.
Features:
- Create and manage expenses with detailed information (amount, category,
vendor, receipts, tax tracking)
- Multi-currency support (EUR, USD, GBP, CHF)
- Approval workflow with admin oversight (pending → approved → rejected)
- Reimbursement tracking and status management
- Billable expense flagging for client invoicing
- Receipt file upload and attachment
- Project and client association with auto-client selection
- Tag-based organization and advanced filtering
- CSV export functionality
- Analytics dashboard with category breakdowns
- API endpoints for programmatic access
Database Changes:
- Add expenses table with comprehensive schema
- Create Alembic migration (029_add_expenses_table.py)
- Add composite indexes for query performance
- Implement proper foreign key constraints and cascading
Routes & Templates:
- Add expenses blueprint with 14 endpoints (CRUD, approval, export, API)
- Create 4 responsive templates (list, form, view, dashboard)
- Implement advanced filtering (status, category, project, client, date range)
- Add permission-based access control (user vs admin)
- Integrate receipt file upload handling
User Experience:
- Add "Expenses" to Insights navigation menu
- Auto-populate client when project is selected
- Provide visual feedback for auto-selections
- Display summary statistics and analytics
- Implement pagination and search functionality
Testing & Documentation:
- Add 40+ comprehensive tests covering models, methods, and workflows
- Create complete user documentation (docs/EXPENSE_TRACKING.md)
- Add API documentation and examples
- Include troubleshooting guide and best practices
Integration:
- Link expenses to projects for cost tracking
- Associate with clients for billing purposes
- Connect billable expenses to invoicing system
- Add PostHog event tracking for analytics
- Implement structured logging for audit trail
Security:
- Role-based access control (users see only their expenses)
- Admin-only approval and reimbursement actions
- CSRF protection and file upload validation
- Proper permission checks on all operations
This implementation follows existing codebase patterns and includes full
test coverage, documentation, and database migrations per project standards.
Implemented a comprehensive Weekly Time Goals system that allows users to set
and track weekly hour targets with real-time progress monitoring.
Features:
- WeeklyTimeGoal model with status tracking (active, completed, failed, cancelled)
- Full CRUD interface for managing weekly goals
- Real-time progress calculation based on logged time entries
- Dashboard widget showing current week's goal progress
- Daily breakdown view with detailed statistics
- Automatic status updates based on goal completion and week end
- API endpoints for goal data and progress tracking
Technical changes:
- Added app/models/weekly_time_goal.py with local timezone support
- Created migration 027_add_weekly_time_goals.py for database schema
- Added app/routes/weekly_goals.py blueprint with all CRUD routes
- Created templates: index.html, create.html, edit.html, view.html
- Integrated weekly goal widget into main dashboard
- Added "Weekly Goals" navigation item to sidebar
- Implemented comprehensive test suite in tests/test_weekly_goals.py
- Added feature documentation in docs/WEEKLY_TIME_GOALS.md
Bug fixes:
- Fixed timezone handling to use TZ environment variable instead of Config.TIMEZONE
- Corrected log_event() calls to use proper signature (event name as first positional argument)
- Manually created database table via SQL when Alembic migration didn't execute
Database schema:
- weekly_time_goals table with user_id, target_hours, week_start_date, week_end_date, status, notes
- Indexes on user_id, week_start_date, status, and composite (user_id, week_start_date)
- Foreign key constraint to users table with CASCADE delete
The feature supports flexible week start days per user, calculates remaining hours,
provides daily average targets, and automatically updates goal status based on progress.
Implement comprehensive time rounding preferences that allow each user to
configure how their time entries are rounded when stopping timers.
Features:
- Per-user rounding settings (independent from global config)
- Multiple rounding intervals: 1, 5, 10, 15, 30, 60 minutes
- Three rounding methods: nearest, up (ceiling), down (floor)
- Enable/disable toggle for flexible time tracking
- Real-time preview showing rounding examples
- Backward compatible with existing global rounding settings
Database Changes:
- Add migration 027 with three new user columns:
* time_rounding_enabled (Boolean, default: true)
* time_rounding_minutes (Integer, default: 1)
* time_rounding_method (String, default: 'nearest')
Implementation:
- Update User model with rounding preference fields
- Modify TimeEntry.calculate_duration() to use per-user rounding
- Create app/utils/time_rounding.py with core rounding logic
- Update user settings route and template with rounding UI
- Add comprehensive unit, model, and smoke tests (50+ test cases)
UI/UX:
- Add "Time Rounding Preferences" section to user settings page
- Interactive controls with live example visualization
- Descriptive help text and method explanations
- Fix navigation: Settings link now correctly points to user.settings
- Fix CSRF token in settings form
Documentation:
- Add comprehensive user guide (docs/TIME_ROUNDING_PREFERENCES.md)
- Include API documentation and usage examples
- Provide troubleshooting guide and best practices
- Add deployment instructions for migration
Testing:
- Unit tests for rounding logic (tests/test_time_rounding.py)
- Model integration tests (tests/test_time_rounding_models.py)
- End-to-end smoke tests (tests/test_time_rounding_smoke.py)
Fixes:
- Correct settings navigation link in user dropdown menu
- Fix CSRF token format in user settings template
This feature enables flexible billing practices, supports different client
requirements, and maintains exact time tracking when needed.