Skip to content

feat: add daily report - #7

Merged
AlexAndrewsAI merged 7 commits into
mainfrom
feature/daily-report
Jul 5, 2026
Merged

feat: add daily report#7
AlexAndrewsAI merged 7 commits into
mainfrom
feature/daily-report

Conversation

@AlexAndrewsAI

Copy link
Copy Markdown
Owner

Adds a new report CLI command that generates daily summaries of time tracking data, along with supporting datetime utilities and comprehensive test coverage.

What's New

report command — Generate a daily report for any date, showing:

  • Total time tracked (formatted as hh:mm)
  • Activity breakdown with per-activity totals
  • Tag breakdown with prorated time distribution
  • Category breakdown with prorated time distribution

Usage:

timetracker report --config config.yml --date 2026-06-20

Key Changes

  • timetracker_utils/cli.py: Added report command and _seconds_to_hhmm helper; fixed timezone offset formatting to handle None offsets gracefully
  • timetracker_utils/datetime_utils.py: Added aggregate_by_date() for timezone-aware date filtering and breakdown aggregation; added _parse_list_field() for robust tag/category parsing from DB
  • tests/test_cli.py: Added integration tests for the report command
  • tests/test_datetime_utils.py: Added unit tests for aggregate_by_date, _parse_list_field, and edge cases (empty data, midnight-crossing entries, timezone handling)

Notes

  • Entries that cross midnight in the report timezone are split and counted toward each respective date
  • Tag and category times are prorated evenly across all tags/categories of each entry

@AlexAndrewsAI AlexAndrewsAI linked an issue Jun 23, 2026 that may be closed by this pull request
@AlexAndrewsAI

Copy link
Copy Markdown
Owner Author

Code Review: feature/daily-reportmain

Reviewer: Cline (terminal-based AI agent)
Primary Model: DeepSeek V4 Flash
Date: 2026-06-23
Branch: feature/daily-report
Base: main
Mode: Code Review Only (no modifications made)


Executive Summary

This branch introduces a daily report generation system with bar chart visualization, date range reporting, CSV export formatters, and a significant codebase reorganization. The overall quality is high — strong type discipline, excellent test coverage (96.7%), clean architecture, and thorough documentation.

Verdict: APPROVED with minor suggestions — no blocking issues found. The branch is merge-ready after addressing a few low-severity items.


What Changed (vs. main)

File Added Changed Purpose
timetracker_utils/report.py ✨ New Daily/range text reports and matplotlib bar charts
timetracker_utils/csv_formatters.py ✨ New TimeCop and SimpleTimeTracker CSV export
timetracker_utils/datetime_utils.py ✅ Extended Added aggregate_by_date() and _parse_list_field()
timetracker_utils/cli.py ✅ Refactored report command, export improvements, cleanup
tests/test_cli.py ✅ Extended 482 lines added for report/export/bar tests
tests/test_datetime_utils.py ✅ Extended aggregate_by_date() tests
pyproject.toml ✅ Tweaked Python 3.13 classifier added
uv.lock ✅ Updated Dependency lockfile

Strengths

1. 🧪 Excellent Test Coverage (96.7%)

All modules except report.py (77%) achieve 100% coverage. Tests are well-structured, cover edge cases, and mock external dependencies (matplotlib) appropriately.

2. 🏗️ Clean Architecture

  • Base class pattern (BaseTimeEntry / BaseTimeTracker) provides clean inheritance for format-specific implementations (TimeCop, SimpleTimeTracker).
  • Separation of concerns: Parsing, persistence, export, reporting, and CLI are well-separated.
  • No circular dependencies detected.

3. 🔤 Comprehensive Type Hints

Nearly all functions and class members have full type annotations. The project enforces disallow_untyped_defs = true in mypy config.

4. 📚 Documentation

Google-style docstrings on all public APIs. README is thorough with installation, usage examples, and CLI commands.

5. 🛠️ Developer Experience

Well-configured pyproject.toml with ruff, mypy, and pytest. GitHub Actions CI runs all quality gates.

6. 🎯 Edge Case Handling

Strong handling of BOM characters, None DictReader values, timezone-naive vs aware datetimes, merge conflict detection, and empty DataFrames.


Issues & Recommendations

