import 'models.dart'; import 'scheduling_engine.dart'; /// Quick actions available from a flexible task card. enum FlexibleTaskQuickAction { done, push, backlog, breakUp, } /// Explicit push destinations shown after choosing the push quick action. enum PushDestination { nextAvailableSlot, tomorrowTopOfQueue, backlog, } /// Domain result for a flexible task quick action. class FlexibleTaskActionResult { const FlexibleTaskActionResult({ required this.action, required this.task, this.pushDestinations = const [], this.startsChildTaskFlow = false, }); final FlexibleTaskQuickAction action; final Task task; final List pushDestinations; final bool startsChildTaskFlow; bool get changedTask => !startsChildTaskFlow && pushDestinations.isEmpty; } /// Applies low-friction quick actions for flexible task cards. class FlexibleTaskActionService { const FlexibleTaskActionService({ this.schedulingEngine = const SchedulingEngine(), }); final SchedulingEngine schedulingEngine; FlexibleTaskActionResult apply({ required Task task, required FlexibleTaskQuickAction action, DateTime? updatedAt, }) { if (!task.isFlexible) { throw ArgumentError.value( task.type, 'task.type', 'Task must be flexible.'); } switch (action) { case FlexibleTaskQuickAction.done: return FlexibleTaskActionResult( action: action, task: task.copyWith( status: TaskStatus.completed, updatedAt: updatedAt ?? DateTime.now(), ), ); case FlexibleTaskQuickAction.push: return FlexibleTaskActionResult( action: action, task: task, pushDestinations: const [ PushDestination.nextAvailableSlot, PushDestination.tomorrowTopOfQueue, PushDestination.backlog, ], ); case FlexibleTaskQuickAction.backlog: return FlexibleTaskActionResult( action: action, task: schedulingEngine.moveToBacklog(task, updatedAt: updatedAt), ); case FlexibleTaskQuickAction.breakUp: return FlexibleTaskActionResult( action: action, task: task, startsChildTaskFlow: true, ); } } }