2.5 KiB
2.5 KiB
TT-003 — Domain Models (freezed)
Type: Story
Priority: High
Labels: domain, models
Depends on: TT-001
Blocks: TT-004, TT-005, TT-006, TT-007, TT-008
Summary
Define all domain-level models using freezed. These are the immutable data
classes used throughout the app's business logic and UI layer — distinct from
the Drift table companion classes.
Models to implement
Project
// lib/features/projects/domain/project.dart
@freezed
class Project with _$Project {
const factory Project({
required int id,
required String name,
required int colorValue,
String? description,
DateTime? archivedAt,
required DateTime createdAt,
}) = _Project;
factory Project.fromJson(Map<String, dynamic> json) => _$ProjectFromJson(json);
}
TimeEntry
// lib/features/entries/domain/time_entry.dart
@freezed
class TimeEntry with _$TimeEntry {
const factory TimeEntry({
required int id,
required int projectId,
required DateTime startTime,
DateTime? endTime,
int? durationSeconds,
String? note,
@Default([]) List<String> tags,
required DateTime createdAt,
}) = _TimeEntry;
factory TimeEntry.fromJson(Map<String, dynamic> json) => _$TimeEntryFromJson(json);
}
Tag
// lib/features/entries/domain/tag.dart
@freezed
class Tag with _$Tag {
const factory Tag({
required int id,
required String name,
}) = _Tag;
factory Tag.fromJson(Map<String, dynamic> json) => _$TagFromJson(json);
}
TimerState
// lib/features/timer/domain/timer_state.dart
@freezed
class TimerState with _$TimerState {
const factory TimerState.idle() = TimerIdle;
const factory TimerState.running({
required int entryId,
required DateTime startTime,
required Project project,
String? note,
}) = TimerRunning;
}
Acceptance Criteria
- All models defined with
@freezed fromJson/toJsongenerated viajson_serializabledart run build_runner buildgenerates*.freezed.dartand*.g.dartwithout errors- Models have no mutable fields
TimerStateis a union type (sealed), not a single class
Files to create
lib/features/projects/domain/project.dartlib/features/entries/domain/time_entry.dartlib/features/entries/domain/tag.dartlib/features/timer/domain/timer_state.dart
Notes
- Drift table rows ≠ domain models. Use mapper extension methods to convert between them.
- Add
extension ProjectMapper on ProjectData { Project toDomain() {...} }in the DAO files.