🔴 High Severity — None found.

All 281 tests pass. The code is functionally correct.

🟡 Medium Severity

1. report.py below 95% coverage threshold (77%)

  • File: /sandbox/GitHub/timetracker-utils/timetracker_utils/report.py
  • Suggestion: Add tests for untested matplotlib code paths (_show_bar_single, _show_bar_range, _import_matplotlib).

2. mypy type error in test file

  • File: /sandbox/GitHub/timetracker-utils/tests/test_cli.py:1262
  • Error: Function is missing a return type annotation [no-untyped-def]
  • Suggestion: Add -> tuple[mock.MagicMock, mock.MagicMock] to _make_mock_plt().

🟢 Low Severity / Suggestions

3. Code duplication in datetime formatting

  • File: /sandbox/GitHub/timetracker-utils/timetracker_utils/csv_formatters.py
  • _format_datetime_iso (lines 19–48) and _format_simple_datetime (lines 189–218) share ~90% identical logic.
  • Suggestion: Extract a shared _format_datetime(dt, target_tz) helper.

4. _parse_date_arg module boundary

  • Defined in: report.py (line 22), imported/re-exported by cli.py.
  • Suggestion: Either define in cli.py or have test_cli.py import from report directly.

5. warnings.filterwarnings at module level

  • File: /sandbox/GitHub/timetracker-utils/timetracker_utils/base_tracker.py, lines 25–29
  • Suggestion: Use warnings.catch_warnings() context manager instead of global suppression.

6. _merge_dataframes complexity

  • File: /sandbox/GitHub/timetracker-utils/timetracker_utils/database.py, lines 314–381 (~68 lines)
  • Suggestion: Extract inner loop into a helper like _process_incoming_row.

7. model_config as plain dict vs. ConfigDict

  • Suggestion: Use from pydantic import ConfigDict and model_config = ConfigDict(...) for better IDE support.

8. CLI add command format branching

  • File: /sandbox/GitHub/timetracker-utils/timetracker_utils/cli.py, lines 79–107
  • Suggestion: Use a format-to-class mapping dict instead of duplicated branches.

9. _seconds_to_hhmm cross-module import

  • Defined in csv_formatters.py, used by report.py and cli.py.
  • Suggestion: Move to datetime_utils.py as a general utility.

10. _compute_hours / _compute_simple_duration overlap

  • File: csv_formatters.py lines 51–75 and 221–247 share datetime parsing.

📝 Nitpicks

  • cli.py lines 60–61: _ = TimeCop / _ = SimpleTimeTracker — use # noqa: F401 on imports instead.
  • pyproject.toml line 15: Remove trailing # Added development artifact.

Test Results Summary

Suite Tests Status
test_base_tracker.py 39 ✅ Passed
test_cli.py 76 ✅ Passed
test_config.py 11 ✅ Passed
test_database.py 49 ✅ Passed
test_datetime_utils.py 35 ✅ Passed
test_simple_time_tracker.py 46 ✅ Passed
test_time_cop.py 25 ✅ Passed
Total 281 ✅ All passed

Quality Gate Checks

Check Result
uv run pytest (281 tests) ✅ Passed, 96.7% coverage
uv run ruff check . ✅ All checks passed
uv run mypy . ⚠️ 1 error in test_cli.py:1262

Conclusion

This is a well-engineered feature branch. The report generation system is cleanly designed, CSV export formatters are comprehensive, and test coverage is excellent. The code maintains the high quality bar set by the existing codebase.

Recommended actions before merging:

  1. (Low effort) Fix the mypy error in test_cli.py:1262
  2. (Low effort) Remove the # Added comment from pyproject.toml line 15
  3. (Medium effort) Consider adding coverage for report.py to meet the 95% threshold

None of these are blocking — the branch is in good shape for merge.

@AlexAndrewsAI AlexAndrewsAI self-assigned this Jun 25, 2026
@AlexAndrewsAI AlexAndrewsAI added the enhancement New feature or request label Jun 25, 2026
@AlexAndrewsAI
AlexAndrewsAI merged commit f8db9b1 into main Jul 5, 2026
1 check passed
@AlexAndrewsAI
AlexAndrewsAI deleted the feature/daily-report branch July 5, 2026 18:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant