TimeTrackingService

Purpose

High-level abstraction over FileStorageService providing business-logic operations for time tracking. Simplifies common workflows like starting/stopping timers and managing tags.

Protocol

public protocol TimeTrackingServiceProtocol: Sendable {
    func getAllTags() async throws -> [Tag]
    func createTag(name: String, color: String) async throws -> Tag
    func updateTag(_ tag: Tag) async throws
    func deleteTag(_ tag: Tag) async throws
    func archiveTag(_ tag: Tag) async throws
    func unarchiveTag(_ tag: Tag) async throws
    func startTimer(tagId: UUID?, comment: String?) async throws -> TimeRecord
    func stopTimer(_ record: TimeRecord) async throws -> TimeRecord
    func getRunningTimers() async throws -> [TimeRecord]
    func getRecords(from startDate: Date, to endDate: Date) async throws -> [TimeRecord]
    func getTodayRecords() async throws -> [TimeRecord]
    func updateRecord(_ record: TimeRecord) async throws
    func deleteRecord(_ record: TimeRecord) async throws
    func createManualRecord(startTime: Date, endTime: Date?, tagId: UUID?, comment: String?) async throws -> TimeRecord

    // Image operations
    func addImage(_ data: Data, to record: TimeRecord, ext: String) async throws -> TimeRecord
    func removeImage(at index: Int, from record: TimeRecord) async throws -> TimeRecord
}

Implementation

public actor TimeTrackingService: TimeTrackingServiceProtocol {
    private let storage: FileStorageService

    public init(storage: FileStorageService)
}

Uses Swift actor model for thread-safe concurrent access.

Tag Operations

MethodDescription
getAllTags()Retrieve all tags from storage
createTag(name:color:)Create new tag with name and hex color
updateTag(_:)Update existing tag properties
deleteTag(_:)Remove tag from storage
archiveTag(_:)Archive tag (hidden from selection UI)
unarchiveTag(_:)Unarchive tag (restore to active)

Timer Operations

MethodDescription
startTimer(tagId:comment:)Start new timer, returns TimeRecord with nil endTime
stopTimer(_:)Stop running timer, sets endTime to current time
getRunningTimers()Get all records with nil endTime

Record Operations

MethodDescription
getRecords(from:to:)Query records within date range
getTodayRecords()Convenience method for today’s records
updateRecord(_:)Update existing record
deleteRecord(_:)Remove record from storage
createManualRecord(startTime:endTime:tagId:comment:)Create record with explicit times

Image Operations

MethodDescription
addImage(_:to:ext:)Add image to record, returns updated record with new filename
removeImage(at:from:)Remove image at index from record

Images are stored via FileStorageService and referenced by filename in TimeRecord.images array.

Related

Models

Services

UI

Testing

  • MockTimeTrackingService for unit tests