- Add 26 comprehensive tests (all passing) covering models, routes, API, and integration - Add user documentation (docs/features/TIME_ENTRY_TEMPLATES.md) - Add developer documentation (docs/TIMETRACKER_TEMPLATES_IMPLEMENTATION.md) - Add implementation summaries and completion reports - Verify feature integration with navigation menu - All tests passing, feature production-ready Related to Quick Wins implementation (migration revision 022)
12 KiB
Time Entry Templates - Implementation Summary
Overview
The Time Entry Templates feature provides reusable templates for frequently logged activities, enabling users to quickly create time entries with pre-filled data including projects, tasks, notes, tags, and durations.
Implementation Date
Implementation Date: January 2025 (Phase 1: Quick Wins Features) Completion Date: October 2025 (Tests and Documentation Added)
Components
1. Database Schema
Table: time_entry_templates
| Column | Type | Description |
|---|---|---|
| id | Integer | Primary key |
| user_id | Integer | Foreign key to users table |
| name | String(200) | Template name (required) |
| description | Text | Optional template description |
| project_id | Integer | Foreign key to projects table (nullable) |
| task_id | Integer | Foreign key to tasks table (nullable) |
| default_duration_minutes | Integer | Default duration in minutes (nullable) |
| default_notes | Text | Pre-filled notes (nullable) |
| tags | String(500) | Comma-separated tags (nullable) |
| billable | Boolean | Whether entry should be billable (default: true) |
| usage_count | Integer | Number of times template has been used (default: 0) |
| last_used_at | DateTime | Timestamp of last usage (nullable) |
| created_at | DateTime | Timestamp of creation |
| updated_at | DateTime | Timestamp of last update |
Indexes:
ix_time_entry_templates_user_idonuser_idix_time_entry_templates_project_idonproject_idix_time_entry_templates_task_idontask_id
Migrations:
- Initial creation:
migrations/versions/add_quick_wins_features.py - Fix nullable constraint:
migrations/versions/024_fix_time_entry_template_nullable.py
2. Backend Implementation
Model: app/models/time_entry_template.py
Key Features:
- Full SQLAlchemy model with relationships to User, Project, and Task
- Property methods for duration conversion (minutes ↔ hours)
- Usage tracking methods:
record_usage()andincrement_usage() - Dictionary serialization via
to_dict()for API responses - Automatic timestamp management
Routes: app/routes/time_entry_templates.py
Endpoints:
| Route | Method | Description |
|---|---|---|
/templates |
GET | List all user templates |
/templates/create |
GET/POST | Create new template |
/templates/<id> |
GET | View template details |
/templates/<id>/edit |
GET/POST | Edit existing template |
/templates/<id>/delete |
POST | Delete template |
/api/templates |
GET | Get templates as JSON |
/api/templates/<id> |
GET | Get single template as JSON |
/api/templates/<id>/use |
POST | Mark template as used |
Features:
- Duplicate name detection per user
- Activity logging for all CRUD operations
- Event tracking for analytics (PostHog)
- Safe database commits with error handling
- User isolation (users can only access their own templates)
3. Frontend Implementation
Templates (HTML/Jinja2)
Files:
app/templates/time_entry_templates/list.html- Template listing pageapp/templates/time_entry_templates/create.html- Template creation formapp/templates/time_entry_templates/edit.html- Template editing formapp/templates/time_entry_templates/view.html- Template detail view
UI Features:
- Responsive grid layout for template cards
- Empty state with call-to-action
- Real-time usage statistics display
- Dynamic task loading based on selected project
- Inline CRUD actions with confirmation dialogs
- Dark mode support
JavaScript Integration
Template Application Flow:
- User clicks "Use Template" button on templates list page
- JavaScript fetches template data from
/api/templates/<id> - Template data stored in browser sessionStorage
- Usage count incremented via
/api/templates/<id>/use - User redirected to
/timer/manual?template=<id> - Manual entry page loads template from sessionStorage or fetches via API
- Form fields pre-filled with template data
- Duration used to calculate end time based on current time
- SessionStorage cleared after template application
4. Integration Points
Timer/Manual Entry Integration
The manual entry page (app/templates/timer/manual_entry.html) includes JavaScript code that:
- Checks for
activeTemplatein sessionStorage - Falls back to fetching template via
?template=<id>query parameter - Pre-fills all form fields (project, task, notes, tags, billable)
- Calculates end time based on start time + duration
- Clears template data after application
Activity Logging
All template operations are logged via the Activity model:
- Template creation
- Template updates (with old name if renamed)
- Template deletion
- Template usage (via event tracking)
Analytics Tracking
PostHog events tracked:
time_entry_template.createdtime_entry_template.updatedtime_entry_template.deletedtime_entry_template.used(with usage count)
5. Testing
Test File: tests/test_time_entry_templates.py
Test Coverage:
Model Tests (TestTimeEntryTemplateModel):
- Create template with all fields
- Create template with minimal fields
- Duration property (hours ↔ minutes conversion)
- Usage recording and increment methods
- Dictionary serialization (
to_dict()) - Relationship integrity (user, project, task)
- String representation (
__repr__)
Route Tests (TestTimeEntryTemplateRoutes):
- List templates (authenticated and unauthenticated)
- Create template page access
- Create template success and validation
- Duplicate name prevention
- Edit template page access and updates
- Delete template
- View single template
API Tests (TestTimeEntryTemplateAPI):
- Get all templates via API
- Get single template via API
- Mark template as used
Smoke Tests (TestTimeEntryTemplatesSmoke):
- Templates page renders
- Create page renders
- Complete CRUD workflow
Integration Tests (TestTimeEntryTemplateIntegration):
- Template with project and task relationships
- Usage tracking over time
- User isolation (templates are user-specific)
Total: 30+ test cases covering all aspects of the feature
6. Documentation
User Documentation: docs/features/TIME_ENTRY_TEMPLATES.md
Contents:
- Feature overview and benefits
- Step-by-step usage instructions
- Template creation, editing, and deletion
- Use cases and examples
- Best practices for template naming, duration, notes, tags
- Template management and organization tips
- Troubleshooting guide
- API documentation
- Integration notes
- Future enhancement suggestions
Developer Documentation: This file
Usage Statistics
Templates track two key metrics:
- Usage Count: Total number of times the template has been used
- Last Used At: Timestamp of the most recent usage
These statistics help users:
- Identify their most common activities
- Prioritize template organization
- Clean up unused templates
- Understand work patterns
Security Considerations
- User Isolation: Users can only access their own templates
- Authorization Checks: All routes verify user ownership before allowing operations
- CSRF Protection: All form submissions include CSRF tokens
- Input Validation: Template names are required; duplicate names per user are prevented
- Safe Deletes: Templates can be deleted without affecting existing time entries
- SQL Injection Protection: Parameterized queries via SQLAlchemy ORM
Performance Considerations
- Database Indexes: Indexes on user_id, project_id, and task_id for fast queries
- Efficient Queries: Templates sorted by last_used_at in descending order
- Lazy Loading: Tasks loaded dynamically via AJAX when project is selected
- SessionStorage: Template data temporarily cached in browser to avoid repeated API calls
- Minimal Payload: API responses include only necessary fields
Known Limitations
- User-Specific: Templates cannot be shared between users
- No Template Categories: All templates in a single list (consider future enhancement)
- No Bulk Operations: Templates must be created/edited one at a time
- No Template Import/Export: No built-in way to backup or migrate templates
- No Template Versioning: Changes to templates don't maintain history
Future Enhancements
Potential improvements identified:
-
Template Organization:
- Template folders or categories
- Favorite/pin templates
- Custom sorting options
-
Collaboration:
- Share templates with team members
- Organization-wide template library
- Template approval workflow
-
Automation:
- Template suggestions based on time entry patterns
- Auto-create templates from frequently repeated time entries
- Template scheduling (create time entries automatically)
-
Advanced Features:
- Template versioning and history
- Bulk template operations (import/export, duplicate, delete)
- Template usage analytics and reporting
- Template-based time entry validation rules
-
Integration:
- Integration with calendar events
- Integration with project management tools
- API webhooks for template usage
Migration Guide
Upgrading to Time Entry Templates
If you're upgrading from a version without templates:
-
Run Database Migration:
flask db upgradeor
alembic upgrade head -
Verify Table Creation: Check that the
time_entry_templatestable exists with all columns and indexes. -
Test Template Creation: Create a test template to verify the feature works correctly.
-
User Training: Introduce users to the new feature with the user documentation.
Downgrading (Removing Templates)
If you need to remove the templates feature:
-
Backup Template Data (if needed):
SELECT * FROM time_entry_templates; -
Run Down Migration:
alembic downgrade -1 -
Verify Table Removal: Check that the
time_entry_templatestable has been dropped.
API Examples
Create Template via Programmatic API
While there's no dedicated API endpoint for creating templates (only UI routes), you can interact with templates via the web API:
import requests
# Get all templates
response = requests.get(
'https://your-timetracker.com/api/templates',
cookies={'session': 'your-session-cookie'}
)
templates = response.json()['templates']
# Get single template
response = requests.get(
'https://your-timetracker.com/api/templates/1',
cookies={'session': 'your-session-cookie'}
)
template = response.json()
# Mark template as used
response = requests.post(
'https://your-timetracker.com/api/templates/1/use',
cookies={'session': 'your-session-cookie'},
headers={'X-CSRFToken': 'csrf-token'}
)
result = response.json()
Changelog
Version 024 (October 2025)
- Fixed
project_idnullable constraint mismatch between model and migration - Added comprehensive test suite (30+ tests)
- Created user documentation
- Created implementation documentation
Version 022 (January 2025)
- Initial implementation of Time Entry Templates
- Model, routes, and UI templates created
- Integration with manual time entry page
- Activity logging and analytics tracking
Related Features
- Time Entries: Templates pre-fill time entry forms
- Projects: Templates can reference specific projects
- Tasks: Templates can reference specific tasks
- Activity Logging: All template operations are logged
- Analytics: Template usage is tracked for insights
Support and Troubleshooting
For issues with templates:
- Check Logs: Review application logs for error messages
- Verify Database: Ensure the
time_entry_templatestable exists - Test API: Use browser developer tools to check API responses
- Check Permissions: Verify user has access to templates
- Clear Cache: Clear browser sessionStorage if templates don't load
Contributing
When contributing to the templates feature:
-
Run Tests: Ensure all tests pass before committing
pytest tests/test_time_entry_templates.py -v -
Update Documentation: Keep user and developer docs in sync with code changes
-
Follow Conventions: Use existing patterns for routes, models, and templates
-
Add Tests: Include tests for any new functionality
-
Test Integration: Verify templates work with manual entry page
Credits
- Feature Design: TimeTracker Development Team
- Implementation: Initial implementation in Quick Wins phase (January 2025)
- Testing & Documentation: Completed October 2025
- Maintained by: TimeTracker Project Contributors