Report Data Models
Data structures for generating time tracking reports. For rendering, see 307-svg-renderer.
Architecture
ReportData.build() --> SVGReportRenderer --> WebKitReportService
| | |
Filters & Pure SVG PDF/PNG via
aggregates string WKWebView See also: 307-svg-renderer, 310-webkit-service
ReportData
Complete data structure for generating a report.
struct ReportData: Codable, Sendable {
let title: String
let dateRange: String
let totalHours: Double
let dayItems: [ReportDayItem] // For stacked bar chart
let commentItems: [ReportCommentItem] // Comments with images
let chartData: [ReportChartItem] // Legacy tag-based chart
let records: [ReportRecordItem] // All filtered records
} ReportDayItem
A day’s data for the stacked bar chart.
struct ReportDayItem: Codable, Sendable {
let date: Date
let totalHours: Double
let tagSegments: [ReportDayTagSegment]
} ReportDayTagSegment
A tag segment within a day’s bar.
struct ReportDayTagSegment: Codable, Sendable {
let tagName: String? // nil for untagged
let tagColor: String? // hex color
let hours: Double
} ReportCommentItem
A record’s comment for the 309-comments-section.
struct ReportCommentItem: Codable, Sendable {
let recordId: UUID
let date: Date
let tagName: String?
let tagColor: String?
let comment: String
let imageFilenames: [String]
} ReportOptions
Configuration for report generation.
struct ReportOptions: Sendable {
var dateRange: ClosedRange<Date>
var tagIds: Set<UUID>? // nil = all tags
var includeUntagged: Bool // default: true
var title: String // default: "Time Report"
} ReportData.build()
Static factory method to create ReportData from raw records.
static func build(
from records: [TimeRecord],
tags: [Tag],
options: ReportOptions
) -> ReportData Filtering Logic
- Date Range: Records where
startTimeis within range - Tag Filter: If
tagIdsset, only matching records - Untagged: Excluded if
includeUntaggedis false
Day Items
Groups records by calendar day AND tag:
- Segments sorted by hours descending
- Days sorted by date ascending
- Untagged uses gray (#888888)
Comment Items
Filters records with content:
- Non-empty comment OR attached images
- Sorted by date descending (newest first)
Test Coverage
62 tests covering all models, build logic, and edge cases.
Related
- 307-svg-renderer - SVG generation
- 308-stacked-chart - Chart rendering
- 309-comments-section - Comments layout
- 310-webkit-service - PDF/PNG conversion
- 202-time-record - Source records
- 201-tag - Tag data
- 302-export - CSV export (similar filtering)