Commit Graph

1155 Commits

Author SHA1 Message Date
Dries Peeters 8752d3d6aa feat(break-time): add break_seconds and pause support to TimeEntry and schemas (Issue #561)
- TimeEntry: break_seconds, paused_at; pause_timer(), resume_timer(); current_duration_seconds and calculate_duration() account for break
- Settings: break_after_hours_1/2, break_minutes_1/2 for default break rules
- Repository: create_manual_entry accepts break_seconds
- Schemas: break_seconds on TimeEntrySchema, Create, Update
2026-03-11 17:58:37 +01:00
Dries Peeters f66d5b7547 feat(break-time): add migrations for break_seconds, paused_at, and default break rules (Issue #561)
- Migration 137: add time_entries.break_seconds, time_entries.paused_at
- Migration 138: add settings break_after_hours_1/2, break_minutes_1/2 (e.g. 6h->30min, 9h->45min)
2026-03-11 17:57:52 +01:00
Dries Peeters 1eadcd090b docs(overtime): accumulated YTD and take as paid leave (Issue #560)
- Document accumulated overtime (YTD) and where it appears (dashboard, analytics, workforce)
- Document take-overtime-as-paid-leave flow, API endpoints, and new helpers
- Add migration 136 and test_overtime_leave.py to Testing section; bump version to 1.2.0
2026-03-11 17:39:44 +01:00
Dries Peeters eefb529ef0 test(overtime): YTD helpers and overtime-as-leave validation (Issue #560)
- TestOvertimeYTD: get_overtime_ytd / get_overtime_last_12_months structure and values
- test_overtime_leave: request within YTD succeeds, exceeding YTD fails with validation
- Smoke test: assert get_overtime_ytd is available on overtime module
2026-03-11 17:39:37 +01:00
Dries Peeters 60551f3720 feat(migration): seed Overtime leave type for take-as-paid-leave (Issue #560)
- Migration 136: insert leave type code 'overtime' if not present
- Enables workforce 'Take as paid leave' flow without manual admin setup
2026-03-11 17:39:28 +01:00
Dries Peeters 251d41bc33 feat(workforce): overtime overview and take as paid leave (Issue #560)
- Workforce dashboard: show Accumulated overtime (YTD) next to Leave Balances
- Add get_overtime_leave_type() and validate requested_hours <= YTD for overtime leave
- Time-off form: 'Take as paid leave' link, overtime type preset, available hours hint
- create_leave_request rejects overtime requests exceeding YTD with clear error
2026-03-11 17:39:20 +01:00
Dries Peeters bd31609ea1 feat(overtime): show accumulated overtime (YTD) on dashboard and in API (Issue #560)
- Main dashboard: compute and display Overtime (YTD) in Month's Hours card
- Analytics: GET /api/analytics/overtime supports period=ytd and start_date/end_date
- API: dashboard stats endpoints include overtime_ytd_hours in response
2026-03-11 17:39:10 +01:00
Dries Peeters ca0c181dc3 feat(overtime): add get_overtime_ytd and get_overtime_last_12_months helpers (Issue #560)
- get_overtime_ytd(user): returns overtime from Jan 1 through today
- get_overtime_last_12_months(user): returns rolling 12-month overtime
- Reuses calculate_period_overtime; no new DB columns
2026-03-11 17:38:56 +01:00
Dries Peeters de2a7db026 fix: restrict subcontractors to assigned projects/clients when starting timers (fixes #558)
- Enforce scope in timer routes: start_timer (POST), start_timer_for_project (GET),
  and start_timer_from_template; deny with flash+redirect when project/client not allowed
- Add user_can_access_project check in api_start_timer (legacy API), API v1 timer/start,
  and kiosk start-timer; return 403 with clear error message
- Scope dashboard Start Timer modal: load active_projects and active_clients via
  apply_project_scope_to_model/apply_client_scope_to_model so subcontractors only see
  assigned options
- Document timer start scope in SUBCONTRACTOR_ROLE.md (web, API, kiosk, 403/redirect)
2026-03-11 16:49:26 +01:00
Dries Peeters 147da2949f Fix(web): prevent mobile browser freeze on Log Time page (Issue #557)
On viewports <=767px, skip loading Toast UI Editor for the notes field on manual entry and edit timer pages; use a plain textarea instead. Toast UI is heavy and was freezing/crashing mobile Safari and Chrome. Desktop behavior unchanged. Document in CHANGELOG and MOBILE_IMPROVEMENTS.md.
2026-03-11 16:37:31 +01:00
Dries Peeters ceae30ecb9 Fix #563: correct route for post-timer toast after Stop & Save
- Use timer.time_entries_overview instead of timer.time_entries when
  building the 'View time entries' URL in the dashboard. The invalid
  route name caused BuildError and an error page after stopping the
  timer, even though the time entry was saved.
- Document the fix in CHANGELOG under Unreleased / Fixed.
2026-03-11 16:23:58 +01:00
Dries Peeters 42c73871ab Update setup.py 2026-03-11 12:50:13 +01:00
Dries Peeters f93103c578 fix(time-entries): add Apply filters button and make export use current filters
Issue #555: Users could set start/end date but had no visible way to apply filters, and CSV/PDF export could ignore the date range if applied before the AJAX filter ran.

- Add explicit 'Apply filters' submit button so date and other filters are applied on click (and on Enter).

- Export CSV/PDF: on click, build URL from current form params so export always reflects the selected date range and filters.

- Initialize export links from form state on load so they match visible filters.

Fixes #555
2026-03-11 12:48:21 +01:00
Dries Peeters 0a4a1535c1 refactor: split API v1 into sub-blueprints, slim bootstrap, move dashboard to AnalyticsService
Architecture and maintainability improvements per production-readiness plan:

- API v1: Split monolithic api_v1.py into per-resource blueprints
  (api_v1_projects, api_v1_tasks, api_v1_clients, api_v1_invoices,
  api_v1_expenses, api_v1_payments, api_v1_mileage, api_v1_deals,
  api_v1_leads, api_v1_contacts). Register all in blueprint_registry;
  keep info, health, auth and remaining routes in api_v1.py.

- Bootstrap: Move setup_logging to app/utils/setup_logging.py and
  legacy migrations (task management, issues tables) to
  app/utils/legacy_migrations.py. Use SQLAlchemy 2-compatible
  db.engine.begin() in legacy_migrations.

- Dashboard: Add AnalyticsService.get_dashboard_top_projects and
  get_time_by_project_chart; thin main dashboard route to call
  services only and remove inline TimeEntry aggregation.

- Docs: Update ARCHITECTURE.md (module table, API structure, data
  flow, design decisions), DEVELOPMENT.md (workflow, build steps,
  test examples), CHANGELOG.md (Unreleased refactor entry).
2026-03-11 11:54:04 +01:00
Dries Peeters 1768ab8839 docs: add UI guidelines and update README, architecture, changelog
- Add docs/UI_GUIDELINES.md: design principles, component usage, layout,
  styling, keyboard/focus; file reference and a11y pointer
- README: add UI overview and Getting around (Dashboard, Timer, Time entries)
- ARCHITECTURE: add UI layer subsection (base, Tailwind, component macros)
- CHANGELOG: document UI/UX redesign under Unreleased
2026-03-11 10:21:03 +01:00
Dries Peeters ce331c6768 feat(ui): dashboard hero block and streamlined recent entries
- Move Timer card to top as hero (primary action: start/stop, quick start, repeat last)
- Replace four adjust-time forms with single form and JS-driven delta submit
- Show only last 5 recent entries with columns: Project, Duration, Date, Actions
- Add View all link to Time entries overview; fix post-stop toast URL to time_entries_overview
2026-03-11 10:20:53 +01:00
Dries Peeters 0e193ec3c1 feat(ui): base layout and sidebar navigation improvements
- Apply max-w-7xl mx-auto to main content for readable width on large screens
- Add first-class sidebar links for Timer and Time entries (above Calendar)
- Fix active state: only Time entries highlighted on time_entries_overview,
  only Timer highlighted on other timer.* routes
- Keep Time Tracking dropdown closed on Log time and Time entries pages
- Remove duplicate Time Entries link from Time Tracking submenu
2026-03-11 10:20:40 +01:00
Dries Peeters 9845a4c62c feat(ui): consolidate components and extend design tokens
- Add form-input-error and disabled state to form-input in input.css
- Add empty_state_compact and loading_overlay macros to components/ui.html
- Migrate tasks/overdue.html from Bootstrap (_components.html) to Tailwind
  (page_header, empty_state, alert from ui.html; consistent cards and grid)
2026-03-11 10:20:32 +01:00
Dries Peeters a3148d9021 docs: update README, CHANGELOG, ARCHITECTURE for product value release
README: document dashboard time-by-project chart, summary report charts and PDF export, post-timer toast, remind-to-log setting; add daily workflow note under dashboard screenshot. CHANGELOG: add Unreleased entries for new features and changes. ARCHITECTURE: mention remind-to-log job and summary report PDF in Data Flow.
2026-03-11 08:59:28 +01:00
Dries Peeters f150b73b94 feat: product value improvements (dashboard, reports, timer, reminders)
Dashboard:
- Add time-by-project chart (last 7 days) with Chart.js horizontal bar; link to Summary report

Summary report:
- Add time-by-project (last 30d) bar chart and daily trend (14d) line chart
- Add one-page PDF export (today/week/month hours + top projects table)

Post-timer flow:
- After stop, show toast "Logged Xh on [Project]" with action link "View time entries"
- Toast manager: optional actionLink/actionLabel for action links in toasts
- Session carries timer_stopped_toast to dashboard; no duplicate flash

Remind to log:
- User setting "Remind me to log time at end of day" + time picker (Settings)
- Hourly job: send one email per day if user has <0.5h logged that day (user TZ)
- Migration 135: notification_remind_to_log, reminder_to_log_time on users
2026-03-11 08:59:13 +01:00
Dries Peeters a78eccfd71 docs: update docs index and PROJECT_STRUCTURE with new root docs
docs/README.md:
- Quick Links: add INSTALLATION, ARCHITECTURE, DEVELOPMENT, API (root)
- Getting Started: add Installation Guide (root)
- Developer: add root Contributing, Development Guide, Architecture
- API: add API quick reference (root)
- Installation & Deployment: list Installation Guide first

docs/development/PROJECT_STRUCTURE.md:
- Documentation Files: list root CONTRIBUTING, ARCHITECTURE, INSTALLATION,
  DEVELOPMENT, API with correct relative links (../../ for root from docs/development)
2026-03-11 08:19:48 +01:00
Dries Peeters 69eff31de4 docs: standardize CHANGELOG (Keep a Changelog, remove TBD placeholders)
- Remove placeholder version entries [4.8.0], [4.7.1], [4.7.0] with TBD dates
- Rename 'Release Notes Format' to 'Release notes format', reference
  Keep a Changelog and Semantic Versioning
- Align section list with actual headings (Added, Changed, Fixed, etc.)
2026-03-11 08:19:38 +01:00
Dries Peeters 24f8e7aef8 docs: update README with version, installation, and doc links
- Version: point to setup.py as single source of truth, link to CHANGELOG
- Tech stack: add Architecture overview link next to Project Structure
- Quick Start: add link to INSTALLATION.md for full steps
- Documentation: add Installation Guide, root Contributing, Development
  Guide, Architecture, API quick reference
- Contributing: link to CONTRIBUTING.md and DEVELOPMENT.md
2026-03-11 08:19:29 +01:00
Dries Peeters 97ca663e15 docs: add PR template and improve bug report template
- Add .github/PULL_REQUEST_TEMPLATE.md: description, type of change,
  checklist (tests, docs, CHANGELOG), links to CONTRIBUTING and CHANGELOG
- Enhance bug_report.md: add Environment section (TimeTracker version,
  deployment type, OS, browser) for easier triage
2026-03-11 08:19:21 +01:00
Dries Peeters 6b8e0404ad docs: add root API.md quick reference
- REST API overview, token auth, base URL /api/v1
- How to get and use API tokens (Admin → Api-tokens, Bearer header)
- Main resources table (projects, time entries, tasks, clients, etc.)
- Curl examples for GET projects and POST time entry
- Links to REST_API.md, API_TOKEN_SCOPES.md, API_VERSIONING.md
2026-03-11 08:19:09 +01:00
Dries Peeters 7faa3186da docs: add INSTALLATION.md and DEVELOPMENT.md
INSTALLATION.md:
- Prerequisites, Docker quick install (env.example, SECRET_KEY)
- First login and minimal config, SQLite quick-test option
- Production and troubleshooting links

DEVELOPMENT.md:
- Run locally (venv + flask run or Docker SQLite compose)
- Env setup, dependencies, folder tree
- Coding conventions, tests (pytest), contributing, releases
- Links to CONTRIBUTING, ARCHITECTURE, PROJECT_STRUCTURE
2026-03-11 08:19:01 +01:00
Dries Peeters 00666381fa docs: add ARCHITECTURE.md with system overview and diagrams
- High-level system overview (Flask, API, Docker, PostgreSQL)
- Main modules table (routes, services, models, desktop, mobile)
- Data flow and backend/frontend separation
- Design decisions (service layer, blueprint registry, API auth)
- Mermaid diagrams for request flow and app structure
- Links to PROJECT_STRUCTURE and Architecture Migration Guide
2026-03-11 08:18:52 +01:00
Dries Peeters a09b83477d docs: add root CONTRIBUTING.md and fix env.example reference
- Add root CONTRIBUTING.md with quick overview and links to full guide,
  Code of Conduct, and CHANGELOG
- Fix docs/development/CONTRIBUTING.md: use env.example (not .env.example)
  for cp command to match repository
2026-03-11 08:18:42 +01:00
Dries Peeters 2ee8da33a0 feat: TimeTracker polish and production readiness (plan implementation)
Quick wins (Phase A):
- A1: Quick timer actions — last timer context, Repeat last button, Quick start one-click form; pre-fill modal and tags from last entry
- A2: Unified empty states using empty_state macro on custom_view, time_entry_templates, saved_filters, issues; add loading_placeholder macro
- A3: Dashboard hierarchy — Activity and Support/Donate moved to secondary row below fold with reduced visual weight
- A4: Error/feedback consistency (flash-to-toast already in place)

Medium impact (Phase B):
- B5: Split API v1 — api_v1_common.py (shared helpers), api_v1_time_entries.py sub-blueprint for time-entries and timer/*; register api_v1_time_entries_bp
- B6: Start Timer UX — templates as prominent chips at top of modal; default last context and quick start from A1
- B7: Week in review — ReportingService.get_week_in_review(), route /reports/week-in-review, template and link from reports index
- B8: Tags discoverability — GET /api/tags, recent_tags in dashboard, tags input with datalist in Start Timer modal; last context includes tags
- B9: Frontend consolidation — document onboarding.js vs onboarding-enhanced.js in base.html
- B10: API validation — Marshmallow TimeEntryCreateSchema/TimeEntryUpdateSchema and handle_validation_error in api_v1_time_entries create/update

UX: Remove duplicate Timer actions — single Repeat last and Start Timer in header; body shows only Resume when recent entries exist (no duplicate Repeat last or Start new).
2026-03-11 08:00:47 +01:00
Dries Peeters 9f3048f6fb Update setup.py 2026-03-09 20:50:02 +01:00
Dries Peeters c1a1592d2f fix(pdf): show decorative images in export when they overflow the page
- In _on_page(), only skip IMAGE elements when their rect does not
  intersect the page (was skipping when top-left was outside, which
  hid overflowing images).
- Coerce element x, y, width, height to float to avoid type issues.
- In _draw_image_on_canvas(), clip all image drawing to the page
  rectangle (beginPath + rect + clipPath) so the visible portion
  is shown and overflow is clipped like in the preview.
- Try template image file path before get_image_base64 for more
  reliable loading across deployments.
- Add INFO log when drawing template images for debugging.

Fixes #537 (export not showing decorative image when over border).
2026-03-09 20:49:06 +01:00
Dries Peeters 55f2ef29fd feat(overtime): allow overtime calculation by weekly hours (Issue #551) 2026-03-09 20:33:48 +01:00
Dries Peeters 846592cbe9 feat(docker): configurable nginx host ports via HTTP_PORT and HTTPS_PORT
Allow overriding nginx port mappings with environment variables so users behind a reverse proxy (Nginx Proxy Manager, Traefik, etc.) or with 80/443 already in use can deploy without editing docker-compose.yml.

- docker-compose.yml: use \:80 and \:443
- env.example: document HTTP_PORT and HTTPS_PORT with example
- DOCKER_COMPOSE_SETUP.md: add Docker/nginx ports to env reference

Closes #553
2026-03-09 20:33:40 +01:00
Dries Peeters 4248a7e6d7 fix(admin): resolve database error when deleting user (#552)
Before deleting a user, explicitly remove their donation_interactions rows so the delete succeeds even when the table is missing (e.g. after support banner was removed via license). Also handle missing donation_interactions table in safe_commit like time_entry_approvals.
2026-03-09 20:32:47 +01:00
Dries Peeters 3641b277f5 Update tests 2026-03-08 06:50:42 +01:00
Dries Peeters ac829c5dbf Update setup.py 2026-03-08 06:22:27 +01:00
Dries Peeters 2c63f3ac78 fix(dashboard): remove cache to fix ORM detachment on second visit (Issue #549)
- Dashboard cached template data containing ORM objects (active_timer,
  recent_entries, top_projects, templates) that became detached when
  served in a different request, causing 'Instance not bound to a Session'
  and 'Database Error' on second visit
- Add migration 133 to merge heads 132 (timesheet governance) and 129
  (task tags) so flask db upgrade runs without conflicts
- Update CHANGELOG
2026-03-08 06:21:20 +01:00
Dries Peeters cac75d9e5e Update setup.py 2026-03-06 22:16:09 +01:00
Dries Peeters 2e1c18a345 feat(invoicing): add Factur-X CII export validation and transport guidance
Switch embedded invoice PDFs to Factur-X CII payloads and tighten the PDF/A-3 and AS4 handling so exports better match the standards they advertise. Document the experimental native Peppol transport path and cover the new validation and embedding behavior with focused tests.
2026-03-06 22:15:29 +01:00
Dries Peeters 463704f054 feat(ui): refresh shared layout patterns and responsive screens
Unify buttons, cards, headers, toasts, and form treatments across the app so screens feel consistent and are easier to scan on desktop and mobile. Update the broader template set to use the shared UI primitives and responsive spacing patterns introduced in this refresh.
2026-03-06 22:15:06 +01:00
Dries Peeters 9b7f6a54b0 docs: update project structure, quality gates, competitive analysis, and index
- PROJECT_STRUCTURE: add workforce/timesheet governance, desktop/mobile, workforce templates
- Add FRONTEND_QUALITY_GATES.md (a11y, performance, modernization milestones)
- Add competitive-analysis (gap rubric, phase 1/2 PRDs)
- Link new docs from development/README and main docs README
2026-03-06 15:46:18 +01:00
Dries Peeters 71900212bc test: add bulk task operations tests 2026-03-06 15:46:07 +01:00
Dries Peeters a52289a20b chore: update CI workflow, pre-commit, Makefile, and docker-compose
- Adjust ci-comprehensive workflow and pre-commit hooks
- Makefile targets and docker-compose configuration updates
2026-03-06 15:46:01 +01:00
Dries Peeters 07186d7b6b feat(web): base-init, PWA, keyboard shortcuts, onboarding, and template updates
- Add base-init.js for shared keyboard/sidebar init; single PWA registration in pwa-enhancements
- Update keyboard-shortcuts, onboarding, enhanced-search, service-worker
- Template updates: base, list pages, dashboard, mileage/gps, timer; fix duplicate IDs and a11y
2026-03-06 15:45:50 +01:00
Dries Peeters 2a283c3074 refactor(app): wire API, tasks, mileage, custom reports to blueprint registry
- Update api, api_docs, api_v1, custom_reports, mileage, tasks routes
- Update custom_report_service and time_tracking_service
- Export services in app/services/__init__.py
2026-03-06 15:45:31 +01:00
Dries Peeters 435e53957c feat(mobile): add finance/workforce screen and providers
- Add FinanceWorkforceScreen and finance_workforce_providers
- Update home_screen with IndexedStack tab state; api_client updates
- Align mobile with web/desktop for workforce and finance
2026-03-06 15:45:14 +01:00
Dries Peeters 80fde2f0c9 feat(desktop): add state module, notifications UI, and esbuild bundle
- Add state.js and ui/notifications.js; update app.js and api client
- Bundle with esbuild; update package.json dependencies
- Improve connection status and accessible notifications (aria-live/role)
2026-03-06 15:44:45 +01:00
Dries Peeters 531f16b597 feat(workforce): add timesheet governance, time-off, and workforce dashboard
- Add TimesheetPeriod, TimesheetPolicy, TimeOff models and migration 132
- Add workforce blueprint, routes, and workforce_governance_service
- Add workforce dashboard template; register blueprint via blueprint_registry
- Extend User model for time-off and policy associations
2026-03-06 15:44:35 +01:00
Dries Peeters fb169778cb Fix collapsed sidebar not expanding without refresh (#547)
Sync sidebar-collapsed class on document.documentElement when toggling.
The early script adds the class to documentElement on load; applyCollapsed
only updated appShell, so expanding left the class on html and labels
stayed hidden. Now both are updated so expand/collapse works correctly.
2026-03-05 18:55:06 +01:00
Dries Peeters a9c3a1b487 Fix collapsed sidebar flyout position when page is scrolled (#546)
The flyout submenu used document coordinates (getBoundingClientRect +
scrollX/scrollY) while having position:fixed, causing it to shift with
scroll and disappear off-screen. Use viewport-relative coordinates only
so the flyout stays aligned with the trigger.
2026-03-05 18:52:09 +01:00