Performance:
- Fix N+1 queries in reports.py with joinedload for TimeEntry.project,
TimeEntry.user, TimeEntry.task, and Project.client across 6 query locations
- Replace per-task time_entries loops with batch UPDATE queries in tasks.py
- Use efficient subquery for favorite project IDs in projects.py
Architecture:
- Add get_by_id() and get_by_name() methods to ProjectService and ClientService
- Route project/client lookups through service layer in timer.py, projects.py,
and clients.py instead of direct Model.query calls
Security:
- Add sanitize_input() with length limits to form inputs in clients.py,
projects.py, timer.py, issues.py, and auth.py
- Add email format validation for client creation
- Warn at startup when SECRET_KEY uses the default value or is too short
in ProductionConfig
- Replace 7 bare except: pass clauses with specific exception types
(OSError, IOError, TypeError, ValueError) in admin.py, settings.py,
and invoice.py
Authorization:
- Migrate all @admin_required decorators to @admin_or_permission_required()
with granular permissions (manage_roles, manage_kanban, manage_webhooks,
manage_api_tokens, manage_integrations, access_admin) across permissions.py,
kanban.py, webhooks.py, and admin.py (28 routes total)
Frontend:
- Remove 40+ console.log debug statements across 18 JS files
- Replace 42 inline onclick/onchange handlers in base.html with delegated
event listeners using data-dropdown and data-no-propagation attributes
- Migrate 6 inline handlers in time_entries_overview.html to addEventListener
- Extract shared typing detection into typing-utils.js, eliminating 5
duplicate isTyping() implementations across keyboard shortcut files
- Add missing aria-label attributes to icon-only buttons
Dependencies:
- Migrate from pytz to stdlib zoneinfo (Python 3.9+) across all 6 files
that used pytz; replace pytz with tzdata in requirements.txt
- Separate dev/test dependencies into requirements-dev.txt
- Configure RotatingFileHandler (10MB, 5 backups) for app and JSON logs
Co-authored-by: Cursor <cursoragent@cursor.com>